summaryrefslogtreecommitdiff
path: root/web/spiderweb
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /web/spiderweb
Initial commit
Diffstat (limited to 'web/spiderweb')
-rw-r--r--web/spiderweb/COPYRIGHT11
-rw-r--r--web/spiderweb/README102
-rw-r--r--web/spiderweb/bug-reports1973
-rw-r--r--web/spiderweb/doc/Makefile3
-rw-r--r--web/spiderweb/doc/abstracts.tex23
-rw-r--r--web/spiderweb/doc/cacm.aux16
-rw-r--r--web/spiderweb/doc/cacm.tex602
-rw-r--r--web/spiderweb/doc/overview.aux12
-rw-r--r--web/spiderweb/doc/overview.tex149
-rw-r--r--web/spiderweb/doc/spdjman.tex2065
-rw-r--r--web/spiderweb/doc/spe.aux70
-rw-r--r--web/spiderweb/doc/spe.bbl186
-rw-r--r--web/spiderweb/doc/spe.tex545
-rw-r--r--web/spiderweb/doc/spiderman.aux56
-rw-r--r--web/spiderweb/doc/spiderman.tex1693
-rw-r--r--web/spiderweb/doc/spiderwebman.tex2268
-rw-r--r--web/spiderweb/doc/spiderwebman.toc1
-rw-r--r--web/spiderweb/fixes-to-be-applied/changes641
-rw-r--r--web/spiderweb/fixes-to-be-applied/dnn.web125
-rw-r--r--web/spiderweb/fixes-to-be-applied/fixes139
-rw-r--r--web/spiderweb/fixes-to-be-applied/latex/README66
-rw-r--r--web/spiderweb/fixes-to-be-applied/latex/WebMakefile172
-rw-r--r--web/spiderweb/fixes-to-be-applied/latex/awkmake5
-rw-r--r--web/spiderweb/fixes-to-be-applied/latex/cmake5
-rw-r--r--web/spiderweb/fixes-to-be-applied/latex/cspider.dif17
-rw-r--r--web/spiderweb/fixes-to-be-applied/latex/latexweb.tex81
-rw-r--r--web/spiderweb/fixes-to-be-applied/latex/spider.ltx107
-rw-r--r--web/spiderweb/fixes-to-be-applied/latex/tangle.ltx79
-rw-r--r--web/spiderweb/fixes-to-be-applied/latex/tie.web1276
-rw-r--r--web/spiderweb/fixes-to-be-applied/latex/tiedoc.tex138
-rw-r--r--web/spiderweb/fixes-to-be-applied/latex/weave.ltx700
-rw-r--r--web/spiderweb/fixes-to-be-applied/latex/web.doc945
-rw-r--r--web/spiderweb/fixes-to-be-applied/latex/web.sty271
-rw-r--r--web/spiderweb/mac/MPW_SpiderWEB_21Mar93.sit.bin1796
-rw-r--r--web/spiderweb/ms-dos/whereis325
-rw-r--r--web/spiderweb/os2/os2.changes688
-rw-r--r--web/spiderweb/patches/00132
-rw-r--r--web/spiderweb/patches/00295
-rw-r--r--web/spiderweb/patches/003179
-rw-r--r--web/spiderweb/patches/00470
-rw-r--r--web/spiderweb/patches/00574
-rw-r--r--web/spiderweb/patches/00692
-rw-r--r--web/spiderweb/patches/007188
-rw-r--r--web/spiderweb/patches/00829
-rw-r--r--web/spiderweb/patches/00944
-rw-r--r--web/spiderweb/patches/01036
-rw-r--r--web/spiderweb/src/68k/68k.spider569
-rw-r--r--web/spiderweb/src/68k/make3
-rw-r--r--web/spiderweb/src/BUGS84
-rw-r--r--web/spiderweb/src/COPYRIGHT11
-rw-r--r--web/spiderweb/src/Makefile44
-rw-r--r--web/spiderweb/src/README104
-rw-r--r--web/spiderweb/src/README.DOS56
-rw-r--r--web/spiderweb/src/ada/ada.spider278
-rw-r--r--web/spiderweb/src/ada/make3
-rw-r--r--web/spiderweb/src/ada/new.spider315
-rw-r--r--web/spiderweb/src/ada/old.spider261
-rw-r--r--web/spiderweb/src/ada/stacks.web443
-rw-r--r--web/spiderweb/src/awk/awk.spider168
-rw-r--r--web/spiderweb/src/awk/make2
-rw-r--r--web/spiderweb/src/awk/tangle.c2172
-rw-r--r--web/spiderweb/src/big-web.ch59
-rw-r--r--web/spiderweb/src/c++/c++.spider368
-rw-r--r--web/spiderweb/src/c++/make3
-rw-r--r--web/spiderweb/src/c/c.spider350
-rw-r--r--web/spiderweb/src/c/local.guide4
-rw-r--r--web/spiderweb/src/c/make3
-rw-r--r--web/spiderweb/src/c/new.spider407
-rw-r--r--web/spiderweb/src/c/tangle.c2214
-rw-r--r--web/spiderweb/src/concrete-kernel.diff200
-rw-r--r--web/spiderweb/src/dijkstra/README3
-rw-r--r--web/spiderweb/src/dijkstra/binary.web267
-rw-r--r--web/spiderweb/src/dijkstra/d.spider155
-rw-r--r--web/spiderweb/src/dijkstra/make2
-rw-r--r--web/spiderweb/src/dijkstra/sp.web28
-rw-r--r--web/spiderweb/src/kelem/ac.spider496
-rw-r--r--web/spiderweb/src/kelem/ac_guide.web292
-rw-r--r--web/spiderweb/src/kelem/indent-troubles40
-rw-r--r--web/spiderweb/src/kelem/make2
-rw-r--r--web/spiderweb/src/kelem/test.web19
-rw-r--r--web/spiderweb/src/larch/l.spider245
-rw-r--r--web/spiderweb/src/larch/lists.web56
-rw-r--r--web/spiderweb/src/larch/make2
-rw-r--r--web/spiderweb/src/master/Make.pretty18
-rw-r--r--web/spiderweb/src/master/Makefile18
-rw-r--r--web/spiderweb/src/master/WebMakefile146
-rw-r--r--web/spiderweb/src/master/common.c1001
-rw-r--r--web/spiderweb/src/master/common.h146
-rw-r--r--web/spiderweb/src/master/common.web1198
-rw-r--r--web/spiderweb/src/master/cycle.awk86
-rw-r--r--web/spiderweb/src/master/cycle.web81
-rw-r--r--web/spiderweb/src/master/junk.list22
-rw-r--r--web/spiderweb/src/master/multitang.ch107
-rw-r--r--web/spiderweb/src/master/newdefs.awk11
-rw-r--r--web/spiderweb/src/master/nodups.awk13
-rw-r--r--web/spiderweb/src/master/pathopen.c122
-rw-r--r--web/spiderweb/src/master/pathopen.h9
-rw-r--r--web/spiderweb/src/master/pathopen.web192
-rw-r--r--web/spiderweb/src/master/pretty.awk2
-rw-r--r--web/spiderweb/src/master/spider.awk4799
-rw-r--r--web/spiderweb/src/master/spider.web2580
-rw-r--r--web/spiderweb/src/master/tangle.web1800
-rw-r--r--web/spiderweb/src/master/transcheck.awk23
-rw-r--r--web/spiderweb/src/master/transcheck.list14
-rw-r--r--web/spiderweb/src/master/weave.web3250
-rw-r--r--web/spiderweb/src/master/webhead2
-rw-r--r--web/spiderweb/src/master/webtail1
-rw-r--r--web/spiderweb/src/nawk/make2
-rw-r--r--web/spiderweb/src/nawk/nawk.spider176
-rw-r--r--web/spiderweb/src/penelope/SpiderMakefile9
-rw-r--r--web/spiderweb/src/penelope/a.spider375
-rw-r--r--web/spiderweb/src/penelope/make5
-rw-r--r--web/spiderweb/src/penelope/nesting.spider21
-rw-r--r--web/spiderweb/src/penelope/processed-a.spider418
-rw-r--r--web/spiderweb/src/penelope/scan_annotations.awk81
-rw-r--r--web/spiderweb/src/penelope/stacks.web445
-rw-r--r--web/spiderweb/src/postscript/README10
-rw-r--r--web/spiderweb/src/postscript/WebMakefile.new147
-rw-r--r--web/spiderweb/src/postscript/local.guide72
-rw-r--r--web/spiderweb/src/postscript/make5
-rw-r--r--web/spiderweb/src/postscript/outline.ps1212
-rw-r--r--web/spiderweb/src/postscript/outline.web162
-rw-r--r--web/spiderweb/src/postscript/ps.spider77
-rw-r--r--web/spiderweb/src/reduce/INSTALL26
-rw-r--r--web/spiderweb/src/reduce/Makefile152
-rw-r--r--web/spiderweb/src/reduce/README69
-rw-r--r--web/spiderweb/src/reduce/make3
-rw-r--r--web/spiderweb/src/reduce/reduce.spider283
-rw-r--r--web/spiderweb/src/reduce/rtangle10
-rw-r--r--web/spiderweb/src/reduce/rtangle.ch135
-rw-r--r--web/spiderweb/src/reduce/rweave.ch149
-rw-r--r--web/spiderweb/src/reduce/underscore.web32
-rw-r--r--web/spiderweb/src/sml/leavens.mail548
-rw-r--r--web/spiderweb/src/sml/make3
-rw-r--r--web/spiderweb/src/sml/mason.mail1031
-rw-r--r--web/spiderweb/src/ssl/make2
-rw-r--r--web/spiderweb/src/ssl/s.spider220
-rw-r--r--web/spiderweb/src/turing+/example.mail195
-rw-r--r--web/spiderweb/src/turing+/make3
-rw-r--r--web/spiderweb/src/turing+/turing+.spider527
-rw-r--r--web/spiderweb/src/turing/make3
-rw-r--r--web/spiderweb/src/turing/turing.spider624
-rw-r--r--web/spiderweb/src/webkernel.tex383
-rw-r--r--web/spiderweb/todo16
-rw-r--r--web/spiderweb/tools/Makefile42
-rw-r--r--web/spiderweb/tools/depend.web128
-rw-r--r--web/spiderweb/tools/excerpt/excerpt54
-rw-r--r--web/spiderweb/tools/excerpt/excerpt.doc31
-rw-r--r--web/spiderweb/tools/excerpt/filesplit.web163
-rw-r--r--web/spiderweb/tools/excerpt/section.c70
-rw-r--r--web/spiderweb/tools/shortindex3
-rw-r--r--web/spiderweb/tools/tie/@read@.me29
-rw-r--r--web/spiderweb/tools/tie/Makefile13
-rw-r--r--web/spiderweb/tools/tie/cf114
-rw-r--r--web/spiderweb/tools/tie/cf219
-rw-r--r--web/spiderweb/tools/tie/cf35
-rw-r--r--web/spiderweb/tools/tie/character.web148
-rw-r--r--web/spiderweb/tools/tie/datadecl.web74
-rw-r--r--web/spiderweb/tools/tie/error.web56
-rw-r--r--web/spiderweb/tools/tie/history.web25
-rw-r--r--web/spiderweb/tools/tie/io.web108
-rw-r--r--web/spiderweb/tools/tie/master10
-rw-r--r--web/spiderweb/tools/tie/newmaster9
-rw-r--r--web/spiderweb/tools/tie/tie.c696
-rw-r--r--web/spiderweb/tools/tie/tie.chf191
-rw-r--r--web/spiderweb/tools/tie/tie.preamble31
-rw-r--r--web/spiderweb/tools/tie/tie.web558
-rw-r--r--web/spiderweb/tools/tie/tie.web,v576
-rw-r--r--web/spiderweb/tools/tie/tie.web.dist1336
-rw-r--r--web/spiderweb/tools/tie/tiedoc.tex149
170 files changed, 54728 insertions, 0 deletions
diff --git a/web/spiderweb/COPYRIGHT b/web/spiderweb/COPYRIGHT
new file mode 100644
index 0000000000..193fdea8b4
--- /dev/null
+++ b/web/spiderweb/COPYRIGHT
@@ -0,0 +1,11 @@
+Spider and Spidery WEB are copyright 1989-1992 by Norman Ramsey,
+Odyssey Research Associates (ORA Corp), 301A Dates Drive, Ithaca, New
+York 14850.
+
+You may use and distribute Spider and Spidery WEB for any purpose, for
+free. You may modify Spider and Spidery WEB and create derived works,
+provided you retain the copyright notice, but the result may not be
+called Spider or Spidery WEB without written permission from ORA Corp.
+You may not sell Spider or Spidery WEB themselves, but you may do
+anything you like with programs created with Spider and Spidery WEB.
+
diff --git a/web/spiderweb/README b/web/spiderweb/README
new file mode 100644
index 0000000000..c615d5adb3
--- /dev/null
+++ b/web/spiderweb/README
@@ -0,0 +1,102 @@
+This is Spidery WEB, tool for building a WEB system for the language
+of your choice. It was probably gotten by anonymous ftp from the
+Comprehensive TeX Archive Network, possibly from niord.shsu.edu. My
+colleagues and I have used Spider to build WEB systems for Ada, C,
+AWK, and other languages. Spidery WEB is no longer supported; the
+lessons learned in its implementation and use have been applied to the
+design of `noweb', a much simpler literate-programming tool. noweb is
+available by anonymous ftp from csservices.princeton.edu:pub/noweb.shar.Z.
+ORA Corp makes some effort to keep Spidery WEB working; bug reports,
+fixes, and new language descriptions can be sent to spider-bugs@oracorp.com.
+The rest of this file contains a brief description of Spidery WEB and
+this distribution; more extensive documentation can be found in the
+doc subdirectory.
+
+INTRODUCTION
+
+Spider reads a description of a programming language, and writes
+source code for a Weave and Tangle which support that language. The
+language-dependent parts are derived from the description given
+Spider, and the language-independent parts are taken from ``master
+copies'' of Weave and Tangle. The master copies are derived from
+Silvio Levy's CWEB, and the Tangle and Weave that are constructed are
+implemented in C. Spider is implemented as an Awk program.
+
+An exhaustive list of Spidery Web's features would interest only Web
+experts, but I do want to mention some features that I hope will
+encourage people to use Spidery {\tt WEB}.
+
+ Tangle and Weave can read from multiple files (this feature is
+ present in Levy's CWEB), and Tangle can write to multiple files.
+ Included files will be searched for on a path if not found in the
+ current directory. These features make Spidery WEB more
+ usable on systems that have make.
+
+ TANGLE can expand macros with multiple parameters.
+
+ TANGLE writes #line directives, so you can debug at the WEB
+ source level if your compiler respects the C~conventions for #line.
+
+
+Many features of WEB seem to exist only to compensate for deficiencies
+in PASCAL, and most of those were dropped in CWEB. I have changed
+much of CWEB in order to avoid being bound too much by C conventions.
+As a result, there are dozens of minor differences between Spidery WEB
+and original WEB. To give just one example, Spidery WEB supports
+octal and hexadecimal constants using WEB-style notation, not the C
+notation used in CWEB.
+
+Spider can generate WEB systems for a variety of languages. The
+author has written Spider description files for C, AWK, Ada, SSL (a
+language that describes attribute grammars to the Cornell Synthesizer
+Generator), the Larch Shared Language (a language for describing
+equational theories), and Dijkstra's language of guarded commands.
+Debugging the grammar that WEAVE uses to prettyprint the language is
+the most time-consuming part of creating a WEB system for a new target
+language, and Spider makes it trivial to change that grammar. To make
+a Spider description file for an Algol-like language that uses infix
+expression notation, an experienced systems programmer should be able
+to adapt an existing Spider description file very quickly.
+
+Spider's major limitations are lexical. All Spidery WEBs assume that
+spaces and tabs in the input are not significant, except as
+separators; this makes it impossible to construct Spidery WEBs for
+languages like Fortran and Miranda, where the position of text on a
+line is significant. (You would have to modify the ``master copies''
+of Tangle and Weave to change the lexical analyzer.) The lexical
+structures of identifiers, string literals, and numeric literals are
+fixed.
+
+Spider's major value is that is makes it possible to create a new WEB
+quickly, and to tinker with it easily. My colleagues and I have used
+Spidery WEB to write programs in Ada, C, and SSL, and has been pleased
+with the result. We have written in WEB an application of 24 thousand
+lines, and we are very pleased at how easy it has been to review and
+maintain this code. I hope that the availability of Spidery WEB will
+encourage other groups to try literate programming, and that they,
+too, will be pleased with the results.
+
+
+WHAT YOU GET
+
+Although Spider is complete and useful, this distribution contains bug
+fixes and enhancements that I have not folded into the code.
+I have tested this system only under Unix, but other users have
+provided Macintosh, MS-DOS, and OS/2 implementations.
+
+This directory contains:
+
+ bug-reports reports of bugs that may or may not have been fixed
+ doc manuals and articles about Spider
+ fixes-to-be-applied bug fixes and enhancements
+ mac Macintosh binaries
+ ms-dos MS-DOS binaries
+ os2 OS/2 source-code changes
+ patches patches for old versions of Spider (now useless)
+ src Spider source code & instructions for building Spider
+ todo a wish list
+ tools auxiliary tools that might be useful with Spidery WEB
+
+Send comments or bug reports to spider-bugs@oracorp.com
+
+Norman Ramsey
diff --git a/web/spiderweb/bug-reports b/web/spiderweb/bug-reports
new file mode 100644
index 0000000000..2f0537b5a6
--- /dev/null
+++ b/web/spiderweb/bug-reports
@@ -0,0 +1,1973 @@
+From chase@orc.olivetti.com Thu Apr 6 16:11:45 1989
+Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA24139; Thu, 6 Apr 89 16:11:43 EDT
+Received: from NET.BIO.NET by Princeton.EDU (5.58+++/2.6)
+ id AA12881; Thu, 6 Apr 89 16:11:18 EDT
+Received: from orc.olivetti.com by net.bio.net (5.59/1.15) with UUCP
+ id AA09769; Thu, 6 Apr 89 13:10:52 PDT
+Received: from ozona.orc.olivetti.com by orc.olivetti.com (3.2/SMI-3.2)
+ id AA14880; Thu, 6 Apr 89 12:31:15 PDT
+Received: by ozona.orc.olivetti.com (3.2/SMI-3.2)
+ id AA06589; Thu, 6 Apr 89 12:40:52 PDT
+From: chase@orc.olivetti.com (David Chase)
+Message-Id: <8904061940.AA06589@ozona.orc.olivetti.com>
+To: nr@Princeton.EDU
+Subject: "cputype?"
+Reply-To: David Chase <chase@orc.olivetti.com>
+Date: Thu, 06 Apr 89 12:40:50 -0700
+Status: RO
+
+is not a command on my Unix machine (a Sun).
+
+David
+
+From chase@orc.olivetti.com Thu Apr 6 16:11:56 1989
+Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA24169; Thu, 6 Apr 89 16:11:53 EDT
+Received: from NET.BIO.NET by Princeton.EDU (5.58+++/2.6)
+ id AA12880; Thu, 6 Apr 89 16:11:17 EDT
+Received: from orc.olivetti.com by net.bio.net (5.59/1.15) with UUCP
+ id AA09765; Thu, 6 Apr 89 13:10:50 PDT
+Received: from ozona.orc.olivetti.com by orc.olivetti.com (3.2/SMI-3.2)
+ id AA14856; Thu, 6 Apr 89 12:27:42 PDT
+Received: by ozona.orc.olivetti.com (3.2/SMI-3.2)
+ id AA06558; Thu, 6 Apr 89 12:37:19 PDT
+From: chase@orc.olivetti.com (David Chase)
+Message-Id: <8904061937.AA06558@ozona.orc.olivetti.com>
+To: nr@Princeton.EDU
+Subject: Spideryweb bug report
+Reply-To: David Chase <chase@orc.olivetti.com>
+Date: Thu, 06 Apr 89 12:37:15 -0700
+Status: RO
+
+An installation problem: People who care about Trojan horses
+don't put "." at the beginning of their path, so shell scripts
+invoked as "make" never get executed. Try "./make" instead.
+I realize that "." at front is the Unix default, but it is an
+exceptionally stupid one (put a benign Trojan horse named "ls"
+in a few world-writeable directories on a time-shared Unix machine,
+and see what happens). I don't know why this isn't more widely
+worried about.
+
+David
+
+From chase@orc.olivetti.com Thu Apr 6 16:12:03 1989
+Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA24179; Thu, 6 Apr 89 16:12:01 EDT
+Received: from NET.BIO.NET by Princeton.EDU (5.58+++/2.6)
+ id AA12883; Thu, 6 Apr 89 16:11:24 EDT
+Received: from orc.olivetti.com by net.bio.net (5.59/1.15) with UUCP
+ id AA09777; Thu, 6 Apr 89 13:10:58 PDT
+Received: from ozona.orc.olivetti.com by orc.olivetti.com (3.2/SMI-3.2)
+ id AA14962; Thu, 6 Apr 89 12:44:22 PDT
+Received: by ozona.orc.olivetti.com (3.2/SMI-3.2)
+ id AA06693; Thu, 6 Apr 89 12:53:57 PDT
+From: chase@orc.olivetti.com (David Chase)
+Message-Id: <8904061953.AA06693@ozona.orc.olivetti.com>
+To: nr@Princeton.EDU
+Subject: That cute trick with '#' in variable definitions
+Reply-To: David Chase <chase@orc.olivetti.com>
+Date: Thu, 06 Apr 89 12:53:54 -0700
+Status: RO
+
+was unknown to me. I broke things badly "cleaning up" the
+definition of the three directories. I think you ought
+to either change the formatting, or mention that there is
+a reason for the '#' immediately following the definitions
+(it's not like I'm a novice at this, either)
+
+David
+
+From chase@orc.olivetti.com Thu Apr 6 16:12:13 1989
+Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA24188; Thu, 6 Apr 89 16:12:10 EDT
+Received: from NET.BIO.NET by Princeton.EDU (5.58+++/2.6)
+ id AA12886; Thu, 6 Apr 89 16:11:27 EDT
+Received: from orc.olivetti.com by net.bio.net (5.59/1.15) with UUCP
+ id AA09786; Thu, 6 Apr 89 13:11:04 PDT
+Received: from ozona.orc.olivetti.com by orc.olivetti.com (3.2/SMI-3.2)
+ id AA15001; Thu, 6 Apr 89 13:02:35 PDT
+Received: by ozona.orc.olivetti.com (3.2/SMI-3.2)
+ id AA06741; Thu, 6 Apr 89 13:12:11 PDT
+From: chase@orc.olivetti.com (David Chase)
+Message-Id: <8904062012.AA06741@ozona.orc.olivetti.com>
+To: nr@Princeton.EDU
+Subject: So far, so good
+Reply-To: David Chase <chase@orc.olivetti.com>
+Date: Thu, 06 Apr 89 13:12:08 -0700
+Status: RO
+
+It made it past "make boot", and I'm fixing to look at
+the documentation. My intention is to see if this can
+easily be made to generate Modula-3 -- if so, (I think)
+I can use it to generate test input for the Modula-3
+compiler. Of course, any such test input is unlikely to
+be incredibly sophisticated, since it will be machine-
+generated, but it's better than none at all.
+
+David
+
+From nr Thu Apr 6 20:12:03 1989
+Received: by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA05087; Thu, 6 Apr 89 20:11:36 EDT
+Date: Thu, 6 Apr 89 20:11:36 EDT
+From: nr (Norman Ramsey)
+Message-Id: <8904070011.AA05087@notecnirp.Princeton.EDU>
+To: chase@orc.olivetti.com
+Subject: Re: "cputype?"
+Cc: nr
+Status: RO
+
+> Subject: "cputype?"
+> is not a command on my Unix machine (a Sun).
+>
+> David
+
+I have added instructions to README and to WebMakefile that deal with
+cputype. As far as I know, it is a local idiosyncracy, and my
+documentation predates it. Thank you for calling it to my attention.
+
+It looks like you've already figured it out, but a shell script
+containing the line `echo sun3' will do fine if it is somewhere on
+your search path.
+
+> An installation problem: People who care about Trojan horses
+> don't put "." at the beginning of their path, so shell scripts
+> invoked as "make" never get executed. Try "./make" instead.
+
+I don't see a clean way to fix this. Are any files affected besides
+WEBROOT/Makefile? The problem is that some of the calls to $(MAKE)
+are calls to shell scripts in subdirectories, while others are calls
+to /bin/make in the current directory. What have you done to improve
+things?
+
+> I realize that "." at front is the Unix default, but it is an
+> exceptionally stupid one (put a benign Trojan horse named "ls"
+> in a few world-writeable directories on a time-shared Unix machine,
+> and see what happens). I don't know why this isn't more widely
+> worried about.
+
+I think this isn't worried about because most people assume the world
+is benign until they are bitten once or twice. Some of my colleagues
+swear by never putting . on their path at all. Me, I haven't been
+bitten yet.
+> Subject: That cute trick with '#' in variable definitions
+> was unknown to me. I broke things badly "cleaning up" the
+> definition of the three directories. I think you ought
+> to either change the formatting, or mention that there is
+> a reason for the '#' immediately following the definitions
+> (it's not like I'm a novice at this, either)
+
+I put a comment in. When I first prepared this for distribution, I
+broke things badly by commenting those (previously uncommented) macro
+definitions.
+
+> It made it past "make boot", and I'm fixing to look at
+> the documentation. My intention is to see if this can
+> easily be made to generate Modula-3 -- if so, (I think)
+> I can use it to generate test input for the Modula-3
+> compiler. Of course, any such test input is unlikely to
+> be incredibly sophisticated, since it will be machine-
+> generated, but it's better than none at all.
+
+Generating Modula-3 from a Modula-3 literate program should be no
+trouble at all. One the other hand, if you want to translate
+something else into Modula-3, you are probably better off using
+WEB-to-C as a basis. Let me know how it goes; I would love to have a
+Modula-3 spider file to add to the distribution.
+
+Norman
+
+
+From Chris.Paris@vega.fac.cs.cmu.edu Mon Jan 23 20:52:57 1989
+Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.68)
+ id AA03118; Mon, 23 Jan 89 20:52:56 EST
+Received: from VEGA.FAC.CS.CMU.EDU by Princeton.EDU (5.58+++/1.98)
+ id AA27627; Mon, 23 Jan 89 20:52:44 EST
+Message-Id: <8901240152.AA27627@Princeton.EDU>
+Received: from VEGA.FAC.CS.CMU.EDU by VEGA.FAC.CS.CMU.EDU; 23 Jan 89 20:51:40 EST
+To: nr@Princeton.EDU
+Reply-To: cap@cs.cmu.edu (Chris Paris)
+Subject: webkernel
+Date: Mon, 23 Jan 89 20:51:36 EST
+From: Chris.Paris@VEGA.FAC.CS.CMU.EDU
+Status: RO
+
+I would be more than happy to help beta test Spider. I think it is a
+wonderful idea that seems very well implimented. I installed the
+webkernel you sent me (thanks), and it fixed most problems I was
+having. However, when ceeweave->TeX comes across something like,
+
+ @u
+ #include <stdio.h>
+ #include <fcntl.h>
+ #include "myinclude.h"
+
+ main()
+
+things happen that I wouldn't expect. First, the filenames in angle
+brackets get set in italics without the brackets. I wouldn't expect
+this because it looks like c.spider has code to recognize and put in
+brackets. "myinclude.h" is set in \tt with the quotes, which is what
+I would expect.
+
+Second, if the first line of code is a preprocessor directive, it is
+indented, so that it lines up with main(). Subsequent directives are
+against the left margin.
+
+I don't want to call these bugs since I don't know if what I'm seeing
+is what you intended or not. I am testing this on a Sun 3/60 running
+Mach (4.3 BSD superset), using TeX 2.9 (generated by web2c). I can
+also test on Vaxen and IBM RT's, but have not done so yet. I'm
+willing to help out with this any way I can as long as I don't get too
+sidetracked from my regular work. Thanks for your help.
+
+/cap
+
+From nr Tue Jan 24 12:41:32 1989
+Received: by notecnirp.Princeton.EDU (5.51/1.68)
+ id AA24196; Tue, 24 Jan 89 12:41:30 EST
+Date: Tue, 24 Jan 89 12:41:30 EST
+From: nr (Norman Ramsey)
+Message-Id: <8901241741.AA24196@notecnirp.Princeton.EDU>
+To: cap.cs.cmu.edu
+Subject: Bugs
+Cc: nr
+Status: RO
+
+> I would be more than happy to help beta test Spider. I think it is a
+> wonderful idea that seems very well implimented.
+
+I'm glad you think so. I myself have some dissatisfactions with the
+implementation, especially with the webkernel macros. I hope to have
+time to work them out this summer.
+
+> I installed the
+> webkernel you sent me (thanks), and it fixed most problems I was
+> having. However, when ceeweave->TeX comes across something like,
+>
+> @u
+> #include <stdio.h>
+> #include <fcntl.h>
+> #include "myinclude.h"
+>
+> main()
+>
+> things happen that I wouldn't expect. First, the filenames in angle
+> brackets get set in italics without the brackets. I wouldn't expect
+> this because it looks like c.spider has code to recognize and put in
+> brackets. "myinclude.h" is set in \tt with the quotes, which is what
+> I would expect.
+
+You found a bug in c.spider, which I have fixed. Generally, the way
+to detect such a bug is to put an @2 in a very small test program, and
+then look at the resulting diagnostic output. The numbers are numbers
+of productions (from productions.list). Anyway I changed the
+following production so that it wouldn't swallow the angle brackets::
+
+ preproc !(less|lesssimp|backslash|newline) --> preproc
+
+
+> Second, if the first line of code is a preprocessor directive, it is
+> indented, so that it lines up with main(). Subsequent directives are
+> against the left margin.
+
+A bug in Knuth's unfathomable macros. I have hacked webkernel and
+just hope I haven't broken anything else.
+
+> I don't want to call these bugs since I don't know if what I'm seeing
+> is what you intended or not.
+
+Not. I think my only nonstandard prettyprinting is of (old-style)
+parameter declarations.
+
+> I am testing this on a Sun 3/60 running
+> Mach (4.3 BSD superset), using TeX 2.9 (generated by web2c). I can
+> also test on Vaxen and IBM RT's, but have not done so yet.
+
+You will have trouble using the makefiles on other machines---I
+unknowingly used some features specific to Sun make (the @#$(&% man
+page didn't say `warning, not portable'), so things like `make boot'
+and `make distribution' may not work right. But `make weave' and
+`make tangle' work fine on a VAX running BSD4.3.
+
+> I'm
+> willing to help out with this any way I can as long as I don't get too
+> sidetracked from my regular work. Thanks for your help.
+
+I'm looking for a guinea pig to try to write a Spider file for ANSI C.
+Be aware that C is by far the most complicated language to prettyprint
+(of the ones in the distribution).
+
+Norman
+
+From crm@summanulla.mc.duke.edu Fri Apr 7 21:29:18 1989
+Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA14862; Fri, 7 Apr 89 21:29:16 EDT
+Received: from duke.cs.duke.edu by Princeton.EDU (5.58+++/2.6)
+ id AA02957; Fri, 7 Apr 89 21:29:01 EDT
+Received: from summanulla.mc.duke.edu by duke.cs.duke.edu (5.59/DUKE/08-19-88)
+ id AA01720; Fri, 7 Apr 89 21:31:47 EDT
+Received: by summanulla.mc.duke.edu (3.2/DUKE/3-1-88)
+ id AA08029; Fri, 7 Apr 89 18:22:28 EDT
+Date: Fri, 7 Apr 89 18:22:28 EDT
+From: Charles R. Martin <crm@summanulla.mc.duke.edu>
+Message-Id: <8904072222.AA08029@summanulla.mc.duke.edu>
+To: nr@Princeton.EDU
+Cc: crm@summanulla.mc.duke.edu
+Subject: Spiders, eeek!
+Status: RO
+
+I got Spider over the wires a little while ago; I'm quite excited about
+it, but I've had a little bit of trouble with the installation:
+
+(1) I set up a cputype to echo sun3; when I do this, it creates a
+subdirectory sun3 of master, and attempts to compile from there.
+unfortunately, the objects aren't there, and so the compilation fails.
+
+(2) compiling the Dijkstra version given a C compile error, with
+duplicate labels in a case statement.
+
+Sorry that I haven't gotten all the details of this, but its Friday
+afternoon.
+
+The compilation record of the dijkstra version is appended below for
+your convenience, if that's the word.
+
+echo "date" `date` | cat - d.spider | awk -f /usr/nbsr/crm/Spider/master/spider.awk
+Warning: numeric constants and strings are identified in this WEAVE.
+Warning: TeX strings have the same category as numeric constants in this WEAVE.
+You used 3 translation keywords.
+You defined 18 reserved words of 12 ilks.
+You used 15 different categories in 14 productions.
+The biggest production had 3 scraps on its left-hand side.
+cat /usr/nbsr/crm/Spider/master/transcheck.list trans_keys.unsorted | awk -f /usr/nbsr/crm/Spider/master/transcheck.awk
+awk -f /usr/nbsr/crm/Spider/master/cycle.awk < cycle.test
+There can't possibly be a cycle in the graph
+sort *.unsorted | awk -f /usr/nbsr/crm/Spider/master/nodups.awk
+mv *web.tex /usr/nbsr/crm/lib/tex
+/bin/rm -f tangle.web
+ln /usr/nbsr/crm/Spider/master/tangle.web tangle.web
+ceetangle -I/usr/nbsr/crm/Spider/master tangle
+This is C TANGLE (generated at 6:13 PM on April 7, 1989)
+*1*14*21*25*34*62*64*84*92*107*131*141
+Writing the output files: (tangle.c).....500.....1000.....1500
+Done.
+(No errors were found.)
+cc -DDEBUG -g -DSTAT -c tangle.c
+"tangle.web", line 838: duplicate case in switch, 10
+*** Error code 1
+
+Stop.
+*** Error code 1
+
+From nr Sun Apr 9 22:24:29 1989
+Received: by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA04177; Sun, 9 Apr 89 22:24:06 EDT
+Date: Sun, 9 Apr 89 22:24:06 EDT
+From: nr (Norman Ramsey)
+Message-Id: <8904100224.AA04177@notecnirp.Princeton.EDU>
+To: crm@summanulla.mc.duke.edu
+Subject: Re: Spiders, eeek!
+Cc: nr
+Status: RO
+
+ From crm@summanulla.mc.duke.edu Sat Apr 8 20:31:56 1989
+ Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA10629; Sat, 8 Apr 89 20:31:53 EDT
+ Received: from duke.cs.duke.edu by Princeton.EDU (5.58+++/2.6)
+ id AA28812; Sat, 8 Apr 89 20:31:39 EDT
+ Received: from summanulla.mc.duke.edu by duke.cs.duke.edu (5.59/DUKE/08-19-88)
+ id AA17447; Sat, 8 Apr 89 20:34:46 EDT
+ Received: by summanulla.mc.duke.edu (3.2/DUKE/3-1-88)
+ id AA09036; Sat, 8 Apr 89 20:31:21 EDT
+ Date: Sat, 8 Apr 89 20:31:21 EDT
+ From: Charles R. Martin <crm@summanulla.mc.duke.edu>
+ Message-Id: <8904090031.AA09036@summanulla.mc.duke.edu>
+ To: nr@Princeton.EDU
+ In-Reply-To: <8904081713.AA03350@notecnirp.Princeton.EDU> "nr@Princeton.EDU"
+ Subject: Spiders, eeek!
+
+ Got the patches, thanks. They appear to be compiling fine, although
+ I've uncovered another minor bug in the makefile: when you make clean,
+ it mashes c/tangle.c and awk/tangle.c, which are needed for compilation.
+
+ I'll look into the dijkstra thing first of next week.
+
+ Thanks again!
+
+That is a Feature. If you've lost them you should be able to get them back
+using `make source'. (Once you've done a `make boot', of course.)
+
+Norman
+
+PS Dijkstra compiles for me now.
+
+From crm@harahan.mc.duke.edu Mon Apr 10 10:19:15 1989
+Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA15358; Mon, 10 Apr 89 10:19:13 EDT
+Received: from duke.cs.duke.edu by Princeton.EDU (5.58+++/2.6)
+ id AA10282; Mon, 10 Apr 89 10:18:38 EDT
+Received: from nbsrws9.mc.duke.edu by duke.cs.duke.edu (5.59/DUKE/08-19-88)
+ id AA24403; Mon, 10 Apr 89 10:21:33 EDT
+Received: by harahan.mc.duke.edu (3.2/DUKE/3-1-88)
+ id AA02511; Mon, 10 Apr 89 10:18:08 EDT
+Date: Mon, 10 Apr 89 10:18:08 EDT
+From: Charles R. Martin <crm@harahan.mc.duke.edu>
+Message-Id: <8904101418.AA02511@harahan.mc.duke.edu>
+To: nr@Princeton.EDU
+In-Reply-To: <8904100224.AA04177@notecnirp.Princeton.EDU> "nr@Princeton.EDU"
+Subject: Spiders, eeek!
+Status: RO
+
+ Date: Sun, 9 Apr 89 22:24:06 EDT
+ From: nr@Princeton.EDU (Norman Ramsey)
+
+ From crm@summanulla.mc.duke.edu Sat Apr 8 20:31:56 1989
+ Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA10629; Sat, 8 Apr 89 20:31:53 EDT
+ Received: from duke.cs.duke.edu by Princeton.EDU (5.58+++/2.6)
+ id AA28812; Sat, 8 Apr 89 20:31:39 EDT
+ Received: from summanulla.mc.duke.edu by duke.cs.duke.edu (5.59/DUKE/08-19-88)
+ id AA17447; Sat, 8 Apr 89 20:34:46 EDT
+ Received: by summanulla.mc.duke.edu (3.2/DUKE/3-1-88)
+ id AA09036; Sat, 8 Apr 89 20:31:21 EDT
+ Date: Sat, 8 Apr 89 20:31:21 EDT
+ From: Charles R. Martin <crm@summanulla.mc.duke.edu>
+ Message-Id: <8904090031.AA09036@summanulla.mc.duke.edu>
+ To: nr@Princeton.EDU
+ In-Reply-To: <8904081713.AA03350@notecnirp.Princeton.EDU> "nr@Princeton.EDU"
+ Subject: Spiders, eeek!
+
+ Got the patches, thanks. They appear to be compiling fine, although
+ I've uncovered another minor bug in the makefile: when you make clean,
+ it mashes c/tangle.c and awk/tangle.c, which are needed for compilation.
+
+ I'll look into the dijkstra thing first of next week.
+
+ Thanks again!
+
+ That is a Feature. If you've lost them you should be able to get them back
+ using `make source'. (Once you've done a `make boot', of course.)
+
+Uh, I think one of us doesn't understand. I do make clean then make
+boot, and get an error. I have to recover c/tangle.c and awk/tangle.c
+from the tar file to get it to work.
+
+Oh, wait -- I see. Now that I've got ceetangle, I can make source and
+get tangle.c. Okay, in that case, how about having a make veryclean
+that really cleans up everything, and have make clean make a
+re-'make-boot'-able state? It is, however, a style question rather
+than a function question at that point.
+
+ Norman
+
+ PS Dijkstra compiles for me now.
+
+Thanks, me too. I haven't had a chance to look at the results, but it
+does compile. (If I could only preview dvi files through my PC at home
+as I do through my 3/60 at work....)
+
+Thanks again,
+
+Charlie Martin (...!mcnc!duke!crm, crm@summanulla.mc.duke.edu)
+NBSR/Box 3709/Duke University Medical Center/Durham, NC 27710
+
+From chase@orc.olivetti.com Mon Apr 10 12:31:21 1989
+Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA21577; Mon, 10 Apr 89 12:31:20 EDT
+Received: from NET.BIO.NET by Princeton.EDU (5.58+++/2.6)
+ id AA14387; Mon, 10 Apr 89 12:31:02 EDT
+Received: from orc.olivetti.com by net.bio.net (5.61/1.15) with UUCP
+ id AA28032; Mon, 10 Apr 89 09:30:25 -0700
+Received: from ozona.orc.olivetti.com by orc.olivetti.com (3.2/SMI-3.2)
+ id AA02330; Mon, 10 Apr 89 09:19:46 PDT
+Received: by ozona.orc.olivetti.com (3.2/SMI-3.2)
+ id AA02170; Mon, 10 Apr 89 09:29:22 PDT
+From: chase@orc.olivetti.com (David Chase)
+Message-Id: <8904101629.AA02170@ozona.orc.olivetti.com>
+To: nr@Princeton.EDU (Norman Ramsey)
+Reply-To: David Chase <chase@orc.olivetti.com>
+Subject: Re: "cputype?"
+In-Reply-To: Your message of Thu, 06 Apr 89 20:11:36 -0400.
+ <8904070011.AA05087@notecnirp.Princeton.EDU>
+Date: Mon, 10 Apr 89 09:29:18 -0700
+Status: RO
+
+
+>> invoked as "make" never get executed. Try "./make" instead.
+
+>I don't see a clean way to fix this. Are any files affected besides
+WEBROOT/Makefile? The problem is that some of the calls to $(MAKE)
+are calls to shell scripts in subdirectories, while others are calls
+to /bin/make in the current directory. What have you done to improve
+things?
+
+It seemed to compile after I changed Makefile in the top-level
+directory to say "./make", but I just now tried a "make -n clean"
+and found a few missing things. I'd suggest that in the case where
+you want "make" to mean "/bin/make" that you just drop in a shell
+script along the lines of
+
+ /bin/make $*
+
+There's a fair chance that I'll be able to translate Pascal into
+Modula-3 with a little assistance. Another worthy project would
+be to get a dialect of Pascal output more acceptable to the
+brain-dead Pascal compilers used on Olivetti machines.
+
+David
+
+From simpson%trwarcadia.UUCP@oberon.usc.edu Mon Apr 10 14:16:57 1989
+Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA07529; Mon, 10 Apr 89 14:16:53 EDT
+Received: from OBERON.USC.EDU by Princeton.EDU (5.58+++/2.6)
+ id AA17855; Mon, 10 Apr 89 14:16:35 EDT
+Received: by oberon.usc.edu (5.59/5.5) id AA01417;
+ Mon, 10 Apr 89 11:15:42 PST
+Received: from localhost by trwarcadia.uucp (3.2/SMI-3.2)
+ id AA22106; Mon, 10 Apr 89 10:55:03 PDT
+Message-Id: <8904101755.AA22106@trwarcadia.uucp>
+To: nr@Princeton.EDU
+Subject: Figure 2 of "Building a Language-Independent WEB"
+Date: Mon, 10 Apr 89 10:55:00 -0700
+From: Scott Simpson <simpson%trwarcadia.UUCP@oberon.usc.edu>
+Status: RO
+
+I believe the line coming into xtangle.c from the right should be labeled
+CTANGLE, not CWEAVE.
+ Scott Simpson, TRW
+
+From nr Tue Apr 11 14:13:27 1989
+Received: by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA11976; Tue, 11 Apr 89 14:12:49 EDT
+Date: Tue, 11 Apr 89 14:12:49 EDT
+From: nr (Norman Ramsey)
+Message-Id: <8904111812.AA11976@notecnirp.Princeton.EDU>
+To: mackay@june.cs.washington.edu
+Subject: Re: spiderweb copyright (last time??)
+Cc: nr
+Status: RO
+
+> One last clarification. The question is bound to come up, especially
+> from the Japanese, who are very sensitive about this.
+>
+> 1. Is it within your intentions in copyrighting this that a firm
+> might develop proprietary software which in no way incorporates
+> any part of spiderweb, but simply uses spiderweb as a development
+> tool for internal documentation.
+>
+> 2. What about the proprietary publication of documented source
+> which was produced with one of the language versions of spiderweb?
+> (Again with the understanding that no part of spiderweb is included
+> in that documentation.)
+
+I personally would be happy with either of these uses of spiderweb,
+but the decision is not entirely up to me. Spiderweb was developed
+partly with government contract money, and is agreed to be released
+``for research purposes only'' (whatever that means). I will have to
+look into this and get back to you.
+
+> -------------------------------------------------------------------------
+> Now for some first impressions.
+>
+> You have already supplied the explanation of how to get around `cputype`
+> in the new version (which I picked up yesterday).
+
+Yes, this was a late-breaking compromise to deal with the heterogenous
+processor environment here at Princeton. I hate it, but it seems to
+get the job done.
+>
+> In WebMakefile, the target boot: does not move the *.o files
+> to the appropriate directory, they remain in the master directory.
+
+Someone else found that too. I have patched the Makefile and added
+some comments. I will send you patches. In the process, I broke the
+Makefile to remove some of the sources. I think I have fixed that
+now, but for about a day a bad version was on princeton.edu
+>
+> The weave output from ceetangle comes out perfectly, but the
+> weave output from weave runs into problems when it includes grammar.web
+>
+> @ Here is where we define |highestposoverall| and where we
+> check the productions.
+> @d highestposoverall = 6
+> @<Test for all of the productions@>=
+> if ((1) &&
+> (pp+1)->cat==SP_ignore_scrap) {
+> /* 1: {\tt ? ignore_scrap --> #1} */
+>
+> This goes fine until it hits the comment line
+>
+> /* 1: {\tt ? ignore_scrap --> #1} */
+> but then TeX is bothered by the _ and the #.
+>
+> What is needed is some sort of \ttverbatim after the {, and possibly an
+> \endttverbatim before the } (I seem to remember that it can be
+> difficult to get \ttverbatim to turn itself off when it drops to
+> a lower level out of {} braces, but perhaps, since you are only
+> dealing with one-line comments and there are no embedded newlines
+> to be formatted, the difficulty can be got around.)
+
+Actually a \ttverbatim kind of solution won't work, because
+\ttverbatim needs to be able to change the catcodes, and they can't be
+changed at that late date because the whole affair is an argument to
+another macro, and the characeters have already been gobbled up (or
+whatever the appropriate parts of TeX's anatomy that sets catcodes).
+I have changed spider.web so the offending characters are escaped with
+backslashes: {\tt ? ignore\_scrap --> \#1} and so on.
+
+> The tangle for C seems to run with very satisfactory speed.
+
+We have Don Knuth to thank for this. The lexer sees the code just
+once, and then converts everything to either eight or sixteen bit
+tokens. Output is very fast.
+
+I would like to speed up WEAVE some day, by making it run from a table
+(decision tree). Doing that and abandoning the internal conversion to
+ASCII would probably gain a factor of three.
+
+> Query? How does the Make variable $(SPIDER) with the equivalent
+> any.spider get changed into the appropriate *.spider. It works, but
+> I can't figure out how it works. Does "any" have some esoteric meaning
+> to make?
+
+This was a horrendous hack to be able to make many different WEBs
+while keeping only one Makefile around. The three magic names
+$(THETANGLE), $(THEWEAVE), and $(SPIDER) are all expected to be set on
+the command line. (Perhaps I shouldn't set them at all inside
+WebMakefile.) Look at ./c/make and you'll see how it works.
+
+
+I am sending you a list of bugs so far and patches for them, under
+separate cover, via tarmail.
+
+Norman
+
+From intvax!drstrip@unmvax.cs.unm.edu Tue Apr 11 12:02:41 1989
+Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA02118; Tue, 11 Apr 89 12:02:39 EDT
+Received: from unmvax.cs.unm.edu by Princeton.EDU (5.58+++/2.6)
+ id AA21790; Tue, 11 Apr 89 12:02:30 EDT
+Received: from intvax.UUCP by unmvax.cs.unm.edu (5.61/3.1) with UUCP
+ id <AA17499@unmvax.cs.unm.edu>; Tue, 11 Apr 89 08:57:53 -0700
+From: intvax!drstrip@unmvax.cs.unm.edu
+Received: by intvax.LOCAL on Tue, 11 Apr 89 09:58:18 mdt
+Date: Tue, 11 Apr 89 09:58:18 mdt
+Message-Id: <8904111558.AA10373@intvax.LOCAL>
+To: unmvax!nr@Princeton.EDU
+Subject: spider
+Status: RO
+
+I was finally able to ftp the spider files. It was just a slow connection
+that was fooling me. The webkernal file appears to have an extra carriage
+return right after the "?" in the comment before you define a verbatim macro.
+Also, in spiderwebman (I like that, also the ref. to Stan Lee), there is an
+endnewstuff missing after the section on macros. (A lot is commented out in
+the section, although not the endnewstuff, which just seems to be missing.)
+Thanks for the contriution. I'll let you know if I apply it.
+Strip
+
+From ramsdell@linus.MITRE.ORG Mon Jun 5 15:02:30 1989
+Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA01963; Mon, 5 Jun 89 15:02:27 EDT
+Received: from MBUNIX.MITRE.ORG by Princeton.EDU (5.58+++/2.17)
+ id AA28417; Mon, 5 Jun 89 15:01:58 EDT
+Posted-From: The MITRE Corp., Bedford, MA
+X-Alternate-Route: user%node@mbunix.mitre.org
+Return-Path: <ramsdell@linus.MITRE.ORG>
+Received: from huxley.mitre.org by linus.MITRE.ORG (5.59/RCF-3S)
+ id AA20583; Mon, 5 Jun 89 14:59:51 EDT
+Posted-Date: Mon, 5 Jun 89 15:00:16 EDT
+Received: by huxley.mitre.org (4.0/RCF-4C)
+ id AA11117; Mon, 5 Jun 89 15:00:16 EDT
+Date: Mon, 5 Jun 89 15:00:16 EDT
+From: ramsdell@linus.MITRE.ORG
+Message-Id: <8906051900.AA11117@huxley.mitre.org>
+To: nr@Princeton.EDU
+Subject: Spidery Scheme
+Reply-To: ramsdell@MDF.mitre.org
+Status: RO
+
+I was playing with the idea of generating WEB for Scheme. There are
+many problem, especially the fact that Scheme users like a pretty
+printed format that seems not generatable by WEB's algorithm. While I
+was playing, I found two bugs.
+
+(1) In WebMakefile: the make command makes common.o and pathopen.o
+even if they exist.
+
+huxley% make
+cc -DDEBUG -g -DSTAT -c /usr/src/local/tex/mitre/Spiderweb/master/common.c
+mv common.o /usr/src/local/tex/mitre/Spiderweb/master/`arch`
+cc -DDEBUG -g -DSTAT -c /usr/src/local/tex/mitre/Spiderweb/master/pathopen.c
+mv pathopen.o /usr/src/local/tex/mitre/Spiderweb/master/`arch`
+echo "date" `date` | cat - scheme.spider | awk -f /usr/src/local/tex/mitre/Spiderweb/master/spider.awk
+Warning: numeric constants and strings are identified in this WEAVE.
+awk: tokentest is not an array
+ record number 30
+*** Error code 2
+make: Fatal error: Command failed for target `grammar.web'
+
+(2) Spider.awk fails as input to GNU's version of make:
+
+huxley% echo "date" `date` | cat - scheme.spider | gawk -f /usr/src/local/tex/mitre/Spiderweb/master/spider.awk
+gawk: syntax error near line 1221:
+temp=sprintf"strncmp("%s",loc-1,%d)==0=0",$2,length($2)
+
+
+ ^ parse error
+
+The problem is gawk's sprintf expects a parenthesized argument list.
+Using gawk is prefered because the error messages are better an Sun
+awk does not always run spider.awk correctly. The input file
+
+scheme.spider:
+-------------
+## A very broken attempt at scheme.
+
+language Scheme extension scm
+
+module definition exp use exp
+# use as stmt is unavoidable since tangle introduces line breaks
+
+comment begin <";"> end newline
+
+line begin <";"-space-"line"> end <"">
+
+default translation <*> mathness no
+
+# identifiers are wrong -- no hope here.
+token identifier category exp mathness yes
+token number category exp mathness yes
+token newline category newline translation <> mathness no
+token pseudo_semi category semi mathness maybe translation <"\\relax">
+
+semi <force> --> exp
+
+token ( category open
+token ) category close
+#token . category binop translation <".\\,"-opt-3>
+
+open exp --> call
+call exp --> call
+call close --> exp
+
+#newline --> ignore_scrap
+
+? ignore_scrap --> #1
+
+-------------------
+
+gives this output: (all is okay using gawk)
+
+huxley% echo "date" `date` | cat - scheme.spider | awk -f /usr/src/local/tex/mitre/Spiderweb/master/spider.awk
+Warning: numeric constants and strings are identified in this WEAVE.
+awk: tokentest is not an array
+ record number 27
+
+---------------------
+
+Thank you for making your software available. I like Levy's CWEB and
+am looking forward to using your version of CWEB.
+John
+
+
+
+From kademan@stat.wisc.edu Thu Jun 8 15:30:58 1989
+Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA12073; Thu, 8 Jun 89 15:30:56 EDT
+Received: from bayes.stat.wisc.edu by Princeton.EDU (5.58+++/2.17)
+ id AA00826; Thu, 8 Jun 89 15:30:47 EDT
+Date: Thu, 8 Jun 89 14:28:47 CDT
+From: kademan@stat.wisc.edu (Ed Kademan)
+Message-Id: <8906081928.AA16941@bayes.stat.wisc.edu>
+Received: by bayes.stat.wisc.edu; Thu, 8 Jun 89 14:28:47 CDT
+To: nr@Princeton.EDU
+Subject: spiderweb bug report
+Status: RO
+
+In case you haven't heard of this one yet, two of the line directives in
+the file WEBROOT/master/common.c did not have any space between the number
+and the file name string. GNU C would not compile it as a result. The
+lines were numbers 168 and 170 I believe:
+----------------------------------------------------------------------
+#line 187"/u/nr/src/web/master/pathopen.web"
+
+#line 188"/u/nr/src/web/master/pathopen.web"
+----------------------------------------------------------------------
+===> Bundled 11 Apr 89; all bugs into patches/003
+
+From nr Sat Jun 17 11:02:26 1989
+Received: by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA00234; Sat, 17 Jun 89 11:02:25 EDT
+Date: Sat, 17 Jun 89 11:02:25 EDT
+From: nr (Norman Ramsey)
+Message-Id: <8906171502.AA00234@notecnirp.Princeton.EDU>
+To: ramsdell@linus.MITRE.ORG
+Subject: Re: Spidery Scheme
+Cc: nr
+Status: RO
+
+> From ramsdell@linus.MITRE.ORG Mon Jun 5 15:02:30 1989
+> I was playing with the idea of generating WEB for Scheme. There are
+> many problem, especially the fact that Scheme users like a pretty
+> printed format that seems not generatable by WEB's algorithm.
+
+What is the difficulty? Are there some lexical elements that WEB
+can't recognize, or does one need semantic information to prettyprint
+Scheme? I have only a nodding acquaintance with Lisp and know even
+less about Scheme, but I shouldn't have expected too much difficulty.
+
+> While I
+> was playing, I found two bugs.
+>
+> (1) In WebMakefile: the make command makes common.o and pathopen.o
+> even if they exist.
+>
+> huxley% make
+> cc -DDEBUG -g -DSTAT -c /usr/src/local/tex/mitre/Spiderweb/master/common.c
+> mv common.o /usr/src/local/tex/mitre/Spiderweb/master/`arch`
+> cc -DDEBUG -g -DSTAT -c /usr/src/local/tex/mitre/Spiderweb/master/pathopen.c
+> mv pathopen.o /usr/src/local/tex/mitre/Spiderweb/master/`arch`
+> echo "date" `date` | cat - scheme.spider | awk -f /usr/src/local/tex/mitre/Spiderweb/master/spider.awk
+> Warning: numeric constants and strings are identified in this WEAVE.
+> awk: tokentest is not an array
+> record number 30
+> *** Error code 2
+> make: Fatal error: Command failed for target `grammar.web'
+
+
+The problem is in your use of `arch` and exposes a flaw in make. Make
+is looking for a file common.o in a directory `arch` and not finding
+it, so it makes the target. You can cure the problem by replacing
+`arch` with $(ARCH) in the Makefile and using ARCH=`arch` in the make
+script that calls /bin/make. I don't know of anything better.
+
+
+> (2) Spider.awk fails as input to GNU's version of make:
+>
+> huxley% echo "date" `date` | cat - scheme.spider | gawk -f /usr/src/local/tex/mitre/Spiderweb/master/spider.awk
+> gawk: syntax error near line 1221:
+> temp=sprintf"strncmp("%s",loc-1,%d)==0=0",$2,length($2)
+>
+>
+> ^ parse error
+>
+> The problem is gawk's sprintf expects a parenthesized argument list.
+> Using gawk is prefered because the error messages are better an Sun
+> awk does not always run spider.awk correctly.
+
+I am reluctant to move to gawk because in the past I have found it
+buggy and unstable. BSD awk is buggy but at least is stable.
+Spider.awk contains a number of workarounds. I will look into the
+tokentest problem.
+
+> Thank you for making your software available. I like Levy's CWEB and
+> am looking forward to using your version of CWEB.
+> John
+
+I'm glad to hear it. Sorry I took so long getting back to you; I've
+been out of town and things piled up while I was away.
+
+Norman
+
+From nr Sat Jun 17 11:08:01 1989
+Received: by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA00397; Sat, 17 Jun 89 11:07:51 EDT
+Date: Sat, 17 Jun 89 11:07:51 EDT
+From: nr (Norman Ramsey)
+Message-Id: <8906171507.AA00397@notecnirp.Princeton.EDU>
+To: kademan@stat.wisc.edu
+Subject: Re: spiderweb bug report
+Cc: nr
+Status: RO
+
+I haven't heard of this one yet; thanks for the report. The problem is that
+TANGLE tries to be clever about removing ``unnecessary'' spaces from its input.
+The lines you found were from a .h file that was @included. Since I'm spending
+my time writing new literate programming tools, I'm not going to attempt to fix
+it. You can work around it by running the code through a sed script:
+ /^#line/s/"/ "/
+
+Good luck.
+
+Norman
+ From kademan@stat.wisc.edu Thu Jun 8 15:30:58 1989
+ Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA12073; Thu, 8 Jun 89 15:30:56 EDT
+ Received: from bayes.stat.wisc.edu by Princeton.EDU (5.58+++/2.17)
+ id AA00826; Thu, 8 Jun 89 15:30:47 EDT
+ Date: Thu, 8 Jun 89 14:28:47 CDT
+ From: kademan@stat.wisc.edu (Ed Kademan)
+ Message-Id: <8906081928.AA16941@bayes.stat.wisc.edu>
+ Received: by bayes.stat.wisc.edu; Thu, 8 Jun 89 14:28:47 CDT
+ To: nr@Princeton.EDU
+ Subject: spiderweb bug report
+ Status: RO
+
+ In case you haven't heard of this one yet, two of the line directives in
+ the file WEBROOT/master/common.c did not have any space between the number
+ and the file name string. GNU C would not compile it as a result. The
+ lines were numbers 168 and 170 I believe:
+ ----------------------------------------------------------------------
+ #line 187"/u/nr/src/web/master/pathopen.web"
+
+ #line 188"/u/nr/src/web/master/pathopen.web"
+ ----------------------------------------------------------------------
+ ===> Bundled 11 Apr 89; all bugs into patches/003
+
+
+From kademan@stat.wisc.edu Mon Jun 26 07:17:06 1989
+Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA14563; Mon, 26 Jun 89 07:17:05 EDT
+Received: from bayes.stat.wisc.edu by Princeton.EDU (5.58+++/2.17)
+ id AA27774; Mon, 26 Jun 89 07:16:24 EDT
+Date: Mon, 26 Jun 89 06:14:15 CDT
+From: kademan@stat.wisc.edu (Ed Kademan)
+Message-Id: <8906261114.AA02589@bayes.stat.wisc.edu>
+Received: by bayes.stat.wisc.edu; Mon, 26 Jun 89 06:14:15 CDT
+To: nr@Princeton.EDU
+Subject: spider bug report
+Status: RO
+
+===> Bundled 11 Apr 89; all bugs into patches/003
+
+The webkernel.tex file has an \eject command on line 221 right after the
+code that sets up an empty page for the first use of the output routine.
+As a result the first "page" gets output before the regular macros get a
+chance to set mark, and the section number in the first header is null.
+Simply deleting that \eject command fixes the problem (and doesn't
+introduce any new ones as far as I can tell.)
+
+I've been having a good time playing with this spider system, and have
+created a web for C++ by tweaking your c.spider file.
+
+From matsl@inmic.se Tue May 23 11:11:17 1989
+Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.81)
+ id AA14352; Tue, 23 May 89 11:11:15 EDT
+Received: from [192.36.125.2] by Princeton.EDU (5.58+++/2.13)
+ id AA28056; Tue, 23 May 89 11:11:01 EDT
+Received: from inmic.se by sunic.sunet.se (5.61+IDA/KTH/LTH/1.53)
+ id AAsunic04212; Tue, 23 May 89 17:11:18 +0200
+Received: from haf2.inmic.se (ha2) by nmpcad.inmic.se (dec-1.2/3.0)
+ id AA14700; Tue, 23 May 89 17:08:19 -0200
+Received: by haf2.inmic.se (hp-13.1/3.0)
+ id AA16364; Tue, 23 May 89 17:10:39 met
+Date: Tue, 23 May 89 17:10:39 met
+From: Mats Lidell <matsl@inmic.se>
+Message-Id: <8905231510.AA16364@haf2.inmic.se>
+To: nr@Princeton.EDU
+In-Reply-To: Norman Ramsey's message of Mon, 22 May 89 11:18:05 EDT <8905221518.AA03626@notecnirp.Princeton.EDU>
+Subject: Spiderweb
+Status: RO
+
+Dear Norman,
+
+Thanks for your quick and helpful answer. It made me try it once again.
+
+> I have only two guesses:
+> -- you are somehow combining Spider with Silvio Levy's CWEB in a way
+> that doesn't work
+> -- you've got a buggy C compiler
+
+Quite right. I was combining Spider with Silvio Levy's CWEB. See note
+below.
+
+> Please let me know more if you can, or at least tell me how big your
+> tangle.c is, so I can tell if it makes sense.
+
+This time I tried to follow the instructions real hard and it worked!
+But I had some small problems.
+
+When doing 'make boot' the link of ceetangle and ceeweave tries to get
+the common object files from the cputype directory but they are not
+there. They are compiled in the master directory! I just removed the
+use of the cputype-directory and then it worked!
+
+I also managed to destroy the tangle.c file in the master directory
+when I typed 'make -p'. Well I shouldn't have done it but away it
+went. Then I realised that this was what happened the last time I
+tried to make spiderweb and that time I copied ctangle.c from CWEB
+just to try it. Stupid me! This time I went back to my copy of the
+distribution and got the real ctangle.c! The previous time I didn't
+realised that it ever was in the master directory. I though it simply
+was missing.
+
+The programs are using the 'index' function that's not available on
+SYSV. (I'm running HP-UX.) This should be substituted with 'strchr'
+since I think that this is now normally available on both SYSV and BSD
+systems. (I haven't checked that though! Maybe a macro is safer.) I
+found no other system problem.
+
+A small error when trying to print out the weave. I haven't tried to
+find out why it fails. See output below.
+
+ ceeweave -I../master weave.web
+ This is C WEAVE (generated at 11:03 AM on May 23, 1989)
+ *1*14*28
+ ! Illegal use of @ in comment. (l. 363)
+ /* identifier =200 or octal @'
+ 310 */ *35*52*65*75*81*84*114*138*150*151*168*188*211*235
+ Writing the output file...*1*14*28
+ ! Illegal use of @ in comment. (l. 363)
+ /* identifier =200 or octal @'
+ 310 */ *35*52*65*75*81*84*114*138*150*151*168*188*211*235
+ Writing the index...Done.
+ Memory usage statistics: 722 of 3999 names, 2988 of 19999 cross-references,
+ 9695 of 89999 bytes;
+ Parsing required 822 of 1000(950) scraps, 1736 of 2000(1950) texts,
+ 3749 of 20000(19950) tokens, 258 of 399 levels;
+
+ Sorting required 47 levels
+
+ (Pardon me, but I think I spotted something wrong.)
+
+
+I can't find any collection of the improvements and/or differences you
+have added to your weave and tangle nor can I find any users manual in
+the same way as for CWEB. Well I will start looking through the
+program documentation but if you have anything better I would
+appreciate that.
+
+Many thanks.
+
+Yours matsl
+---
+Mats Lidell
+ Swedish Institute of Microelectronics, VHDL CAD Tools,
+ PO Box 1084, S-164 21 KISTA, SWEDEN
+ Tel: +46 8 752 11 42 Ttx: 128 75 INMIC S Fax: +46 8 750 80 56
+Internet: matsl@inmic.se or {uunet,unido,mcvax,ukc,munnari}sunic!inmic.se!matsl
+
+From campbell@vx2.GBA.NYU.EDU Sat Jul 1 18:34:13 1989
+Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.82)
+ id AA13480; Sat, 1 Jul 89 18:34:12 EDT
+Received: from VX2.GBA.NYU.EDU by Princeton.EDU (5.58+++/2.19)
+ id AA22478; Sat, 1 Jul 89 18:34:04 EDT
+Received: by vx2.GBA.NYU.EDU (5.61/1.34)
+ id AA25315; Sat, 1 Jul 89 17:35:25 -0500
+Date: Sat, 1 Jul 89 17:35:25 -0500
+From: campbell@vx2.GBA.NYU.EDU (bruce dietrich-campbell)
+Message-Id: <8907012235.AA25315@vx2.GBA.NYU.EDU>
+To: nr@Princeton.EDU
+Subject: spider installation on 3b1
+Status: RO
+
+Hi,
+
+I've just installed spider on my ATT 3b1 (aka UnixPC). Thought you
+might be interested in a few minor changes I had to make.
+
+ 1. In common.c I added the definition
+
+ #define index strchr
+
+ since the routine is named differently on SysV machines.
+ I probably should have added a -DUSG compilation flag, but
+ since this was the only dependency ...
+
+ 2. In spider.awk, three sprintf lines were missing the
+ surrounding parentheses:
+
+1221c1221
+< temp=sprintf"strncmp(\"%s\",loc-1,%d)==0",$2,length($2)
+---
+> temp=sprintf("strncmp(\"%s\",loc-1,%d)==0",$2,length($2))
+1231c1231
+< temp=sprintf"'%s'",$2
+---
+> temp=sprintf("'%s'",$2)
+3040c3040
+< temp=sprintf"(pp+%d)->cat",$i-1
+---
+> temp=sprintf("(pp+%d)->cat",$i-1)
+
+ This was confusing, since BSD4.3 awk doesn't mind.
+
+ 3. My awk then wouldn't digest c.spider or awk.spider,
+ complaining of an
+
+ awk : unexpected break, continue or next at record ###
+
+ where ### was one more than the number of lines in c.spider
+ or awk.spider. Rather than fight it, I installed gawk2.10
+ and everything went fine. (Note that gawk also burps on
+ the missing parentheses mentioned in 2 above.)
+
+
+The last line of BUGS is:
+
+===> Bundled 11 Apr 89; all bugs into patches/003
+
+Cheers!
+
+.............................................................................
+Bruce Dietrich-Campbell ARPA: campbell@vx2.gba.nyu.edu
+ USENET: ...!{uunet,rocky,harvard}!cmcl2!vx2!campbell
+
+From purtill@math.mit.edu Thu Jul 20 18:19:07 1989
+Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.83)
+ id AA19356; Thu, 20 Jul 89 18:19:05 EDT
+Received: from BOURBAKI.MIT.EDU by Princeton.EDU (5.58+++/2.20)
+ id AA27225; Thu, 20 Jul 89 18:18:47 EDT
+Received: from jacobi.mit.edu by math.mit.edu; Thu, 20 Jul 89 18:18:32 EDT
+Received: by jacobi.mit.edu; Thu, 20 Jul 89 18:18:23 EDT
+Date: Thu, 20 Jul 89 18:18:23 EDT
+From: purtill@math.mit.edu
+Message-Id: <8907202218.AA05761@jacobi.mit.edu>
+To: nr@Princeton.EDU (Norman Ramsey)
+Subject: spider bug(?)
+Status: R
+
+
+If foo.web is:
+----------
+@* Oink.
+
+@<Oink |#include|s@>=
+#include <oink.h>
+----------
+
+Then foo.tex (produced by ceeweave) is:
+----------
+\input cweb.tex
+
+\N1. Oink.
+
+\Y\P\4\X1:Oink s\X${}\S{}$\par
+\fi
+
+
+\inx
+\:\\{include}, 1.
+\:\\{oink}, 1.
+\fin
+\:\X1:Oink s\X
+\con
+----------
+
+Notice that the module name which should be "<Oink #includes>"
+cleverly formated ends up being just "<Oink s>". (Also, I'm no longer
+using gawk!)
+
+^.-.^ Mark Purtill purtill@math.mit.edu (617)623-6238 - H
+((")) Dept. of Math, MIT 2-229, Cambridge, MA 02139 (617)253-1589 - O
+
+
+
+
+From nr Thu Jul 20 18:43:45 1989
+Received: by notecnirp.Princeton.EDU (5.51/1.83)
+ id AA19658; Thu, 20 Jul 89 18:43:44 EDT
+Date: Thu, 20 Jul 89 18:43:44 EDT
+From: nr (Norman Ramsey)
+Message-Id: <8907202243.AA19658@notecnirp.Princeton.EDU>
+To: purtill@math.mit.edu
+Subject: Re: spider bug(?)
+Cc: nr
+Status: R
+
+This is a bug. A production is matching a token that isn't
+there, and for some reason this is making WEAVE drop all its
+text. I haven't found a quick workaround; you'll have to put
+something else in that title (it needs a newline to terminate
+the #include, and it can never get one within @<...@>).
+
+I'll let you know when I get the bug fixed.
+
+Norman
+
+From alexande@cs.unc.edu Fri Jan 19 17:52:39 1990
+Received: by cs.Princeton.EDU (5.57/1.98)
+ id AA05330; Fri, 19 Jan 90 17:52:38 EST
+Received: from Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.98)
+ id AA08642; Fri, 19 Jan 90 17:52:10 EST
+Received: from mcnc.mcnc.org by Princeton.EDU (5.58+++/2.29/mailrelay)
+ id AA17810; Fri, 19 Jan 90 17:45:02 EST
+Received: from mercury.cs.unc.edu by mcnc.mcnc.org (5.59/MCNC/5-16-88)
+ id AA21523; Fri, 19 Jan 90 17:43:28 EST
+Received: from dopey.cs.unc.edu by mercury.cs.unc.edu (5.59/UNC/6-17-88)
+ id AA11354; Fri, 19 Jan 90 17:42:24 EST
+Received: by dopey.cs.unc.edu (5.59/UNC/06-13-88)
+ id AA00405; Fri, 19 Jan 90 17:41:01 EST
+Date: Fri, 19 Jan 90 17:41:01 EST
+From: Geoffrey D. Alexander <alexande@cs.unc.edu>
+Message-Id: <9001192241.AA00405@dopey.cs.unc.edu>
+To: nr@Princeton.EDU
+Subject: Problem installing spidery WEB
+Cc: alexande@cs.unc.edu
+Status: RO
+
+Norman,
+
+I have run into a problem installing Spidery WEB. The problem occur when I
+try to run make boot from WEBROOT. Here is the output produced:
+
+===============================================================================
+cd c; make boot; cd ..
+cd ../master; rm -f *.o; for i in /unc/alexande/spiderweb/master/common.c /unc/alexande/spiderweb/master/pathopen.c; do \
+ cc -DDEBUG -g -DSTAT -c $i; \
+ mv *.o /unc/alexande/spiderweb/master/sparc_sunos ; \
+done; cd ../c
+cc -DDEBUG -g -DSTAT -c tangle.c; \
+cc -DDEBUG -g -DSTAT -o /unc/alexande/bin/sparc_sunos/ceetangle /unc/alexande/spiderweb/master/sparc_sunos/common.o /unc/alexande/spiderweb/master/sparc_sunos/pathopen.o tangle.o
+ld: /unc/alexande/spiderweb/master/sparc_sunos/common.o: Not a directory
+*** Error code 4
+make: Fatal error: Command failed for target `boot'
+Current working directory /tmp_mnt/auto/phi/phi2/unc/alexande/spiderweb/c
+*** Error code 1
+make: Fatal error: Command failed for target `boot'
+===============================================================================
+
+The problem is that there is no directory WEBROOT/master/sparc_sunos where
+sparc_sunos is the value returned by cputype. I see that Spidery WEB is
+distributed with null directories WEBROOT/master/sun3 and WEBROOT/master/vax.
+Instead of "precreating" these null directories, why not dynamically create
+them? Note that there wasn't anything in WEBROOT/README or
+EBROOT/master/WebMake which indicated that cputype has to return either sun3
+or vax (or that a null directory has to be created).
+
+The last line of WEBROOT/BUGS is
+
+===============================================================================
+===> Bundled 29 Nov 89; all bugs into patches/008
+===============================================================================
+
+If you have any questions, please let me know.
+
+Thanks,
+Geoff
+
+From nr Mon Apr 16 10:57:52 1990
+Received: by cs.Princeton.EDU (5.57/1.100)
+ id AA08937; Mon, 16 Apr 90 10:57:34 EDT
+Date: Mon, 16 Apr 90 10:57:34 EDT
+From: Norman Ramsey <nr>
+Message-Id: <9004161457.AA08937@cs.Princeton.EDU>
+To: alexande@cs.unc.edu
+Subject: Re: Problem installing spidery WEB
+Cc: nr
+Status: R
+
+>
+> Norman,
+>
+> I havd the following problems installing Spidery WEB:
+>
+> * I was unable to make web in the larch subdirectory.
+> Error: "comment begin" must have a restricted translation
+> Error: "line begin" must have a restricted translation
+
+Fixed. You need <"%"> not % and <"%line"> not %line
+
+> * I had two problems making web in the penelope subdirectory although I did
+> get a tangle and weave wiich run. Why did I get a Fatal error from make
+> (I believe it comes from /bin/make -f SpiderMakefile $*)?
+
+Beats me.
+
+
+> Why is there
+> potential cycle error?
+
+Cleverness about newlines in annotations. Context eliminates the
+possibility of a cycle---check the productions.list file if you're not
+clear about that.
+
+> I recently started using Spidery WEB. I have encountered a few minor problems.
+> The first problem is that I would like to use C code in a module name. This
+> is illustrated by the following short example.
+>
+> ===============================================================================
+> @*= Starred module with |C_code|.
+
+This is broken just like anything else that changes catcodes in
+arguments. It's a TeX problem that nobody knows how to fix.
+
+> As a temporary soultion for using C code in module names, I tried using \it.
+> This illustrated by
+>
+> ===============================================================================
+> @*= Starred module with {\it C\_code}.
+>
+> @*= Index.
+> ===============================================================================
+>
+> This didn't work. When I ran TeX, I got
+> ......
+> A solution which worked for me was to move \write\cont{\string... after
+> \openout\cont=\contentsfile. This is similar to the code in CWEB's
+> cwebmac.tex. Is this a good fix?
+
+Looks good to me.
+
+> This problem has to do with C preprocessor commands and the index. Consider
+> the following short example.
+>
+> Ceeweave and TeX both run fine. However, the index contains entries for ifdef,
+> include, and endif (in italics and without the #). I don't think preprocessor
+> commands should be in the index (in any form). What do you think? How do I
+> fix this?
+>
+> This problem invloves #include and the index. Consider the following short
+> example.
+>
+> Both ceeweave and TeX run fine. However the index contains entries for test
+> and it. It should contain instead an entry for test.it (or no entry). What
+> do you think? How do I fix this?
+
+You're not going to be able to do anything about this without
+fundamentally changing Weave's idea of what an identifier is.
+If you want you could make the preprocessor directives reserved words,
+suppressing their appearance in the index, but that will have
+unpleasant repercussions, I'm sure. If you really want to fix this
+you'll have to do some hacking.
+
+> This problem has to do with spacing in ANSI C function parameter
+> specifications. Consider the following short example.
+
+Nobody has written a Spider description for ANSI C that I am aware of.
+If you care to write one I'll be happy to put it in the distribution.
+
+> This problem has to do with the running head. Consider the following short
+> example.
+>
+> ===============================================================================
+> @*= Test of starred modules -- chapter.
+>
+> @*2 Test of starred modules -- subsection.
+>
+> @*4 Test of starred modules -- subsubsection.
+>
+> @*=Index.
+> ===============================================================================
+>
+> Both ceeweave and TeX run fine. However, the running head on page 1 has module
+> number 1 and the title for module 3. I believe that they should be consistent.
+
+Fidget with \firstmark, \topmark, and all of their friends in
+webkernel.tex. Let me know when you have something you're happy with.
+
+> Actually, I would like to have only starred modules which cause page ejects be
+> reflected in the running head. What do you think? How do I fix this?
+
+Not a bad idea. Get hacking.
+
+> This is not really a problem as much as a design question. I feel that @f
+> should not result in any text in the TeX output (either in the module in
+> which it occurs or in the index). @f is a directive to ceeweave; it does not
+> contribute to understanding the C program. For example, if I use Xlib, I need
+> to @f a number (20+) of indetifiers which are "typed" in the Xlib header files.
+> I feel that having the @f's appear in a module (and in the index) simply
+> detracts from the program. What do you think? How might I "fix" @f?
+
+I think that if you're going to lie to your reader by using @f, your
+reader should at least have a chance to catch you in the act. From
+this you may infer that I never use @f.
+
+
+Norman
+
+From ndn@seg.npl.co.uk Thu Mar 29 04:58:29 1990
+Received: by cs.Princeton.EDU (5.57/1.98)
+ id AA02242; Thu, 29 Mar 90 04:58:28 EST
+Received: from mcsun.eu.net by Princeton.EDU (5.58+++/2.32/mailrelay)
+ id AA14282; Thu, 29 Mar 90 04:56:23 EST
+Received: by mcsun.EU.net via EUnet; Thu, 29 Mar 90 11:57:25 +0200 (MET)
+Received: from psg.npl.co.uk by kestrel.Ukc.AC.UK with UUCP id aa29895;
+ 29 Mar 90 10:32 BST
+Received: from guava.seg.npl.co.uk by snow.psg.npl.co.uk; Thu, 29 Mar 90 09:29:47 BST
+From: Nick North <ndn@seg.npl.co.uk>
+Date: Thu, 29 Mar 90 09:32:36 BST
+Message-Id: <10449.9003290832@guava.seg.npl.co.uk>
+To: nr@Princeton.EDU
+Subject: Spiderweb bug
+Status: RO
+
+We are using the adaweave generated by Spiderweb and have run into
+problems with the ** operator: the ada.spider supplied generates a
+weave which turns
+ i := 3 ** Integer(p);
+into
+ $\|i\mathbin{:=}\O{3}C\\{Integer}\ (\|p); \32$
+So the ** has disappeared.
+The following patch solves the problem (I don't know if it is the best
+solution though):
+
+*** ada.spider.old Wed Mar 28 11:46:50 1990
+--- ada.spider Wed Mar 28 10:04:03 1990
+***************
+*** 46,52 ****
+
+ token => category arrow translation <"\\AR">
+ token .. category binop translation <"\\.{..}">
+! token ** category binop
+ token := category binop translation <"\\mathbin{:=}">
+ token /= translation <"\\I"> category binop
+ token >= translation <"\\G"> category binop
+--- 46,52 ----
+
+ token => category arrow translation <"\\AR">
+ token .. category binop translation <"\\.{..}">
+! token ** category binop translation <"\\mathbin{**}">
+ token := category binop translation <"\\mathbin{:=}">
+ token /= translation <"\\I"> category binop
+ token >= translation <"\\G"> category binop
+
+We are running the version of Spiderweb whose BUGS file ends with:
+===> Bundled 11 Apr 89; all bugs into patches/003
+
+Nick North
+National Physical Laboratory, UK
+
+From alexande@cs.unc.edu Tue Apr 24 11:26:22 1990
+Received: by cs.Princeton.EDU (5.57/1.101)
+ id AA29083; Tue, 24 Apr 90 11:26:18 EDT
+Received: from bashful.cs.unc.edu by mcnc.mcnc.org (5.59/MCNC/5-16-88)
+ id AA18202; Tue, 24 Apr 90 11:25:14 EDT
+Received: from fillmore.cs.unc.edu by bashful.cs.unc.edu (5.61/UNC_02-28-90)
+ id AA21656; Tue, 24 Apr 90 11:24:49 -0400
+Received: by fillmore.cs.unc.edu (5.61/UNC_02-28-90)
+ id AA10498; Tue, 24 Apr 90 11:24:40 -0400
+Date: Tue, 24 Apr 90 11:24:40 -0400
+From: Geoffrey D. Alexander <alexande@cs.unc.edu>
+Message-Id: <9004241524.AA10498@fillmore.cs.unc.edu>
+To: nr@cs
+Subject: 3 more SpiderWEB problems
+Cc: alexande@cs.unc.edu
+Status: RO
+
+I have run into three more Spidery WEB problems:
+
+8. Page number may be off by one in table of contents. Illustrated by the
+ following example. Not that module 2 starts on page 2 -- table of contents
+ entry for module 2 gives page 1.
+
+===============================================================================
+@*= A Page Number Test.
+
+Include a large amount of vertical space.
+\vskip 6in
+
+@*2 A level 2 module.
+
+Include a large amount of vertical space.
+\vskip 6in
+
+@*= Index.
+===============================================================================
+
+9. Enums not formatted correctly by ceeweave. Illustrated by the following
+ example. I think enums should be formatted similar to structures. Also,
+ left arrows are not appropriate; I think a colon might be better. Finally,
+ enumerated values (false and true) should be underscored in index.
+
+===============================================================================
+@*= Test of enum.
+
+@c
+enum {
+ false=0,
+ true=1
+} boolean;
+
+@*= Index.
+===============================================================================
+
+10. Typedefs not formated correctly by ceeweave. Illustrated by the following
+ example. The new types (boolean, lstring_head, lstring, and string) should
+ be formatted as types (ie. in bold). I tried using @f to redefine them.
+ See second example. This caused there to be no line break between typedefs
+ and a small white space between the new type and ;.
+
+===============================================================================
+@*= Test of typedef.
+
+@c
+typedef enum {
+ @!false=0,
+ @!true=1
+} boolean;
+typedef struct {
+ int buf_len;
+ int cur_len;
+} lstring_head;
+typedef lstring_head *lstring;
+typedef char *string;
+
+@*= Index.
+===============================================================================
+
+===============================================================================
+@*= Test of typedef.
+
+@f boolean char
+@f lstring_head char
+@f lstring char
+@f string char
+
+@c
+typedef enum {
+ @!false=0,
+ @!true=1
+} boolean;
+typedef struct {
+ int buf_len;
+ int cur_len;
+} lstring_head;
+typedef lstring_head *lstring;
+typedef char *string;
+
+@*= Index.
+===============================================================================
+
+The last line of the BUGS file is
+
+ ==> Bundled 29 Nov 89; all bugs into patches/008
+
+I think that problem 8 requires a change to webkernel.tex and that problems 9
+and 10 reguire changes to the C definition source. I plan to look at problem
+8 later this week. I'll take a look at problems 9 and 10 when I get around to
+creating a Spidery WEB for ANSI C.
+
+If you have any suggestions or fixes, please let me know.
+
+Thanks,
+Geoff Alexander
+
+From nr Tue Apr 24 17:05:07 1990
+Received: by cs.Princeton.EDU (5.57/1.101)
+ id AA08862; Tue, 24 Apr 90 17:04:56 EDT
+Date: Tue, 24 Apr 90 17:04:56 EDT
+From: Norman Ramsey <nr>
+Message-Id: <9004242104.AA08862@cs.Princeton.EDU>
+To: alexande@cs.unc.edu
+Subject: Re: 3 more SpiderWEB problems
+Cc: nr
+Status: R
+
+>
+> I have run into three more Spidery WEB problems:
+>
+> 8. Page number may be off by one in table of contents.
+
+This is a problem with the underlying TeX macros (marks, and so on).
+I'll be delighted if you can find a fix.
+
+> 9. Enums not formatted correctly by ceeweave.
+
+enums are not K&R (old-style C). An ANSI C spider definition is badly
+needed, but I don't have funding to produce one.
+
+> 10. Typedefs not formated correctly by ceeweave.
+
+Only if you believe ``correctly'' == ``what Silvio does.''
+The problem is that the logical structure of typedefs follows the
+structure of the C program, whereas the formatting is done on the
+structure of the WEB source. There are nasty problems of scoping, and
+even doing a botched job requires a two-pass algorithm.
+
+> I tried using @f to redefine them.
+> See second example. This caused there to be no line break between typedefs
+> and a small white space between the new type and ;.
+>
+> ===============================================================================
+> @*= Test of typedef.
+>
+> @f boolean char
+> @f lstring_head char
+> @f lstring char
+> @f string char
+
+This should be fixable by fiddling the c.spider definition; let me
+know how you make out.
+
+> I'll take a look at problems 9 and 10 when I get around to
+> creating a Spidery WEB for ANSI C.
+
+Sorry to be so unhelpful, but I have been putting my time into new,
+better-designed tools, instead of continually patching web.
+
+Norman
+
+From alexande@cs.unc.edu Tue Apr 24 21:51:59 1990
+Received: by cs.Princeton.EDU (5.57/1.101)
+ id AA11728; Tue, 24 Apr 90 21:51:55 EDT
+Received: from bashful.cs.unc.edu by mcnc.mcnc.org (5.59/MCNC/5-16-88)
+ id AA00785; Tue, 24 Apr 90 21:50:54 EDT
+Received: from fillmore.cs.unc.edu by bashful.cs.unc.edu (5.61/UNC_02-28-90)
+ id AA23752; Tue, 24 Apr 90 21:50:29 -0400
+Received: by fillmore.cs.unc.edu (5.61/UNC_02-28-90)
+ id AA01306; Tue, 24 Apr 90 21:50:20 -0400
+Date: Tue, 24 Apr 90 21:50:20 -0400
+From: Geoffrey D. Alexander <alexande@cs.unc.edu>
+Message-Id: <9004250150.AA01306@fillmore.cs.unc.edu>
+To: nr@cs
+Subject: Some Spidery WEB fixes
+Cc: alexande@cs.unc.edu
+Status: R
+
+Norman,
+
+I have fixed some of the Spidery WEB problem is snet you. First, a fix for the
+"code in a module name" problem (this also allows italic text in a module
+name). This fix involves two changes to webkernel.tex:
+
+Initialize \DC:
+===== old =====================================================================
+\def\CD{\relax\ifmmode\let\DC\egroup\hbox\bgroup\else\let\DC\relax\fi}
+===== new =====================================================================
+\def\CD{\relax\ifmmode\let\DC\egroup\hbox\bgroup\else\let\DC\relax\fi}
+\let\DC\relax
+===============================================================================
+
+Move the he code that writes "\catcode`@=11" to the toc file:
+===== old =====================================================================
+\newwrite\cont
+\output{\setbox0=\page % the first page is garbage
+ \openout\cont=\contentsfile
+ \global\output{\normaloutput\page\lheader\rheader\lfooter\rfooter}}
+\setpage
+\vbox to \vsize{} % the first \topmark won't be null
+% Delete as per bug report from kademan@stat.wisc.edu
+% Causes headings on first page to be missing
+% \eject
+\write\cont{\string\catcode`\string\@=11}% a hack to make contents
+ % take stuff in \.{---}
+===== new =====================================================================
+\newwrite\cont
+\output{\setbox0=\page % the first page is garbage
+ \openout\cont=\contentsfile
+ \write\cont{\string\catcode`\string\@=11} % a hack to make contents
+ % take stuff in \.{---}
+ \global\output{\normaloutput\page\lheader\rheader\lfooter\rfooter}}
+\setpage
+\vbox to \vsize{} % the first \topmark won't be null
+% Delete as per bug report from kademan@stat.wisc.edu
+% Causes headings on first page to be missing
+% \eject
+===============================================================================
+
+Next, a fix for the "module name in running head" problem. This fix makes the
+module name in the running head change only a "page eject" module is
+encountered. This fix involves a a single change.
+
+Move the code that sets \rhead from \N to the \headcheck.
+=== old \N ====================================================================
+\outer\def\N#1.#2.{\MN#1.\headcheck#2\headcheck
+ \edef\rhead{\uppercase{\ignorespaces\themodtitle}} % define running headline
+ \message{*\modno} % progress report
+ \edef\next{\write\cont{\thetocskip
+ \Z{\theopen\relax
+ \themodtitle}{\modno}{\the\pageno}}}\next % to contents file
+ \ifon\startsection{\bf\ignorespaces\themodtitle.\quad}\ignorespaces}
+=== new \N (includes third fix) ===============================================
+\outer\def\N#1.#2.{\MN#1.\headcheck#2\headcheck
+ \message{*\modno} % progress report
+ \edef\next{\write\cont{\thetocskip\Z{\theopen\relax
+ \themodtitle}{\modno}{\noexpand\the\pageno}}}\next % to contents file
+ \ifon\startsection{\bf\ignorespaces\themodtitle.\quad}\ignorespaces}
+===============================================================================
+
+=== old \headcheck ============================================================
+\def\headcheck#1#2\headcheck{%
+ \makethechar{#1}%
+ \def\theskipper{\vfil\penalty-100\vfilneg\vskip12ptminus3pt}%
+ % skip before new module
+ \def\theopen{}% opening skip in toc entry
+ \def\thetocskip{}% vertical skip before toc entry
+ \def\themodtitle{{#2}}
+ \ifnextchar={%
+ \def\theskipper{\vfil\eject}%
+ \canceltrue
+ \def\theopen{\bf}%
+ \def\thetocskip{\vskip3ptplus1in\penalty-100
+ \vskip0ptplus-1in}%
+ }{\ifnextchar1{%
+ \cancelfalse
+ \def\theskipper{\vfil\eject}%
+ \def\theopen{\hskip2em}%
+ }{\ifnextchar2{%
+ \cancelfalse
+ \def\theopen{\hskip2em}%
+ }{\ifnextchar3{%
+ \cancelfalse
+ \def\theskipper{\vfil\eject}%
+ \def\theopen{\hskip4em}%
+ }{\ifnextchar4{%
+ \cancelfalse
+ \def\theopen{\hskip4em}%
+ }{% else
+ \ifcancel\else
+ \def\theskipper{\vfil\eject}%
+ \fi
+ \cancelfalse
+ \def\themodtitle{#1{#2}}%
+ }}}}}%
+ \theskipper
+}
+=== new \headcheck ============================================================
+\def\headcheck#1#2\headcheck{%
+ \makethechar{#1}%
+ \def\theskipper{\vfil\penalty-100\vfilneg\vskip12ptminus3pt}%
+ % skip before new module
+ \def\theopen{}% opening skip in toc entry
+ \def\thetocskip{}% vertical skip before toc entry
+ \def\themodtitle{{#2}}
+ \ifnextchar={%
+ \def\theskipper{\vfil\eject%
+ \edef\rhead{\uppercase{\ignorespaces%
+ \themodtitle}}}%
+ \canceltrue
+ \def\theopen{\bf}%
+ \def\thetocskip{\vskip3ptplus1in\penalty-100
+ \vskip0ptplus-1in}%
+ }{\ifnextchar1{%
+ \cancelfalse
+ \def\theskipper{\vfil\eject%
+ \edef\rhead{\uppercase{\ignorespaces%
+ \themodtitle}}}%
+ \def\theopen{\hskip2em}%
+ }{\ifnextchar2{%
+ \cancelfalse
+ \def\theopen{\hskip2em}%
+ }{\ifnextchar3{%
+ \cancelfalse
+ \def\theskipper{\vfil\eject%
+ \edef\rhead{\uppercase{\ignorespaces%
+ \themodtitle}}}%
+ \def\theopen{\hskip4em}%
+ }{\ifnextchar4{%
+ \cancelfalse
+ \def\theopen{\hskip4em}%
+ }{% else
+ \ifcancel\else
+ \def\theskipper{\vfil\eject%
+ \edef\rhead{\uppercase{\ignorespaces%
+ \themodtitle}}}%
+ \fi
+ \cancelfalse
+ \def\themodtitle{#1{#2}}%
+ }}}}}%
+ \theskipper
+}
+===============================================================================
+
+Last, a fix for the "table of contents page number off by one" problem. This
+invloves a single change to webkernel.tex:
+
+Add \noexpand before \the\pageno in \N.
+=== old \N ====================================================================
+\outer\def\N#1.#2.{\MN#1.\headcheck#2\headcheck
+ \edef\rhead{\uppercase{\ignorespaces\themodtitle}} % define running headline
+ \message{*\modno} % progress report
+ \edef\next{\write\cont{\thetocskip
+ \Z{\theopen\relax
+ \themodtitle}{\modno}{\the\pageno}}}\next % to contents file
+ \ifon\startsection{\bf\ignorespaces\themodtitle.\quad}\ignorespaces}
+=== new \N (includes second fix) ==============================================
+\outer\def\N#1.#2.{\MN#1.\headcheck#2\headcheck
+ \message{*\modno} % progress report
+ \edef\next{\write\cont{\thetocskip\Z{\theopen\relax
+ \themodtitle}{\modno}{\noexpand\the\pageno}}}\next % to contents file
+ \ifon\startsection{\bf\ignorespaces\themodtitle.\quad}\ignorespaces}
+===============================================================================
+
+Note that there are two distinct changes to \N (one for the second fix and one
+for the third fix). Feel free to make the changes to the distributed
+webkernel.tex. If you have any questions or you have problems with any of the
+fixes, please let me know.
+
+Geoff Alexander
+
+From alexande@cs.unc.edu Tue Apr 24 21:51:59 1990
+Received: by cs.Princeton.EDU (5.57/1.101)
+ id AA11728; Tue, 24 Apr 90 21:51:55 EDT
+Received: from bashful.cs.unc.edu by mcnc.mcnc.org (5.59/MCNC/5-16-88)
+ id AA00785; Tue, 24 Apr 90 21:50:54 EDT
+Received: from fillmore.cs.unc.edu by bashful.cs.unc.edu (5.61/UNC_02-28-90)
+ id AA23752; Tue, 24 Apr 90 21:50:29 -0400
+Received: by fillmore.cs.unc.edu (5.61/UNC_02-28-90)
+ id AA01306; Tue, 24 Apr 90 21:50:20 -0400
+Date: Tue, 24 Apr 90 21:50:20 -0400
+From: Geoffrey D. Alexander <alexande@cs.unc.edu>
+Message-Id: <9004250150.AA01306@fillmore.cs.unc.edu>
+To: nr@cs
+Subject: Some Spidery WEB fixes
+Cc: alexande@cs.unc.edu
+Status: RO
+
+Norman,
+
+I have fixed some of the Spidery WEB problem is snet you. First, a fix for the
+"code in a module name" problem (this also allows italic text in a module
+name). This fix involves two changes to webkernel.tex:
+
+Initialize \DC:
+===== old =====================================================================
+\def\CD{\relax\ifmmode\let\DC\egroup\hbox\bgroup\else\let\DC\relax\fi}
+===== new =====================================================================
+\def\CD{\relax\ifmmode\let\DC\egroup\hbox\bgroup\else\let\DC\relax\fi}
+\let\DC\relax
+===============================================================================
+
+Move the he code that writes "\catcode`@=11" to the toc file:
+===== old =====================================================================
+\newwrite\cont
+\output{\setbox0=\page % the first page is garbage
+ \openout\cont=\contentsfile
+ \global\output{\normaloutput\page\lheader\rheader\lfooter\rfooter}}
+\setpage
+\vbox to \vsize{} % the first \topmark won't be null
+% Delete as per bug report from kademan@stat.wisc.edu
+% Causes headings on first page to be missing
+% \eject
+\write\cont{\string\catcode`\string\@=11}% a hack to make contents
+ % take stuff in \.{---}
+===== new =====================================================================
+\newwrite\cont
+\output{\setbox0=\page % the first page is garbage
+ \openout\cont=\contentsfile
+ \write\cont{\string\catcode`\string\@=11} % a hack to make contents
+ % take stuff in \.{---}
+ \global\output{\normaloutput\page\lheader\rheader\lfooter\rfooter}}
+\setpage
+\vbox to \vsize{} % the first \topmark won't be null
+% Delete as per bug report from kademan@stat.wisc.edu
+% Causes headings on first page to be missing
+% \eject
+===============================================================================
+
+Next, a fix for the "module name in running head" problem. This fix makes the
+module name in the running head change only a "page eject" module is
+encountered. This fix involves a a single change.
+
+Move the code that sets \rhead from \N to the \headcheck.
+=== old \N ====================================================================
+\outer\def\N#1.#2.{\MN#1.\headcheck#2\headcheck
+ \edef\rhead{\uppercase{\ignorespaces\themodtitle}} % define running headline
+ \message{*\modno} % progress report
+ \edef\next{\write\cont{\thetocskip
+ \Z{\theopen\relax
+ \themodtitle}{\modno}{\the\pageno}}}\next % to contents file
+ \ifon\startsection{\bf\ignorespaces\themodtitle.\quad}\ignorespaces}
+=== new \N (includes third fix) ===============================================
+\outer\def\N#1.#2.{\MN#1.\headcheck#2\headcheck
+ \message{*\modno} % progress report
+ \edef\next{\write\cont{\thetocskip\Z{\theopen\relax
+ \themodtitle}{\modno}{\noexpand\the\pageno}}}\next % to contents file
+ \ifon\startsection{\bf\ignorespaces\themodtitle.\quad}\ignorespaces}
+===============================================================================
+
+=== old \headcheck ============================================================
+\def\headcheck#1#2\headcheck{%
+ \makethechar{#1}%
+ \def\theskipper{\vfil\penalty-100\vfilneg\vskip12ptminus3pt}%
+ % skip before new module
+ \def\theopen{}% opening skip in toc entry
+ \def\thetocskip{}% vertical skip before toc entry
+ \def\themodtitle{{#2}}
+ \ifnextchar={%
+ \def\theskipper{\vfil\eject}%
+ \canceltrue
+ \def\theopen{\bf}%
+ \def\thetocskip{\vskip3ptplus1in\penalty-100
+ \vskip0ptplus-1in}%
+ }{\ifnextchar1{%
+ \cancelfalse
+ \def\theskipper{\vfil\eject}%
+ \def\theopen{\hskip2em}%
+ }{\ifnextchar2{%
+ \cancelfalse
+ \def\theopen{\hskip2em}%
+ }{\ifnextchar3{%
+ \cancelfalse
+ \def\theskipper{\vfil\eject}%
+ \def\theopen{\hskip4em}%
+ }{\ifnextchar4{%
+ \cancelfalse
+ \def\theopen{\hskip4em}%
+ }{% else
+ \ifcancel\else
+ \def\theskipper{\vfil\eject}%
+ \fi
+ \cancelfalse
+ \def\themodtitle{#1{#2}}%
+ }}}}}%
+ \theskipper
+}
+=== new \headcheck ============================================================
+\def\headcheck#1#2\headcheck{%
+ \makethechar{#1}%
+ \def\theskipper{\vfil\penalty-100\vfilneg\vskip12ptminus3pt}%
+ % skip before new module
+ \def\theopen{}% opening skip in toc entry
+ \def\thetocskip{}% vertical skip before toc entry
+ \def\themodtitle{{#2}}
+ \ifnextchar={%
+ \def\theskipper{\vfil\eject%
+ \edef\rhead{\uppercase{\ignorespaces%
+ \themodtitle}}}%
+ \canceltrue
+ \def\theopen{\bf}%
+ \def\thetocskip{\vskip3ptplus1in\penalty-100
+ \vskip0ptplus-1in}%
+ }{\ifnextchar1{%
+ \cancelfalse
+ \def\theskipper{\vfil\eject%
+ \edef\rhead{\uppercase{\ignorespaces%
+ \themodtitle}}}%
+ \def\theopen{\hskip2em}%
+ }{\ifnextchar2{%
+ \cancelfalse
+ \def\theopen{\hskip2em}%
+ }{\ifnextchar3{%
+ \cancelfalse
+ \def\theskipper{\vfil\eject%
+ \edef\rhead{\uppercase{\ignorespaces%
+ \themodtitle}}}%
+ \def\theopen{\hskip4em}%
+ }{\ifnextchar4{%
+ \cancelfalse
+ \def\theopen{\hskip4em}%
+ }{% else
+ \ifcancel\else
+ \def\theskipper{\vfil\eject%
+ \edef\rhead{\uppercase{\ignorespaces%
+ \themodtitle}}}%
+ \fi
+ \cancelfalse
+ \def\themodtitle{#1{#2}}%
+ }}}}}%
+ \theskipper
+}
+===============================================================================
+
+Last, a fix for the "table of contents page number off by one" problem. This
+invloves a single change to webkernel.tex:
+
+Add \noexpand before \the\pageno in \N.
+=== old \N ====================================================================
+\outer\def\N#1.#2.{\MN#1.\headcheck#2\headcheck
+ \edef\rhead{\uppercase{\ignorespaces\themodtitle}} % define running headline
+ \message{*\modno} % progress report
+ \edef\next{\write\cont{\thetocskip
+ \Z{\theopen\relax
+ \themodtitle}{\modno}{\the\pageno}}}\next % to contents file
+ \ifon\startsection{\bf\ignorespaces\themodtitle.\quad}\ignorespaces}
+=== new \N (includes second fix) ==============================================
+\outer\def\N#1.#2.{\MN#1.\headcheck#2\headcheck
+ \message{*\modno} % progress report
+ \edef\next{\write\cont{\thetocskip\Z{\theopen\relax
+ \themodtitle}{\modno}{\noexpand\the\pageno}}}\next % to contents file
+ \ifon\startsection{\bf\ignorespaces\themodtitle.\quad}\ignorespaces}
+===============================================================================
+
+Note that there are two distinct changes to \N (one for the second fix and one
+for the third fix). Feel free to make the changes to the distributed
+webkernel.tex. If you have any questions or you have problems with any of the
+fixes, please let me know.
+
+Geoff Alexander
+
diff --git a/web/spiderweb/doc/Makefile b/web/spiderweb/doc/Makefile
new file mode 100644
index 0000000000..6f24dc9dbd
--- /dev/null
+++ b/web/spiderweb/doc/Makefile
@@ -0,0 +1,3 @@
+clean:
+ -rm -f *.dvi *.log *~
+
diff --git a/web/spiderweb/doc/abstracts.tex b/web/spiderweb/doc/abstracts.tex
new file mode 100644
index 0000000000..bb4f38208e
--- /dev/null
+++ b/web/spiderweb/doc/abstracts.tex
@@ -0,0 +1,23 @@
+\centerline{Spider User's Guide}
+
+This manual explains how to use the {Spider} program to generate a
+{\tt WEB} system for any programming language.
+It describes the syntax of the {Spider} description file used to
+describe a programming language, giving several examples.
+It does not say how to use the generated {\tt WEB} system; for that
+see ``The Spidery {\tt WEB} System of Structured Documentation.''
+
+\bigskip
+
+\centerline{The Spidery {\tt WEB} System of Structured Documentation}
+
+
+This manual describes how to write programs in the {\tt WEB} language,
+using {\tt WEB} systems generated by {Spider}.
+Most of the material is taken verbatim from Donald Knuth's original
+memo introducing {\tt WEB}.
+It contains a brief introduction to the idea of literate programming,
+a short explanation of how to run {\tt WEAVE} and {\tt TANGLE}, and a
+list of all of the control sequences that can be used in {\tt WEB}
+programs and their effects.
+
diff --git a/web/spiderweb/doc/cacm.aux b/web/spiderweb/doc/cacm.aux
new file mode 100644
index 0000000000..7a91431f55
--- /dev/null
+++ b/web/spiderweb/doc/cacm.aux
@@ -0,0 +1,16 @@
+\relax
+\citation{ramsey:developing}
+\citation{levy:cweb}
+\@writefile{lof}{\string\contentsline\space {figure}{\string\numberline\space {1}{\ignorespaces Processing a C\penalty \@M \ {\string\ptt\space web} file}}{2}}
+\newlabel{instance}{{1}{2}}
+\@writefile{lof}{\string\contentsline\space {figure}{\string\numberline\space {2}{\ignorespaces Building and using an instance of {\string\ptt\space WEB} (for language X)}}{3}}
+\newlabel{building}{{2}{3}}
+\@writefile{lof}{\string\contentsline\space {figure}{\string\numberline\space {3}{\ignorespaces Table Inversion}}{4}}
+\newlabel{fragment}{{3}{4}}
+\citation{oppen:prettyprinting}
+\bibcite{bentley:lp}{Bentley\penalty \@M \ 86}
+\bibcite{knuth:literate-programming}{Knuth\penalty \@M \ 84}
+\bibcite{levy:cweb}{Levy\penalty \@M \ 87}
+\bibcite{oppen:prettyprinting}{Oppen\penalty \@M \ 80}
+\bibcite{ramsey:developing}{Ramsey\penalty \@M \ 89}
+\bibcite{cvw:loom}{Van\penalty \@M \ Wyk\penalty \@M \ 87}
diff --git a/web/spiderweb/doc/cacm.tex b/web/spiderweb/doc/cacm.tex
new file mode 100644
index 0000000000..d16ccf5dff
--- /dev/null
+++ b/web/spiderweb/doc/cacm.tex
@@ -0,0 +1,602 @@
+\documentstyle[11pt]{article}
+\title{Building a Language-Independent {\tt WEB}\thanks{This research
+has been sponsored in part by the USAF, Rome Air Development Center,
+under contract number F30602--86--C--0071.}}
+%\author{Norman Ramsey\\Department of Computer Science\\Princeton University}
+\author{Norman Ramsey\thanks{Current address: Department of Computer
+Science, Princeton University, Princeton, New Jersey 08544}%
+\\Odyssey Research Associates}
+
+\newcommand{\token}{\cstok}
+\def\sizedboxit#1#2{\vtop{\vbox{\hrule\hbox{\vrule\kern #2%
+ \vtop{\vbox{\kern #2\hbox{#1}}\kern #2}\kern #2\vrule}}\hrule}}
+\def\boxit#1{\sizedboxit{#1}{3pt}}
+\newcommand{\remark}{\marginpar}
+\def\remark#1{\marginpar{\footnotesize\it #1}}
+\def\cstok#1{\leavevmode\thinspace\hbox{\vrule\vtop{\vbox{\hrule\kern1pt
+ \hbox{\vphantom{\tt/}\thinspace{\tt#1}\thinspace}}
+ \kern1pt\hrule}\vrule}\thinspace} % control sequence token
+\def\ttok#1{\leavevmode\thinspace\hbox{\vrule\vtop{\vbox{\hrule\kern1pt
+ \hbox{\vphantom{\tt(j}\thinspace{\tt#1}\thinspace}}
+ \kern1pt\hrule}\vrule}\thinspace} % token
+\newcommand{\X}{}
+\def\X:#1\X{\mbox{$\langle${#1}$\rangle$}}
+
+\begin{document}
+\maketitle
+
+In the fall of~1987 I started planning the implementation of a
+suite of tools for building verified Ada
+programs~\cite{ramsey:developing}.
+The first tool to be built was a
+verification condition generator, which was to be formally defined
+using the typed lambda calculus.
+I was eager to include the definition with the code
+so that it would be easy to check the code's correctness.
+Using {\tt WEB} would have made this easy, but,
+unfortunately, the target programming language was
+SSL (a language for specifying structure editors), and the only
+languages for which {\tt WEB} implementations were
+available were Pascal and~C.
+
+Writing a new {\tt WEB} from scratch didn't make sense, so
+I decided to modify Silvio Levy's implementation of {\tt WEB}
+in~C~\cite{levy:cweb},
+to get a {\tt WEB} that would be written in C, but would read and
+write SSL code.
+From my previous experiences modifying {\tt WEB}, I knew that the
+most time-consuming job would be fine-tuning the grammar that {\tt
+WEAVE} uses to prettyprint code.
+I believed I could make debugging that grammar a lot less painful
+if, instead of trying to make dozens of small modifications by hand, I
+ wrote a simple program, perhaps an AWK script, that would read
+a description of the grammar and generate C~code for {\tt WEAVE}.
+That AWK script became {\tt SPIDER}, a program that turns language
+descriptions into C~code for {\tt TANGLE} and {\tt WEAVE}.
+I have used {\tt SPIDER} to generate {\tt WEB}s for C, AWK, SSL, Ada,
+and a couple of other languages.
+I won't go into the details of {\tt SPIDER}; instead, I'll try to
+describe what {\tt SPIDER} does to accomplish its mission, or
+how to take the ``essence of {\tt WEB}'' and make it
+language-independent.
+
+\medskip
+
+When using {\tt WEB}, a programmer writes a single source file, {\tt
+foo.{\tt web}}, that holds both code and documentation.
+{\tt TANGLE} and {\tt WEAVE} read that file.
+{\tt TANGLE} extracts
+the code from the {\tt WEB} file and rewrites it in a form suitable
+for compiling.
+{\tt WEAVE} passes the documentation parts to a document formatter
+({\TeX}), and prettyprints the code parts.
+The whole process is shown in Figure~\ref{instance}, for C~programs
+written in {\tt WEB}.
+The~{\S} represents files that have to be written by hand.
+{\sl Slant} type is used for the names of executable programs.
+{\sl CTANGLE} and {\sl CWEAVE} are the C-language versions of {\tt
+TANGLE} and {\tt WEAVE}, {\sl cc}~is a C~compiler, and {\sl ld}~is a
+loader.
+
+\begin{figure}
+\caption{Processing a C~{\tt web} file}
+\label{instance}
+\footnotesize
+\setlength{\unitlength}{2pt}
+\begin{picture}(170,80)(0,-40)
+\tt
+\put(20,12.5){\makebox(0,0)[l]{\ \sl CTANGLE}}
+\put(20,-12.5){\makebox(0,0)[l]{\ \sl CWEAVE}}
+
+\put(0,-5){\framebox(30,10){foo.{\tt web}\smash{${}^{\S}$}}}
+\put(15,5){\vector(1,2){7.5}}
+\put(10,20){\framebox(30,10){foo.c}}
+\put(15,-5){\vector(1,-2){7.5}}
+\put(10,-30){\framebox(30,10){foo.tex}}
+
+\put(40,-25){\vector(1,0){20}}
+\put(50,-23.5){\makebox(0,0)[b]{\sl {\TeX}}}
+\put(60,-30){\framebox(30,10){foo.dvi}}
+\put(90,-25){\vector(1,0){20}}
+\put(100,-25){\makebox(0,0){\shortstack{\strut dvi\\\strut \rm driver}}}
+\put(110,-25){\makebox(0,0)[l]{\rm\strut \ Typeset documentation for
+{\tt foo}}}
+
+\put(40,25){\vector(1,0){20}}
+\put(50,26.5){\makebox(0,0)[b]{\sl cc}}
+\put(60,20){\framebox(30,10){foo.o}}
+\put(90,25){\vector(1,0){20}}
+\put(100,26.5){\makebox(0,0)[b]{\sl ld}}
+\put(110,25){\makebox(0,0)[l]{\rm\strut \ Executable \sl foo}}
+
+
+
+\end{picture}
+
+\hrule
+\end{figure}
+
+{\tt SPIDER} is used to construct {\em instances} of {\tt TANGLE} and
+{\tt WEAVE}, and these instances are used to process programs as
+shown in Figure~\ref{instance}.
+Code for the language-dependent parts of these instances is generated
+by {\tt SPIDER} when it
+reads a language description file written by a {\tt WEB} designer.
+Figure~\ref{building} shows how instances of {\tt TANGLE} and {\tt
+WEAVE} are generated.
+{\tt SPIDER} converts a hand-written description of a programming language
+into C~{\tt WEB} code for the language-dependent parts of {\tt TANGLE}
+and {\tt WEAVE}.
+In Figure~\ref{building} the target programming language is a hypothetical
+``X,'' and the description file is called ``{\tt x.spider}.''
+{\tt CTANGLE} combines the code {\tt SPIDER} writes with the ``master
+copies'' of {\tt tangle.web} and {\tt weave.web}, which contain the
+language-independent parts of {\tt TANGLE} and {\tt WEAVE}.
+The result is C~source code for {\tt XTANGLE} and {\tt XWEAVE}.
+After that code is compiled and loaded with {\tt WEB}'s I/O code, the
+resulting executable versions of {\tt XTANGLE} and {\tt XWEAVE} can be
+used to process X-language programs written in {\tt WEB} format, as
+shown around the periphery of Figure~\ref{building}.
+
+
+The master copies of {\tt tangle.web} and {\tt weave.web} are about
+1800 and 3200 lines long, respectively.
+About one third of these lines are comments.
+To illustrate the other size, suppose X is the Ada programming language.
+The {\tt ada.spider} file is about 260 lines long, and from it {\tt
+SPIDER} generates
+about 1400~lines of {\tt ADATANGLE} and {\tt ADAWEAVE}.
+About one tenth of these lines are comments.
+It is typical for {\tt SPIDER} to generate between $5n$ and $6n$ lines
+of C~{\tt WEB} code from an $n$~line language description.
+
+\begin{figure}
+\caption{Building and using an instance
+of {\tt WEB} (for language X)}
+\label{building}
+\footnotesize
+\setlength{\unitlength}{2pt}
+\begin{picture}(215,115)(10,-55)
+\tt
+\put(185,-5){\framebox(30,10){x.spider\smash{${}^{\S}$}}}
+\put(185,0){\line(-1,0){20}}
+\put(174,1.5){\makebox(0,0)[b]{$\,$\sl SPIDER}}
+\put(165,0){\vector(-1,1){10}}
+\put(165,0){\vector(-1,-1){10}}
+
+\put(125,5){\framebox(30,10){xt.web}}
+\put(125,-15){\framebox(30,10){xw.web}}
+\put(125,25){\framebox(30,10){\shortstack{{\rm Master}\\tangle.{\tt web}}}}
+\put(125,-35){\framebox(30,10){\shortstack{{\rm Master}\\weave.{\tt web}}}}
+\put(125,-30){\line(-1,1){10}}
+\put(125,-10){\line(-1,-1){10}}
+\put(115,-20){\vector(-1,0){25}}
+
+\put(104,-18.5){\makebox(0,0)[b]{\scriptsize\sl CTANGLE}}
+
+\put(125,10){\line(-1,1){10}}
+\put(125,30){\line(-1,-1){10}}
+\put(115,20){\vector(-1,0){25}}
+
+\put(104,21.5){\makebox(0,0)[b]{\scriptsize\sl CTANGLE}}
+
+\put(60,15){\framebox(30,10){xtangle.c}}
+\put(60,-25){\framebox(30,10){xweave.c}}
+\put(60,-20){\vector(-1,0){20}}
+\put(50,-18.5){\makebox(0,0)[b]{\sl cc, ld}}
+\put(60,20){\vector(-1,0){20}}
+\put(50,21.5){\makebox(0,0)[b]{\sl cc, ld}}
+\put(38,20){\makebox(0,0)[r]{\sl XTANGLE}}
+\put(38,-20){\makebox(0,0)[r]{\sl XWEAVE}}
+
+\put(-6.25,-5){\framebox(30,10){foo.{\tt web}\smash{${}^{\S}$}}}
+\put(8.75,5){\vector(1,4){6.25}}
+\put(0,30){\framebox(30,10){foo.x}}
+\put(8.75,-5){\vector(1,-4){6.25}}
+\put(0,-40){\framebox(30,10){foo.tex}}
+
+\put(30,-35){\vector(4,-1){20}}
+\put(50,-48.75){\framebox(30,10){foo.dvi}}
+\put(80,-47.5){\vector(4,-1){20}}
+\put(100,-52.5){\makebox(0,0)[l]{\rm\strut \ Typeset documentation for
+{\tt foo}}}
+
+\put(30,35){\vector(4,1){20}}
+\put(50,38.75){\framebox(30,10){foo.o}}
+\put(80,47.5){\vector(4,1){20}}
+\put(100,52.5){\makebox(0,0)[l]{\rm\strut \ Executable \sl foo}}
+
+
+
+\end{picture}
+
+\hrule
+\end{figure}
+
+\medskip
+
+A {\tt WEB} program is a collection of ``sections,'' each of which has a
+documentation part, a definition part, and a code part.
+The documentation part describes what the section is supposed to do,
+and is intended to be processed by a formatter---my {\tt WEB}s use
+{\TeX}, which is especially convenient for mathematical symbols like
+those used in writing a formal semantics.
+The definition part contains macro definitions.
+Each macro may have parameters or not, as the programmer chooses.
+The code in the code part is a fragment of the whole program.
+It is called a ``module'' and can be named or unnamed.
+When the module is named, the module name ``stands for'' that code,
+just as a macro name stands for the code in its definition.
+The unnamed module is special; the code in the unnamed module is
+considered to be ``the program.''
+
+Figure~\ref{fragment} shows a fragment of a {\tt WEB} program; the
+fragment inverts an
+EBCDIC-to-ASCII table to obtain an ASCII-to-EBCDIC table.
+The target programming language is C.
+One module, \X:Invert {\it to\_ascii}, producing {\it to\_ebcdic}\X,
+uses the code defined in the other, \X:Set ${\it
+to\_ebcdic}[i]\leftarrow {\it UNDEFINED\_CODE}$ for all $i$\X.
+The program, {\tt foo}, of which this fragment is a part, can be input
+to {\tt CTANGLE} and {\tt CWEAVE}, to produce {\tt foo.c} and {\tt
+foo.tex} respectively, as shown in Figure~\ref{instance}.
+
+\begin{figure}
+\caption{Table Inversion}
+\label{fragment}
+\begin{verbatim}
+@ The array |to_ascii| converts an EBCDIC code to
+an ASCII code, or to |-1| if there is no ASCII
+equivalent to the given code.
+@d UNDEFINED_CODE = -1
+@<Invert |to_ascii|, producing |to_ebcdic|@>=
+ @<Set |to_ebcdic[i]=UNDEFINED_CODE| for all |i|@>@;
+ for (i=0; i<256; i++)
+ if (to_ascii[i] != UNDEFINED_CODE)
+ to_ebcdic[to_ascii[i]]=i;
+
+@ @<Set |to_ebcdic[i]=UNDEFINED_CODE| for all |i|@>=
+ for (i=0; i<128; i++) to_ebcdic[i] = UNDEFINED_CODE;
+\end{verbatim}
+\hrule
+\end{figure}
+
+
+
+{\tt TANGLE}'s job is to take a collection of sections and to
+produce a compilable program.
+{\tt TANGLE} reads all the sections, skipping the documentation parts
+completely, but storing the macro definitions from the definition parts
+and the module definitions from the code parts.
+After it has read all the sections, {\tt TANGLE} then
+writes out the code in the unnamed module.
+But whenever it encounters a module name in that code, instead of
+writing out the name, it writes out the code for which this name
+stands.
+That code may itself contain module names, which are replaced with the
+code for which they stand, and so on until {\tt TANGLE} reaches code
+which contains no occurrences of module names.
+{\tt TANGLE} processes macros similarly, except that macros may
+have parameters (modules may not).
+
+As I've described it, the ``essence of tangling'' is
+language-independent.
+In the full implementation of {\tt TANGLE} there are only a few
+language-dependent details, and almost all of them come up only in
+lexical analysis.
+During its input phase, {\tt TANGLE} converts macro definitions and
+module definitions into token lists.
+%%%Every token is represented using either eight or sixteen bits.
+The major kinds of tokens are
+module name tokens, identifier tokens, and ordinary tokens.
+Identifier tokens may be expandable (when they are macro names) or
+unexpandable (when they are programming-language identifiers).
+Module name tokens are always expandable, and ordinary tokens are
+never expandable.
+{\tt TANGLE} uses a stack to write out the token list corresponding to
+the unnamed module, expanding expandable tokens as it goes.
+No token is ever expanded until the time comes to write that token on
+the output.
+
+To build the language-dependent part of {\tt TANGLE}, it is enough to
+tell {\tt TANGLE} how to tokenize the input and how to write out a
+token list.
+{\tt TANGLE} uses a ``lowest common denominator'' lexical analyzer to
+tokenize its input.
+The set of tokens recognized by this lexical analyzer is the union of
+the sets of legal tokens of many different languages.
+For example, different ways of delimiting string literals are
+recognized.
+Identifiers may have underscores, even though some languages
+(e.g.~Pascal) may not permit underscores in identifiers, and others
+(e.g.~Ada) may not permit consecutive underscores in an identifier.
+In general, {\tt TANGLE} and {\tt WEAVE} do the right thing with legal
+programs, but they do not detect illegalities in a program.
+
+{\tt TANGLE}'s lexical analyzer recognizes a fixed set of tokens
+representing identifiers, string literals, and numeric literals.
+Any printable ASCII character which is not part of some other
+token forms a token all by itself.
+A {\tt WEB} builder can specify that certain strings should
+be treated as single tokens, and
+{\tt SPIDER} will convert the specifications into appropriate code for
+{\tt TANGLE}.
+For example, when building {\tt WEB} for~C, we tell {\tt SPIDER}
+that the strings {\tt ++}, {\tt ==}, and {\tt \&\&} (and many others)
+should be treated as single tokens, by putting the statements
+\begin{quote}\tt
+token ++ ...\\
+token == ...\\
+token \&\&\ ...
+\end{quote}
+into the language description file, {\tt c.spider}.
+
+{\tt TANGLE} discards comments, rather than attempting to tokenize
+them.
+Comments are assumed to begin with a special string, and to end either
+with another string or with a newline.
+We specify C comment conventions by telling {\tt SPIDER}
+\begin{quote}\tt
+comment begin <"/*"> end <"*/">
+\end{quote}
+
+
+On output, {\tt TANGLE} converts tokens to text by inverting the
+process of lexical analysis, so, for example, the token \token{++} is
+written out as ``{\tt ++}''.
+{\tt TANGLE}'s output phase inserts white space between adjacent
+identifiers and numeric literals, but otherwise does not write white
+space.
+This can cause problems in some cases; for example, in older
+C~compilers the string
+``{\tt =-}'' is ambiguous.
+We can solve this problem by telling {\tt SPIDER} to build a {\tt
+TANGLE} that uses the text
+ ``{\tt =~}'' when writing the \token{=}:
+\begin{quote}\tt
+token = tangleto <"= ">
+\end{quote}
+
+In sum, we can make {\tt TANGLE} language-independent with almost no
+effort.
+We do this by using a lowest common denominator lexical analyzer whose
+only parameter is a description of comments, and by providing a way to
+fine-tune the way {\tt TANGLE} writes tokens.
+
+
+
+\medskip
+Unlike {\tt TANGLE}, {\tt WEAVE} does no rearranging of the sections;
+its job is to translate its input into a prettyprinted program
+listing.
+The documentation part of each section is simply copied to the output,
+but the definition and code parts are prettyprinted.
+{\tt WEAVE}'s output is handed to a document formatter, which is
+assumed to implement a prettyprinting algorithm like that described by
+Oppen~\cite{oppen:prettyprinting}.
+Since my {\tt WEB}s use {\TeX} as the document formatter, the back-end
+prettyprinting is implemented by {\TeX} macros.
+
+{\tt WEAVE} copies the documentation parts as texts, but it converts
+definition and code parts to token lists using the same lexical
+analyzer used by {\tt TANGLE}.
+{\tt WEAVE}'s part of the prettyprinting task (as distinct from
+{\TeX}'s part) is converting these token lists to streams of {\TeX}
+text, possibly with prettyprinting instructions intercalated between
+tokens.
+If you like, {\tt WEAVE}'s job is to produce the input to Oppen's
+algorithm.
+For simplicity, we'll discuss only three prettyprinting instructions:
+{\em indent}
+(increase the level of indentation), {\em outdent} (decrease the level
+of indentation), and {\em force} (force a line break).
+
+We tell {\tt WEAVE} how to convert tokens to {\TeX} text by specifying
+a {\em translation} for each token.
+Suppose we want the C token \token{!=} to be printed as~``$\ne$'',
+which is produced by the {\TeX} text ``\verb+\ne+''.
+Then we write
+\begin{quote}
+\begin{verbatim}
+token != translation <"\\ne">
+\end{verbatim}
+\end{quote}
+(Two backslashes appear in the translation because {\tt SPIDER} uses
+C~conventions for string literals.
+The angle brackets {\tt <...>} delimit translations.)
+The default for translation is just as in {\tt TANGLE}, so if we want
+``{\tt +}'' on input to produce ``$+$'' on output we need not specify a
+translation for the token \token{+}.
+
+The process of deciding where to put line breaks and indentation is
+the most complicated part of {\tt WEAVE}.
+We have to do this based on the sequence of tokens we have, but the
+exact details of which token is where usually aren't needed to do
+prettyprinting.
+Hence we introduce the {\em scrap}, which abstracts away from the
+detail not needed to do prettyprinting.
+A scrap has two parts: the translation, which we have already seen,
+and the {\em category}, which
+ corresponds to a ``part of speech'' or a symbol in a grammar.
+{\tt WEAVE} uses categories to decide where to put
+indentation and line breaks.
+Since there are usually many different tokens having the same category,
+prettyprinting is simplified enormously.
+
+{\tt WEAVE} begins processing a program fragment by tokenizing the
+fragment, then converting each token in the resulting token list into
+a scrap.
+It then attempts to reduce the length of the resulting scrap list by
+combining adjacent scraps into a single scrap, possibly intercalating
+additional translations, which may include
+{\em indent}, {\em outdent}, and {\em force} instructions.
+The scraps are combined according to one of many {\em reduction rules}.
+{\tt WEAVE} decides which adjacent scraps are eligible to be reduced
+based only on the categories of the scraps and a knowledge of the
+reduction rules.
+The reduction rules are the productions of the {\em prettyprinting
+grammar}.
+{\tt WEAVE}'s reductions of scraps are like the reductions done in
+bottom-up parsing.
+
+To take an example, suppose that we want statements to be separated by
+line breaks.
+If we can guarantee that any scrap representing a statement has
+category {\tt stmt}, it will be enough to specify the reduction rule
+\begin{quote}\tt
+stmt <force> stmt --> stmt
+\end{quote}
+which says ``two adjacent {\tt stmt} scraps may be reduced to a single
+{\tt stmt} scrap by intercalating a forced line break between them.''
+
+So we tell {\tt WEAVE} how to prettyprint a language by telling
+how to assign a category to each token and how to combine scraps.
+Here's another example: the language of C~expressions.
+ Let {\tt math} be the category of expressions,
+{\tt binop} be the category of binary infix operators, and
+{\tt unop} be the category of both unary prefix and unary postfix
+operators.
+Here are some sample tokens:
+\begin{quote}
+\begin{verbatim}
+token identifier category math
+token + category binop
+token - category binop
+token = category binop translation <"\\leftarrow">
+token == translation <"\\equiv"> category binop
+token ( category open
+token ) category close
+\end{verbatim}
+\end{quote}
+Notice we print the \token{=} token (assignment) as $\leftarrow$,
+whereas we print the \token{==}~token (comparison) as $\equiv$.
+This makes it a bit easier for us to see when a programmer has
+mistakenly used \token{=} instead of \token{==}.
+
+
+The prettyprinting grammar for C~expressions is:
+\begin{quote}
+\begin{verbatim}
+math binop math --> math
+math unop --> math
+unop math --> math
+open math close --> math
+\end{verbatim}
+\end{quote}
+Using this grammar, {\tt WEAVE} can take a long expression consisting
+of many scraps, and reduce it all to a single scrap of category {\tt
+math}.
+
+What about an operator like ``{\tt *}'', which is both binary infix
+and unary prefix?
+This does the job:
+\begin{quote}
+\begin{verbatim}
+token * category unorbinop
+unorbinop math --> math
+math unorbinop math --> math
+\end{verbatim}
+\end{quote}
+
+% No Note about context-sensitive reductions?
+
+There is a mechanism for assigning categories and translations to
+reserved words as well as to tokens, using slightly different syntax.
+
+To give an idea of the complexity of the grammars, the grammar
+describing AWK uses 24~categories in 39~productions.
+The Ada grammar uses 40~categories in 65~productions, and the
+C~grammar uses 54~categories in 129~productions.
+
+\medskip
+
+{\tt SPIDER}-generated versions of {\tt TANGLE} and {\tt WEAVE} differ
+subtly from the originals written by Donald Knuth.
+The most important difference is that {\tt SPIDER}-generated {\tt WEB}
+is not self-contained: where Knuth's Pascal {\tt WEB} required only a
+Pascal compiler to bring up, {\tt SPIDER} would need a C~compiler and
+an AWK~interpreter to generate a Pascal {\tt WEB}, and a Pascal
+compiler for the resulting {\tt WEB} to be of any use.
+Other differences are minor; for example, Knuth's {\tt TANGLE}
+does arithmetic on constants at {\tt TANGLE} time, but {\tt
+SPIDER}-generated {\tt TANGLE}s do not.
+Knuth's {\tt TANGLE} provides three different kinds of macros, but
+none with more than one parameter;
+{\tt SPIDER}-generated {\tt TANGLE}s provide only one kind of macro,
+but macros of that kind may have from zero to thirty-two parameters.
+
+
+
+{\tt SPIDER} is a {\tt WEB} generator, akin to parser generators.
+Both read formal descriptions of some part of a programming language,
+and both produce code that processes programs written in that language.
+Since both produce code that is part of the ``compiler,'' using them
+doesn't introduce any extra steps into the processing of user programs.
+{\tt SPIDER} itself is a large AWK script, written as a {\tt WEB}
+program.
+{\tt spider.web} is about 2600 lines long; about a third of these are
+comments.
+
+
+The major cost of using {\tt SPIDER} is the cost of learning yet
+another language.
+Learning this language is supposed to substitute for learning how to
+modify {\tt WEB}, so it is probably not an exorbitant cost.
+Some other limitations are the the need for a C~compiler and an
+AWK~interpreter, and the need to use a lowest-common-denominator
+lexical analyzer.
+
+The major benefit of using {\tt SPIDER} is the ease with which new
+{\tt WEB}s can be built.
+%\remark{(Here is the place to talk about Oberon.)}
+The {\tt SPIDER} description of a language is much smaller than the
+{\tt WEB} implementation generated from that description, and {\tt
+SPIDER} descriptions of similar languages are similar.
+Using {\tt SPIDER} one can build a {\tt WEB} without understanding the
+details of {\tt WEB}'s implementation, and one can easily adjust that
+{\tt WEB} to change as a language definition changes.
+%\remark{Could mention work with Larch/Ada-88}
+
+
+
+{\tt SPIDER} should make one literate programming tool, {\tt WEB},
+available to a much larger audience.
+I hope that, by separating the language-independent parts of {\tt WEAVE}
+and {\tt TANGLE}, {\tt SPIDER} will encourage us not just to think
+about what the essence of tangling and weaving is, but also about what
+the essence of literate programming is.
+
+
+\medskip
+
+I enjoyed many useful discussions of {\tt WEB} with Charlie Mills.
+I am grateful to
+Silvio Levy for providing his {\tt CWEB} as the basis for the
+``master copies'' of {\tt TANGLE} and {\tt WEAVE}, and to
+Dave Hanson for comments on an earlier version of this paper.
+
+\begin{thebibliography}{van~Knuth~999}
+\bibitem[Bentley~86]{bentley:lp}
+Jon L. Bentley, ``Programming Pearls,''
+{\sl Communications of the ACM} {\bf 29:5} (May~1986), 364--368, and
+{\bf 29:6} (June~1986), 471--483.
+\bibitem[Knuth~84]{knuth:literate-programming}
+Donald E. Knuth, ``Literate Programming,'' {\sl The Computer Journal}
+{\bf 27:2}(1984), 97-111.
+\bibitem[Levy~87]{levy:cweb}
+Silvio Levy, ``{\tt WEB} Adapted to C, Another Approach,''
+ {\sl TUGBoat} {\bf 8:1}(1987), 12--13.
+\bibitem[Oppen~80]{oppen:prettyprinting}
+Derek Oppen, ``Prettyprinting,'' TOPLAS~{\bf 2:4} (October 1980),
+465--483.
+\bibitem[Ramsey~89]{ramsey:developing}
+Norman Ramsey, ``Developing Formally Verified Ada Programs,''
+Proceedings, {\sl Fifth International Workshop on Software
+Specification and Design}, to appear.
+\bibitem[Van~Wyk~87]{cvw:loom}
+Christopher J. Van~Wyk, ``Literate Programming,''
+{\sl Communications of the ACM} {\bf 30:7} (July~1987), 593--599, and
+{\bf 30:12} (December~1987), 1000--1010.
+\end{thebibliography}
+
+\end{document}
diff --git a/web/spiderweb/doc/overview.aux b/web/spiderweb/doc/overview.aux
new file mode 100644
index 0000000000..67eea2a819
--- /dev/null
+++ b/web/spiderweb/doc/overview.aux
@@ -0,0 +1,12 @@
+\relax
+\citation{bentley:lp,cvw:loom}
+\citation{knuth:literate-programming}
+\citation{levy:cweb}
+\@writefile{toc}{\string\contentsline\space {section}{Introduction}{1}}
+\@writefile{toc}{\string\contentsline\space {section}{Features of Spidery {\string\ptt\space WEB}}{2}}
+\@writefile{toc}{\string\contentsline\space {section}{Scope of {\string\ptt\space SPIDER}}{2}}
+\bibcite{bentley:lp}{Bentley\penalty \@M \ 86}
+\bibcite{knuth:literate-programming}{Knuth\penalty \@M \ 84}
+\bibcite{levy:cweb}{Levy\penalty \@M \ 87}
+\bibcite{cvw:loom}{Van\penalty \@M \ Wyk\penalty \@M \ 87}
+\@writefile{toc}{\string\contentsline\space {section}{Conclusions}{3}}
diff --git a/web/spiderweb/doc/overview.tex b/web/spiderweb/doc/overview.tex
new file mode 100644
index 0000000000..0e568d0392
--- /dev/null
+++ b/web/spiderweb/doc/overview.tex
@@ -0,0 +1,149 @@
+% Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+% Not to be sold, but may be used freely for any purpose
+% For more information, see file COPYRIGHT in the parent directory
+
+\documentstyle[11pt]{article}
+\title{A note about a new implementation of {\tt WEB}}
+\author{Norman Ramsey\\Odyssey Research Associates}
+\date{July 4, 1988}
+\setcounter{secnumdepth}{0}
+\begin{document}
+\maketitle
+
+\begin{abstract}
+Literate programming has received recent attention in the {\sl
+Communications of the ACM}~\cite{bentley:lp,cvw:loom}.
+{\tt WEB} is a tool intended for literate programming, but
+until recently it was useful only for writing PASCAL programs.
+The author has developed a new tool, {\tt SPIDER}, which reads a
+description of a programming language and writes a {\tt WEB} system
+that can be used to write programs in that language.
+{\tt SPIDER} has been used in the author's organization to build {\tt
+WEB} systems for Ada, C, AWK, and other languages.
+The author hopes that {\tt SPIDER} will enable people to write
+literate programs in many more languages than they could before.
+\end{abstract}
+
+
+\section{Introduction}
+Donald Knuth developed the {\tt WEB} system of structured documentation
+as part of the {\TeX} project~\cite{knuth:literate-programming}.
+His implementation of {\tt WEB} combined PASCAL and {\TeX}.
+ The {\tt WEB} idea suggests a way of combining {\em any}
+programming language with {\em any} document formatting language,
+but until recently there was no software support for writing in {\tt
+WEB} anything but PASCAL programs.
+In~1987, Silvio Levy rewrote the {\tt WEB} system in C for C,
+while retaining {\TeX} as the formatting language~\cite{levy:cweb}.
+I have has modified Levy's implementation by removing the parts
+that make C the target programming language, and I have
+ added a third tool, {\tt SPIDER}, which complements {\tt WEAVE}
+and {\tt TANGLE}.
+{\tt SPIDER} reads a description of a programming language, and writes
+source code for a {\tt WEAVE} and {\tt TANGLE} which support that
+language.
+Using {\tt SPIDER}, a C~compiler, and an AWK~interpreter, an experienced
+systems programmer can generate in a few hours a {\tt WEB} system for
+an Algol-like language.
+
+\section{Features of Spidery {\tt WEB}}
+An exhaustive list of Spidery {\tt WEB}'s features would interest only
+{\tt WEB} experts,
+but I do want to mention some features that I hope will encourage
+people to use Spidery {\tt WEB}.
+\begin{itemize}
+\item
+{\tt TANGLE} and {\tt WEAVE} can read from multiple files (this
+feature is present in Levy's {\tt CWEB}), and
+{\tt TANGLE} can write to multiple files.
+Included files will be searched for on a path if not found in the
+current directory.
+These features make Spidery {\tt WEB} more usable on systems that have
+{\tt make}.
+\item
+{\tt TANGLE} can expand macros with multiple parameters.
+\item
+The starred sections in Spidery {\tt WEB} can be organized
+hierarchically (in three levels).
+We have a UNIX tool that can extract different pieces of the hierarchy
+from the output of {\tt WEAVE}, so that it is possible to take
+excerpts from {\tt WEB} documents.
+\item
+{\tt TANGLE} writes {\tt \#line} directives, so you can debug at the
+{\tt WEB} source level if your compiler respects the C~conventions for
+{\tt\#line}.
+\item
+Many features of {\tt WEB} seem to exist only to compensate for
+deficiencies in PASCAL, and most of those were dropped in {\tt CWEB}.
+I have changed much of {\tt CWEB} in order to avoid being bound too
+much by C conventions.
+As a result, there are dozens of minor differences between Spidery
+{\tt WEB} and original {\tt WEB}.
+To give just one example, Spidery {\tt WEB} supports
+octal and hexadecimal constants using {\tt WEB}-style
+notation, not the C~notation used in {\tt CWEB}.
+\end{itemize}
+
+\section{Scope of {\tt SPIDER}}
+{\tt SPIDER} can generate {\tt WEB} systems for a variety
+of languages.
+The author has written {\tt SPIDER} description files for C, AWK, Ada,
+SSL (a language that describes attribute grammars to the
+Cornell Synthesizer Generator),
+the Larch Shared Language (a language for describing equational
+theories),
+and Dijkstra's language of guarded commands.
+Debugging the grammar that {\tt WEAVE} uses to
+prettyprint the language is the most time-consuming part of creating a
+{\tt WEB} system for a new target language,
+and {\tt SPIDER} makes it trivial to change that grammar.
+To make a {\tt SPIDER} description file for an Algol-like language
+that uses infix expression notation, an experienced systems programmer
+should be able to adapt an existing {\tt SPIDER} description file very
+quickly.
+
+{\tt SPIDER}'s major limitations are lexical.
+ All Spidery {\tt WEB}s
+assume that spaces and tabs in the input are not significant, except
+as separators;
+this makes it impossible to construct Spidery {\tt WEB}s for languages
+like Fortran and Miranda, where the position of text on a line is
+significant.
+The lexical structures of identifiers, string literals, and numeric
+literals are fixed.
+
+\section{Conclusions}
+{\tt SPIDER} is a modest piece of engineering; it does not introduce
+new ideas.
+{\tt SPIDER} does make it possible to create a new {\tt WEB} quickly,
+and to tinker with it easily.
+The author's group routinely uses Spidery {\tt WEB} to write programs
+in Ada, C, and~SSL, and has been pleased with the result.
+We have written in {\tt WEB} an application of eighteen thousand
+lines, and
+we are very pleased at how easy it has been to review and maintain
+this code.
+The author hopes that the availability of Spidery {\tt WEB} will
+encourage other groups to try literate programming, and that they,
+too, will be pleased with the results.
+
+
+
+\begin{thebibliography}{Van~Wyk~9999}
+\bibitem[Bentley~86]{bentley:lp}
+Jon L. Bentley, ``Programming Pearls,''
+{\sl Communications of the ACM} {\bf 29:5} (May~1986), 364--368, and
+{\bf 29:6} (June~1986), 471--483.
+\bibitem[Knuth~84]{knuth:literate-programming}
+Donald E. Knuth, ``Literate Programming,'' {\sl The Computer Journal}
+{\bf 27:2} (1984), 97--111.
+\bibitem[Levy~87]{levy:cweb}
+Silvio Levy, ``{\tt WEB} Adapted to C, Another Approach,''
+ {\sl TUGBoat} {\bf 8:1} (1987), 12--13.
+\bibitem[Van~Wyk~87]{cvw:loom}
+Christopher J. Van~Wyk, ``Literate Programming,''
+{\sl Communications of the ACM} {\bf 30:7} (July~1987), 593--599, and
+{\bf 30:12} (December~1987), 1000--1010.
+\end{thebibliography}
+
+\end{document}
diff --git a/web/spiderweb/doc/spdjman.tex b/web/spiderweb/doc/spdjman.tex
new file mode 100644
index 0000000000..bcb6b28a8a
--- /dev/null
+++ b/web/spiderweb/doc/spdjman.tex
@@ -0,0 +1,2065 @@
+% $Header: /usr2/nabe/Tools/WEB_Tool/Spiderweb/doc-j/RCS/spdjman.tex,v 1.5 92/02/28 16:34:11 nabe Exp $
+% This file is translated from English into Japanese by Izumi Watanabe,
+% (nabe@miya.fujifilm.co.jp).
+% As Mr. Ramsey wrote, to be used for reserch purposes only.
+% This file contains Japanese Kanji-character codes, called EUC (Extended
+% Unix Code), and is written for Japanese-LaTeX, called ASCII-jLaTeX.
+
+
+%% Copyright 1989 by Norman Ramsey and Odyssey Research Associates
+%% To be used for research purposes only
+%% For more information, see file COPYRIGHT in the parent directory
+
+% ¤³¤ÎÆüËܸìÌõ¤Ï»²¹Í¤È¤·¤Æ ÅÏÊÕÀô(nabe@miya.fujifilm.co.jp)¤¬¹Ô¤Ê¤¤¤Þ¤·¤¿¡£
+% ¤³¤Î¥É¥­¥å¥á¥ó¥È¤Ï¥ª¥ê¥¸¥Ê¥ë¤Î spider.man ¤ò½¤Àµ¤·¤¿¤â¤Î¤Ê¤Î¤Ç¡¢
+% Mr. Ramsey ¤Î»ØÄêÄ̤ê¤Ë¸¦µæÌÜŪ¤Ë¤Î¤ß»ÈÍѲÄǽ¤Ç¤¹¡£
+% °·¤¤¤Ë¤ÏÃí°Õ¤·¤Æ²¼¤µ¤¤¡£
+
+%% spiderman.tex, with apologies to Stan Lee
+
+%%\documentstyle[11pt]{article}
+\documentstyle[a4j]{jarticle}
+\setcounter{secnumdepth}{0}
+\newcommand{\syntax}[1]{\mbox{$\langle\hbox{\sl #1\/}\rangle$}}
+\newcommand{\produces}{\mbox{${}::={}$}}
+\newcommand{\opt}[1]{$[$#1$]$}
+\newcommand{\BS}{\relax}
+\chardef\BS=`\\ % backslash in a string
+\def\jem{\em\gt}
+\def\P#1#2{#2:#1}
+\newcommand {\WEB}{{\tt WEB}}
+
+\title{{Spider} ¥æ¡¼¥¶¡¼¥º¥¬¥¤¥É}
+\author{Norman Ramsey\thanks{
+ Department of Computer Science, Princeton University,
+ ``A {Spider} User's Guide'',{July 1989}.}\ Ãø \\
+ ÅÏÊÕÀô\thanks{Æü·Ðmix:w.izumi, nabe@miya.fujifilm.co.jp}\ Ìõ}
+\date{Feb 1992 \\ J-$Revision: 1.5 $}
+
+\begin{document}
+\maketitle
+
+\section{¤Ï¤¸¤á¤Ë}
+Donald Knuth ¤Ï {\tt WEB} ¤È¤¤¤¦¡¢¹½Â¤²½¥É¥­¥å¥á¥ó¥Æ¡¼¥·¥ç¥ó¡¦¥·¥¹¥Æ¥à¤ò
+{\TeX} ¥×¥í¥¸¥§¥¯¥È~\cite{knuth:literate-programming} ¤Î°ìÉô¤È¤·¤Æ³«È¯¤·¤¿¡£
+{\tt WEB}¤ò»È¤¦¤È¡¢¥×¥í¥°¥é¥Þ¡¼¤Ï¼«Ê¬¤Î¥×¥í¥°¥é¥à¤ò¤¤¤¯¤Ä¤â¤Î¤«¤¿¤Þ¤ê (
+{\jem ¥â¥¸¥å¡¼¥ë}) ¤Ëʬ³ä¤·¤Æ¡¢¤½¤ì¤é¤Ëʸ¾Ï¤òÉÕÍ¿¤·¡¢¹¥¤­¤Ê½çÈÖ¤ËÀâÌÀ¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ë¡£
+Knuth ¤¬ºî¤Ã¤¿¤â¤Î¤Ç¤Ï¡¢³Æ¥â¥¸¥å¡¼¥ë¤Ï PASCAL ¥×¥í¥°¥é¥à¤Ç¤¢¤ê¡¢
+¤½¤ì¤é¤¬ {\TeX} ¤ò»ÈÍѤ·¤ÆÀ¶½ñ¤µ¤ì¤ë¡£
+
+ {\tt WEB} ¤Î¥¢¥¤¥Ç¥¢¤Ï¡¢{\jem Ǥ°Õ}¤Î¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì¤È
+{\jem Ǥ°Õ}¤Îʸ½ñÀ¶½ñ¸À¸ì\index{\P{document formatting language}{ʸ½ñÀ¶½ñ¸À¸ì}}
+¤ò·ë¹ç¤¹¤ëÊýË¡¤òÄó°Æ¤·¤Æ¤¤¤ë¡£
+¤·¤«¤·¡¢ºÇ¶á¤Þ¤Ç¤Ï¡¢PASCAL ¥×¥í¥°¥é¥àÍѤΠ\WEB °Ê³°¤Î
+»Ù±ç¥½¥Õ¥È¥¦¥§¥¢¤Ï¤Ê¤«¤Ã¤¿¡£
+\hbox{1987ǯ}¤Ë¡¢Silvio Levy ¤¬ C¤Î¤¿¤á¤Î{\tt WEB} ¥·¥¹¥Æ¥à¤òC ¤Ç½ñ¤­Ä¾¤·¤¿¡£
+¤³¤Î»þ¤âʸ½ñÀ¶½ñ¸À¸ì¤È¤·¤Æ¤Ï {\TeX} ¤¬°ú¤­Â³¤­»È¤ï¤ì¤¿~\cite{levy:cweb}¡£
+É®¼Ô¤Ï¡¢Levy ¤Î½ñ¤¤¤¿¤â¤Î¤ò½¤Àµ¤·¡¢ C ¤ò¥¿¡¼¥²¥Ã¥È¸À¸ì¤È¤¹¤ëÉôʬ¤ò¼è¤ê½ü¤¤¤¿¡£
+¤½¤·¤Æ¡¢{Spider}¤È¤¤¤¦ {\tt WEAVE}¤È{\tt TANGLE}¤òºî¤ë
+Â裳¤Î¥Ä¡¼¥ë¤òÄɲä·¤¿¡£
+{Spider} ¤Ï¡¢¤¢¤ë ¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì¤Ë¤Ä¤¤¤Æ¤Îµ­½Ò¤òÆɤߡ¢
+¤½¤Î¸À¸ì¤ò¥µ¥Ý¡¼¥È¤·¤¿ {\tt WEAVE} ¤È {\tt TANGLE} ¤Î¥½¡¼¥¹¥³¡¼¥É¤ò
+½ñ¤­½Ð¤¹¡£
+ {Spider}¡¢ C~¥³¥ó¥Ñ¥¤¥é¡¢ Awk~¥¤¥ó¥¿¥×¥ê¥¿¤ò»È¤¨¤Ð¡¢
+ ·Ð¸³¤òÀѤó¤À¥·¥¹¥Æ¥à¥×¥í¥°¥é¥Þ¤Ê¤é Algol ¤Î¤è¤¦¤Ê¸À¸ì¤Î
+{\tt WEB} ¥·¥¹¥Æ¥à¤ò ¿ô»þ´Ö¤ÇÀ¸À®¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¤À¤í¤¦¡£
+
+¤³¤Î¥É¥­¥å¥á¥ó¥È¤Ï¡¢Ç¤°Õ¤Î¥×¥í¥°¥é¥à¸À¸ì¤Î¤¿¤á¤Î{\WEB}¥·¥¹¥Æ¥à¤òºî¤ë¤¿¤á¤Î
+{Spider} ¤Î»È¤¤Êý¤òÀâÌÀ¤·¤Æ¤¤¤ë (¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì¤ÎÁªÂò¤Ï¡¢
+¸å¤Ç¸«¤ë¤³¤È¤Ë¤Ê¤ë¤¬¡¢Spidery {\tt WEB}¤ÎÃæ
+¤Ëºî¤ê¹þ¤Þ¤ì¤¿»ú¶ç¹½Â¤\index{\P{lexical structure}{»ú¶ç¹½Â¤}}
+¤ÎÀ©¸Â¤Ë¤Î¤ßÀ©¸Â¤ò¼õ¤±¤ë)¡£
+»²¹Í½ñ¤È¤·¤Æ
+¡ÖThe Spidery {\WEB} system of structured documentation¡×¤Ç¡¢
+{\WEB} system ¤Îºî¤êÊý¤ò³Ø¤ó¤Ç¤ª¤¯¤È¤è¤¤¡£
+
+
+\paragraph{»öÁ°½àÈ÷}
+{Spider} ¤ò»È¤Ã¤Æ {\WEB} ¥·¥¹¥Æ¥à¤ò
+ºî¤í¤¦¤È¤·¤Æ¤¤¤ë¤Ê¤é¡¢{\tt WEB}¤Ë¤Ê¤¸¤ó¤Ç¤ª¤¯¤³¤È¡£
+{\tt WEB} ¤¬²¿¤ò¤É¤¦¤¹¤ë¤Î¤«¤òÃΤꤿ¤±¤ì¤Ð¡¢
+Knuth ¤Î½ñ¤¤¤¿{\WEB}~\cite{knuth:literate-programming}¤Î¾Ò²ðµ­»ö:
+ {\WEB} users' manual ¤òÆɤó¤Ç¤ª¤¯¤Ù¤­¤Ç¤¢¤ë ( {\WEB} user's manual ¤Ï¡¢
+¼ê»Ï¤á¤È¤·¤Æ¤Ï¤«¤Ê¤ê½ÅÎ̵é¤Ç¤¢¤ë¡£
+»²¹Íʸ¸¥¤ÎÃæ¤Ë¡¢{\WEB}¤Î¤â¤Ã¤ÈƳÆþŪ¤Ê¤â¤Î¤òÁܤ·µá¤á¤Æ¤âÎɤ¤¡£
+Wayne Sewell ¤Î {\it Weaving a Program: Literate Programming in {\tt
+WEB}}
+¤ÏÌò¤ËΩ¤Ä¤À¤í¤¦~\cite{sewell:weaving})¡£
+
+¤³¤ì°Ê¹ß¤Ï¡¢ÆɼԤ¬{\tt WEAVE} ¤È {\tt TANGLE} ¤È¤Ï¤Ê¤Ë¤«¤òÃΤäƤª¤ê¡¢
+¤½¤ì¤é¤¬²¿¤òÆþÎϤȤ·¡¢½ÐÎϤ¹¤ë¤â¤Î¤¬¤Ê¤Ë¤«¤òÃΤäƤ¤¤ë¤â¤Î¤È¤·¤ÆÏäò¿Ê¤á¤ë¡£
+
+
+\paragraph{¤³¤Î¥¬¥¤¥É¤Î¿Ê¤áÊý}
+¤Þ¤º¡¢weaving ¤È tangling ¤ÎÉü½¬¤«¤é»Ï¤á¡¢¸À¸ì¤Ë°Í¸¤·¤Ê¤¤ {\WEB}¤ò
+ºî¤ë¤Î¤ËɬÍפʥ¢¥¤¥Ç¥¢¤ò¤Ä¤«¤á¤ë¤è¤¦¤Ë¤¹¤ë¡£
+¤½¤ì¤«¤é¡¢{\WEB}¤Ë¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì¤Ë¤Ä¤¤¤Æ¶µ¤¨¤ë¤È¤¤¤¦¡¢
+{Spider} ¤ÎÆÃħ¤Ë¤Ä¤¤¤Æ¤ÎµÄÏÀ¤ò½Ò¤Ù¤ë¡£
+¤³¤ì¤é¤ò¾ÜºÙ¤ËÄêµÁ¤·¡¢¤¤¤¯¤Ä¤«¤ÎÎã¤ò¼¨¤¹¡£
+¤½¤·¤ÆºÇ¸å¤Ë¡¢
+{Spider} ¸À¸ì¤È¥Ä¡¼¥ë¤Ë¤Ä¤¤¤Æ¤Î´°Á´¤Êµ­½Ò¤ò¤â¤Ã¤Æ½ª¤ï¤ë¤³¤È¤Ë¤¹¤ë¡£
+
+
+\section{{\tt WEAVE} ¤È {\tt TANGLE} ¤«¤é¸«¤¿À¤³¦}
+{\tt WEAVE} ¤È {\tt TANGLE} ¤Ï¤¤¤º¤ì¤âƱ°ì¤Î{\WEB}¥Õ¥¡¥¤¥ë¤òÆþÎϤȤ¹¤ë¡£
+{\tt WEAVE} ¤Ï¡¢ÆþÎϤò¸¡ºº¤·¡¢{\TeX}¥Æ¥­¥¹¥È¤òÀ¸À®¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£°ìÊý¡¢
+{\tt TANGLE} ¤Ï¡¢Æ±¤¸ÆþÎϤ«¤é¥×¥í¥°¥é¥à¥Æ¥­¥¹¥È¤òÀ¸À®¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
+ÆþÎϤϡ¢{\TeX}Éô¡¢ÄêµÁÉô¡¢¥³¡¼¥ÉÉô¤«¤é¤Ê¤ë¡£
+ {\TeX}Éô¤Ï¤â¤Ã¤È¤â°·¤¤¤¬ÍưפǤ¢¤ë: {\tt WEAVE} ¤Ç¤Ï¥³¥Ô¡¼¤·¡¢
+ {\tt TANGLE} ¤Ç¤Ï¼Î¤Æ¤ì¤ÐÎɤ¤¡£
+ÄêµÁÉô¤Ï¾¯¤·Ê£»¨¤Ç¤¢¤ë: {\tt WEAVE}¤Î»Å»ö¤Ï¡¢¤½¤ì¤é¤òÁÈÈǤ·¡¢
+°ìÊý{\tt TANGLE} ¤ÏÄêµÁ¤òµ­²±¤·Å¬ÀڤʤȤ­¤ËŸ³«¤¹¤ë¡£
+¥³¡¼¥ÉÉô¤Ï°ìÈÖÊ£»¨¤Ç¤¢¤ë: {\tt WEAVE} ¤Ï¤½¤ì¤é¤òÀ¶½ñ¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤·¡¢
+{\tt TANGLE} ¤Ï°ì´Ó¤·¤¿¥×¥í¥°¥é¥à¥Æ¥­¥¹¥È¤ËÀ°Íý¤·Ä¾¤µ¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
+
+
+\paragraph{{\WEB}¤Î»ú¶ç²òÀÏ}
+{\tt WEAVE} ¤È {\tt TANGLE} ¤Î¤¤¤º¤ì¤â¡¢¥³¡¼¥ÉÉô¤ò{\jem ¥È¡¼¥¯¥ó}¤ÎÏ¢¤Ê¤ê¤È¤·¤Æ
+²ò¼á¤¹¤ë¡£
+¤¹¤Ù¤Æ¤Î¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì¤¬Æ±¤¸¥È¡¼¥¯¥ó¤ò»ý¤Ã¤Æ¤¤¤ë¤ï¤±¤Ç¤Ï¤Ê¤¤¤Î¤Ç¡¢
+{Spider}¤Î»Å»ö¤Ï¡¢ {\tt WEAVE} ¤È {\tt TANGLE} ¤Ë
+ÆþÎϤò¥È¡¼¥¯¥ó¤Ëʬ²ò¤¹¤ë¤ä¤êÊý¤ò¶µ¤¨¤ë¤³¤È¤Ë¤Ê¤ë
+\footnote{%
+¸½ºß¤Î{\tt WEB}¤Î»ú¶ç²òÀϤμÂÁõ¤Ï¸ÂÄꤵ¤ì¤Æ¤¤¤ë¡£
+¤³¤ì¤Ï¡¢Àµµ¬É½¸½¤ò»È¤Ã¤¿¤â¤Î¤ËÃÖ¤­´¹¤¨¤é¤ì¤ë¤Ù¤­¤Ç¤¢¤ë¡£
+}¡£
+Spidery {\WEB} ¥·¥¹¥Æ¥à¤Ï°Ê²¼¤Î¥È¡¼¥¯¥ó¤òǧ¼±¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£
+\begin{itemize}
+\item ¼±ÊÌ»Ò(identifiers)
+\item ¿ôÃÍÄê¿ô¤Èʸ»úÎóÄê¿ô
+\item ²þ¹Ô
+\item ``µ¿»÷¥»¥ß¥³¥í¥ó'' ({\tt @;})
+\item ͽÌó¸ì
+\item Èó±Ñ¿ô»ú¥È¡¼¥¯¥ó
+\end{itemize}
+
+{\tt TANGLE} ¤Ï¡¢¤³¤ì¤é¤Î¥È¡¼¥¯¥ó¤ò1¤Ä¤ÎŤ¤¥×¥í¥°¥é¥à¥Æ¥­¥¹¥È¤È¤·¤ÆºÆÀ°Íý
+¤·¤¿¤Î¤Á¡¢¥È¡¼¥¯¥óËè¤Ë¥×¥í¥°¥é¥à¥Æ¥­¥¹¥È¤ò½ñ¤­½Ð¤¹¡£
+Ä̾ï {\tt TANGLE} ¤Ï¡¢¥È¡¼¥¯¥ó¤Î´Ö¤Ë¶õÇòʸ»ú¤òÁÞÆþ¤·¤Ê¤¤¡£
+¤·¤«¤·¡¢¼±Ê̻ҡ¢Í½Ìó¸ì¡¢¿ôÃÍÄê¿ô¤Î²ó¤ê¤Ë¤Ï¶õÇò¤ò¤ª¤¯¡£
+ÆþÎϤ¬¡¢
+\begin{quote}
+\tt if 0 > x-y then z := -1;
+\end{quote}
+¤Ê¤é¤Ð¡¢½ÐÎϤϡ¢
+\begin{quote}
+\tt if 0>x-y then z:=-1;
+\end{quote}
+¤È¤Ê¤ê¡¢²òÀϤǤ­¤Ê¤¤¤è¤¦¤Ê
+\begin{quote}
+\tt if0>x-ythenz:=-1;
+\end{quote}
+¤È¤Ï¤Ê¤é¤Ê¤¤¡£
+{\tt TANGLE} ¤¬ÊÑ´¹¤¹¤ë¤Î¤È°ã¤¦¥È¡¼¥¯¥ó¤ò˾¤à»þ¤Ë¤Ï¡¢
+³Æ¥È¡¼¥¯¥ó¤Ë {\tt tangleto}°À­¤òÍ¿¤¨¤ë¤³¤È¤¬¤Ç¤­¤ë¡£
+¤³¤Î»ØÄê¤Ï¡¢¤½¤Î¥È¡¼¥¯¥ó¤ò¥×¥í¥°¥é¥à¥Æ¥­¥¹¥È¤È¤·¤Æ¤É¤¦°õºþ¤¹¤Ù¤­¤«¤ò»ØÄꤹ¤ë
+¤â¤Î¤Ç¤¢¤ë¡£
+Î㤨¤Ð¡¢
+C{\WEB}¤òÀ¸À®¤¹¤ë¤¿¤á¤Î{\tt spider}¥Õ¥¡¥¤¥ë¤Ç¤Ï¡¢{\tt =} ¤ò\ {\tt "=\ "}
+¤È¤¤¤¦Ê¸»úÎó¤Ç°õºþ¤µ¤ì¤ë¥È¡¼¥¯¥ó¤È¤·¤Æ¤ª¤­¤¿¤¤¡£ C ¤Ç¤Ï\ {\tt "=-"} ¤È¤¤¤¦
+ʸ»úÎó¤Î°ÕÌ£¤¬Û£Ëæ¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¦¤«¤é¤Ç¤¢¤ë¡£
+
+%{\tt WEAVE} must turn the token stream into a {\TeX} text that will
+{\tt WEAVE} ¤Ï¥È¡¼¥¯¥ó¤ÎʤӤò{\TeX} ¥Æ¥­¥¹¥È¤ËÊÑ´¹¤·¡¢
+À°·Á°õºþ¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
+¤³¤ì¤Ï 3¤Ä¤Î¥¹¥Æ¥Ã¥×¤Ç¼Â¸½¤µ¤ì¤ë¡£
+\begin{enumerate}
+\item
+{\tt WEAVE} ¤Ï¡¢³Æ¥È¡¼¥¯¥ó¤ò {\jem ¥¹¥¯¥é¥Ã¥×}¤ËÊÑ´¹¤¹¤ë¡£
+¥¹¥¯¥é¥Ã¥×¤Ï¡¢2¤Ä¤Î½ÅÍפÊÆÃÀ­Ãͤò»ý¤Ä: ¤½¤ì¤Ï¡¢
+¹½Ê¸¾å¤Î{\jem ¥«¥Æ¥´¥ê¡¼} ¤È
+{\jem ËÝÌõ$($translation$)$}\index{\P{translation}{ËÝÌõ}}
+¤Ç¤¢¤ë¡£
+¥«¥Æ¥´¥ê¡¼¤Ï¡¢À¶½ñ¤ò¤¹¤ë¤¿¤á¤Îʸˡ¾å¤Îµ­¹æ¤Ç¤¢¤ë;
+¤³¤Îʸˡ¤È¤Ï¡¢{\tt WEAVE} ¤¬À¶½ñÍѤÎÌ¿Îá¤ò»È¤Ã¤Æ¥¹¥¯¥é¥Ã¥×¤òÁȤ߹ç¤ï¤»¤ë
+ÊýË¡¤Ç¤¢¤ë¡£
+%The translations are the {\TeX} texts that will tell {\TeX} exactly
+%how to print the scraps.
+translation\index{translation}¤È¤Ï¡¢{\TeX}¤¬¥¹¥¯¥é¥Ã¥×¤ò°õºþ¤¹¤ë¤¿¤á¤Î
+{\TeX}¥Æ¥­¥¹¥È¤Ç¤¢¤ë¡£
+\item
+{\tt WEAVE}¤Ï¡¢¥¹¥¯¥é¥Ã¥×¤ÎʤӤòÀ¶½ñʸˡ¤Ë¤·¤¿¤¬¤Ã¤Æ´Ô¸µ¤·¤Æ¤¤¤¯(
+{\tt WEAVE} ¤Ï¡¢shift-reduce ¹½Ê¸²òÀϤΰì¼ï¤ò¹Ô¤Ê¤¦)¡£
+translation \index{translation} ¤ò·ë¹ç¤·¤Æ¤¤¤ë¤¢¤¤¤ÀÃæ¡¢{\tt WEAVE} ¤Ï
+¥¤¥ó¥Ç¥ó¥È¡¢¥¢¥¦¥È¥Ç¥ó¥È¡¢¹ÔÊѤ¨¤Ê¤É¤ò¤¹¤ë¤¿¤á¤Î
+{\TeX} ¥Æ¥­¥¹¥È¤òÄɲ䷤Ƥ¤¤¯¡£
+\item
+ÍýÁÛŪ¤Ê¾ì¹ç¤Ë¤Ï¡¢{\tt WEAVE}¤ÏÈó¾ï¤ËŤ¤ translation\index{translation}¤ò»ý¤Ã¤¿
+°ì¤Ä¤Î¥¹¥¯¥é¥Ã¥×¤Ë¤Ê¤ë¤Þ¤Ç¡¢´Ô¸µ¤·¤¿¥¹¥¯¥é¥Ã¥×¤òÊÝ»ý¤¹¤ë¡£
+¤·¤«¤·¡¢¤¿¤Ö¤ó¡¢´Ô¸µ¤Ç¤­¤Ê¤¤¥¹¥¯¥é¥Ã¥×¤ÎʤӤˤè¤Ã¤Æ½ª¤Ã¤Æ¤·¤Þ¤¦¤À¤í¤¦¡£
+¤¤¤º¤ì¤Ë¤»¤è¡¢¤½¤ì°Ê¾å´Ô¸µ¤Ç¤­¤Ê¤¯¤Ê¤Ã¤¿¸å¤Ï¡¢
+»Ä¤Ã¤¿¥¹¥¯¥é¥Ã¥×¤Î translation\index{translation}¤ò°ì¤Ä¤º¤Ä½ÐÎϤ¹¤ë¡£
+\end{enumerate}
+
+
+\section{{Spider}¤ò»È¤Ã¤Æ {\WEB}¤Î¥È¡¼¥¯¥óʬ²ò¤ò·è¤á¤ë}
+{Spider} ¤Ï ¥È¡¼¥¯¥ó¤ò ͽÌó¸ì¤È¤½¤Î¾ ¤Î 2¼ïÎà¤Ë¶èÊ̤¹¤ë¡£
+ͽÌó¸ì¤Ï¡¢¥³¥Þ¥ó¥É {\tt reserved} ¤È {\tt ilk}
+¤ò»È¤Ã¤Æ»ØÄꤹ¤ë¡£
+¤½¤Î¾¤Î¥È¡¼¥¯¥ó¤Ï¡¢¥³¥Þ¥ó¥É{\tt token}¤ò»È¤Ã¤Æ»ØÄꤹ¤ë(
+%This somewhat unusual setup is dictated by the way {\tt
+%WEAVE} works; its advantage is that is is easy to define a whole group
+%of reserved words that will be treated identically.)
+¤³¤Î¤¤¤µ¤µ¤«ÈóÄê¾ïŪ¤ÊÀßÄê¤Ï¡¢{\tt WEAVE}¤ÎÊʤ˹ç¤ï¤»¤ë¤¿¤á¤Ç¤¢¤ë¡£
+¤³¤ì¤Ï¡¢¶èÊ̤·¤Æ°·¤Ã¤ÆÍߤ·¤¤Í½Ìó¸ì¤Î¥°¥ë¡¼¥×Á´ÂΤò´Êñ¤ËÄêµÁ¤Ç¤­¤ë¤È¤¤¤¦
+Ĺ½ê¤ò»ý¤Ä)¡£
+%Here's how it works: the {\tt reserved} command designates
+Ư¤­¤ò°Ê²¼¤Ë¼¨¤½¤¦: {\tt reserved} ¥³¥Þ¥ó¥É¤ÏÆÃÄê¤Î¼±Ê̻Ҥò
+ͽÌó¸ì¤È¤·¤Æ¤ß¤Ê¤·¡¢¤É¤Î¤è¤¦¤Ê{\jem ilk $($°À­$)$}¤È¤·¤Æ°·¤ï¤ì¤ë¤«¤ò
+ÌÀ¼¨¤¹¤ë¡£
+% a particular identifier as a reserved word, and says
+%what {\jem ilk} it belongs to.
+%The {\tt token} and {\tt ilk} commands tell {\tt WEAVE} and {\tt
+%TANGLE} what to do with a particular token, or with all the reserved
+%words of a particular ilk.
+¥³¥Þ¥ó¥É {\tt token} ¤È {\tt ilk} ¤Ï¡¢{\tt WEAVE} ¤È {\tt TANGLE}¤Ë
+¤½¤Î¥È¡¼¥¯¥ó¤ò¤É¤¦¤¹¤ë¤«¡¢¤Þ¤¿¤Ï¤½¤Î°À­¤ò»ý¤ÄÁ´¤Æ¤ÎͽÌó¸ì¤ò
+¤É¤¦¤¹¤ë¤«¤ò»ØÄꤹ¤ë¡£
+
+%For each token or ilk one can specify the {\jem tangleto} field, the
+%token's {\jem mathness} (whether it has to be typeset in math mode), and
+%its {\jem category} and {\jem translation} (for conversion to scraps).
+³Æ¥È¡¼¥¯¥ó¤È°À­¤Ï {\jem tangleto} ¥Õ¥£¡¼¥ë¥É¤ò»ý¤Ä¤³¤È¤¬¤Ç¤­¡¢
+¥È¡¼¥¯¥ó¤Î {\jem mathness} (¿ô¼°¥â¡¼¥É¤ÇÁÈÈǤ¹¤ë¤³¤È¤Î»ØÄê)¤È¡¢
+{\jem ¥«¥Æ¥´¥ê¡¼}¡¢{\jem translation}\index{translation} (¥¹¥¯¥é¥Ã¥×¤Ç¤Î
+µ­½Ò¤ò»²¾È)¤ò
+»ØÄê¤Ç¤­¤ë¡£
+¥«¥Æ¥´¥ê¡¼°Ê³°¤Ï¡¢{\tt defaults}¤Ç¤½¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤòÀßÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤ë¡£
+¥«¥Æ¥´¥ê¡¼Ì¾¤Ï¥æ¡¼¥¶¡¼¤ÎǤ°Õ¤Ç¤¢¤ë¡£
+
+¥È¡¼¥¯¥óʬ²ò¤Î¥³¥Þ¥ó¥É¤Ë¤Ä¤¤¤Æ¤Ï¡¢¸å¤Û¤É{Spider}¤Î¹½Ê¸¤ò¾ÜºÙ¤ËÀâÌÀ¤¹¤ë»þ¤Ë
+µÄÏÀ¤·¤¿¤¤¡£
+¤È¤â¤«¤¯¡¢
+C~¸À¸ìÍѤÎ{\tt spider} ¥Õ¥¡¥¤¥ë¤Î¥È¡¼¥¯¥óʬ²ò¥³¥Þ¥ó¥É¤ÎÎã¤ò
+¸«¤ë¤³¤È¤Ë¤·¤è¤¦:
+\begin{verbatim}
+token + category unorbinop
+token - category unorbinop
+token * category unorbinop
+token = category equals translation <"\\leftarrow"> tangleto <"="-space>
+token ~ category unop translation <"\\TI">
+token & category unorbinop translation <"\\amp">
+token ^ translation <"\\^"> category binop
+token ? translation <"\\?"> category question
+token % translation <"\\%"> category binop
+token # translation <"\\#"> category sharp
+token ! category unop translation <"\\neg">
+token ( category lpar
+token ) category rpar
+token [ category lpar
+token ] category rpar
+token { translation <"\\{"> category lbrace
+token } translation <"\\}"> category rbrace
+token ++ category unop translation <"\\PP">
+token -- category unop translation <"\\MM">
+token != translation <"\\I"> category binop
+token == translation <"\\S"> category binop
+token && translation <"\\W"> category binop
+
+ilk case_like category case
+ilk int_like category int
+
+reserved auto ilk int_like
+reserved break ilk case_like
+reserved case ilk case_like
+reserved char ilk int_like
+\end{verbatim}
+¤³¤³¤Ë¤Ï¡¢C¤Ç»È¤ï¤ì¤ë¥È¡¼¥¯¥ó¤Î¤¤¤¯¤Ä¤«¤ÎÄêµÁÎ㤬¼¨¤µ¤ì¤Æ¤¤¤ë¡£
+{\tt tangleto}¥ª¥×¥·¥ç¥ó¤¬ ¤Û¤È¤ó¤É¤Î¾ì¹ç¥Ç¥Õ¥©¥ë¥È¤Î¤Þ¤Þ¤Ç¤¢¤ë¤³¤È¤È¡¢
+¤½¤·¤Æ {\tt translation} ¥ª¥×¥·¥ç¥ó¤¬¤·¤Ð¤·¤Ð¥Ç¥Õ¥©¥ë¥È¤Î¤Þ¤Þ¤Ç¤¢¤ë¤³¤È¤Ë
+Ãí°Õ¤·¤ÆÍߤ·¤¤¡£
+
+%Once the tokens are specified, and each has a {\tt tangleto} string,
+%we can almost construct a {\tt TANGLE} for the language.
+°ìÅ٥ȡ¼¥¯¥ó¤¬»ØÄꤵ¤ì¡¢¤½¤ì¤¾¤ì{\tt tangleto} ʸ»úÎó¤ò»ý¤Ã¤Æ¤¤¤ì¤Ð¡¢
+¸À¸ì¤È¤·¤Æ¤Î{\tt TANGLE} ¤Ï¡¢¤Û¤È¤ó¤É¹½ÃۤǤ­¤¿¤è¤¦¤Ê¤â¤Î¤Ç¤¢¤ë¡£
+% Before we can construct a {\tt WEAVE}, we have to tell it how to
+%combine and reduce scraps.
+{\tt WEAVE}¤ò¹½ÃÛ¤¹¤ë¤¿¤á¤Ë¤Ï¡¢¥¹¥¯¥é¥Ã¥×¤Î·ë¹ç¤È´Ô¸µ¤Ë¤Ä¤¤¤Æ¤Î¤ä¤êÊý¤ò
+»ØÄꤷ¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
+
+
+
+\section{{Spider}¤Ç{\tt WEAVE}¤Î¥¹¥¯¥é¥Ã¥×¤Î´Ô¸µ¤Î»ÅÊý¤ò»ØÄꤹ¤ë}
+%The most intricate part of {\tt WEAVE} is its mechanism for converting
+%programming language code into \TeX\ code.
+{\tt WEAVE}¤Î¤â¤Ã¤È¤âÊ£»¨¤ÊÉôʬ¤Ï¡¢¥×¥í¥°¥é¥à¸À¸ì¤Î¥³¡¼¥É¤ò \TeX\ ¥³¡¼¥É¤Ë
+ËÝÌõ¤¹¤ë¤È¤³¤í¤Ë¤¢¤ë¡£
+%{\tt WEAVE} uses a simple bottom-up parsing algorithm, since it
+% must deal with fragmentary
+%constructions whose overall ``part of speech'' is not known.
+{\tt WEAVE} ¤Ï¡¢Ã±½ã¤Ê ¾å¾º·¿¹½Ê¸²òÀÏ¥¢¥ë¥´¥ê¥º¥à¤ò»È¤Ã¤Æ¤¤¤ë¡£
+¤½¤ì¤Ï¡¢ ´ûÃΤΡÖÏä·¸ÀÍդΰìÉô¡×¤Ç¤Ï¤Ê¤¤¡¢Ê¬ÃǤµ¤ì¤Æ¤¤¤ë¹½Â¤¤ò
+°·¤ï¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤¿¤á¤Ç¤¢¤ë¡£
+
+ÆþÎϤϡ¢{\jem ¥¹¥¯¥é¥Ã¥×} ¤ÎʤӤȤ·¤ÆÍ¿¤¨¤é¤ì¡¢
+³Æ¥¹¥¯¥é¥Ã¥×¤Ï 2¤Ä¤Î¾ðÊó¤ò´Þ¤ó¤Ç¤¤¤ë¡£
+{\jem category} ¤È {\jem translation}\index{translation}¤Ç¤¢¤ë¡£
+¥«¥Æ¥´¥ê¡¼¤Ï´ðËÜŪ¤Ë¹½Ê¸Åª¤Ê¥¯¥é¥¹¤ò¼¨¤·¡¢
+translation\index{translation} ¤Ï{\TeX}¥³¡¼¥É¤ò¼¨¤·¤Æ¤¤¤ë¡£
+¹½Ê¸µ¬Â§¤È°ÕÌ£µ¬Â§¤ÏÎÙ¤¢¤Ã¤¿¥¹¥¯¥é¥Ã¥×¤ò¤è¤êÂ礭¤Ê¤â¤Î¤Ë¤Þ¤È¤á¤ëÊýË¡¤òµ¬Äꤹ¤ë¡£
+±¿¤¬Îɤ±¤ì¤Ð¡¢¥×¥í¥°¥é¥à¥Æ¥­¥¹¥ÈÁ´Éô¤¬¡¢
+²¿É´¤â¤Î¾®¤µ¤Ê¥¹¥¯¥é¥Ã¥×¤À¤Ã¤¿¤È¤³¤í¤«¤é¡¢¸ß¤¤¤Ë·ë¹ç¤µ¤ì¤Æ¹Ô¤­¡¢
+°ì¤Ä¤ÎµðÂç¤Ê¥¹¥¯¥é¥Ã¥×¤Ë¤Ê¤ê¡¢
+¤½¤Î translation\index{translation} ¤¬´üÂÔ¤·¤Æ¤¤¤¿ \TeX\ ¥³¡¼¥É¤Ë¤Ê¤ë¤À¤í¤¦¡£
+±¿¤¬°­¤±¤ì¤Ð¡¢¤¤¤¯¤Ä¤«¤Î¥¹¥¯¥é¥Ã¥×¤Ï·ë¹ç¤µ¤ì¤Ê¤¤¤Þ¤Þ¤Ë¤Ê¤ë¤À¤í¤¦;
+¤½¤ì¤é¤Î translation\index{translation} ¤Ïñ½ã¤Ë°ì¤Ä¤º¤Ä½ÐÎϤµ¤ì¤ë¤³¤È¤Ë¤Ê¤ë¡£
+
+·ë¹çµ¬Â§¤Ï¡¢º¸¤«¤é±¦¤Ø¤Îʸ̮°Í¸À¸À®µ¬Â§\index{\P{context-sensitive productions}{
+ʸ̮°Í¸À¸À®µ¬Â§}}
+¤È¤·¤ÆÍ¿¤¨¤é¤ì¤ë¡£
+º£¡¢ $s_1\,s_2\ldots s_n$ ¤È¤¤¤¦¥¹¥¯¥é¥Ã¥×¤ÎʤӤò½èÍý¤·¤Æ¤¤¤ë¤È¤¹¤ë¡£
+ºÇ½é¤ÎʤӤǤ¢¤ë$s_1\,s_2\ldots\,$ ¤ËÂФ¹¤ëºÇŤÎÀ¸À®µ¬Â§¤òõ¤¹¡£
+¤·¤«¤·¡¢¤â¤·¤½¤Î¤è¤¦¤ÊÀ¸À®µ¬Â§¤¬Â¸ºß¤·¤Ê¤±¤ì¤Ð¡¢
+¼¡¤Î $s_2\,s_3\ldots\,$ ¤ËÂФ·¤ÆºÇŤÎÀ¸À®µ¬Â§¤ò¼¡¡¹¤Ëõ¤·¤Æ¤æ¤¯¡£
+¤½¤·¤Æ¡¢¤½¤ì¤â¼ºÇÔ¤·¤¿¤é $s_3\,s_4\ldots\,$, etc. ¤È¤¤¤¦¶ñ¹ç¤Ë¥Þ¥Ã¥Á¥ó¥°¤ò»î¹Ô¤¹¤ë¡£
+
+À¸À®µ¬Â§¤Ï¡¢¤¢¤é¤«¤¸¤áÍ¿¤¨¤é¤ì¤¿¥«¥Æ¥´¥ê¡¼¥³¡¼¥É¤Î¥Ñ¥¿¡¼¥ó¤ò»ý¤Ä»þ¤ËŬÍѤµ¤ì¤ë¡£
+Î㤨¤Ð¡¢¤¢¤ëÀ¸À®µ¬Â§¤¬
+$$\hbox{\tt open [ math semi <"\BS\BS,"-opt-5> ] -->
+open math}$$
+¤Ç¤¢¤ì¤Ð¡¢¤½¤ì¤Ï¡¢
+¤½¤ì¤¾¤ì{\tt open}¡¢ {\tt math}¡¢ {\tt semi}¤È¤¤¤¦¥«¥Æ¥´¥ê¡¼¤ò»ý¤Ä3¤Ä¤Î
+Ϣ³¤·¤¿¥¹¥¯¥é¥Ã¥×¤Ï¡¢
+ {\tt open} ¤È {\tt math}¤È¤¤¤¦¥«¥Æ¥´¥ê¡¼¤ò»ý¤Ä
+2¤Ä¤Î¥¹¥¯¥é¥Ã¥×¤ËÊÑ´¹¤µ¤ì¤ë¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
+{\tt open}¥¹¥¯¥é¥Ã¥×¤ÏÊÑ´¹¤µ¤ì¤Ê¤¤¡£°ìÊý¡¢
+ʸ»úÎó {\tt <"\BS\BS,"-opt-5>} ¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¤Î¤Ç¡¢
+¿·¤·¤¤ {\tt math} ¥¹¥¯¥é¥Ã¥×¤Ï
+¸µ¤Î{\tt math}¤Îtranslation\index{translation}¡¢
+{\tt semi} ¤Îtranslation\index{translation}¡¢
+ `{\tt \BS,}'¡¢ `{\tt opt}'¡¢ `{\tt5}'
+¤È¤¤¤¦°ìÏ¢¤Î¤â¤Î¤Ç¹½À®¤µ¤ë¤³¤È¤Ë¤Ê¤ë(
+ \TeX\ ¥Õ¥¡¥¤¥ë¤Ë¤ª¤¤¤Æ¡¢¤³¤ì¤ÏÄɲäµ¤¤¥¹¥Ú¡¼¥¹¤¬¥»¥ß¥³¥í¥ó¤Î¸å¤Ë
+ÉÕ¤­¡¢
+penalty 50 ¤Î optional line break ¤¬Â³¤¯¤³¤È¤ò°ÕÌ£¤¹¤ë)¡£
+translation\index{translation} ¤Ï ³Ñ³ç¸Ì ({\tt <>}) ¤Ç³ç¤é¤ì¤Æ¤ª¤ê¡¢
+°úÍÑÉä({\tt "})¤Ç³ç¤é¤ì¤¿Ê¸»úÎó(
+C ¤Î´Ä¶­¤Ç¤Ï¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å({\tt \BS}) ¤Ç¥¨¥¹¥±¡¼¥×¤µ¤ì¤¿Ê¸»ú¤Ç¤âÎɤ¤)¡¢
+ÆÃÊ̤ʥ­¡¼¥ï¡¼¥É¤ò´Þ¤à¤³¤È¤¬¤Ç¤­¤ë¡£
+
+Ìò¤ËΩ¤ÄÀ¸À®µ¬Â§¤ÎÎã¤ò¼¨¤¹Á°¤Ë¡¢
+{Spider}¤Î¹½Ê¸¤ÎÂçÉôʬ¤ò´Þ¤à¥µ¥Ö¥»¥Ã¥È¤Î¾ÜºÙ¤òÀâÌÀ¤·¤è¤¦¡£
+
+
+
+\section{{\tt spider} ¥Õ¥¡¥¤¥ë¤Î¹½Ê¸}
+
+{Spider} ¤Ï¡¢{\tt WEAVE} ¤È {\tt TANGLE}¤Î¤¿¤á¤Ë
+¸À¸ì¤Îµ­½Ò¤òC¤Î¥³¡¼¥É¤ËÊÑ´¹¤¹¤ë Awk ¥×¥í¥°¥é¥à¤Ç¤¢¤ë¡£
+{Spider}¤¬ Awk ¥×¥í¥°¥é¥à¤Ê¤Î¤Ç¡¢ÆþÎϤϹԤΥ·¡¼¥±¥ó¥¹¤Ç¤¢¤ê¡¢
+Á´¤Æ¤Î {Spider} ¥³¥Þ¥ó¥É¤¬1¹Ô¤Ë¼ý¤Þ¤é¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
+
+\paragraph{¥³¥á¥ó¥È¤È¶õÇò¹Ô}
+{\jem Ǥ°Õ¤Î} ʸ»úÎó¤¬¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì¤Î¥È¡¼¥¯¥ó¤Ë¤Ê¤êÆÀ¤ë¤Î¤Ç¡¢
+ÆÃÄê¤Îʸ»úʤӤò ``¥³¥á¥ó¥È¤Î³«»Ïµ­¹æ''¤È¤·¤Æ·è¤á¤Æ¤ª¤¯¤³¤È¤¬¤Ç¤­¤Ê¤¤¡£
+½¾¤Ã¤Æ¡¢ {Spider} ¤Ë¤Ï¥³¥á¥ó¥È¤Ï¤Ê¤¯¡¢ {\jem ¥³¥á¥ó¥È¹Ô}¤Î¤ß¤¬¤¢¤ë¡£
+¥³¥á¥ó¥È¹Ô¤Ï¡¢ºÇ½é¤¬ ``{\tt \#}'' ¤Ç»Ï¤Þ¤Ã¤Æ¤¤¤ë¹Ô¤Ç¤¢¤ë¡£
+{Spider}½èÍý·Ï¤Ï¥³¥á¥ó¥È¹Ô¤È¶õÇò¹Ô¤ò̵»ë¤¹¤ë¡£
+
+\paragraph{¥Õ¥£¡¼¥ë¥É}
+{\tt spider} ¤Î³Æ¥³¥Þ¥ó¥É¤Ï¡¢{\jem ¥Õ¥£¡¼¥ë¥É}¤ÎʤӤ«¤é¤Ê¤ë¡£
+¤³¤ì¤Ï¡¢Awk ¤Î¥Õ¥£¡¼¥ë¥É¤ÈƱ°ì¤Ç¡¢¥Û¥ï¥¤¥È¥¹¥Ú¡¼¥¹\index{white space}
+¤Ç¶èÀÚ¤é¤ì¤Æ¤¤¤ë¡£
+¤³¤Î Awk ¤«¤é·Ñ¾µ¤·¤¿À­¼Á¤Î¤æ¤¨¤Ë¡¢{Spider}¤Ï¥Õ¥£¡¼¥ë¥ÉÃæ¤Ë
+¥Û¥ï¥¤¥È¥¹¥Ú¡¼¥¹¤Ï»ÈÍѤǤ­¤Ê¤¤¡£
+
+
+\subsection{ËÝÌõ}
+%Most fields in a {Spider} file are simple identifiers, or perhaps
+%strings of non-alphanumeric characters.
+{Spider}¥Õ¥¡¥¤¥ë¤ÎÂçÉôʬ¤Î¥Õ¥£¡¼¥ë¥É¤Ï¡¢Ã±½ã¤Ê¼±ÊÌ»Ò\index{identifier}¤«¡¢
+¤¿¤Ö¤óÈó±Ñ¿ô»úʸ»ú\index{non-alphanumeric character}¤Ç¤¢¤ë¡£
+%The major exception is {\jem translations}.
+ºÇÂç¤ÎÎã³°¤Ï¡¢{\jem ËÝÌõ}\index{translations}¤Ç¤¢¤ë¡£
+%Translations are always surrounded by angle brackets ({\tt <>}),
+ËÝÌõ¤Ï¾ï¤Ë³Ñ¥«¥Ã¥³\index{angle bracket} ({\tt <>}) ¤Ç°Ï¤Þ¤ì¤Æ¤ª¤ê¡¢
+%and consist of a (possibly empty) list of translation pieces.
+(¶õ¤Ç¤âÎɤ¤)ËÝÌõÍ×ÁÇ\index{translation pieces}¤Î¥ê¥¹¥È¤Ç¤¢¤ë¡£
+%The pieces on a list are separated by dashes ({\tt -}).
+¥ê¥¹¥ÈÃæ¤Î³ÆÍ×ÁǤϡ¢¥À¥Ã¥·¥å({\tt -})¤Ç¶èÀÚ¤é¤ì¤ë¡£
+ËÝÌõÍ×ÁǤϡ¢²¼µ­¤Î°ì¤Ä¤Ç¤¢¤ë¡£
+\begin{itemize}
+\item °úÍÑÉä¤Ç°Ï¤Þ¤ì¤¿Ê¸»úÎó.
+¤³¤Îʸ»úÎó¤Ï¡¢``\verb+\+'' ¤Ç¥¨¥¹¥±¡¼¥×¤µ¤ì¤¿Ê¸»ú¤òµö¤¹¤¬¡¢
+¥Û¥ï¥¤¥È¥¹¥Ú¡¼¥¹¤È¥À¥Ã¥·¥å¤ò´Þ¤ó¤Ç¤Ï¤Ê¤é¤Ê¤¤¡£
+\item ``self'' ¥Þ¡¼¥«¡¼, ``{\tt *}'',
+ ¤Ï¡¢ËÝÌõ¤µ¤ì¤è¤¦¤È¤·¤Æ¤¤¤ë¥È¡¼¥¯¥ó¤Îʸ»úÎó¤ò»²¾È¤¹¤ë¡£
+%refers to the sequence of characters making up the token being translated.
+%The self marker is permitted only in certain contexts, and its precise
+%meaning depends on the context.
+¥»¥ë¥Õ¥Þ¡¼¥«¤Ï³ÎÄꤷ¤Æ¤¤¤ëʸ̮¤ÎÃæ¤Ç¤Î¤ßµö¤µ¤ì¤Æ¤ª¤ê¡¢¤½¤Î°ÕÌ£¤¹¤ë¤È¤³¤í¤Ï
+ʸ̮¤Ë°Í¸¤·¤Æ¤¤¤ë¡£
+\item ¿ô»ú
+\item ¥­¡¼¥ï¡¼¥É:
+{Spider} ¤Î¥­¡¼¥ï¡¼¥É¤Ï¡¢°Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡£
+\begin{description}
+\item [\tt space] 1¤Ä¤Î¶õÇòʸ»ú ({\tt "\ "})¤ò°ÕÌ£¤¹¤ë.
+\item[\tt dash] 1¤Ä¤Î¥À¥Ã¥·¥å ({\tt "-"})¤ò°ÕÌ£¤¹¤ë.
+\end{description}
+¤½¤Î¾¤Î¥­¡¼¥ï¡¼¥É¤Ï{\tt WEAVE}¤ËÅϤµ¤ì¤ë¡£
+
+{\tt WEAVE} ¤Ï¡¢°Ê²¼¤Î¥­¡¼¥ï¡¼¥É¤òǧ¼±¤¹¤ë:
+\begin{description}
+\item[\tt break\_space] optional line break ¤Þ¤¿¤Ï ¶õÇò;
+\item[\tt force] line break;
+\item[\tt big\_force] ¿âľ¥¹¥Ú¡¼¥¹¤ò»ý¤Ä line break;
+\item[\tt opt] optional line break ( °Ê¹ß¤Î¹Ô¤ÏÄ̾ï¤Î³«»Ï°ÌÃÖ¤è¤ê
+2em ¥¤¥ó¥Ç¥ó¥È¤µ¤ì¤ë)---
+¤³¤Î¥³¡¼¥É¤Ï¡¢À°¿ô$n$ ¤òȼ¤¤¡¢break ¤Ï¥Ú¥Ê¥ë¥Æ¥£ $10n$ ¤È¤·¤Æ°·¤ï¤ì¤ë¡£
+%code is followed by an integer $n$, and the break will occur with penalty
+%$10n$;
+\item[\tt backup] 1em ¤Î backspace;
+\item[\tt cancel] Àè¹Ô¤·¤Æ¤¤¤¿\ ¤Þ¤¿¤Ï³¤¯¤¹¤Ù¤Æ¤Î {\tt break\_space},
+ {\tt force},{\tt big\_force} ¤ò¼è¤ê¾Ã¤¹¡£¤µ¤é¤Ë¡¢
+³¤¯ {\tt backup} ¥È¡¼¥¯¥ó¤â¥­¥ã¥ó¥»¥ë¤¹¤ë;
+\item[\tt indent] °Ê¹ß¤Î¹Ô¤ò 1em ¥¤¥ó¥Ç¥ó¥È¤¹¤ë
+\item[\tt outdent] °Ê¹ß¤Î¹Ô¤ò -1em ¥¤¥ó¥Ç¥ó¥È¤¹¤ë
+\item[\tt math\_rel] \verb+\mathrel{+ ¤ËÊÑ´¹¤µ¤ì¤ë
+\item[\tt math\_bin] \verb+\mathbin{+ ¤ËÊÑ´¹¤µ¤ì¤ë
+\item[\tt math\_op] \verb+\mathop{+ ¤ËÊÑ´¹¤µ¤ì¤ë
+\end{description}
+¿ô¼°¥â¡¼¥É¤Ç¤âÀµ¤·¤¯½èÍý¤µ¤ì¤ë {\jem Í£°ì} ¤Î¥­¡¼¥ï¡¼¥É¤Ï¡¢{\tt
+indent} ¤È {\tt outdent}¤À¤±¤Ç¤¢¤ë¡£
+¤â¤·¡¢Â¾¤Î¥­¡¼¥ï¡¼¥É¤ò´Þ¤àËÝÌõ¤òÄêµÁ¤·¤¿¤¤»þ¤Ï¡¢
+¤½¤Î¥È¡¼¥¯¥ó¤Ë¤Ï{\tt mathness~no} ¤ò»È¤ï¤Í¤Ð¤Ê¤é¤Ê¤¤¡£
+%You may use any recognized key words in the translations of a
+%production; there the mathness is automatically taken care of for you.
+À¸À®µ¬Â§¤ÎËÝÌõ¤ÎÃæ¤Ç¤Ï¡¢¤É¤ó¤Ê¥­¡¼¥ï¡¼¥É¤ò»È¤Ã¤Æ¤â¹½¤ï¤Ê¤¤¡£
+¤½¤ì¤é¤Î¿ô¼°À­¤Ï¼«Æ°Åª¤Ë½èÍý¤µ¤ì¤ë¡£
+\end{itemize}
+
+°Ê²¼¤Ï¡¢ËÝÌõ\index{translation}¤ÎÎã¤Ç¤¢¤ë¡£:
+\begin{verbatim}
+<"\\"-space>
+<indent-force>
+<"{\\let\\\\=\\bf"-space>
+<"}"-indent-"{}"-space>
+\end{verbatim}
+
+\paragraph{À©¸Â¤µ¤ì¤¿ËÝÌõ}\index{Restricted translations}
+¤¤¤¯¤Ä¤«¤Î¾ì¹ç¤Ï¡¢Î㤨¤Ð¡¢{\tt tangleto} µ­½Ò¤Ê¤É¤Ç¤Ï¡¢
+ËÝÌõ\index{translations}¤ÏÀ©¸Â¤µ¤ì¤ë¡£
+À©¸Â¤µ¤ì¤¿ËÝÌõ\index{restricted translation} ¤Ï¡¢¥¿¥¤¥×¥»¥Ã¥Æ¥£¥ó¥°¥³¡¼¥É¤Ë
+ÊÑ´¹¤µ¤ì¤ë¤³¤È¤Ï¤Ê¤¯ ¾ï¤Ë ASCII ʸ»úÎó¤È¤Ê¤ë¡£
+%is never converted to typesetting code,
+%but is always converted to an ASCII string,
+%usually for output by {\tt
+%TANGLE}, but sometimes for other things.
+¤¿¤¤¤Æ¤¤¤Ï{\tt TANGLE} ¤Î½ÐÎÏÍѤ˻Ȥï¤ì¤ë¤¬¡¢Ê̤ÎÍÑÅӤǤâ»È¤¦¡£
+À©¸Â¤µ¤ì¤¿ËÝÌõ\index{restricted translation}¤Ï¡¢
+{\jem °úÍÑÉä¤Ç³ç¤é¤ì¤¿Ê¸»úÎó} ¤ª¤è¤Ó¡¢
+{\tt space} ¤È{\tt dash} ¤Î2¤Ä¤Î¥­¡¼¥ï¡¼¥É¤Î¤ß¤¬µö¤µ¤ì¤ë¡£
+
+
+\subsection{{\tt token} ¥³¥Þ¥ó¥É}
+{\tt token} ¥³¥Þ¥ó¥É¤Î¹½Ê¸¤Ï¡¢¼¡¤ÎÄ̤ê¤Ç¤¢¤ë:
+\begin{quote}
+\tt
+\syntax{command} \produces~token \syntax{token-designator}
+\syntax{token-descriptions}
+\end{quote}
+¤³¤³¤Ç \syntax{token-descriptions} ¤Ï (¶õ¤Ç¤âÎɤ¤) ¥È¡¼¥¯¥óµ­½Ò¤Î¥ê¥¹¥È¤Ç¤¢¤ë¡£
+
+\paragraph{¥È¡¼¥¯¥óµ­½Ò}
+¥È¡¼¥¯¥óµ­½Ò¤Ï
+\begin{itemize}\parindent=0pt
+\item
+{\tt tangleto \syntax{restricted translation}}
+
+\syntax{restricted translation} ¤Ï {\tt TANGLE}¤Ë
+¤³¤Î¥È¡¼¥¯¥ó¤ò¥×¥í¥°¥é¥à¥Æ¥­¥¹¥È¤Ë½ñ¤­½Ð¤¹¤â¤Î¤òµ¬Äꤹ¤ë¡£
+À©¸Â¤µ¤ì¤¿ËÝÌõ\index{restricted translation}¤ÇÍ­¸ú¤Ê¤â¤Î¤Ï¡¢
+{\jem °úÍÑÉä¤Ç³ç¤é¤ì¤¿Ê¸»úÎó} ¤ª¤è¤Ó¡¢
+{\tt space} ¤È{\tt dash} ¤Î2¤Ä¤Î¥­¡¼¥ï¡¼¥É¤Î¤ß¤Ç¤¢¤ë¡£
+¤â¤· {\tt tangleto} µ­½Ò¤¬¤Ê¤±¤ì¤Ð¡¢ {\tt TANGLE} ¤Ï
+¥È¡¼¥¯¥ó¤ò¹½À®¤·¤¿Ê¸»úÎó¤ò½ñ¤­½Ð¤¹¡£
+
+\item
+{\tt translation \syntax{translation}}
+
+%Tells {\tt WEAVE} what translation to assign when making this token into
+%a scrap.
+{\tt WEAVE} ¤¬¥È¡¼¥¯¥ó¤ò¥¹¥¯¥é¥Ã¥×¤ÎÃæ¤ËÃÖ¤¯»þ¤Ë¤É¤¦ËÝÌõ¤¹¤ë¤«¤ò»Ø¼¨¤¹¤ë¡£
+%The self
+%marker~({\tt*}) stands for the sequence of characters that were read in to
+%make up the token.
+¥»¥ë¥Õ¥Þ¡¼¥«¡¼~({\tt*}) ¤Ï¡¢¥È¡¼¥¯¥ó¤ò¹½À®¤·¤Æ¤¤¤ëʸ»úÎ󤽤Τâ¤Î¤ò¼¨¤¹¡£
+ËÝÌõ¤Ï¤·¤Ð¤·¤Ð \verb+translation <*>+ ¤¬¥Ç¥Õ¥©¥ë¥È¤È¤Ê¤ë; {Spider}
+¤Ï¤³¤ì¤ò¤¢¤é¤«¤¸¤á¥Ç¥Õ¥©¥ë¥È¤È¤·¤ÆÁȤ߹þ¤ó¤Ç¤¢¤ë¡£
+
+\item
+{\tt category \syntax{category-name}}
+
+%Tells {\tt WEAVE} what category to assign when making this token into
+%a scrap.
+{\tt WEAVE} ¤¬¤³¤Î¥È¡¼¥¯¥ó¤ò¥¹¥¯¥é¥Ã¥×¤Ë¤¤¤ì¤ë¤È¤­¤Ë»È¤¦¥«¥Æ¥´¥ê¡¼¤ò»ØÄꤹ¤ë¡£
+{Spider} ¥Õ¥¡¥¤¥ë¤ò½ñ¤¯»þ¤Ï¹¥¤­¤Ê¥«¥Æ¥´¥ê¡¼Ì¾¤ò
+»È¤¦¤³¤È¤¬¤Ç¤­¤ë¡£
+¼é¤ë¤Ù¤­¾ò·ï¤Ï¡¢{Spider} ¤¬ÃΤäƤ¤¤ë¾¤Î̾Á°(ͽÌó¥­¡¼¥ï¡¼¥É¡¢
+ilk¤Î̾Á° ¤Ê¤É)¤È¾×Æͤ·¤Ê¤¤¤è¤¦¤Ë¤¹¤ë¤³¤È¤À¤±¤Ç¤¢¤ë¡£
+%Using category names that are identical to reserved words of the
+%target programming language (¤Þ¤¿¤Ï C~¤ÎͽÌó¸ì) is not only
+%supported, it is strongly encouraged, for clarity.
+%Using category names that are identical to reserved words of the
+¥«¥Æ¥´¥ê¡¼Ì¾¤ò
+¥¿¡¼¥²¥Ã¥È¸À¸ì¤ÎͽÌó¸ì(¤Þ¤¿¤Ï C~¤ÎͽÌó¸ì)¤ÈƱ°ì¤Ë¤·¤Æ¤ª¤¯¤³¤È¤Ï¡¢
+ÌÀ²÷¤µ¤Î°Ù¤À¤±¤Ç¤Ê¤¯¡¢¶¯¤¤Í×ÀÁ¤Ç¤¢¤ë¡£
+%Also, when we get to the sample grammars later on, you will see some
+%other conventions we use for category names.
+¸å¤Û¤Éʸˡ¤ÎÎã¤ò¸«¤ë¤³¤È¤Ë¤Ê¤ë¤¬¡¢
+¥«¥Æ¥´¥ê¡¼Ì¾¤ò»È¤¦¤¿¤á¤Î¤¤¤¯¤Ä¤«¤ÎÌó«»ö¤¬¤¢¤ë¡£
+
+\item
+{\tt mathness \syntax{mathness-indicator}}
+
+¤³¤³¤Ç¡¢\syntax{mathness-indicator} ¤Ï {\tt yes}¡¢{\tt no}¡¢{\tt
+maybe}¤Î¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£
+%This indicates to {\tt WEAVE} whether the translation for this token
+%needs to be typeset in {\TeX}'s math mode or not, or whether it
+%doesn't matter.
+¤³¤ì¤Ï {\tt WEAVE} ¤¬¤³¤Î¥È¡¼¥¯¥ó¤ò°õºþ¤¹¤ë¤¿¤á¤Î translation ¤È¤·¤Æ
+{\TeX}¤Î¿ô¼°¥â¡¼¥É¤ò»È¤¦¤«Èݤ«¡¢¤Þ¤¿¤Ïµ¤¤Ë¤¹¤ëɬÍפ¬¤Ê¤¤¤«¤ò»Ø¼¨¤¹¤ë¡£
+¤³¤ÎÀ¸À®µ¬Â§¤¬Å¬ÍѤµ¤ì¤¿¤È¤­¡¢
+{\tt WEAVE} ¤Ï¿ô¼°¥·¥Õ¥Èʸ»ú~(\verb+$+) ¤ò{\TeX}¥Æ¥­¥¹¥ÈÃæ¤Ë¤ª¤¯¤³¤È¤Ç
+Àµ¤·¤¤¥â¡¼¥É¤Ë¥È¡¼¥¯¥ó¤¬ÃÖ¤«¤ì¤ë¤³¤È¤òÊݾڤ·¤è¤¦¤È¤¹¤ë¡£
+%Tokens with the {\jem empty translation} (\verb+<>+) should always have
+%{\tt mathness maybe}, lest they cause {\tt WEAVE} to place two
+%consecutive math shift characters.
+{\jem ¶õ¤Î translation} (\verb+<>+) ¤ò»ý¤Ä¥È¡¼¥¯¥ó¤Ï¾ï¤Ë
+{\tt mathness maybe}¤Ç¤¢¤ë¤È¤ß¤Ê¤µ¤ì¡¢¤½¤Î·ë²Ì¤È¤·¤Æ {\tt WEAVE}¤¬
+2¤Ä¤Î¿ô¼°¥·¥Õ¥Èʸ»ú¤òÃÖ¤¯¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë°·¤ï¤ì¤ë¡£
+
+\item
+{\tt name \syntax{token-name}}
+
+¤³¤ì¤Ï¡¢{Spider} ¤Þ¤¿¤Ï {\WEB}¤Î¥Ç¥Ð¥Ã¥°¤Î»þ¤Î¤ß¤Ë»È¤ï¤ì¤ë¡£
+%It causes the specified name to be attached to the token,
+¤³¤ì¤Ë¤è¤Ã¤Æ¡¢¥È¡¼¥¯¥ó¤Ï»ØÄꤵ¤ì¤¿Ì¾Á°¤¬ÉÕÍ¿¤µ¤ì¡¢
+%so that a programmer can search for that name in the C~code generated by
+%{Spider}.
+¥×¥í¥°¥é¥Þ¡¼¤Ï{Spider}¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤¿C~¥³¡¼¥É¤ÎÃ椫¤é¤³¤Î̾Á°¤ò
+¸¡º÷¤¹¤ë¤³¤È¤¬²Äǽ¤Ë¤Ê¤ë¡£
+
+\end{itemize}
+
+%\paragraph{Token designators}
+\paragraph{¥È¡¼¥¯¥ó̾}
+{Spider} ¤Ï°Ê²¼¤Î ¥È¡¼¥¯¥ó̾¤òǧ¼±¤¹¤ë:
+\begin{description}
+\item[{\tt ¼±ÊÌ»Ò(identifier)}]
+¤³¤ì¤ò»È¤¦ {\tt token} ¥³¥Þ¥ó¥É¤Ï
+{\tt WEAVE} ¤È {\tt TANGLE} ¤Ë¼±Ê̻ҥȡ¼¥¯¥ó¤ËÂФ¹¤ë½èÍý¤ò»Ø¼¨¤¹¤ë¡£
+»ÄÇ°¤Ê¤¬¤é¡¢{Spider} ¤Ë²¿¤ò¼±Ê̻ҤȤ¹¤Ù¤­¤«¤ò»ØÄꤹ¤ë¤³¤È¤Ï¤Ç¤­¤Ê¤¤¡£
+¼±Ê̻ҤÎÄêµÁ¤Ï{\tt WEAVE} ¤È {\tt TANGLE}¤ÎÆâÉô¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ë¡£
+¼±Ê̻Ҥϰʲ¼¤ÎÀµµ¬É½¸½¼°¤Ë¹çÃפ¹¤ëºÇŤÎʸ»úÎó¤Ç¤¢¤ë%
+\footnote{ÆɼԤ¬ Unix ¤ÎÀµµ¬É½¸½¤ËÆëÀ÷¤ß¤¬¤Ê¤¤¤Î¤Ç¤¢¤ì¤Ð¡¢
+{\it ed(1)} ¤Î¥Þ¥Ë¥å¥¢¥ë¥Ú¡¼¥¸¤ò»²¹Í¤Ë¤·¤ÆÍߤ·¤¤¡£}:
+\begin{verbatim}
+[a-zA-Z_][a-zA-Z0-9_]*
+\end{verbatim}
+
+\item[{\tt ¿ôÃÍ(number)}]
+{Spider} ¤È {\tt WEAVE}¤Î¸½¾õ¤Î¼Â¸½¤Î»ÅÊý¤Ç¤Ï¡¢
+{\tt token} ¥³¥Þ¥ó¥É¤Ï¿ôÃÍÄê¿ô¤Èʸ»úÎóÄê¿ô¤ÎξÊý¤ò¥«¥Ð¡¼¤¹¤ë¡£
+¼±Ê̻ҤÈƱÍͤˡ¢¿ôÃÍÄê¿ô¤Èʸ»úÄê¿ô¤¬²¿¤Ç¹½À®¤µ¤ì¤ë¤«¤È¤¤¤¦ÄêµÁ¤Ï
+Êѹ¹¤¹¤ë¤³¤È¤¬¤Ç¤­¤Ê¤¤¡£
+{\samepage
+¿ôÃÍÄê¿ô¤Ï°Ê²¼¤Î¤è¤¦¤ÊºÇĹ¹çÃפǤ¢¤ë%
+\footnote{¸À¸ì¤¬»ý¤ÄÉâÆ°¾®¿ôÅÀɽµ­¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤¿¤á¤Î
+{\WEB} ¥³¥ó¥È¥í¡¼¥ë¥·¡¼¥±¥ó¥¹¤¬¤¢¤Ã¤ÆÅöÁ³¤Ç¤¢¤ë¡£}:
+\begin{verbatim}
+[0-9]+(\.[0-9]*)?
+\end{verbatim}
+}
+ʸ»úÎóÄê¿ô¤Ï°Ê²¼¤Î¤è¤¦¤ÊºÇĹ¹çÃפǤ¢¤ë
+\begin{verbatim}
+\"([^"]*\\\")*[^"]*\"|'[^@\]'|'\\.'|'@@'
+\end{verbatim}
+¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å~(\verb+\+)¤Ç¥¨¥¹¥±¡¼¥×¤µ¤ì¤¿²þ¹Ô¤Ïʸ»úÎóÄê¿ô¤Ë
+´Þ¤à¤³¤È¤¬¤Ç¤­¤ë¡£
+
+\item[{\tt newline}]
+¤³¤ì¤ò»È¤¦{\tt token} ¥³¥Þ¥ó¥É¤Ï {\tt WEAVE} ¤È {\tt
+TANGLE} ¤Ë²þ¹Ô¤Î°·¤¤Êý¤ò»Ø¼¨¤¹¤ë¡£
+¸å¤Û¤É¡¢{\tt WEAVE} ¤Ë²þ¹Ô¤ò̵»ë¤µ¤»¤ëÊýË¡¤ò¼¨¤¹¡£
+
+\item[{\tt pseudo\_semi}]
+¤³¤ì¤ò»È¤¦{\tt token} ¥³¥Þ¥ó¥É¤Ï¡¢
+{\tt WEAVE} ¤¬
+{\tt @;}¤È¤¤¤¦{\WEB} ¥³¥ó¥È¥í¡¼¥ë¥·¡¼¥±¥ó¥¹¤Ç½èÍý¤¹¤ë¤³¤È¤ò»ØÄꤹ¤ë¡£
+¤³¤Î¥³¥ó¥È¥í¡¼¥ë¥·¡¼¥±¥ó¥¹¤Ï{\tt TANGLE}¤Ç¤Ï¾ï¤Ë̵»ë¤µ¤ì¤ë¡£
+
+\item[\syntax{characters}]
+¤³¤³¤Ç¡¢characters ¤ÏÈó±Ñ¿ô»ú¤Ç¤¢¤ë¡£
+¤³¤ì¤ò»È¤¦ {\tt token} ¥³¥Þ¥ó¥É¤Ï¡¢
+ʸ»úÎó¤ò¥È¡¼¥¯¥ó¤È¤·¤ÆÄêµÁ¤·¡¢
+{\tt WEAVE} ¤È {\tt TANGLE} ¤¬¤³¤Î¥È¡¼¥¯¥ó¤ËÂФ·¤Æ¹Ô¤Ê¤¦½èÍý¤ò»Ø¼¨¤¹¤ë¡£
+¥È¡¼¥¯¥ó¤Ï¾¤Î¥È¡¼¥¯¥ó¤ÎÀÜƬ¼­¤Ç¤¢¤Ã¤Æ¤âÎɤ¤; {\tt WEAVE} ¤È {\tt TANGLE}
+¤ÏºÇŤΤâ¤Î¤òºÎÍѤ¹¤ë¡£
+¤½¤¦¤¤¤¦¤ï¤±¤Ç¡¢ C~{\WEB}¤Ç¤Ï¡¢ \verb+==+ ¤Ïñ°ì¤Î\ \verb+==+ ¥È¡¼¥¯¥ó
+¤È¤·¤ÆÆɤ߹þ¤Þ¤ì¡¢
+Æó¤Ä¤Î \verb+=+ ¥È¡¼¥¯¥ó¤È¤µ¤ì¤ë¤³¤È¤Ï¤Ê¤¤¡£
+\end{description}
+
+
+
+
+\subsection{ͽÌó¸ì¥È¡¼¥¯¥ó}
+%Reserved words are attached to a particular {\jem ilk} using the {\tt
+%reserved} command.
+ͽÌó¸ì¤Ï{\tt reserved} ¥³¥Þ¥ó¥É¤ÇÆÃÄê¤Î {\jem ilk} ¤È·ë¤ÓÉÕ¤±¤é¤ì¤ë¡£
+\begin{quote}
+\tt reserved \syntax{reserved-word} $[$ilk \syntax{ilk-name}$]$
+\end{quote}
+%If you're writing a {Spider} file, you may choose any ilk
+%names you like, subject only to the restriction that they not conflict
+%with other names known to {Spider} (e.g.~predefined key words,
+%names of categories, and so on).
+{Spider} ¥Õ¥¡¥¤¥ë¤ò½ñ¤¯»þ¤Ï¹¥¤­¤Ê¥«¥Æ¥´¥ê¡¼Ì¾¤ò
+»È¤¦¤³¤È¤¬¤Ç¤­¤ë¡£
+¼é¤ë¤Ù¤­¾ò·ï¤Ï¡¢{Spider} ¤¬ÃΤäƤ¤¤ë¾¤Î̾Á°(ͽÌó¥­¡¼¥ï¡¼¥É¡¢
+ilk¤Î̾Á°¡¢ ¤Ê¤É)¤È¾×Æͤ·¤Ê¤¤¤è¤¦¤Ë¤¹¤ë¤³¤È¤À¤±¤Ç¤¢¤ë¡£
+%The convention, however, is to use ilk {\tt with\_like} for a reserved
+%word {\tt with}, and so on.%
+¤·¤«¤·¤Ê¤¬¤é¡¢Ìó«»ö¤È¤·¤ÆÎ㤨¤Ð{\tt with}¤È¤¤¤¦Í½Ìó¸ì¤Ë¤Ï{\tt with\_like}
+¤È¤¤¤¦ ilk ¤¬»È¤ï¤ì¤ë%
+\footnote{%
+¤³¤ÎÌó«»ö¤Î¤»¤¤¤Ç¡¢É®¼Ô¤ÏÍ­³²¤Êµ¡Ç½¤ò{Spider}¤Ë²Ã¤¨¤ë¤È¤¤¤¦Í¶ÏǤË
+É餱¤Æ¤·¤Þ¤Ã¤¿ --- ¤â¤· {\tt reserved}¡¡¥³¥Þ¥ó¥É¤Ç ilk ¤ò¾Êά¤·¤Æ¤·¤Þ¤Ã¤¿¤é¡¢
+%{Spider} will make an ilk name by appending {\tt \_like}
+%to the name of the reserved word.
+{Spider}¤ÏͽÌó¸ì¤Î̾Á°¤Î¸å¤í¤Ë{\tt \_like}¤òÉղä·¤¿ ilk ̾¤òºî¤í¤¦¤È¤¹¤ë¡£
+%Furthermore, if that ilk doesn't already exist, {Spider} will
+%construct one.
+¤µ¤é¤Ë¡¢¤½¤Î¤è¤¦¤Ê ilk ¤¬¤Þ¤À¸ºß¤·¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢
+{Spider}¤Ï¤½¤ì¤òºî¤Ã¤Æ¤·¤Þ¤¦¡£
+¤³¤Îµ¡Ç½¤ò»È¤Ã¤Æ¤Ï¤¤¤±¤Ê¤¤¡£
+}¡£
+
+{\tt ilk}¥³¥Þ¥ó¥É¤È {\tt token} ¥³¥Þ¥ó¥É¤ÏÈó¾ï¤Ë»÷¤¿¹½Ê¸¤ò»ý¤Ä¡£
+{\tt ilk} ¥³¥Þ¥ó¥É¤Î¹½Ê¸¤Ï¡¢°Ê²¼¤ÎÄ̤ê:
+\begin{quote}\tt
+\syntax{command} \produces~ilk \syntax{ilk-name}
+\syntax{token-descriptions}
+\end{quote}
+%In translations that appear in {\tt ilk} commands, the self
+%marker~({\tt *}) designates the string of characters making up the
+%reserved word, surrounded by \verb+\&{...}+, which makes the reserved
+%words appear in bold face.
+{\tt ilk}¥³¥Þ¥ó¥ÉÃæ¤Ë¸½¤ì¤ë translation ¤Ë¤ª¤¤¤Æ¡¢
+¥»¥ë¥Õ¥Þ¡¼¥«¡¼~({\tt *})¤ÏͽÌó¸ì¼«¿È¤ò¹½À®¤¹¤ëʸ»úÎó\ ¤ò°ÕÌ£¤·¡¢
+\verb+\&{...}+ ¤Ç°Ï¤Þ¤ì¤Æ
+ͽÌó¸ì¤ò°ÕÌ£¤¹¤ë¥Ü¡¼¥ë¥ÉÂΤǰõºþ¤µ¤ì¤ë¡£
+
+
+
+
+
+
+
+
+\section{À°·Á°õºþʸˡ¤Î¹½Ê¸}
+%Defining the tokens of a language is somewhat tedious, but it is
+%essentially straightforward, and the definition usually does not need
+%fine tuning.
+¸À¸ì¤Î¥È¡¼¥¯¥ó¤òÄêµÁ¤¹¤ë¤³¤È¤Ï¡¢¤¤¤µ¤µ¤«Âà¶þ¤Ê¤â¤Î¤Ç¤¢¤ë¡£
+¤·¤«¤·¡¢´ðËÜŪ¤Ë¤ÏľÀÜŪ¤Ë¤Ç¤­¡¢
+ÉáÄ̤ÏÄêµÁ¼«ÂΤ˥Á¥å¡¼¥Ë¥ó¥°¤ò¤¹¤ëɬÍפϤʤ¤¡£
+%When developing a new {\WEB} with {Spider}, you will spend most of
+%your time writing the grammar that tells {\tt WEAVE} how to reduce
+%scraps.
+{Spider} ¤Ë¤è¤Ã¤Æ¿·¤·¤¤ {\WEB} ¤ò³«È¯¤¹¤ë¤È¤­¤Ë¤Ï¡¢
+¤Û¤È¤ó¤É¤Î»þ´Ö¤ò {\tt WEAVE} ¤¬¥¹¥¯¥é¥Ã¥×¤ò´Ô¸µ¤¹¤ë¤¿¤á¤Îʸˡ¤ò½ñ¤¯¤³¤È¤Ë
+Èñ¤ä¤¹¤³¤È¤Ë¤Ê¤ë¤À¤í¤¦¡£
+%The grammar is defined as a sequence of context-sensitive productions.
+ʸˡ¤Ï¡¢Ê¸Ì®¤Ë°Í¸¤¹¤ëÀ¸À®µ¬Â§¤È¤·¤ÆÄêµÁ¤µ¤ì¤ë¡£
+%Each production has the form:
+³Æ¡¹¤ÎÀ¸À®µ¬Â§¤Ï¼¡¤Î¤è¤¦¤Ê·Á¼°¤ò»ý¤Ä:
+\begin{quote}
+\tt
+\syntax{left context} [ \syntax{firing instructions} ] \syntax{right context}
+\\\null\qquad
+--> \syntax{left context} \syntax{target category} \syntax{right context}
+\end{quote}
+%where the left and right contexts are (possibly empty) sequences of
+%scrap designators,
+¤³¤³¤Ç¡¢ left context ¤È right context ¤Ï(¶õ¤Ç¤âÎɤ¤)
+¥¹¥¯¥é¥Ã¥×¥·¡¼¥±¥ó¥¹¤ò¼¨¤·¡¢
+%the firing instructions are a sequence of scrap
+%designators and translations (containing at least one scrap
+%designator),
+firing instructions ¤Ï¡¢
+¥¹¥¯¥é¥Ã¥×̾¾Î¤È(¾¯¤Ê¤¯¤È¤â°ì¤Ä¤Î¥¹¥¯¥é¥Ã¥×¤ò»ØÄꤷ¤Æ¤¤¤ë)
+¥È¥é¥ó¥¹¥ì¡¼¥·¥ç¥ó¤Î¥·¡¼¥±¥ó¥¹¤Ç¤¢¤ê¡¢¤½¤·¤Æ
+%and the target category is a category designator.
+target category ¤Ï¥«¥Æ¥´¥ê¡¼Ì¾¾Î¤Ç¤¢¤ë¡£
+%If the left and right contexts are both empty, the square brackets
+%({\tt []}) can be omitted, and the production is context free.
+¤â¤·¡¢ left context ¤È right context ¤Î¤¤¤º¤ì¤â¶õ¤Ç¤¢¤ì¤Ð¡¢
+³Ñ³ç¸Ì({\tt []}) ¤Ï¾Êά²Äǽ¤Ç¤¢¤ê¡¢À¸À®µ¬Â§¤Ïʸ̮¤Ë°Í¸¤·¤Ê¤¤¤â¤Î¤È¤Ê¤ë¡£
+%The left and right contexts must be the same on both sides of the {\tt
+%-->}.
+left context ¤È right context ¤Ï {\tt -->} ¤ÎξÊÕ¤ÇƱ°ì¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
+
+%What does the production mean?
+À¸À®µ¬Â§¤Î°ÕÌ£¤¹¤ë¤â¤Î¤Ï²¿¤À¤í¤¦¤« ?
+%Well, {\tt WEAVE} is trying to reduce a sequence of scraps.
+¤½¤¦¡¢{\tt WEAVE} ¤Ï¥¹¥¯¥é¥Ã¥×¤Î¥·¡¼¥±¥ó¥¹¤ò´Ô¸µ¤·¤è¤¦¤È¤¹¤ë¡£
+%So what {\tt WEAVE} does is look at the sequence, to find out whether
+%the left hand side of some production matches an initial subsequence
+%of the scraps.
+¤·¤¿¤¬¤Ã¤Æ¡¢{\tt WEAVE} ¤Ï¥·¡¼¥±¥ó¥¹¤òÄ´¤Ù¡¢¤É¤ÎÀ¸À®µ¬Â§¤Îº¸ÊÕ¤¬
+ºÇ½é¤Ë¥¹¥¯¥é¥Ã¥×¤ÎÉôʬ¥·¡¼¥±¥ó¥¹¤Ë¹çÃפ¹¤ë¤«¤ò¸«¤Ä¤±¤è¤¦¤È¤¹¤ë¡£
+%{\tt WEAVE} picks the first matching production, and {\jem fires} it,
+%reducing the scraps described in the firing instructions to a single
+%scrap, and it gives the new scrap the {\jem target category}.
+{\tt WEAVE} ¤ÏºÇ½é¤Ë¹çÃפ·¤¿À¸À®µ¬Â§¤ò¼è¤ê¾å¤²¡¢¤½¤ì¤ò {\jem ŬÍѤ·}¡¢
+{firing instructions} ¤Ëµ­½Ò¤µ¤ì¤Æ¤¤¤¿¥¹¥¯¥é¥Ã¥×¤ò°ì¤Ä¤Î¥¹¥¯¥é¥Ã¥×¤Ë´Ô¸µ¤·¡¢
+¿·¤·¤¤¥¹¥¯¥é¥Ã¥×¤ò{\jem target category} ¤È¤¹¤ë¡£
+%The translation of the new scrap is formed by concatenating the
+%translations in the {\jem firing instructions}, where a scrap
+%designator stands for the translation of the designated scrap.
+¿·¤·¤¤¥¹¥¯¥é¥Ã¥×¤Î¥È¥é¥ó¥¹¥ì¡¼¥·¥ç¥ó¤Ï{\jem fireing instructions} ¤Î
+¥È¥é¥ó¥¹¥ì¡¼¥·¥ç¥ó¤È·ë¹ç¤¹¤ë¤³¤È¤Ë¤è¤Ã¤ÆÀ°·Á¤µ¤ì¤ë¡£
+¤³¤³¤Ç¡¢¥¹¥¯¥é¥Ã¥×̾¾Î¤Ï¡¢»ØÄꤵ¤ì¤¿¥¹¥¯¥é¥Ã¥×¤Î
+¥È¥é¥ó¥¹¥ì¡¼¥·¥ç¥ó¤Î¤³¤È¤Ç¤¢¤ë¡£
+
+%Here is the syntax that describes contexts, firing instructions, scrap
+%designators, and so on.
+°Ê²¼¤Ï¡¢Ê¸Ì®¡¢Ì¿Îá¤Îµ¯Æ°¡¢¥¹¥¯¥é¥Ã¥×¤Î»ØÄê¤Ê¤É¤òµ­½Ò¤·¤¿¤â¤Î¤Ç¤¢¤ë¡£
+\begin{quote}
+\tt
+\syntax{left context} \produces~\syntax{scrap designators}\\
+\syntax{right context} \produces~\syntax{scrap designators}\\
+\syntax{firing instruction} \produces \syntax{scrap designator}\\
+\syntax{firing instruction} \produces \syntax{translation}\\
+\syntax{scrap designator} \produces~?\\
+\syntax{scrap designator} \produces~\opt{!}\syntax{category name}\opt{*}\\
+\syntax{scrap designator}
+ \produces~\opt{!}\syntax{category alternatives}\opt{*}\\
+\syntax{category alternatives}
+ \produces~\rlap{(\syntax{optional alternatives}\syntax{category name})}\\
+\syntax{optional alternative} \produces~\syntax{category name}|\\
+\syntax{target category} \produces~\#\syntax{integer}\\
+\syntax{target category} \produces~\syntax{category name}\\
+\end{quote}
+
+
+%\paragraph{Matching the left hand side of a production}
+\paragraph{À¸À®µ¬Â§¤Îº¸ÊդιçÃ×}
+%When does a sequence of scraps match the left hand side of a
+%production?
+À¸À®µ¬Â§¤Îº¸ÊÕ¤¬¥¹¥¯¥é¥Ã¥×¤ÎʤӤȹçÃפ¹¤ë»þ¤È¤Ï¤¤¤Ä¤À¤í¤¦¤« ?
+%For matching purposes, we can ignore the translations and the square
+%brackets~({\tt []}), and look at the left hand side just as a sequence
+%of scrap designators.
+¹çÃפµ¤»¤ë¤È¤¤¤¦ÌÜŪ¤«¤é¤¤¤¨¤Ð¡¢¥È¥é¥ó¥¹¥ì¡¼¥·¥ç¥ó¤È³Ñ³ç¸Ì~({\tt []})¤Ï
+̵»ë¤·¤Æ¡¢º¸ÊÕ¤ò¤¢¤¿¤«¤â¥¹¥¯¥é¥Ã¥×̾¾Î¤ÎʤӤ«¤é¤À¤±¤Ê¤ë¤â¤Î¤È¤ß¤Ê¤¹
+¤³¤È¤¬¤Ç¤­¤ë¡£
+%A sequence of scraps matches a sequence of scrap designators if and
+%only if each scrap on the sequence matches the corresponding scrap
+%designator.
+¤½¤ÎʤӤÎÃæ¤ÎÂбþ¤¹¤ë¤¹¤Ù¤Æ¤Î¥¹¥¯¥é¥Ã¥×¤Î̾¾Î¤¬°ìÃפ·¤¿¤È¤­¤Ë¤Î¤ß
+¥¹¥¯¥é¥Ã¥×¤ÎʤӤ¬¥¹¥¯¥é¥Ã¥×̾¾Î¤ÎʤӤ˰ìÃפ·¤¿¤È¸«¤Ê¤»¤ë¡£
+%Here are the rules for matching scrap designators (we can
+%ignore starring%
+¤³¤³¤Ç¡¢¥¹¥¯¥é¥Ã¥×̾¾Î¤Î°ìÃפΤ¿¤á¤Îµ¬Â§¤Ï°Ê²¼¤ÎÄ̤ê(¥¹¥¿¡¼¤Ï̵»ë¤·¤ÆÎɤ¤
+\footnote{¥ª¥×¥·¥ç¥ó¤Î {\tt *}¤òȼ¤¦¥«¥Æ¥´¥ê¡¼Ì¾¤Ï¡¢
+{\jem ¥¹¥¿¡¼ÉÕ¤­(starred)}¤È¸Æ¤Ð¤ì¤ë¡£}%
+):
+\begin{itemize}
+\item
+%Every scrap matches the designator {\tt ?}.
+¤¹¤Ù¤Æ¤Î¥¹¥¯¥é¥Ã¥×¤Ï {\tt ?}¤Ë°ìÃפ¹¤ë¡£
+\item
+%A scrap matches \syntax{marked category} if and only if its category
+%is the same as the category of the designator.
+¤½¤Î¥¹¥¯¥é¥Ã¥×¤Î¥«¥Æ¥´¥ê¡¼¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¥¹¥¯¥é¥Ã¥×̾¤È°ìÃפ·¤¿¤È¤­¤Ë¸Â¤ê¡¢
+¤½¤Î¥¹¥¯¥é¥Ã¥×¤Ï \syntax{marked category} ¤È°ìÃפ¹¤ë¡£
+\item
+%A scrap matches {\tt!}\syntax{marked category} if and only if its category
+%is {\jem not} the same as the category of the designator.
+¥¹¥¯¥é¥Ã¥×¤Î¥«¥Æ¥´¥ê¡¼¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¥«¥Æ¥´¥ê¡¼Ì¾¤È°ìÃפ·¤Æ{\jem ¤¤¤Ê¤«¤Ã¤¿}
+»þ¤Ë¤Î¤ß¡¢¤½¤Î¥¹¥¯¥é¥Ã¥×¤Ï {\tt!}\syntax{marked category} ¤È°ìÃפ¹¤ë
+({\tt !} ¤ÏÈÝÄê¤ò°ÕÌ£¤¹¤ë)¡£
+\item
+%A scrap matches a list of category alternatives if and only if its
+%category is on the list of alternatives.
+¥¹¥¯¥é¥Ã¥×¤Î¥«¥Æ¥´¥ê¡¼¤¬ÁªÂò¥ê¥¹¥È¤ÎÃæ¤Ë¤¢¤Ã¤¿¾ì¹ç¤Î¤ß¡¢
+¤½¤Î¥¹¥¯¥é¥Ã¥×¤Ï¥«¥Æ¥´¥ê¡¼¤ÎÁªÂò¥ê¥¹¥È¤Ë°ìÃפ¹¤ë¡£
+\item
+%A scrap matches a {\jem negated} list of category alternatives if and
+%only if its category is {\jem not} on the list of alternatives.
+¥¹¥¯¥é¥Ã¥×¤Î¥«¥Æ¥´¥ê¡¼¤¬ÁªÂò¥ê¥¹¥È¤ÎÃæ¤Ë{\jem ̵¤«¤Ã¤¿}¾ì¹ç¤Ë¤Î¤ß¡¢
+¤½¤Î¥¹¥¯¥é¥Ã¥×¤Ï{\jem ÈÝÄꤵ¤ì¤¿}ÁªÂò¥ê¥¹¥È¤Ë°ìÃפ¹¤ë¡£
+\end{itemize}
+
+
+%\paragraph{Firing a production}
+\paragraph{À¸À®µ¬Â§¤ÎŬÍÑ}
+%Once a match is found, {\tt WEAVE} fires the production by replacing
+%the subsequence of scraps matching the firing instructions.
+¤¤¤Ã¤¿¤ó¹çÃפ¹¤ë¤â¤Î¤¬¸«¤Ä¤«¤Ã¤¿¤é¡¢{\tt WEAVE} ¤ÏÀ¸À®µ¬Â§¤òŬÍѤ·¡¢
+ŬÍѤ·¤¿Ì¿Îá¤Ë°ìÃפ·¤¿¥¹¥¯¥é¥Ã¥×¤Î¥µ¥Ö¥·¡¼¥±¥ó¥¹¤òÃÖ¤­´¹¤¨¤Æ¤æ¤¯¡£
+%{\tt WEAVE} replaces this subsequence with a new scrap whose category
+%is the target category, and whose translation is the concatenation of
+%all the translations in the firing instructions.
+{\tt WEAVE}¤Ï¤³¤Î¥µ¥Ö¥·¡¼¥±¥ó¥¹¤òÌÜŪ¤Î¥«¥Æ¥´¥ê¡¼¤ò»ý¤Ä¿·¤·¤¤¥¹¥¯¥é¥Ã¥×¤Ç
+ÃÖ¤­´¹¤¨¡¢¤½¤Î¥È¥é¥ó¥¹¥ì¡¼¥·¥ç¥ó¤ÏŬÍѤµ¤ì¤¿µ¬Â§¤ÎÃæ¤Î
+¤¹¤Ù¤Æ¤Î¥È¥é¥ó¥¹¥ì¡¼¥·¥ç¥ó¤ò¹ç¤ï¤»¤¿¤â¤Î¤È¤¹¤ë
+%(When the new translation is constructed, the
+%translations of the old scraps are included at the positions of the
+%corresponding scrap designators.)
+(¿·¤·¤¤¥È¥é¥ó¥¹¥ì¡¼¥·¥ç¥ó¤¬ºîÀ®¤µ¤ì¤ë¤È¤­¤Ï¡¢
+¸Å¤¤¥¹¥¯¥é¥Ã¥×¤Î¥È¥é¥ó¥¹¥ì¡¼¥·¥ç¥ó¤Ï¥¹¥¯¥é¥Ã¥×¤ÎÂбþ¤¹¤ë¾ì½ê¤Ë¼è¤ê¹þ¤Þ¤ì¤ë
+)¡£
+%If the target category is not given by name, but rather by
+%number~({\tt \#$n$}), {\tt WEAVE} will take the category of the $n$th
+%scrap in the subsequence that matches the left hand side of the
+%production, and make that the target category.
+¤â¤·ÌÜŪ¤Î¥«¥Æ¥´¥ê¡¼¤¬Ì¾Á°¤Ç¤Ï¤Ê¤¯ {\tt \#$n$}¤È¤¤¤¦ÈÖ¹æ¤Ç»ØÄꤵ¤ì¤Æ¤¤¤¿¤é¡¢
+{\tt WEAVE} ¤ÏÀ¸À®µ¬Â§¤Îº¸ÊÕ¤ÎÂбþ¤¹¤ë $n$ÈÖÌܤΥ«¥Æ¥´¥ê¡¼¤ò¼è¤ê¾å¤²¡¢
+¤½¤ì¤òÌÜŪ¤Î¥«¥Æ¥´¥ê¡¼¤È¤ß¤Ê¤¹¡£
+
+\subparagraph{À¸À®µ¬Â§Å¬ÍѤÎÉûºîÍÑ}
+À¸À®µ¬Â§¤¬Å¬ÍѤµ¤ì¤ë¤È¡¢ {\tt WEAVE} ¤Ï
+%for the first identifier in any {\jem starred} scrap.
+¥¹¥¿¡¼¥É¡¦¥¹¥¯¥é¥Ã¥×¤ÎºÇ½é¤Î¼±Ê̻Ҥò \hbox{\jem ²¼ÀþÉդθ«½Ð¤·¸ì}¤È¤¹¤ë¡£
+
+
+%\paragraph{If no initial subsequence matches any production}
+\paragraph{ºÇ½é¤Î¥µ¥Ö¥·¡¼¥±¥ó¥¹¤¬À¸À®µ¬Â§¤Ë¹çÃפ·¤Ê¤«¤Ã¤¿¾ì¹ç}
+%If the initial subsequence of scraps does not match the left hand side
+%of any production, {\tt WEAVE} will try to match the subsequence
+%beginning with the second scrap, and so on, until a match is found.
+%Once a match is found, {\tt WEAVE} fires the production, changing its
+%sequence of scraps.
+%It then starts all over again at the beginning of the new sequence,
+%looking for a match.%
+½é´ü¥µ¥Ö¥·¡¼¥±¥ó¥¹¤¬º¸ÊÕ¤ÎÀ¸À®µ¬Â§¤È¹çÃפ·¤Ê¤±¤ì¤Ð¡¢
+{\tt WEAVE}¤Ï¼¡¤Î¥µ¥Ö¥·¡¼¥±¥ó¥¹°Ê¹ß¤Ç¹çÃפ¹¤ë¤â¤Î¤ò¸«¤Ä¤±¤è¤¦¤È¤¹¤ë¡£
+¹çÃפ¹¤ë¤â¤Î¤¬¸«¤Ä¤«¤ì¤Ð¡¢ {\tt WEAVE}¤ÏÀ¸À®µ¬Â§¤òŬÍѤ·¡¢
+³Æ¥¹¥¯¥é¥Ã¥×¤ÎʤӤòÊѹ¹¤¹¤ë¡£
+¤½¤·¤Æ¡¢¿·¤·¤¤¥·¡¼¥±¥ó¥¹¤ËÂФ·¤ÆºÇ½é¤«¤é¤â¤¦°ìÅÙ¤ä¤êľ¤¹%
+\footnote{
+%The implementation is better than that; {Spider} figures out just
+%how much {\tt WEAVE} must backtrack to get the same effect as
+%returning to the beginning.%
+¤³¤Î¼Â¸½ÊýË¡¤Ï¡¢
+¡ÖºÇ½é¤ËÌá¤ë¤ÈƱ¤¸¸ú²Ì¤òÆÀ¤ë¤¿¤á¤Ë¤Ï
+{\tt WEAVE}¤¬²¿²ó¥Ð¥Ã¥¯¥È¥é¥Ã¥¯¤ò¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤«¤ò
+{Spider}¤¬ »»½Ð¤¹¤ë¡×
+¤È¤¤¤¦¤â¤Î¤è¤ê¤âÎɤ¤¡£
+}¡£
+%If {\jem no} subsequence of the scraps matches any production, then the
+%sequence of scraps is irreducible, and {\tt WEAVE} writes out the
+%translations of the scraps, one at a time.
+¤¹¤Ù¤Æ¤Î¥µ¥Ö¥·¡¼¥±¥ó¥¹¤¬¤¤¤º¤ì¤ÎÀ¸À®µ¬Â§¤È¤â¹çÃפ·¤Ê¤«¤Ã¤¿¤Ê¤é¤Ð¡¢
+¥¹¥¯¥é¥Ã¥×¤Î¥·¡¼¥±¥ó¥¹¤Ï¸µ¤ËÌᤵ¤ì¤ë¤³¤È¤Ê¤¯ {\tt WEAVE} ¤Ï
+°ì¤Ä¤º¤Ä¥¹¥¯¥é¥Ã¥×¤ÎËÝÌõ¤ò½ñ¤­½Ð¤¹¡£
+
+
+
+
+
+\section{{\tt WEAVE} ʸˡ¤ÎÎã}
+%This all must seem very intimidating, but it's not really.
+%In this section we present some grammar fragments and explain what's
+%going on.
+¤³¤³¤Þ¤Ç¤Î¤¹¤Ù¤Æ¤Î¤³¤È¤Ï¶¼¤·¤Î¤è¤¦¤Ë´¶¤¸¤¿¤«¤âÃΤì¤Ê¤¤¤¬¡¢Á´¤¯¤½¤ó¤Ê¤³¤È¤Ï¤Ê¤¤¡£
+¤³¤Î¾Ï¤Ç¤Ï¤¤¤¯¤Ä¤«¤Îʸˡ¤ò¼¨¤·¡¢²¿¤¬¤Ê¤µ¤ì¤ë¤«¤ò²òÀ⤹¤ë¡£
+
+\paragraph{´Êñ¤ÊÎã}
+\begin{verbatim}
+? ignore_scrap --> #1
+\end{verbatim}
+%This production should appear in every grammar, because Spidery {\tt
+%WEAVE} expects category \verb+ignore_scrap+ to exist with roughly this
+%semantics.
+¤³¤ÎÀ¸À®µ¬Â§¤Ï¤¹¤Ù¤Æ¤Îʸˡ¤Ë¸ºß¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
+¤Ê¤¼¤Ê¤é¡¢Spidery {\tt WEAVE} ¤Ï
+\verb+ignore_scrap+ ¤È¤¤¤¦¥«¥Æ¥´¥ê¡¼¤¬Íð˽¤Ë¤â¤³¤Î°ÕÌ£¤Ç¸ºß¤·¤Æ¤¤¤ë¤È
+¤ß¤Ê¤·¤Æ¤¤¤ë¤¿¤á¤Ç¤¢¤ë
+(Î㤨¤Ð¡¢¥³¥á¥ó¥È¤ÏÁ´¤Æ {\tt ignore\_scrap} ¤È¤¤¤¦¥«¥Æ¥´¥ê¡¼¤Î
+¥¹¥¯¥é¥Ã¥×¤òÀ¸À®¤¹¤ë) ¡£
+%Any scrap of category \verb+ignore_scrap+ essentially doesn't affect
+%the reduction of scraps: it is absorbed into the scrap to its left.
+\verb+ignore_scrap+ ¤È¤¤¤¦¥«¥Æ¥´¥ê¡¼¤Î¤¤¤«¤Ê¤ë¥¹¥¯¥é¥Ã¥×¤â
+´ðËÜŪ¤Ë¤Ï¥¹¥¯¥é¥Ã¥×¤Î´Ô¸µ¤Î±Æ¶Á¤ò¼õ¤±¤Ê¤¤:
+¤½¤Î¤Þ¤Þ¥¹¥¯¥é¥Ã¥×¤ÎÃæ¤ËÃÖ¤«¤ì¤¿¤Þ¤Þ¤Ë¤Ê¤ë¡£
+
+\begin{verbatim}
+token newline category newline translation <>
+newline --> ignore_scrap
+\end{verbatim}
+%This token definition and production, combined with the previous
+%production, causes {\tt WEAVE} to ignore all newlines.
+¤³¤ÎÄêµÁ¤ÈÀ¸À®µ¬Â§¤Ï¡¢Á°½Ò¤ÎÀ¸À®µ¬Â§¤ÈÁȤ߹ç¤ï¤µ¤ì¤Æ
+¤¹¤Ù¤Æ¤Î newline ¤ò{\tt WEAVE}¤Ë̵»ë¤µ¤»¤ë¤³¤È¤Ë¤Ê¤ë¡£
+
+%For this next example, from the C~grammar, you will need to know that
+%{\tt math} represents a mathematical expression, {\tt semi} a
+%semicolon, and {\tt stmt} a statement or sequence of statements.
+¼¡¤Î C¤Îʸˡ¤ÎÎã¤Ç¤Ï¡¢{\tt math} ¤Ï»»½Ñ¼°¡¢
+{\tt semi}¤Ï¥»¥ß¥³¥í¥ó¡¢{\tt stmt}¤Ïʸ¤Þ¤¿¤Ïʸ¤ÎʤӤò°ÕÌ£¤·¤Æ¤¤¤ë¤³¤È¤ò
+ÃǤäƤª¤³¤¦¡£
+\begin{verbatim}
+math semi --> stmt
+stmt <force> stmt --> stmt
+\end{verbatim}
+%The first production says that a mathematical expression, followed by
+%a semicolon, should be treated as a statement.
+Âè°ì¤ÎÀ¸À®µ¬Â§¤Ï¥»¥ß¥³¥í¥ó¤òȼ¤¦»»½Ñ¼°¤Ïʸ¤È¤·¤Æ°·¤ï¤ì¤ë¤³¤È¤ò»Ø¼¨¤¹¤ë¡£
+%The second says that two statements can be combined to make a single
+%statement by putting a line break between them.
+ÂèÆó¤ÎÀ¸À®µ¬Â§¤Ç¤Ï¡¢ 2 ¤Ä¤Îʸ¤Ï 1 ¤Ä¤Îʸ¤È¤·¤Æ·ë¹ç¤µ¤ì¡¢
+´Ö¤Ë²þ¹Ô¤¬ÃÖ¤«¤ì¤ë¤³¤È¤ò»Ø¼¨¤¹¤ë¡£
+
+\paragraph{¼°}
+%This more extended example shows the treatment of expressions in Awk.
+¤³¤Î³ÈÄ¥¤µ¤ì¤¿Îã¤Ï¡¢ Awk ¤Î¼°¤Î°·¤¤¤ò¼¨¤·¤Æ¤¤¤ë¡£
+%This is identical to the treatment of expressions in C and in several
+%other languages.
+¤³¤ì¤Ï¡¢C ¤ä¤¤¤¯¤Ä¤«¤Î¸À¸ì¤Ë¤ª¤±¤ë¼°¤Î°·¤¤¤ÈƱ°ì¤Ç¤¢¤ë¡£
+%We will use the following categories:
+°Ê²¼¤Î¤è¤¦¤Ê¥«¥Æ¥´¥ê¡¼¤ò»È¤¦¤³¤È¤Ë¤¹¤ë:
+\begin{description}
+\item[math] »»½Ñ¼° %A mathematical expression
+\item[binop] Æó¹àÃæÃֱ黻»Ò %A binary infix operator
+\item[unop] ñ¹àÁ°Ãֱ黻»Ò¤Þ¤¿¤Ïñ¹à¸åÃֱ黻»Ò
+ %A unary prefix or postfix operator
+\item[unorbinop] Æó¹àÃæÃÖ¤«Ã±¹àÁ°Ã֤ˤʤꤦ¤ë±é»»»Ò
+ %An operator that could be binary infix or unary prefix
+\end{description}
+%To show you how these might be used, here are some sample token
+%definitions using these categories:
+¤É¤¦¤ä¤Ã¤Æ»È¤ï¤ì¤ë¤«¤ò¼¨¤¹¤¿¤á¤Ë¡¢¤³¤ì¤é¤Î¥«¥Æ¥´¥ê¡¼¤òÍѤ¤¤¿
+¥È¡¼¥¯¥ó¤ÎÄêµÁÎã¤ò¼¨¤¹¡£
+\begin{verbatim}
+token + category unorbinop
+token - category unorbinop
+token * category binop
+token / category binop
+token < category binop
+token > category binop
+token , category binop translation <",\\,"-opt-3>
+token = category binop translation <"\\K">
+token != translation <"\\I"> category binop
+token == name eq_eq translation <"\\S"> category binop
+token ++ name gt_gt category unop translation <"\\uparrow">
+token -- name lt_lt category unop translation <"\\downarrow">
+\end{verbatim}
+%Notice that the translation for the comma specifies a thin space and
+%an optional line break after the comma.
+¤³¤³¤Ç¤Ï¥«¥ó¥Þ¤Ï¾®¤µ¤Ê¥¹¥Ú¡¼¥¹¤Î¸å optional line break
+¤òÃÖ¤¯¤³¤È¤ËÃí°Õ¤·¤ÆÍߤ·¤¤¡£
+{\tt =}¡¢ {\tt !=}¡¢ {\tt ==} ¤ÎËÝÌõ¤Ï¤½¤ì¤¾¤ì
+\ $\leftarrow$¡¢ $\ne$¡¢ $\equiv$ ¤È¤Ê¤ë¡£
+
+
+%Here is the grammar for expressions.
+°Ê²¼¤Ï¡¢¼°¤Î¤¿¤á¤Îʸˡ¤Ç¤¢¤ë¡£
+\begin{verbatim}
+math (binop|unorbinop) math --> math
+(unop|unorbinop) math --> math
+math unop --> math
+math <"\\"-space> math --> math
+\end{verbatim}
+%In Awk there is no concatenation operator; concatenation is by
+%juxtaposition.
+Awk ¤Ç¤Ï¡¢Ê¸»úÎó¤Î·ë¹ç»Ò¤¬¤Ê¤¤; ·ë¹ç¤Ïʤ٤ÆÃÖ¤¯¤³¤È¤Çɽµ­¤µ¤ì¤ë¡£
+%The last production tells {\tt WEAVE} to insert a space between two
+%juxtaposed expressions.
+ºÇ¸å¤ÎÀ¸À®µ¬Â§¤Ï {\tt WEAVE} ¤ËÊÂÃÖ¤µ¤ì¤¿¼°¤Î´Ö¤Ë
+¥¹¥Ú¡¼¥¹¤òÁÞÆþ¤µ¤»¤ë¤¿¤á¤Î¤â¤Î¤Ç¤¢¤ë¡£
+
+%So far we haven't dealt with parentheses, but that's easily done:
+º£¤Þ¤Ç¤Ï³ç¸Ì¤ò½èÍý¤·¤Æ¤¤¤Ê¤«¤Ã¤¿¤¬¡¢°Ê²¼¤Î¤è¤¦¤ËÍưפ˵­½Ò¤Ç¤­¤ë:
+\begin{verbatim}
+token ( category open
+token ) category close
+token [ category open
+token ] category close
+open math close --> math
+\end{verbatim}
+
+
+%Now this grammar just given doesn't handle the Awk or C {\tt +=}
+%feature very well; {\tt x+=1} comes out as~$x+\leftarrow 1$, and {\tt
+%x/=2} is irreducible!
+¤µ¤Æ¡¢¤³¤Îʸˡ¤Î¤Þ¤Þ¤Ç¤Ï Awk ¤ä C ¤Î {\tt +=} ¤È¤¤¤¦µ¡Ç½¤ò
+¤¦¤Þ¤¯°·¤¦¤³¤È¤¬¤Ç¤­¤Ê¤¤;
+{\tt x+=1} ¤Ï $x+\leftarrow 1$ ¤Î¤è¤¦¤Ë¤Ê¤ê¡¢{\tt x/=2} ¤Ï
+´Ô¸µ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Ê¤¤¡£
+%Here's the cure; first, we make a new category for assignment:
+°Ê²¼¤Ë½¤Àµ¤Î»ÅÊý¤ò½Ò¤Ù¤ë;
+¤Þ¤ººÇ½é¤Ë¡¢ÂåÆþ¤Î¤¿¤á¿·¤·¤¤¥«¥Æ¥´¥ê¡¼¤òºî¤ë¤³¤È¤Ë¤¹¤ë¡£
+\begin{verbatim}
+token = category equals translation <"\\K">
+\end{verbatim}
+%And then we write productions that reduces assignment (possibly
+%preceded by another operator) to a binary operator:
+¼¡¤Ë¡¢(¾¤Î±é»»»Ò¤¬Àè¹Ô¤·¤Æ¤â¤«¤Þ¤ï¤Ê¤¤)ÂåÆþ¤òÆó¹à±é»»»Ò¤Ë´Ô¸µ¤¹¤ë¤¿¤á¤Î
+À¸À®µ¬Â§¤ò½ñ¤³¤¦¡£
+\begin{verbatim}
+<"\\buildrel"> (binop|unorbinop) <"\\over{"> equals <"}"> --> binop
+equals --> binop
+\end{verbatim}
+%Notice that, given the rules stated above, the second production can
+%fire only if {\tt equals} is {\jem not} preceded by an operator.
+¾åµ­¤Îµ¬Â§¤ÇÃí°Õ¤¹¤Ù¤­¤³¤È¤Ï¡¢ÂèÆó¤ÎÀ¸À®µ¬Â§¤Ï
+{\tt equals}¤¬±é»»»Ò¤òÁ°¤Ë{\jem ȼ¤ï¤Ê¤¤}»þ¤Ë¤Î¤ßŬÍѲÄǽ¤À¤È¤¤¤¦¤³¤È¤Ç¤¢¤ë¡£
+%On input~{\tt x+=1}, the first production fires, and we have the
+%translation~$x\buildrel+\over{\leftarrow} 1$.
+{\tt x+=1}¤È¤¤¤¦ÆþÎϤËÂФ·¤Æ¡¢Âè°ì¤ÎÀ¸À®µ¬Â§¤¬ºÇ½é¤ËŬÍѤµ¤ì¡¢
+$x\buildrel+\over{\leftarrow} 1$ ¤È¤¤¤¦ËÝÌõ¤òÆÀ¤ë¤³¤È¤Ë¤Ê¤ë¡£
+
+\paragraph{¾ò·ïʸ}
+%Here is the grammar for (possibly nested) conditional statements in
+%Awk.
+°Ê²¼¤Ï¡¢Awk ¤Ë¤ª¤±¤ë(¥Í¥¹¥È²Äǽ¤Ê)¾ò·ïʸ¤Îʸˡ¤Ç¤¢¤ë¡£
+\begin{verbatim}
+if <"\\"-space> math --> ifmath
+ifmath lbrace --> ifbrace
+ifmath newline --> ifline
+ifbrace <force> stmt --> ifbrace
+ifbrace <outdent-force> close else <"\\"-space> if --> if
+ifbrace <outdent-force> close else lbrace --> ifbrace
+ifbrace <outdent-force> close else newline --> ifline
+ifbrace <outdent-force> close --> stmt
+(ifline|ifmath) <indent-force> stmt <outdent> --> stmt
+\end{verbatim}
+%It relies on the following token definitions:
+°Ê²¼¤Î¥È¡¼¥¯¥ó¤ÎÄêµÁ¤Ë°Í¸¤¹¤ë:
+\begin{verbatim}
+ilk if_like category if
+reserved if
+ilk else_like category else
+reserved else
+token { translation <"\\;\\{"-indent> category lbrace
+token } translation <"\\}\\"-space> category close
+token newline category newline translation <>
+\end{verbatim}
+
+\paragraph{C ¤Î¥×¥ê¥×¥í¥»¥Ã¥µÍÑÌ¿Îá¤Î°·¤¤}
+¤³¤³¤Ç¤ÏC¥×¥ê¥×¥í¥»¥Ã¥µÍÑÌ¿Îá¤ò°·¤¦¤¿¤á¤Îʸˡ¤Î
+´Êñ¤Ê¥Ð¡¼¥¸¥ç¥ó¤ò¼¨¤¹¡£
+¥×¥ê¥×¥í¥»¥Ã¥µÌ¿Îá¤Ï¹Ô¤Îº¸Ã¼¤Ë¤ª¤«¤ì¡¢¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤Ç¥¨¥¹¥±¡¼¥×¤µ¤ì¤¿
+²þ¹Ô¤âÀµ¤·¤¯°·¤ï¤ì¤ë¡£
+(ºÇ½ª¥Ð¡¼¥¸¥ç¥ó¤Ï¥Õ¥¡¥¤¥ë̾¤ò {\tt <...>}¤È¤¤¤¦
+``¤è¤ê¾®¤µ¤¤'' ¤È ``¤è¤êÂ礭¤¤'' ¤ò°ÕÌ£¤¹¤ëƱ°ì¤Îµ­¹æ¤Ç³ç¤Ã¤¿É½µ­¤â
+²Äǽ¤Ç¤¢¤ë¡£)
+
+{\small\advance\hsize 1in
+\begin{verbatim}
+# control sequence \8 puts things on the left margin
+<"\\8"> sharp <"{\\let\\\\=\\bf"-space> math <"}"-indent-"{}"-space> --> preproc
+preproc backslash <force-"\\8\\hskip1em"-space> newline --> preproc
+<force> preproc <force-outdent> newline --> ignore_scrap
+preproc math --> preproc
+newline --> ignore_scrap
+\end{verbatim}
+}
+ºÇ½é¤ÎÀ¸À®µ¬Â§¤Ë¤¢¤ë \verb+\let+ ¤Ë¤è¤Ã¤Æ¡¢
+{\tt \#} ¤Ë³¤¯¼±Ê̻Ҥò¥Ü¡¼¥ë¥ÉÂΤËÊѹ¹¤¹¤ë¡£
+
+
+%\subsection{Using context-dependent productions}
+\subsection{ʸ̮°Í¸À¸À®µ¬Â§¤Î»ÈÍÑ}
+%So far we've been able to do a lot without using the
+%context-dependent features of {Spider} productions.
+%(For example, the entire {\tt spider} file for Awk is written using
+%only context-free productions.)
+%Now we'll show some examples that use the context-dependence.
+º£¤Þ¤Ç¤Î¤Ï¡¢Â¿¤¯¤Î¤³¤È¤òʸ̮¤Ë°Í¸¤·¤Ê¤¤ÊýË¡¤Ç¤ä¤Ã¤Æ¤³¤ì¤¿
+(Î㤨¤Ð¡¢Awk ÍѤΠ{\tt spider}¥Õ¥¡¥¤¥ë¤Ïʸ̮¼«Í³µ¬Â§¤Î¤ß¤Ç½ñ¤«¤ì¤Æ¤¤¤ë)¡£
+º£¤«¤é¡¢Ê¸Ì®°Í¸ʸˡ¤ò»È¤Ã¤¿Îã¤ò¼¨¤¹¤³¤È¤Ë¤¹¤ë¡£
+
+%In the grammar for Ada, a semicolon is used as a terminator for
+%statements.
+%But semicolons are also used as {\jem separators} in parameter
+%declarations.
+%The first two productions here find the statements, but the third
+%production supersedes them when a semicolon is seen in a parenthesized
+%list.
+Ada ¤Îʸˡ¤Ç¤Ï¡¢¥»¥ß¥³¥í¥ó¤Ïʸ¤Î½ªÃ¼µ­¹æ¤Ç¤¢¤ë¡£
+¤·¤«¤·¡¢¥Ñ¥é¥á¡¼¥¿Àë¸À¤Ç¤Ï {\jem ¥»¥Ñ¥ì¡¼¥¿} ¤È¤·¤Æ¤â»È¤ï¤ì¤ë¡£
+°Ê²¼¤ÎºÇ½é¤Î 2 ¤Ä¤Îµ¬Â§¤Ïʸ¤ò¸«¤Ä¤±¤ë¤¿¤á¤Ë¤¢¤ë¡£
+¤·¤«¤·3ÈÖÌܤϡ¢³ç¸Ì¤Ç³ç¤é¤ì¤¿¥ê¥¹¥È¤ÎÃæ¤Ë¤¢¤ë¥»¥ß¥³¥í¥ó¤Î°·¤¤¤òÊѤ¨¤ë¡£
+\begin{verbatim}
+semi --> terminator
+math terminator --> stmt
+open [ math semi ] --> open math
+\end{verbatim}
+
+
+%\paragraph{Underlining the index entry for the name of a declared
+%function}
+\paragraph{Àë¸À¤µ¤ì¤¿´Ø¿ô̾¤Î²¼ÀþÉÕ¤±¤µ¤ì¤¿º÷°úÅÐÏ¿}
+%In SSL, function declarations begin with the type of the function
+%being declared, followed by the name of that function.
+SSL ¤Ç¤Ï¡¢´Ø¿ô¤ÎÀë¸À¤Ï´Ø¿ô̾¤ÎÁ°¤Ë´Ø¿ô¤Î·¿¤òÀë¸À¤¹¤ë¡£
+%The following production causes the index entry for that function to
+%be underlined, so that we can look up the function name in the index
+%and easily find the section in which the function is declared:
+°Ê²¼¤ÎÀ¸À®µ¬Â§¤Ï¡¢´Ø¿ô¤ò²¼ÀþÉÕ¤­¤Çº÷°ú¤ËÅÐÏ¿¤¹¤ë¡£¤·¤¿¤¬¤Ã¤Æ¡¢
+º÷°ú¤ÎÃæ¤Ç´Ø¿ô̾¤òÄ´¤Ù¤ë¤³¤È¤¬¤Ç¤­¡¢Àë¸À¤µ¤ì¤Æ¤¤¤ë¥»¥¯¥·¥ç¥ó¤ò
+¸«¤Ä¤±¤ë¤³¤È¤¬²Äǽ¤Ç¤¢¤ë¡£
+\begin{verbatim}
+decl simp [ simp* ] --> decl simp math
+\end{verbatim}
+%Where we've relied on
+¤³¤³¤Ç¤Ï¡¢°Ê²¼¤ÎÄêµÁ¤Ë°Í¸¤·¤Æ¤¤¤ë¡£
+\begin{verbatim}
+token identifier category simp mathness yes
+\end{verbatim}
+
+
+\paragraph{¾ò·ï¼°}
+%Suppose we want to format conditional expressions (for example in C)
+%like this:
+(Î㤨¤Ð C ¤Ë¤ª¤¤¤Æ)¼¡¤Î¤è¤¦¤Ë¾ò·ï¼°¤òÀ°·Á¤¹¤ë¤³¤È¤ò¹Í¤¨¤è¤¦¡£
+\begin{quote}
+\syntax{condition}\\
+\mbox{\qquad}$?$ \syntax{expression}\\
+\mbox{\qquad}$:$ \syntax{expression}
+\end{quote}
+%The problem is that it's hard to know when the conditional expression
+%ends.
+¤³¤³¤Ç¤ÎÌäÂê¤Ï¡¢¤¤¤Ä¾ò·ï¼°¤¬½ª¤ë¤«¤òȽÃǤ¹¤ë¤Î¤¬Æñ¤·¤¤¤³¤È¤Ç¤¢¤ë¡£
+%It's essentially a question of precedence,
+¤³¤ì¤Ï¡¢´ðËÜŪ¤ËÀèÆɤßÌäÂê¤Ç¤¢¤ê¡¢
+%and what we're going to do
+%is look ahead until we see an operator with sufficiently low
+%precedence that it terminates a conditional expression.
+¤ä¤ë¤Ù¤­¤³¤È¤Ï¡¢¾ò·ï¼°¤ò½ªÃ¼¤µ¤»¤ë¤Ë½½Ê¬¤ÊÄøÅÙ¤Ë
+±é»»»Ò¤òÀèÆɤߤ¹¤ë¤³¤È¤Ç¤¢¤ë¡£
+%In SSL a conditional expression can be terminated by a semicolon, a
+%right parenthesis, a comma, or a colon.
+SSL ¤Ç¤Ï¡¢¾ò·ï¼°¤Ï¥»¥ß¥³¥í¥ó¡¢±¦³ç¸Ì¡¢¥«¥ó¥Þ¡¢¥³¥í¥ó¤Ç½ªÃ¼¤·ÆÀ¤ë¡£
+%We'll use the {\jem right context} to do the lookahead.
+ÀèÆɤߤò¤¹¤ë¤¿¤á¤Ë¡¢{\jem right context} ¤ò»È¤¦¤³¤È¤Ë¤·¤è¤¦¡£
+{\small
+\begin{verbatim}
+token ? translation <"\\?"> category question
+token : category colon
+
+<indent-force> question math <force> colon --> condbegin
+[ condbegin math <outdent> ] (semi|close|comma|colon) --> math (semi|close|comma|colon)
+\end{verbatim}
+}
+
+
+
+
+\subsection{À°·Á°õºþʸˡ¤Î¥Ç¥Ð¥Ã¥°}
+{\tt WEAVE} ¤ÏÀ°·Á°õºþʸˡ¤Î¥Ç¥Ð¥Ã¥°¤ËÌòΩ¤Ä 2 ¤Ä¤Î¥â¡¼¥É¤ò»ý¤Ä¡£
+{\tt @1} ¤È¤¤¤¦À©¸æ¥·¡¼¥±¥ó¥¹¤ÏÉôʬ¥È¥ì¡¼¥¹¤ò³«»Ï¤·¡¢
+{\tt @2} ¤Ï¥Õ¥ë¥È¥ì¡¼¥¹¤ò³«»Ï¤¹¤ë¡£
+{\tt @0} ¤Ï¥È¥ì¡¼¥¹¤ò¥ª¥Õ¤Ë¤¹¤ë¡£%turns tracing back off again.
+%In the partial tracing mode, {\tt WEAVE} applies all the productions
+%as many times as possible,
+Éôʬ¥È¥ì¡¼¥¹¥â¡¼¥É¤Ç¤Ï¡¢{\tt WEAVE} ¤Ï²Äǽ¤Ê¸Â¤ê¤¹¤Ù¤Æ¤ÎÀ¸À®µ¬Â§¤ò
+ŬÍѤ·¡¢·ë²Ì¤È¤·¤Æ´Ô¸µ¤Ç¤­¤Ê¤«¤Ã¤¿»Ä¤ê¤Î¥¹¥¯¥é¥Ã¥×¤ò¥×¥ê¥ó¥È¥¢¥¦¥È¤¹¤ë¡£
+%and then it prints out the irreducible
+%scraps that remain.
+%If the scraps reduce to a single scrap, no diagnostics are printed.
+¥¹¥¯¥é¥Ã¥×¤¬¤¹¤Ù¤Æ°ì¤Ä¤Î¥¹¥¯¥é¥Ã¥×¤Ë´Ô¸µ¤Ç¤­¤¿¾ì¹ç¤Ï¡¢
+¿ÇÃÇ¥á¥Ã¥»¡¼¥¸¤Ï¥×¥ê¥ó¥È¤µ¤ì¤Ê¤¤¡£
+
+%When a scrap is printed, {\tt WEAVE} prints a leading
+%{\tt+}~or~{\tt-}, the name of the category of that scrap, and a
+%trailing {\tt+}~or~{\tt-}.
+¥¹¥¯¥é¥Ã¥×¤¬¥×¥ê¥ó¥È¤µ¤ì¤ë¤È¤­¡¢{\tt WEAVE} ¤Ï¡¢{\tt+}~¤«~{\tt-}¤Î¥ê¡¼¥À¡¼¡¢
+¤½¤Î¥¹¥¯¥é¥Ã¥×¤Î¥«¥Æ¥´¥ê¡¼Ì¾¡¢{\tt+}~¤«~{\tt-}¤Î¥È¥ì¡¼¥é¡¼¤ò¥×¥ê¥ó¥È¤¹¤ë¡£
+%The {\tt+} indicates that {\TeX} should be in math mode, and the
+%{\tt-} that {\TeX} should not be in math mode, at the beginning and
+%end of the scrap's translation, respectively.
+¤½¤ì¤¾¤ì¤Î¥¹¥¯¥é¥Ã¥×¤Î¥È¥é¥ó¥¹¥ì¡¼¥·¥ç¥ó¤Î»Ï¤á¤È½ª¤ï¤ê¤Ç¡¢
+{\tt+} ¤Ï {\TeX} ¤¬¿ô¼°¥â¡¼¥É¤ËÆþ¤Ã¤¿¤³¤È¤ò¼¨¤·¡¢
+{\tt-} ¤Ï {\TeX} ¤¬¿ô¼°¥â¡¼¥É¤Ç¤Ê¤¯¤Ê¤Ã¤¿¤³¤È¤ò¼¨¤¹
+%(You can see the translations by looking at the {\tt.tex} file, since
+%that's where they're written out.)
+(¥È¥é¥ó¥¹¥ì¡¼¥·¥ç¥ó¤Ï{\tt.tex}¥Õ¥¡¥¤¥ë¤ò¸«¤ì¤Ð²ò¤ë)¡£
+
+%For beginners, the full trace is more helpful.
+½é¿´¼Ô¤Ë¤È¤Ã¤Æ¤Ï¡¢¥Õ¥ë¥È¥ì¡¼¥¹¤ÎÊý¤¬Ìò¤ËΩ¤Ä¡£
+%It prints out the following information every time a production is
+%fired:
+¥Õ¥ë¥È¥ì¡¼¥¹¥â¡¼¥É¤Ç¤Ï¡¢À¸À®µ¬Â§¤¬Å¬ÍѤµ¤ì¤ëÅ٤˰ʲ¼¤Î¾ðÊó¤ò¥×¥ê¥ó¥È¤¹¤ë:
+\begin{itemize}
+\item
+%The number of the production just fired (from {\tt productions.list});
+ŬÍѤ·¤¿À¸À®µ¬Â§¤Î({\tt productions.list}¤Ë½ñ¤­½Ð¤µ¤ì¤¿)ÈÖ¹æ;
+\item
+%The sequence of scraps {\tt WEAVE} is now trying to reduce;
+{\tt WEAVE}¤¬¸½ºß´Ô¸µ¤·¤è¤¦¤È¤·¤Æ¤¤¤ë¥¹¥¯¥é¥Ã¥×¤ÎʤÓ;
+\item
+%A {\tt*} indicating what subsequence {\tt WEAVE} will try to reduce next.
+{\tt*} ¤Ç¼¨¤µ¤ì¤ë {\tt WEAVE} ¤¬¼¡¤Ë´Ô¸µ¤·¤è¤¦¤È¤·¤Æ¤¤¤ë¥µ¥Ö¥·¡¼¥±¥ó¥¹¡£
+\end{itemize}
+%A good way to understand how À°·Á°õºþʸˡ work is to take
+%a {\tt productions.list} file, and look at a full trace of the
+%corresponding {\tt WEAVE}.
+À°·Á°õºþʸˡ ¤ÎƯ¤­¤òÃΤëÎɤ¤ÊýË¡¤Ï¡¢
+{\tt productions.list} ¥Õ¥¡¥¤¥ë¤ò¼ê¤Ë¤È¤Ã¤Æ¡¢
+{\tt WEAVE} ¤¬¥×¥ê¥ó¤È¤·¤¿¥Õ¥ë¥È¥ì¡¼¥¹¤È
+Æͤ­¹ç¤ï¤»¤ë¤³¤È¤Ç¤¢¤ë¡£
+%Or, if you prefer, you can simulate by hand the action of {\tt WEAVE}
+%on a sequence of scraps.
+¤â¤·¤¯¤Ï¡¢¤ªË¾¤ß¤Ê¤é¤Ð¡¢{\tt WEAVE} ¤¬¥¹¥¯¥é¥Ã¥×¤ÎʤӤËÂФ·¤Æ¹Ô¤¦Æ°ºî¤ò¼ê¤Ç
+¥·¥ß¥å¥ì¡¼¥È¤·¤Æ¤â¤¤¤¤¤À¤í¤¦¡£
+
+
+\section{{Spider} ¸À¸ì¤Î»Ä¤ê}
+%The tokens and the grammar are not quite the whole story.
+%Here's the rest of the truth about what you can do with {Spider}.
+¥È¡¼¥¯¥ó¤Èʸˡ¤ÇÏä·¤¬¤¹¤Ù¤Æ½ª¤Ã¤¿¤ï¤±¤Ç¤Ï¤Ê¤¤¡£
+¤³¤Î¾Ï¤Ç¤Ï¡¢ {Spider} ¤Ç¤Ç¤­¤ë¤³¤È¤Î̤ÀâÌÀ¤ÎÉôʬ¤ò½Ò¤Ù¤ë¡£
+
+\subsection{¥¿¡¼¥²¥Ã¥È¸À¸ì¤Î̿̾}
+%When a Spidery {\tt WEAVE} or {\tt TANGLE} starts up, it prints the
+%target language for which it was generated, and the date and time of
+%the generation.
+Spidery {\tt WEAVE} ¤Þ¤¿¤Ï Spidery {\tt TANGLE} ¤¬µ¯Æ°¤µ¤ì¤¿»þ¡¢
+¥¿¡¼¥²¥Ã¥È¸À¸ì¤ÈºîÀ®Æü»þ¤òɽ¼¨¤¹¤ë¡£
+{\tt language} ¥³¥Þ¥ó¥É¤Ï¥¿¡¼¥²¥Ã¥È¤Ë¤¹¤ë¸À¸ì¤ò»ØÄꤹ¤ë¡£
+
+¹½Ê¸¤Ï°Ê²¼¤ÎÄ̤ꡣ
+\begin{quote}
+\tt language \syntax{language-name}
+\opt{extension \syntax{extension-name}}\\
+\mbox{\qquad\qquad}\opt{version \syntax{version-name}}
+\end{quote}
+extension--name ¤Ï¡¢{\tt TANGLE} ¤¬¥×¥í¥°¥é¥à¤ò½ñ¤­½Ð¤¹
+³ÈÄ¥»Ò¤È¤·¤Æ({\tt .web}¥Õ¥¡¥¤¥ë¤ËËä¤á¹þ¤à¤¿¤á¤Ë)»È¤ï¤ì¤ë¡£
+extension ¤Ï¡¢{\tt WEAVE} ¤Ç»È¤ï¤ì¤ë ¸À¸ì¤Ë¸ÇÍ­¤Î
+{\TeX} ¥Þ¥¯¥í¥Õ¥¡¥¤¥ë¤òÀ¸À®¤¹¤ë»þ¤Ë¤â»È¤ï¤ì¤ë¡£
+¤·¤¿¤¬¤Ã¤Æ¡¢°Û¤Ê¤ë¸À¸ì¤Ï°Û¤Ê¤ë³ÈÄ¥»Ò(extension) ¤ò»ý¤¿¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
+extension ¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤¤»þ¤Ï¡¢¸À¸ì̾¤¬¥Ç¥Õ¥©¥ë¥È¤È¤Ê¤ë¡£
+version ¾ðÊ󤬻ØÄꤵ¤ì¤Æ¤¤¤ì¤Ð¡¢¤½¤ì¤â¥×¥í¥°¥é¥àµ¯Æ°»þ¤Ëɽ¼¨¤µ¤ì¤ë¤è¤¦¤Ë¤Ê¤ë¡£
+
+É®¼Ô¤¬ Unix ¤Ç»È¤Ã¤Æ¤¤¤ë {\tt c.spider} ¤Ç¤Ï¡¢°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤ë¡£
+\begin{verbatim}
+language C extension c
+\end{verbatim}
+
+
+
+
+\subsection{{\TeX} ¥Þ¥¯¥í¤ÎÄêµÁ}
+%In addition to the ``kernel'' {\WEB} macros stored in {\tt
+%webkernel.tex}, you may want to create some {\TeX} macros of your
+%own for use in translations.
+{\tt webkernel.tex}¤Ëµ­½Ò¤µ¤ì¤Æ¤¤¤ë¡Ö¥«¡¼¥Í¥ë¡×{\WEB}¥Þ¥¯¥í¤ò³ÈÄ¥¤¹¤ë¤¿¤á¤Ë¡¢
+translations ¤ÎÃæ¤Ç»È¤¦ÀìÍѤÎ{\TeX}¥Þ¥¯¥í¤ò
+ÄêµÁ¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£
+%Any macro definitions you put between lines saying {\tt macros begin}
+%and {\tt macros end} will be included verbatim in the {\TeX} macro
+%file for this language.
+¤É¤ó¤Ê¥Þ¥¯¥í¤Ç¤â¡¢{\tt macros begin}¹Ô¤È
+{\tt macros end} ¹Ô¤Î´Ö¤Ë¤¢¤ë¤â¤Î¤Ï
+¤½¤Î¤Þ¤Þ¤½¤Î¸À¸ìÍѤΠ{\TeX} ¥Þ¥¯¥í¥Õ¥¡¥¤¥ë¤ÎÃæ¤Ë¼è¤ê¹þ¤Þ¤ì¤ë¡£
+%That macro file will automatically be \verb+\input+ by every {\TeX}
+%file generated by this {\tt WEAVE}.
+¤³¤Î¥Þ¥¯¥í¥Õ¥¡¥¤¥ë¤Ï¡¢%That macro file will automatically be
+{\tt WEAVE}¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤ë¤¹¤Ù¤Æ¤Î {\TeX}¥Õ¥¡¥¤¥ë¤Ë
+\verb+\input+ Ì¿Îá¤Ç¼«Æ°Åª¤Ë¼è¤ê¹þ¤Þ¤ì¤ë¤è¤¦¤Ë¤Ê¤ë¡£
+
+%For example, the C grammar includes productions to handle preprocessor
+%directives.
+%These directives may include file names that are delimited by angle
+%brackets.
+%I wanted to use the abbreviations \verb+\LN+ and \verb+\RN+ for left
+%and right angle brackets, so I included
+Î㤨¤Ð¡¢C ¤Îʸˡ¤Ï¥×¥ê¥×¥í¥»¥Ã¥µÌ¿Îá¤ò°·¤¦µ¬Â§¤ò´Þ¤ó¤Ç¤¤¤ë¡£
+¤³¤ÎÌ¿Îá¤Ï³Ñ¥«¥Ã¥³¤Ç³ç¤Ã¤¿¥Õ¥¡¥¤¥ë̾¤ò»È¤¦¡£
+É®¼Ô¤Ï¡¢\verb+\LN+ , \verb+\RN+ ¤òº¸³Ñ¥«¥Ã¥³,
+±¦³Ñ¥«¥Ã¥³¤Îû½Ì·Á¤È¤·¤Æ»È¤¦¤¿¤á¡¢
+°Ê²¼¤ÎÄêµÁ¤ò{\tt c.spider} ¥Õ¥¡¥¤¥ë¤Ë½ñ¤¤¤Æ¤¢¤ë¡£
+\begin{verbatim}
+macros begin
+\let\LN\langle
+\let\RN\rangle
+macros end
+\end{verbatim}
+
+
+\subsection{¥Ç¥Õ¥©¥ë¥È¤Î¥È¡¼¥¯¥ó¾ðÊó¤ÎÀßÄê}
+%It's possible to set default values for the {\tt translation} and {\tt
+%mathness} properties of tokens, so that they don't have to be
+%repeated.
+¥È¡¼¥¯¥ó¤Î \hbox{\tt translation} ¤È \hbox{\tt mathness} ¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤò
+ÀßÄꤹ¤ë¤³¤È¤Ë¤è¤ê¡¢Ëè²ó·«¤êÊÖ¤·¤Æµ­½Ò¤¹¤ëɬÍפ¬¤Ê¤¯¤Ê¤ë¡£
+%This is done with the {\tt default} command, whose syntax is:
+¤³¤ì¤Ï\hbox{\tt default} ¥³¥Þ¥ó¥É¤ò»È¤¦¡£½ñ¼°¤Ï°Ê²¼¤ÎÄ̤ê:
+\begin{quote}
+\tt
+default \syntax{token descriptions}
+\end{quote}
+%The initial defaults (when {Spider} begins execution) are {\tt
+%translation~<*>} and {\tt mathness~maybe}.
+({Spider}¤¬¼Â¹Ô³«»Ï¤·¤¿¤È¤­¤Î)¥Ç¥Õ¥©¥ë¥ÈÃͤνé´üÃͤÏ
+{\tt translation~<*>} ¤È {\tt mathness~maybe}¤Ç¤¢¤ë¡£
+
+
+
+
+
+
+\subsection{¥â¥¸¥å¡¼¥ë¤Î°·¤¤Êý¤Î»ØÄê}
+{\WEB} ¤Ï¡¢Â¾¤Î¤É¤ó¤Ê¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì¤Ë¤â¤Ê¤«¤Ã¤¿¼ïÎà¤Î¥È¡¼¥¯¥ó
+¡Ö¥â¥¸¥å¡¼¥ë̾¡×¤òƳÆþ¤·¤¿({\tt @<...@>} ¤Þ¤¿¤Ï {\tt @(...@>})¡£
+%introduces a new kind of token that isn't in any programming
+%language, and that's the module name ({\tt @<...@>} or {\tt @(...@>}).
+{\tt TANGLE}¤Î»Å»ö¤Ï¡¢¤³¤Î¥â¥¸¥å¡¼¥ë̾¤ò¥×¥í¥°¥é¥à¥Æ¥­¥¹¥È¤Ë¤¹¤ë¤³¤È¤Ç¤¢¤ê¡¢
+%'s job is to convert the module names to program text, and
+¥â¥¸¥å¡¼¥ë̾¤¬¤Ê¤¯¤Ê¤Ã¤¿»þ¤Ë½ªÎ»¤¹¤ë¡£
+%when {\tt TANGLE} is finished no module names remain.
+¤·¤«¤·¡¢{\tt WEAVE} ¤Ï¥â¥¸¥å¡¼¥ë̾¤òÁÈÈǤ·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤Î¤Ç¡¢
+%has to typeset the module names, and we need to tell
+{\tt WEAVE} ¤¬¥â¥¸¥å¡¼¥ë̾¤ò¤É¤ó¤Ê¥«¥Æ¥´¥ê¡¼¤Î¥¹¥¯¥é¥Ã¥×¤Ë¤¹¤ë¤«¤ò
+µ¬Äꤷ¤Æ¤ä¤ëɬÍפ¬¤¢¤ë¡£
+%what category to give a scrap created from a module name.
+2¤Ä¤Î¥«¥Æ¥´¥ê¡¼¤¬µö¤µ¤ì¤ë¡£
+%We allow two different categories,
+1¤Ä¤Ï¥â¥¸¥å¡¼¥ë̾¤ÎÄêµÁ (¥â¥¸¥å¡¼¥ë¤Î³«»Ï)ÍѤǤ¢¤ê¡¢
+¤â¤¦°ì¤Ä¤Ï¡¢¥â¥¸¥å¡¼¥ë̾¤Î»ÈÍÑ»þ¤Î¤â¤Î¤Ç¤¢¤ë¡£
+{\samepage
+{\tt module}¥³¥Þ¥ó¥É¤Î¹½Ê¸¤Ï°Ê²¼¤ÎÄ̤ꡣ
+\begin{quote}
+\tt
+module \opt{definition \syntax{category name}}
+\opt{use \syntax{category name}}
+\end{quote}
+}
+
+{\tt c.spider} ¤Ç¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ¤¤¤ë¡£
+\begin{verbatim}
+module definition decl use math
+\end{verbatim}
+
+\subsection{at sign ¤Î·èÄê}
+{Spider}¤Ç{\WEB}¥·¥¹¥Æ¥à¤òºî¤ë¤Ê¤é¤Ð¡¢
+ ``{\tt @}'' ¤ò ``magic at sign'' ¤È¤·¤Æ{\WEB}¤ÎÀ©¸æ¥³¥Þ¥ó¥É¤Î
+³«»Ï¥­¥ã¥é¥¯¥¿¤Ë¤¹¤ëɬÍפϤʤ¤¡£
+¤·¤«¤·¤Ê¤¬¤é¡¢´·Îã¤È¤·¤Æ¡¢Ë¾¤Þ¤·¤¯¤Ê¤¤¾ì¹ç°Ê³°¤Ï ``{\tt @}''
+¤ò»È¤¦¤³¤È¤Ë¤·¤è¤¦¡£
+``{\tt @}'' ¤¬Ë¾¤Þ¤·¤¯¤Ê¤¤»þ¤Ï¡¢Âå¤ï¤ê¤Ë ``{\tt \#}''¤ò»È¤¦¤³¤È¤Ë¤¹¤ë¡£
+{Spider} ¤Ç {\tt WEAVE} ¤È {\tt TANGLE} ¤Î C~{\WEB} ¥³¡¼¥É¤ò½ñ¤¯¤Ë¤Ï¡¢
+¿¤¯¤Î {\tt @} ¤ò½ñ¤¯¤³¤È¤Ë¤Ê¤ë¡£
+°ì¤Ä°ì¤Ä¤ò¥¨¥¹¥±¡¼¥×¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤»þ¤ËÉ®¼Ô¤Ï¤½¤¦¤Ï¤·¤Ê¤«¤Ã¤¿¡£
+``{\tt \#}'' Awk~{\WEB}¤Î at~sign ¤ò ``{\tt \#}'' ¤Ë¤·¤¿:
+\begin{verbatim}
+at_sign #
+\end{verbatim}
+»ØÄꤵ¤ì¤Ê¤¤»þ¤Ë¤Ï¥Ç¥Õ¥©¥ë¥È¤Ï ``{\tt @}'' ¤Î¤Þ¤Þ¤Ç¤¢¤ë¡£
+
+\paragraph{¥³¥ó¥È¥í¡¼¥ë¥·¡¼¥±¥ó¥¹¤ÎÊѹ¹}
+at~sign ¤ÎÊѹ¹¤Ï¤Ò¤È¤Ä¤«Æó¤Ä¤Î¥³¥ó¥È¥í¡¼¥ë¥·¡¼¥±¥ó¥¹¤Î°ÕÌ£¤òÊѹ¹¤¹¤ë¡£
+%This is more easily illustrated by example than explained.
+¸ÀÍÕ¤ÇÀâÌÀ¤¹¤ë¤è¤ê¤ÏÎã¤ò¼¨¤·¤¿Êý¤¬²ò¤ê¤ä¤¹¤¤¤Î¤Ç¡¢
+at~sign ¤ò{\tt\#}¤ËÊѤ¨¤¿¾ì¹ç¤ò¼¨¤½¤¦¡£
+·ë²Ì¤È¤·¤Æ {\WEB} ¤ÎÆó¤Ä¤Î¥³¥ó¥È¥í¡¼¥ë¥·¡¼¥±¥ó¥¹¤Ï¿·¤·¤¤°ÕÌ£¤ò»ý¤Ä¤³¤È¤Ë¤Ê¤ë:
+\begin{description}
+\item[{\tt \#\#}]
+%Stands for a {\tt \#} in the input, by analogy with {\tt @@} in normal
+%{\WEB}.
+Ä̾ï¤Î{WEB}¤Î{\tt @@}¤ÈƱÍͤʰÕÌ£¤Ç¡¢ÆþÎÏÃæ¤Î{\tt\#}¤ò¼¨¤¹¡£
+%You will need this when defining {\TeX} macros that take parameters.
+¥Ñ¥é¥á¡¼¥¿¤òȼ¤¦{\TeX} ¥Þ¥¯¥í¤òÄêµÁ¤¹¤ë¤È¤­¤ËɬÍפˤʤ롣
+\item[{\tt \#@}]
+%This is the new name of the control sequence normally represented by
+%{\tt@\#}.
+¤³¤ì¤Ï¡¢Ä̾ï¤Î{\tt@\#}¤È¤¤¤¦À©¸æ¥·¡¼¥±¥ó¥¹¤Î¿·¤·¤¤Ì¾Á°¤Ç¤¢¤ë¡£
+% You would use {\tt\#@} to get a line break followed by vertical
+%white space.
+{\tt\#@}¤Ï¡¢¿âľ¥¹¥Ú¡¼¥¹¤òȼ¤¦²þ¹Ô¤òÆÀ¤ë¤È¤­¤Ë»È¤¦¡£
+\end{description}
+%If you change the at sign to something other than {\tt@}~or~{\tt\#},
+%the above will still hold provided you substitute your at sign for
+%{\tt\#}.
+¤â¤·¤¢¤Ê¤¿¤¬ at~sign ¤ò {\tt@}~¤Þ¤¿¤Ï~{\tt\#} °Ê³°¤Î²¿¤«¤ËÊѤ¨¤¿¤Ê¤é¡¢
+¾å¤Îµ­½Ò¤Î{\tt\#}¤ò¤¢¤Ê¤¿¤¬»ØÄꤷ¤¿ at~sign ¤ËÃÖ¤­´¹¤¨¤ÆÆɤá¤ÐÎɤ¤¡£
+
+
+
+
+\subsection{¥×¥í¥°¥é¥à¸À¸ìÆâ¤Ç¤Î¥³¥á¥ó¥È}
+{\tt WEAVE} ¤È {\tt TANGLE} ¤Ë¥¿¡¼¥²¥Ã¥È¸À¸ì¤ÎÃæ¤Î¥³¥á¥ó¥È¤Î°·¤¤¤ò
+»ØÄꤷ¤Æ¤ª¤«¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
+¥³¥á¥ó¥È¥Æ¥­¥¹¥È¤Ï¡¢
+{\tt WEAVE}¤Ç¤Ï{\TeX}¥Æ¥­¥¹¥È¤È¤·¤Æ°·¤ï¤ì¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤·¡¢
+{\tt TANGLE}¤Ç¤Ï̵»ë¤µ¤ì¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
+{\tt comment} ¥³¥Þ¥ó¥É¤Î¹½Ê¸¤Ï¡¢°Ê²¼¤ÎÄ̤ꡣ
+\begin{quote}
+\tt
+comment begin \syntax{restricted translation} \\
+\null\qquad end $(\syntax{restricted translation}|{\tt newline})$
+\end{quote}
+³ç¤é¤ì¤¿Ê¸»úÎó¡¢{\tt space}¡¢{\tt dash} ¤Î¤ß¤¬¡¢
+À©¸Â¤Ä¤­¤Î translation ¤È¤·¤Æµ­½Ò¤Ç¤­¤ë¡£
+%They give the character sequences that begin and end comments.
+¤³¤ì¤é¤Ï¥³¥á¥ó¥È¤Î³«»Ï¤È½ªÎ»¤Îʸ»úÎó¤Ç¤¢¤ë¡£
+¥³¥á¥ó¥È¤¬²þ¹Ô¤Ç½ªÎ»¤¹¤ë¤Î¤Ê¤é¡¢Àµ¤·¤¤¤ª¤Þ¤¸¤Ê¤¤¤Ï {\tt end
+newline}¤Ç¤¢¤ë¡£
+
+¤â¤·¥³¥á¥ó¥Èʸ»ú¤¬ ``at sign''¤ÈƱ¤¸¤Ç¤¢¤ì¤Ð¡¢
+{\WEB} ¥Õ¥¡¥¤¥ë¤ÎÃæ¤Ç¤ÏÆó½Å¤Ë½ñ¤«¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
+%file to have any effect.
+É®¼Ô¤¬Ëº¤ì¤Æ¤·¤Þ¤Ã¤¿¤»¤¤¤Ç¡¢
+{Spider} ¤³¤ì¤ò¸¡½Ð¤Ç¤­¤Ê¤¤Çϼ¯¼Ô¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¤¡¢
+%is too dumb to figure this out
+{\jem {\tt Spider} ¥Õ¥¡¥¤¥ë¤ÎÃæ¤Ç
+¥³¥á¥ó¥Èʸ»ú¤òÆó½Å¤Ë½ñ¤«¤Í¤Ð¤Ê¤é¤Ê¤¯¤Ê¤Ã¤Æ¤·¤Þ¤Ã¤¿}¡£
+%This is not totally unreasonable since any at sign that actually appears in a
+%{\WEB} file will have to be double to be interpreted correctly.
+{\WEB}¥Õ¥¡¥¤¥ë¤¬Àµ¤·¤¯²ò¼á¤¹¤ë¤¿¤á¤Ë at~sign ¤¬¸½¼Â¤Ë¤Ï
+Æó½Å¤Ë½ñ¤«¤ì¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤Î¤Ç¡¢Áí¹çŪ¤Ë¤ÏÁ´¤¯ÉÔÅö¤È¤¤¤¦¤ï¤±¤Ç¤Ï¤Ê¤¤¡£
+
+
+{\tt WEAVE} ¤Ï \verb+\commentbegin+ ¤È
+\verb+\commentend+ ¤È¤¤¤¦¥Þ¥¯¥í¤ò
+¥³¥á¥ó¥È¤Î³«»Ï¤È½ªÎ»¤Ë»È¤¦¡£
+%at the beginning and end of comments, so you can
+¤è¤Ã¤Æ¡¢{Spider}¤Î¥Ç¥Õ¥©¥ë¥È¤¬µ¤¤ËÆþ¤é¤Ê¤±¤ì¤Ð
+({\tt macros}¥³¥Þ¥ó¥É¤ò»È¤Ã¤Æ)¹¥¤­¤Ê¤è¤¦¤ËÄêµÁ¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£
+{Spider} ¤Ï{\TeX}¤Î¥Ç¥Õ¥©¥ë¥È¤ÎÆüìʸ»ú¤ò²óÈò¤¹¤ëÄøÅ٤ˤϽ½Ê¬¥¹¥Þ¡¼¥È¤Ç¤¢¤ë¡£
+%is smart enough to escape {\TeX}'s special characters in
+%coming up with these defaults.
+
+%Here's a real-world ugly example of how things really are, from the
+%{\tt spider} file for Awk:
+°Ê²¼¤Ë¼ÂºÝ¤Ë¤É¤¦¤·¤Æ¤¤¤ë¤«¤ò Awk ¤Î{\tt spider} ¥Õ¥¡¥¤¥ë¤«¤é°úÍѤ¹¤ë:
+\begin{verbatim}
+comment begin <"##"> end newline
+macros begin
+\def\commentbegin{\#} % we don't want \#\#
+macros end
+\end{verbatim}
+
+
+
+\subsection{¹ÔÈÖ¹æ¤ÎÀ©¸æ}
+ ¥³¥ó¥Ñ¥¤¥é¤¬{\WEB}¥Õ¥¡¥¤¥ë¤òľÀܸ«¤ë¤³¤È¤Ï¤Ê¤¤¡£{\tt TANGLE} ¤Î
+½ÐÎϤòÆɤޤͤФʤé¤Ê¤¤¡£
+{\tt TANGLE}¤¬ºî¤Ã¤¿¥Õ¥¡¥¤¥ë¤Î¹ÔÈÖ¹æ¤ò¼¨¤¹¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤Ï¡¢
+Èó¾ï¤ËÍ­¸ú¤À¤È¤Ï¸À¤¤Æñ¤¤¡£¤½¤³¤Ç¡¢
+Spidery {\tt TANGLE} ¤Ï¡¢Â¿¾¯²þÁ±¤·¤¿¾õ¶·¤òÄ󶡤¹¤ë¤¿¤á¡¢
+ C~¥×¥ê¥×¥í¥»¥Ã¥µ¡¼ÍѤΠ{\tt \#line} Ì¿Îá¤ò½ÐÎϤ˽ñ¤¯(
+{\tt TANGLE} ¤â{\WEB} ¥½¡¼¥¹¤Î²þ¹Ô¾ðÊó¤òÊÝ»ý¤·¤Æ¤¤¤ë¤Î¤Ç¡¢
+ {\tt \#line} ¾ðÊó¤ÏÍ­ÍѤÀ¤í¤¦)¡£
+{\tt cc} ¤È {\tt dbx}¤ò»ý¤Ã¤¿
+Unix ¤Î¤è¤¦¤Ê¥·¥¹¥Æ¥à¤Ç¤Ï¡¢¥³¥ó¥Ñ¥¤¥ë»þ¤È¥é¥ó¥¿¥¤¥à»þ¤ÎξÊý¤Ç
+{\WEB}¥½¡¼¥¹¤ÎÍѸì¤Ç¥Ç¥Ð¥Ã¥°¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡£
+Ãæ´Ö¤Î¥×¥í¥°¥é¥ß¥ó¥°¥½¡¼¥¹¤Ï¤±¤Ã¤·¤ÆÄ´¤Ù¤ëɬÍפ¬¤Ê¤¤¡£
+
+Á´¤Æ¤Î¥³¥ó¥Ñ¥¤¥é¤¬{\tt \#line}Ì¿Îá¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¤ï¤±¤Ç¤Ï¤Ê¤¤¤Î¤Ç¡¢
+{Spider}¤Ï {\tt line} ¥³¥Þ¥ó¥É¤Ç
+ {\tt \#line} Ì¿Îá¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤òÊѹ¹¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤ë¡£
+¼«Ê¬¤Î¥³¥ó¥Ñ¥¤¥é¤¬ {\tt \#line} ¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢
+{\tt line} ¥³¥Þ¥ó¥É¤ò»È¤Ã¤Æ¹ÔÈÖ¹æ¾ðÊó¤ò¥³¥á¥ó¥È¤ÎÃæ¤ËÆþ¤ì¤ë¤è¤¦¤Ë
+Êѹ¹¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë\footnote{%
+¹ÔÈÖ¹æ¤ò½Ð¤µ¤Ê¤¤¥³¥Þ¥ó¥É¤¬¤¢¤ë¤Ù¤­¤Ç¤¢¤ë¡£%
+}¡£
+¹½Ê¸¤Ï°Ê²¼¤ÎÄ̤ê:
+\begin{quote}
+\tt
+line begin \syntax{restricted translation} end \syntax{restricted translation}
+\end{quote}
+{\tt begin} ¤Ï¥Õ¥¡¥¤¥ë̾¤È¹ÔÈÖ¹æ¤ÎÁ°¤ËÃÖ¤¯Ê¸»úÎó¤ò»ØÄꤷ¡¢
+{\tt end} ¤Ï¸å¤ËÃÖ¤¯Ê¸»úÎó¤ò»ØÄꤹ¤ë¡£
+¥Ç¥Õ¥©¥ë¥È¤Ï (CÍѤËÀßÄꤵ¤ì¤Æ¤¤¤ë¤¬)°Ê²¼¤ÎÄ̤ꡣ
+\begin{verbatim}
+line begin <"#line"> end <"">
+\end{verbatim}
+¼¡¤Î¤Ï Ada~{Spider}¥Õ¥¡¥¤¥ë¤Ç¤ÎÎã¤Ç¤¢¤ë¡£
+¤³¤³¤Ç¤Ï¡¢¹ÔÈÖ¹æ¾ðÊó¤ò Ada ¤Î¥³¥á¥ó¥È¤È¤·¤Æ¤¤¤ë:
+\begin{verbatim}
+line begin <"--"-space-"line"> end <"">
+\end{verbatim}
+
+
+
+
+\subsection{ºîÀ®Æü»þ¤Îɽ¼¨}
+Spidery {\tt WEAVE} ¤È{\tt TANGLE}¤¬½èÍý¤ò»Ï¤á¤ë»þ¡¢
+{Spider}¥Õ¥¡¥¤¥ë¤ò½èÍý¤·¤¿Æü»þ¤¬É½¼¨¤µ¤ì¤ë¡£
+¤³¤ì¤Ï¡¢{Spider}¤Î {\tt date}¥³¥Þ¥ó¥É¤Ë¤è¤Ã¤Æ¼¡¤Î¤è¤¦¤ËÀßÄꤵ¤ì¤ë¡£
+\begin{quote}
+\tt
+date \syntax{date}
+\end{quote}
+¤³¤³¤Ç \syntax{date} ¤Ï¡¢{\tt "Fri Dec 11 11:31:18 EST 1987"} ¤Ê¤É¤Ç¤¢¤ë¡£
+Ä̾{\tt date} ¥³¥Þ¥ó¥É¤ÎɬÍפϤʤ¤¡£
+{Spider} ¥Ä¡¼¥ë¤¬¼«Æ°Åª¤ËÁÞÆþ¤¹¤ë¡£
+¤·¤«¤·¡¢Unix ¥Þ¥·¥ó¤Ç¤Ê¤¤¥·¥¹¥Æ¥à¤Ë{Spider}¤ò°Ü¿¢¤¹¤ë»þ¤Ë¤Ï¡¢
+¾åµ­¤Î¤³¤È¤¬É¬Íפˤʤ롣
+
+
+
+
+
+\section{Spider¤Î¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸}
+{Spider} ¤Ï»ÅÍ;å¤Î¥¨¥é¡¼¤ò¸¡½Ð¤¹¤ë¤¿¤á¤ËÈó¾ï¤ÊÅØÎϤò¤¹¤ë¡£
+{Spider}¤Î¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤ÏÆɤá¤Ð¤ï¤«¤ë¤è¤¦¤Ëºî¤ë¤Ä¤â¤ê¤Ç¤¢¤ë¤¬¡¢
+¤¦¤Þ¤¯À®¸ù¤µ¤»¤ëÊýË¡¤òÃΤé¤Ê¤¤¡£
+¥È¥é¥Ö¥ë¤Ë¤¢¤Ã¤¿»þ¤Î¤¿¤á¤Ë¡¢°Ê²¼¤Ë{Spider}¤¬¸¡½Ð¤·¤è¤¦¤È¤·¤Æ¤¤¤ë¾ò·ï¤ò¼¨¤·¤Æ¤ª¤¯:
+\begin{itemize}
+\item
+ ̤ÄêµÁ¤Ê¥³¥Þ¥ó¥É¡¢¸í¤Ã¤¿¥Õ¥£¡¼¥ë¥É¤ò´Þ¤à¹Ô¡¢
+%Garbled commands, lines with bad fields in them, or commands with
+»È¤ï¤ì¤Ê¤¤¥Õ¥£¡¼¥ë¥É¤ò»ý¤Ä¥³¥Þ¥ó¥É¡£
+%Any command with a field {Spider} can't follow or with an extra
+%field is ignored from the bad field onward, but the earlier fields may
+%have an effect.
+¥Õ¥£¡¼¥ë¥É¤¬É¬Íפʤ¹¤Ù¤Æ¤Î¥³¥Þ¥ó¥É¤Ë¤Ä¤¤¤Æ¡¢
+{Spider}¤Ï¥Õ¥£¡¼¥ë¥É¤òÊä¤ï¤Ê¤¤¤·¤è¤±¤¤¤Ê¥Õ¥£¡¼¥ë¥É°Ê¹ß¤ò̵¸ú¤È¤¹¤ë¡£
+¤¿¤À¤·¡¢¤½¤ì°ÊÁ°¤Î¥Õ¥£¡¼¥ë¥É¤ÏÍ­¸ú¤Ë¤Ê¤ë¤«¤âÃΤì¤Ê¤¤¡£
+¸í¤Ã¤¿¥Õ¥£¡¼¥ë¥É¤ä¥¨¥é¡¼¤Î¤¢¤ëÀ¸À®µ¬Â§¤Ï´°Á´¤Ë̵¸ú¤È¤µ¤ì¤ë¡£
+\item
+{\tt language} ¥³¥Þ¥ó¥É¤¬¤Ê¤¤¡£
+\item
+{\tt macros} ¤Þ¤¿¤Ï {\tt comment} ¥³¥Þ¥ó¥É¤¬ {\tt language} ¥³¥Þ¥ó¥É¤Î
+Á°¤ËÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡£
+{Spider} ¤Ï {\tt extension} ¾ðÊó¤ò
+from the {\tt language} ¥³¥Þ¥ó¥É¤«¤éÆÀ¤Æ¤ª¤ê¡¢
+¥Þ¥¯¥í¤ò½ñ¤­½Ð¤¹¥Õ¥¡¥¤¥ë̾¤ò·èÄꤹ¤ë¤¿¤á¤Ë»È¤¦¡£
+¤Þ¤¿{\tt comment} ¥³¥Þ¥ó¥É¤Ï
+{Spider} ¤¬{\TeX}¤Î¤¿¤á¤Ë¥³¥á¥ó¥È¤Î»Ï¤Þ¤ê¤È½ª¤ê¤ò
+¥Þ¥¯¥í¥Õ¥¡¥¤¥ë¤Ë½ñ¤¯¤³¤È¤òÍ×ÀÁ¤¹¤ë¡£
+\item
+ʸ̮¤¬º¸Æ³½Ð¡¢±¦Æ³½Ð¤Î¤¤¤º¤ì¤Ë¤â¹çÃפ·¤Ê¤¤¡£
+\item
+%A numbered target token doesn't fall in the range defined by the
+%left hand side of its production.
+ÈÖ¹æ¤Ç»²¾È¤µ¤ì¤¿¥È¡¼¥¯¥ó¤¬¤½¤ÎÀ¸À®µ¬Â§¤Îº¸Êդˤʤ¤¡£
+\item
+{\jem ÄɲäǤ­¤Ê¤¤}¥«¥Æ¥´¥ê¡¼¤¬¤¢¤ë¡£
+¤³¤ì¤Ï¡¢¤½¤Î¥«¥Æ¥´¥ê¡¼¤¬¥¹¥¯¥é¥Ã¥×¤òÀ¸À®¤¹¤ëÊýË¡¤¬¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
+{Spider} ¤Ïñ¤Ë¤¹¤Ù¤Æ¤Î¥«¥Æ¥´¥ê¡¼¤¬¾¯¤Ê¤¯¤È¤â°ìÅÙ¤Ï
+¥È¡¼¥¯¥ó¤«¥¿¡¼¥²¥Ã¥È¥È¡¼¥¯¥ó¤È¤·¤ÆÀ¸À®µ¬Â§¤ÎÃæ¤Ë¸½¤ì¤ë¤³¤È¤ò
+Ä´¤Ù¤Æ¤¤¤ë¤À¤±¤Ç¤¢¤ë¡£
+(¤â¤·¤±¤·¤ÆŬÍѤµ¤ì¤Ê¤¤À¸À®µ¬Â§¤¬¤¢¤ë¤Ê¤é¤Ð)
+{Spider}¤Ï¾ò·ï¤ò¸¡½Ð¤Ç¤­¤Ê¤¤¤Î¤Ç¼ºÇÔ¤¹¤ë¡£
+\item
+{\jem ´Ô¸µ¤Ç¤­¤Ê¤¤}¥«¥Æ¥´¥ê¡¼¤¬¤¢¤ë¡£
+¤³¤ì¤Ï¡¢¤³¤Î¥«¥Æ¥´¥ê¡¼¤¬À¸À®µ¬Â§¤ÎÃæ¤Ç»²¾È¤µ¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò°ÕÌ£¤¹¤ë¡£
+%This means that the category never appears in a scrap
+%designator from the firing instructions of a production.
+¥«¥Æ¥´¥ê¡¼¤¬´Ô¸µ¤Ç¤­¤Ê¤±¤ì¤Ð¡¢
+{Spider} ¤Ïñ¤Ë·Ù¹ð¤ò½Ð¤¹¤Î¤ß¤Ç¡¢
+¥¨¥é¡¼¤Ë¤è¤Ã¤Æ½èÍý¤òÄä»ß¤¹¤ë¤³¤È¤Ï¤Ê¤¤¡£
+
+¥«¥Æ¥´¥ê¡¼Ì¾¤ÎÄ֤θí¤ê¤Ë¤è¤ëÄɲäȴԸµ¤Î¥Á¥§¥Ã¥¯¤Ï¤¿¤¤¤Æ¤¤¸¡½Ð¤µ¤ì¤ë¡£
+\item
+{\tt WEAVE} ¤È {\tt TANGLE} ¤¬°·¤¨¤ë°Ê¾å¤Î
+¥È¡¼¥¯¥ó¤ò»ØÄꤷ¤Æ¤¤¤ë¡£
+\item
+¥È¡¼¥¯¥ó¤Î¾ðÊó¤¬ÉÔ´°Á´; ¼±Ê̻ҡ¢¿ôÃÍÄê¿ô¡¢newline¡¢
+µ¿»÷¥»¥ß¥³¥í¥ó~({\tt @;})¡¢¥â¥¸¥å¡¼¥ëÄêµÁ¡¢¥â¥¸¥å¡¼¥ë¤Î»ÈÍѤò˺¤ì¤Æ¤¤¤ë¡£
+\item
+ilk ¤¬ translation ¤ò»ý¤¿¤Ê¤¤¡¢¤Þ¤¿¤ÏͽÌó¸ì¤ò»ý¤¿¤Ê¤¤ ilk ¤¬¤¢¤Ã¤¿¡£
+%no reserved words.
+\end{itemize}
+
+
+
+
+\section{{Spider}¤Î½ÐÎÏ¥Õ¥¡¥¤¥ë}
+{Spider} ¤Ï¿¤¯¤Î½ÐÎÏ¥Õ¥¡¥¤¥ë¤òÀ¸À®¤¹¤ë¡£É¬Íפʤ餽¤ì¤é¤òÄ´¤Ù¡¢
+²¿¤¬¤Ê¤µ¤ì¤Æ¤¤¤ë¤«¤ò²òÀϤǤ­¤ë¡£
+°Ê²¼¤Ï¤½¤Î°ìÉô¤Ç¤¢¤ë (´°Á´¤Ê¥Õ¥¡¥¤¥ë¤Î¥ê¥¹¥È¤Ï
+{\tt spider.web}¤òÄ´¤Ù¤ì¤Ð¤ï¤«¤ë):
+\begin{description}
+\item[\tt cycle.test]
+ʸˡ¤Î¥ë¡¼¥×²ÄǽÀ­¤ò¸¡½Ð¤¹¤ë¤Î¤Ë»ÈÍѤµ¤ì¤ë¡£
+¤³¤Î¤è¤¦¤Ê¥ë¡¼¥×¤Ï ÆÃÄê¤ÎÆþÎϤËÂФ·{\tt WEAVE} ¤ò̵¸Â¤Ë (¥á¥â¥ê¡¼¤ò»È¤¤¤­¤ë¤Þ¤Ç)
+Áö¤é¤»¤ë¤³¤È¤Ë¤Ê¤ë¤è¤¦¤Ê¤â¤Î¤Ç¤¢¤ë¡£
+¸å¤Ç {Spider}¥Ä¡¼¥ë¤È°ì½ï¤ËµÄÏÀ¤¹¤ë¡£
+\item[\tt spider.slog]
+{Spider} ¤¬¥Õ¥¡¥¤¥ë¤ò½èÍýÃæ¤Î¤¹¤Ù¤Æ¤Î¾éŤÊÆâÍÆ¡£
+¤Ò¤É¤¤¤³¤È¤¬µ¯¤­¤¿»þ¤ËÄ´¤Ù¤ë¤¿¤á¤Î¤â¤Î¤Ç¤¢¤ë¡£
+\item[\tt *web.tex]
+À¸À®¤µ¤ì¤¿{\WEB}¤Î¤¿¤á¤Î¥Þ¥¯¥í¡£
+\item[\tt productions.list]
+¤¹¤Ù¤Æ¤Îµ¬Â§¤ÎÈÖ¹æÉÕ¤±¤·¤¿¥ê¥¹¥È¡£
+Spidery {\tt WEAVE}¤Î¥È¥ì¡¼¥¹µ¡Ç½ ({\tt @2})¤ò»È¤Ã¤Æʸˡ¤Î¥Ç¥Ð¥Ã¥°¤ò
+¤¹¤ëºÝ¤Ë½ÅÊõ¤¹¤ë¡£
+\end{description}
+
+
+
+
+\section{{Spider} ¤Ç{\WEB}¤òºî¤ë ({Spider} tools)}
+¿¤¯¤Î {Spider} ¥Ä¡¼¥ë¤¬¥¨¥é¡¼¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡£Î㤨¤Ð:
+\begin{itemize}
+\item
+¥«¥Æ¥´¥ê¡¼¡¢ilk¡¢translation ¤Î¥­¡¼¥ï¡¼¥É̾¤Î½ÅÊ£¥Á¥§¥Ã¥¯¤ò¤¹¤ë¡£
+\item
+translation ¥­¡¼¥ï¡¼¥É¤¬{\tt WEAVE}¤Î¥­¡¼¥ï¡¼¥É¤È¾×Æͤ·¤Æ¤¤¤Ê¤¤¤«¤ò¥Á¥§¥Ã¥¯¤·¡¢
+¾×Æͤ·¤Æ¤¤¤ì¤Ð·Ù¹ð¤òȯ¤¹¤ë¡£
+%keywords against a list of those recognized by
+% and yelps if trouble happens.
+\item
+{\tt WEAVE}¤¬Ìµ¸Â¥ë¡¼¥×¤Ë´Ù¤ë¤è¤¦¤Ê¡ÖÀ¸À®µ¬Â§¤Î½Û´Ä¡×¤¬¤Ê¤¤¤«¤ò¸¡½Ð¤¹¤ë¡£
+%Try to determine whether there is a ``production cycle'' that could
+%cause to loop infinitely by firing the productions in the
+%cycle one after another.
+\end{itemize}
+
+¤³¤³¤Ç¤Ï¡¢¤½¤ì¤é¤¬¤É¤¦¤Ê¤Ã¤Æ¤¤¤ë¤«¡¢{\tt WEAVE} ¤ä {\tt TANGLE}¤ò
+¤É¤¦¤ä¤Ã¤ÆÀ¸À®¤¹¤ë¤«¤Ë¤Ä¤¤¤Æ¡¢Â¿¤¯¤òÀâÌÀ¤¹¤ë¤Ä¤â¤ê¤Ï¤Ê¤¤¡£
+%I'm not going to say much about how to do all this, or how to make
+Âå¤ï¤ê¤Ë¡¢{\tt Makefile} ¤òÄ󼨤·¡¢¾¯¡¹¥³¥á¥ó¥È¤¹¤ë¤³¤È¤Ë¤·¤è¤¦¡£
+%and comment on it a little bit.
+%Since right now Spidery {\tt WEB} is available only on Unix systems,
+%chances are you have the {\tt Makefile} and can just type ``{\tt
+%make~tangle}'' or ``{\tt make~weave}.''
+¸½ºß¤Î¤È¤³¤í¡¢ Spidery {\tt WEB} ¤Ï Unix ¥·¥¹¥Æ¥à¤Î¾å¤Ë¤·¤«Â¸ºß¤·¤Æ¤¤¤Ê¤¤¡£
+{\tt Makefile} ¤òÆþ¼ê¤·¡¢
+ ``{\tt make~tangle}'' ¤Þ¤¿¤Ï ``{\tt make~weave}'' ¤È¥¿¥¤¥×¤¹¤ë¤À¤±¤Ç
+¤è¤¤²ÄǽÀ­¤¬¤¢¤ë¡£
+%If not, reading the Makefile is still your best bet to figure out what
+%the tools do.
+¤½¤¦¤Ç¤Ê¤¤¤È¤·¤Æ¤â¡¢ Makefile ¤òÆɤó¤Ç¥Ä¡¼¥ë¤Î¤¹¤ë¤³¤È¤òÍý²ò¤¹¤ë¤Î¤¬
+ºÇÁ±¤ÎÊýË¡¤Ç¤¢¤ë¡£
+
+%We assume that you are making {\tt WEAVE} and {\tt TANGLE} in some
+%directory, and that the ``master sources'' for Spidery {\WEB} are kept
+%in some other directory.
+¤¢¤Ê¤¿¤Ï´û¤Ë {\tt WEAVE} ¤È {\tt TANGLE} ¤ò¤É¤³¤«¤Î¥Ç¥£¥ì¥¯¥È¥ê¡¼¤Ëºî¤Ã¤Æ¤¢¤ê¡¢
+Spidery {\WEB} ¤Î ``master sources'' ¤¬¤É¤³¤«Ê̤Υǥ£¥ì¥¯¥È¥ê¡¼¤Ë
+Êݴɤµ¤ì¤Æ¤¤¤ë¤Î¤òÁ°Äó¤È¤¹¤ë¡£
+%Some of the {\tt Makefile} macros deserve special mention:
+{\tt Makefile} ¤Î ¥Þ¥¯¥í¤Î¤¤¤¯¤Ä¤«¤ÏÆä˸ÀµÚ¤¹¤ë²ÁÃͤ¬¤¢¤ë:
+\begin{description}
+\renewcommand{\makelabel}[1]{{\tt#1}\hfil}
+\item[THETANGLE]
+À¸À®¤·¤è¤¦¤È¤·¤Æ¤¤¤ë {\tt TANGLE} ¤Î̾Á°¡£
+\item[THEWEAVE]
+À¸À®¤·¤è¤¦¤È¤·¤Æ¤¤¤ë{\tt WEAVE} ¤Î̾Á°¡£
+\item[SPIDER]
+{Spider} ¤ÎÆþÎÏ¥Õ¥¡¥¤¥ë̾¡£
+\item[DEST]
+\verb+$(TANGLE)+ ¤È\verb+$(WEAVE)+ ¤È¤·¤ÆÄêµÁ¤µ¤ì¤¿¼Â¹Ô¥Õ¥¡¥¤¥ë¤¬ÃÖ¤«¤ì¤ë¤Ù¤­
+¥Ç¥£¥ì¥¯¥È¥ê¡¼¡£
+\item[WEBROOT]
+Spidery {\WEB} ÇÛÉÛʪ¤Î¥ë¡¼¥È¥Ç¥£¥ì¥¯¥È¥ê¡¼¡£
+\item[MASTER]
+``¥Þ¥¹¥¿¡¼¥½¡¼¥¹''¤Î¤¢¤ë¾ì½ê¡£
+¤³¤ì¤Ï¡¢É¬¤º {\tt make} ¤¬¼Â¹Ô¤µ¤ì¤ë¥Ç¥£¥ì¥¯¥È¥ê¡¼¤È°Û¤Ê¤Ã¤Æ¤¤¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
+¤µ¤â¤Ê¤±¤ì¤ÐÂæ̵¤·¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¦¤À¤í¤¦¡£
+%This should always be different from the directory in which {\tt make}
+%is called, or havoc will result.
+\item[CTANGLE]
+tangle ¤Î C ¥³¡¼¥É¤Ç»È¤ï¤ì¤ë¥×¥í¥°¥é¥à̾¡£
+\item[AWKTANGLE]
+Awk¤Î¥³¡¼¥É¤ò tangle ¤¹¤ë¥×¥í¥°¥é¥à¤Î̾Á°¡£
+
+\item[MACROS]
+%The name of a directory in which to put {\TeX} macro definitions (a
+%{\tt *web.tex} file.
+{\TeX}¥Þ¥¯¥í¥Õ¥¡¥¤¥ë({\tt *web.tex} )¤ò³ÊǼ¤¹¤ë¤Ù¤­¥Ç¥£¥ì¥¯¥È¥ê¡¼Ì¾¡£
+\end{description}
+
+%Usually we will only be interested in two commands: ``\/{\tt
+%make~weave}'' and ``\/{\tt make~tangle}.''
+ÉáÃÊÎɤ¯»È¤¦¤Î¤Ï \hbox{``{\tt make~weave}''} ¤È
+\hbox{``\/{\tt make~tangle}''} ¤Î
+2¤Ä¤Î¥³¥Þ¥ó¥É¤À¤±¤Ç¤¢¤í¤¦¡£
+%It's safe to use ``\/{\tt make~clean}'' only if you use the current
+%directory for nothing exception spidering; ``\/{\tt make~clean}'' is
+%really vicious.
+\hbox{``{\tt make~clean}''} ¤Ï¡¢ ¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¡¼¤Ç
+{\WEB} ºîÀ®ºî¶È°Ê³°¤Î¤³¤È¤ò¤·¤Ê¤¤»þ¤Ç¤Ê¤±¤ì¤Ð°ÂÁ´¤Ç¤Ï¤Ê¤¤¡£
+%only if you use the current directory
+%for nothing exception spidering;
+\hbox{``\/{\tt make~clean}''}¤Ï¡¢ ËÜÅö¤Ë¤Ò¤É¤¤¤³¤È¤ò¤¹¤ë¡£
+
+ËÜÅö¤Ë¶½Ì£¿¼¤¤¹Ô¤Ï¡¢
+{\tt grammar.web} ¤Î°Í¸´Ø·¸¤òɽµ­¤·¤Æ¤¤¤ë¤È¤³¤í¤Ç¤¢¤ë¡£
+Âè°ì¤Ë¡¢ {Spider}¤òµ¯Æ°¤¹¤ë¡£
+¼¡¤Ë¡¢À°·Á°õºþʸˡ ¤ÎÃæ¤Ë¡¢´Ö°ã¤Ã¤¿ translation ¥­¡¼¥ï¡¼¥É¤ä
+½Û´Ä¤Î²ÄǽÀ­¤¬¤Ê¤¤¤«¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡£
+¤½¤·¤Æ¡¢Ì¾Á°¤Î¤Ë½ÅÊ£ÄêµÁ¤¬¤Ê¤¤¤³¤È¤ò¥Á¥§¥Ã¥¯¤·¡¢
+ºÇ¸å¤Ë (Á´¤Æ¤¬OK¤À¤Ã¤¿¤é)
+{\tt *web.tex} ¥Õ¥¡¥¤¥ë¤ò½ÐÎϤ¹¤ë¡£
+
+\newpage
+°Ê²¼¤Ï¡¢ \verb+$(MASTER)/WebMakefile+¤Ç¤¢¤ë:
+\begingroup\small
+\begin{verbatim}
+# Copyright 1989 by Norman Ramsey and Odyssey Research Associates.
+# To be used for research purposes only.
+# For more information, see file COPYRIGHT in the parent directory.
+
+HOME=/u/nr# # Make no longer inherits environment vars
+THETANGLE=tangle
+THEWEAVE=weave
+SPIDER=any.spider
+#
+DVI=dvi
+CFLAGS=-DDEBUG -g -DSTAT
+
+# CPUTYPE is a grim hack that attempts to solve the problem of multiple
+# cpus sharing a file system. In my environment I have to have different
+# copies of object and executable for vax, sun3, next, iris, and other
+# cpu types. If you will be using Spidery WEB in a homogeneous processor
+# environment, you can just set CPUTYPE to a constant, or eliminate it
+# entirely.
+#
+# In my environment, the 'cputype' program returns a string that
+# describes the current processor. That means that the easiest thing
+# for you to do is to define a 'cputype' program that does something
+# sensible. A shell script that says 'echo "vax"' is fine.
+
+CPUTYPE=`cputype`
+
+# Change the following three directories to match your installation
+#
+# the odd placement of # is to prevent any trailing spaces from slipping in
+
+WEBROOT=$(HOME)/web/src# # root of the WEB source distribution
+DEST=$(HOME)/bin/$(CPUTYPE)# # place where the executables go
+MACROS=$(HOME)/tex/macros# # place where the macros go
+
+MASTER=$(WEBROOT)/master# # master source directory
+OBDIR=$(MASTER)/$(CPUTYPE)# # common object files
+
+TANGLESRC=tangle
+CTANGLE=ceetangle -I$(MASTER)
+CWEAVE=ceeweave -I$(MASTER)
+AWKTANGLE=awktangle -I$(MASTER)
+COMMONOBJS=$(OBDIR)/common.o $(OBDIR)/pathopen.o
+COMMONC=$(MASTER)/common.c $(MASTER)/pathopen.c
+COMMONSRC=$(COMMONC) $(MASTER)/spider.awk
+
+
+
+# Our purpose is to make tangle and weave
+
+web: tangle weave
+
+tangle: $(COMMONOBJS) $(TANGLESRC).o
+ cc $(CFLAGS) -o $(DEST)/$(THETANGLE) $(COMMONOBJS) $(TANGLESRC).o
+
+weave: $(COMMONOBJS) weave.o
+ cc $(CFLAGS) -o $(DEST)/$(THEWEAVE) $(COMMONOBJS) weave.o
+
+
+source: $(TANGLESRC).c $(COMMONSRC) # make tangle.c and common src, then clean
+ if [ -f WebMakefile ]; then exit 1; fi # don't clean the master!
+ if [ -f spiderman.tex ]; then exit 1; fi # don't clean the manual
+ -rm -f tangle.web weave.* common.* # remove links that may be obsolete
+ -rm -f *.unsorted *.list grammar.web outtoks.web scraps.web
+ -rm -f cycle.test spider.slog
+ -rm -f *.o *.tex *.toc *.dvi *.log *.makelog *~ *.wlog *.printlog
+
+# Here is how we make the common stuff
+
+$(MASTER)/common.c: $(MASTER)/common.web # no change file
+ $(CTANGLE) $(MASTER)/common
+
+$(OBDIR)/common.o: $(MASTER)/common.c
+ cc $(CFLAGS) -c $(MASTER)/common.c
+ mv common.o $(OBDIR)
+
+
+$(MASTER)/pathopen.c: $(MASTER)/pathopen.web # no change file
+ $(CTANGLE) $(MASTER)/pathopen
+ mv pathopen.h $(MASTER)
+
+$(OBDIR)/pathopen.o: $(MASTER)/pathopen.c
+ cc $(CFLAGS) -c $(MASTER)/pathopen.c
+ mv pathopen.o $(OBDIR)
+
+
+## Now we make the tangle and weave source locally
+
+$(TANGLESRC).c: $(MASTER)/$(TANGLESRC).web $(MASTER)/common.h grammar.web
+ -/bin/rm -f $(TANGLESRC).web
+ ln $(MASTER)/$(TANGLESRC).web $(TANGLESRC).web
+# chmod -w $(TANGLESRC).web
+ $(CTANGLE) $(TANGLESRC)
+
+weave.c: $(MASTER)/weave.web $(MASTER)/common.h grammar.web
+ -/bin/rm -f weave.web
+ ln $(MASTER)/weave.web weave.web
+# chmod -w weave.web
+ $(CTANGLE) weave
+
+## Here's where we run SPIDER to create the source
+
+grammar.web: $(MASTER)/cycle.awk $(MASTER)/spider.awk $(SPIDER)
+ echo "date" `date` | cat - $(SPIDER) | awk -f $(MASTER)/spider.awk
+ cat $(MASTER)/transcheck.list trans_keys.unsorted | awk -f $(MASTER)/transcheck.awk
+ awk -f $(MASTER)/cycle.awk < cycle.test
+ sort *.unsorted | awk -f $(MASTER)/nodups.awk
+ mv *web.tex $(MACROS)
+
+## We might have to make spider first.
+
+$(MASTER)/spider.awk: $(MASTER)/spider.web
+ $(AWKTANGLE) $(MASTER)/spider
+ mv cycle.awk nodups.awk transcheck.awk $(MASTER)
+ rm junk.list
+
+
+# $(MASTER)/cycle.awk: $(MASTER)/cycle.web # making spider also makes cycle
+# $(AWKTANGLE) $(MASTER)/cycle
+
+
+# This cleanup applies to every language
+
+clean:
+ if [ -f WebMakefile ]; then exit 1; fi # don't clean the master!
+ if [ -f spiderman.tex ]; then exit 1; fi # don't clean the manual
+ -rm -f tangle.* weave.* common.* # remove links that may be obsolete
+ -rm -f *.unsorted *.list grammar.web outtoks.web scraps.web
+ -rm -f cycle.test spider.slog
+ -rm -f *.c *.o *.tex *.toc *.dvi *.log *.makelog *~ *.wlog *.printlog
+
+
+
+# booting the new distribution
+boot:
+ cd ../master; rm -f *.o; for i in $(COMMONC); do \
+ cc $(CFLAGS) -c $$i; \
+ mv *.o $(OBDIR) ; \
+ done; cd ../c
+ cc $(CFLAGS) -c $(TANGLESRC).c; \
+ cc $(CFLAGS) -o $(DEST)/$(THETANGLE) $(COMMONOBJS) $(TANGLESRC).o
+
+
+\end{verbatim}
+\endgroup
+
+\section{¼«Ê¬ÍѤΠSpidery {\tt WEB}¤òºî¤ë}
+º£¤Î¤È¤³¤í¡¢ Spidery {\tt WEB} ¤ÏUnix ¥Þ¥·¥ó¤Ç¤·¤«¥Æ¥¹¥È¤µ¤ì¤Æ¤¤¤Ê¤¤¡£
+C¥³¥ó¥Ñ¥¤¥é¤È Awk ¥¤¥ó¥¿¡¼¥×¥ê¥¿¡¼¤ÎÆ°¤¯¥Þ¥·¥ó¤Ç¤¢¤ì¤Ð¡¢°Ü¿¢¤Ï´Êñ¤Ê¤Ï¤º¤À¤¬¡¢
+´Ö°ã¤¤¤Ê¤¯¡¢¤¤¤¯¤Ä¤«¤Î½¤Àµ¤¬É¬ÍפǤ¢¤í¤¦¡£
+¤³¤Î¥Þ¥Ë¥å¥¢¥ë¤â´Þ¤ó¤À ´°Á´¤Ê{Spider}¤ÎÇÛÉۤϡ¢anonymous {\tt ftp}
+( {\tt princeton.edu:~ftp/pub/spiderweb.tar.Z}) ¤ÇÆþ¼ê¤Ç¤­¤ë¡£
+{Spider} ¤ò¥¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¡¼¤òÁª¤Ó¡¢ÇÛÉÛ¤µ¤ì¤¿¤â¤Î¤ò untar ¤·¡¢
+%distribution, and follow the directions in the
+README ¥Õ¥¡¥¤¥ë¤Î»Ø¼¨¤Ë½¾¤¨¤ÐÎɤ¤¡£
+Áª¤ó¤À¥Ç¥£¥ì¥¯¥È¥ê¡¼¤Ï¡¢{\tt WEBROOT}¤È¤Ê¤ë¡£
+
+¤â¤·¡¢ÇÛÉÛ¤ÎÃæ¤Î {\tt Makefile} ¤¬¡¢¾åµ­¤Ç¼¨¤·¤¿¤â¤Î¤È°ã¤Ã¤Æ¤¤¤¿¤é¡¢
+ÇÛÉÛ¤ÎÃæ¤Î¤â¤Î¤¬Àµ¤·¤¤¤È¹Í¤¨¤ÆÍߤ·¤¤¡£
+
+
+
+
+\pagebreak
+\section{¼ÂºÝ¤Î {Spider} ¥Õ¥¡¥¤¥ë}
+¤³¤ì¤Þ¤Ç¡¢{Spider}¤Î»È¤¤Êý¤òÀâÌÀ¤¹¤ë¤¿¤á¤Ë¼ÂºÝ¤ÎÎã¤ò»È¤Ã¤Æ¤­¤¿¡£
+¤³¤³¤Ç¤Ï¡¢Awk ¸À¸ìÍѤδ°Á´¤Ê {Spider} ¥Õ¥¡¥¤¥ë¤òȯŸ¤·¤¿Îã¤È¤·¤Æ°Ê²¼¤Ë¼¨¤¹¡£
+ÇÛÉÛ¤µ¤ì¤¿¤â¤Î¤ò´Êñ¤Ë¸¦µæ¤Ç¤­¤Ê¤¤¿Í¤Ï¡¢¤³¤ì¤¬ÌòΩ¤Ä¤Ç¤¢¤í¤¦¡£
+\begingroup\small
+\begin{verbatim}
+# Copyright 1989 by Norman Ramsey and Odyssey Research Associates.
+# To be used for research purposes only.
+# For more information, see file COPYRIGHT in the parent directory.
+
+language AWK extension awk
+
+at_sign #
+
+module definition stmt use stmt
+# use as stmt is unavoidable since tangle introduces line breaks
+
+comment begin <"##"> end newline
+macros begin
+\def\commentbegin{\#} % we don't want \#\#
+macros end
+
+line begin <"#line"> end <"">
+
+default translation <*> mathness yes
+
+token identifier category math mathness yes
+token number category math mathness yes
+token newline category newline translation <> mathness maybe
+token pseudo_semi category ignore_scrap mathness no translation <opt-0>
+
+token \ category backslash translation <> mathness maybe
+token + category unorbinop
+token - category unorbinop
+token * category binop
+token / category binop
+token < category binop
+token > category binop
+token >> category binop translation <"\\GG">
+token = category equals translation <"\\K">
+token ~ category binop translation <"\\TI">
+token !~ category binop translation <"\\not\\TI">
+token & category binop translation <"\\amp">
+token % translation <"\\%"> category binop
+token ( category open
+token [ category lsquare
+token ) category close
+token ] category close
+token { translation <"\\;\\{"-indent> category lbrace
+token } translation <"\\}\\"-space> category close
+token , category binop translation <",\\,"-opt-3>
+
+token ; category semi translation <";"-space-opt-2> mathness no
+# stuff with semi can be empty in for statements
+open semi --> open
+semi semi --> semi
+semi close --> close
+semi --> binop
+
+# token : category colon
+# token | category bar
+token != name not_eq translation <"\\I"> category binop
+token <= name lt_eq translation <"\\L"> category binop
+token >= name gt_eq translation <"\\G"> category binop
+token == name eq_eq translation <"\\S"> category binop
+token && name and_and translation <"\\W"> category binop
+token || name or_or translation <"\\V"> category binop
+# token -> name minus_gt translation <"\\MG"> category binop
+token ++ name gt_gt category unop translation <"\\uparrow">
+token -- name lt_lt category unop translation <"\\downarrow">
+# preunop is for unary operators that are prefix only
+token $ category preunop translation <"\\DO"> mathness yes
+
+default mathness yes translation <*>
+
+ilk pattern_like category math
+reserved BEGIN ilk pattern_like
+reserved END ilk pattern_like
+
+ilk if_like category if
+reserved if
+ilk else_like category else
+reserved else
+
+ilk print_like category math
+# math forces space between this and other math...
+reserved print ilk print_like
+reserved printf ilk print_like
+reserved sprintf ilk print_like
+
+
+ilk functions category unop mathness yes
+reserved length ilk functions
+reserved substr ilk functions
+reserved index ilk functions
+reserved split ilk functions
+reserved sqrt ilk functions
+reserved log ilk functions
+reserved exp ilk functions
+reserved int ilk functions
+
+ilk variables category math mathness yes
+reserved NR ilk variables
+reserved NF ilk variables
+reserved FS ilk variables
+reserved RS ilk variables
+reserved OFS ilk variables
+reserved ORS ilk variables
+
+ilk for_like category for
+reserved for ilk for_like
+reserved while ilk for_like
+
+ilk in_like category binop translation <math_bin-*-"}"> mathness yes
+# translation <"\\"-space-*-"\\"-space>
+reserved in ilk in_like
+
+ilk stmt_like category math
+reserved break ilk stmt_like
+reserved continue ilk stmt_like
+reserved next ilk stmt_like
+reserved exit ilk stmt_like
+
+
+backslash newline --> math
+# The following line must be changed to make a backslash
+backslash <"\\backslash"> --> math
+
+math (binop|unorbinop) math --> math
+<"\\buildrel"> (binop|unorbinop) <"\\over{"> equals <"}"> --> binop
+equals --> binop
+(unop|preunop|unorbinop) math --> math
+# unorbinop can only act like unary op as *prefix*, not postfix
+math unop --> math
+math <"\\"-space> math --> math
+# concatenation
+
+math newline --> stmt
+newline --> ignore_scrap
+
+stmt <force> stmt --> stmt
+
+(open|lsquare) math close --> math
+
+math lbrace --> lbrace
+lbrace <force> stmt --> lbrace
+lbrace <outdent-force> close --> stmt
+
+if <"\\"-space> math --> ifmath
+ifmath lbrace --> ifbrace
+ifmath newline --> ifline
+ifbrace <force> stmt --> ifbrace
+ifbrace <outdent-force> close else <"\\"-space> if --> if
+ifbrace <outdent-force> close else lbrace --> ifbrace
+ifbrace <outdent-force> close else newline --> ifline
+ifbrace <outdent-force> close --> stmt
+(ifline|ifmath) <indent-force> stmt <outdent-force> else <"\\"-space> if --> if
+(ifline|ifmath) <indent-force> stmt <outdent-force> else lbrace --> ifbrace
+(ifline|ifmath) <indent-force> stmt <outdent-force> else newline --> ifline
+(ifline|ifmath) <indent-force> stmt <outdent-force> else --> ifmath
+(ifline|ifmath) <indent-force> stmt <outdent> --> stmt
+
+for <"\\"-space> math --> formath
+formath lbrace --> forbrace
+formath newline --> forline
+forbrace <force> stmt --> forbrace
+forbrace <outdent-force> close --> stmt
+(forline|formath) <indent-force> stmt <outdent> --> stmt
+
+
+? ignore_scrap --> #1
+\end{verbatim}
+\endgroup
+
+
+\newpage
+\section{Bibliography}
+\begin{thebibliography}{Knuth~999}
+\bibitem[Bentley~87]{bentley:pearls}
+Jon L. Bentley, ``Programming Pearls,'' {\sl Communications of the
+ACM}~{\bf 29:5}(May 1986), 364--?, and {\bf 29:6}(June 1986),
+471--483.
+ʸ½ñ²½¥×¥í¥°¥é¥ß¥ó¥°¤Ë¤Ä¤¤¤Æ¤Î2¤Ä¤Î¥³¥é¥à¡£
+ºÇ½é¤Î¤â¤Î¤ÏÆþÌçÊÔ¡£ÆóÈÖÌܤΤÏ
+Donald Knuth ¤Ë¤è¤ë³ÈÄ¥¤µ¤ì¤¿Îã¤Ç
+Douglas MacIlroy ¤¬¥³¥á¥ó¥È¤·¤Æ¤¤¤ë¡£
+\bibitem[Knuth~83]{knuth:web}
+Donald~E. Knuth,
+``The {{\tt WEB}} system of structured documentation''
+ Technical Report 980, Stanford Computer Science, Stanford,
+ California, September 1983.
+¥ª¥ê¥¸¥Ê¥ë¤Î {\tt WEB}¤Î¥Þ¥Ë¥å¥¢¥ë¡£
+\bibitem[Knuth~84]{knuth:literate-programming}
+Donald E. Knuth, ``Literate Programming,'' {\sl The Computer Journal}
+{\bf 27:2}(1984), 97--111.
+{\WEB}¤Ë¤è¤ëʸ½ñ²½¥×¥í¥°¥é¥ß¥ó¥°¤Î¥ª¥ê¥¸¥Ê¥ë¤ÎÆþÌç½ñ¡£
+\bibitem[Levy~87]{levy:cweb}
+Silvio Levy, ``Web Adapted to C, Another Approach'' {\sl TUGBoat}
+{\bf 8:2}(1987), 12--13.
+{\WEB}¤ò C ¤Ç¼Â¸½¤¹¤ë¤³¤È¤Ë¤Ä¤¤¤Æ¤Î¾®Êó¹ð½ñ¡£
+¤³¤ì¤«¤é Spidery {\WEB} ¤ÏÇÉÀ¸¤·¤¿¡£
+\bibitem[Sewell~89]{sewell:weaving}
+Wayne Sewell, ``Weaving a program: Literate programming in {\tt
+WEB},''
+Van Nostrand Reinhold, 1989.
+\end{thebibliography}
+
+
+\end{document}
diff --git a/web/spiderweb/doc/spe.aux b/web/spiderweb/doc/spe.aux
new file mode 100644
index 0000000000..c2471f652f
--- /dev/null
+++ b/web/spiderweb/doc/spe.aux
@@ -0,0 +1,70 @@
+\relax
+\citation{knuth:literate}
+\citation{bentley:lp1,bentley:lp2,cvw:loom,gries:pearls}
+\citation{knuth:tex,knuth:metafont}
+\citation{bentley:lp1,bentley:lp2}
+\citation{cvw:loom}
+\citation{gries:pearls}
+\citation{cvw:assessment}
+\citation{thimbleby:review}
+\citation{knuth:literate,thimbleby:cweb,guntermann:cweb,levy:cweb,sewell:mangle,ramsey:building}
+\@writefile{toc}{\string\contentsline\space {section}{Introduction}{2}}
+\citation{knuth:literate}
+\citation{ramsey:developing,marceau:interactive,guaspari:formal}
+\citation{reps:synthesizer:89}
+\citation{reps:generating}
+\citation{adalrm,polak:predicate}
+\citation{marceau:verified,weber:beyond,anderson:asos}
+\@writefile{toc}{\string\contentsline\space {section}{Using Literate Programming}{3}}
+\citation{polak:predicate,polak:program}
+\citation{adalrm}
+\citation{ganzinger:operator}
+\citation{cvw:assessment}
+\citation{thimbleby:review}
+\citation{bentley:more-pearls:graphics,bentley:lp2,sedgewick:algorithms}
+\@writefile{toc}{\string\contentsline\space {section}{Evaluating {\string\ptt\space WEB}}{5}}
+\citation{knuth:tex}
+\citation{feldman:make}
+\citation{johnson:yacc}
+\citation{kernighan:unix}
+\citation{ramsey:spiderwebman}
+\citation{thimbleby:review}
+\citation{parnas:rational}
+\@writefile{toc}{\string\contentsline\space {section}{Discussion}{9}}
+\citation{reps:synthesizer:89}
+\bibstyle{unsrt}
+\bibdata{web,ada,cs,ramsey}
+\bibcite{knuth:literate}{1}
+\bibcite{bentley:lp1}{2}
+\bibcite{bentley:lp2}{3}
+\bibcite{cvw:loom}{4}
+\bibcite{gries:pearls}{5}
+\bibcite{knuth:tex}{6}
+\bibcite{knuth:metafont}{7}
+\bibcite{cvw:assessment}{8}
+\@writefile{toc}{\string\contentsline\space {section}{Acknowledgments}{11}}
+\bibcite{thimbleby:review}{9}
+\bibcite{thimbleby:cweb}{10}
+\bibcite{guntermann:cweb}{11}
+\bibcite{levy:cweb}{12}
+\bibcite{sewell:mangle}{13}
+\bibcite{ramsey:building}{14}
+\bibcite{ramsey:developing}{15}
+\bibcite{marceau:interactive}{16}
+\bibcite{guaspari:formal}{17}
+\bibcite{reps:synthesizer:89}{18}
+\bibcite{reps:generating}{19}
+\bibcite{adalrm}{20}
+\bibcite{polak:predicate}{21}
+\bibcite{marceau:verified}{22}
+\bibcite{weber:beyond}{23}
+\bibcite{anderson:asos}{24}
+\bibcite{polak:program}{25}
+\bibcite{ganzinger:operator}{26}
+\bibcite{bentley:more-pearls:graphics}{27}
+\bibcite{sedgewick:algorithms}{28}
+\bibcite{feldman:make}{29}
+\bibcite{johnson:yacc}{30}
+\bibcite{kernighan:unix}{31}
+\bibcite{ramsey:spiderwebman}{32}
+\bibcite{parnas:rational}{33}
diff --git a/web/spiderweb/doc/spe.bbl b/web/spiderweb/doc/spe.bbl
new file mode 100644
index 0000000000..fe18d98426
--- /dev/null
+++ b/web/spiderweb/doc/spe.bbl
@@ -0,0 +1,186 @@
+\begin{thebibliography}{10}
+
+\bibitem{knuth:literate}
+Donald~E. Knuth.
+\newblock Literate programming.
+\newblock {\em The Computer Journal}, 27(2):97--111, 1984.
+
+\bibitem{bentley:lp1}
+Donald~E. Knuth and Jon~L. Bentley.
+\newblock Programming pearls: Literate programming.
+\newblock {\em Communications of the ACM}, 29(5):364--368, May 1986.
+
+\bibitem{bentley:lp2}
+Donald~E. Knuth.
+\newblock Programming pearls: A literate program.
+\newblock {\em Communications of the ACM}, 29(6):471--483, June 1986.
+\newblock Reviewed by M. Douglas McIlroy.
+
+\bibitem{cvw:loom}
+David~R. Hanson.
+\newblock Literate programming: Printing common words.
+\newblock {\em Communications of the ACM}, 30(7):593--599, July 1987.
+\newblock Reviewed by John Gilbert.
+
+\bibitem{gries:pearls}
+David Gries and Jon Bentley.
+\newblock Programming pearls: Abstract data types.
+\newblock {\em Communications of the ACM}, 30(4):284--290, April 1987.
+
+\bibitem{knuth:tex}
+Donald~E. Knuth.
+\newblock {\em {{\TeX}}: The Program}, volume~B of {\em Computers \&
+ Typesetting}.
+\newblock Addison-Wesley, 1986.
+
+\bibitem{knuth:metafont}
+Donald~E. Knuth.
+\newblock {\em {{\metafont}}: The Program}, volume~D of {\em Computers \&
+ Typesetting}.
+\newblock Addison-Wesley, 1986.
+
+\bibitem{cvw:assessment}
+Christopher~J. Van~Wyk.
+\newblock Literate programming: An assessment.
+\newblock {\em Communications of the ACM}, 33(3):361--365, March 1990.
+
+\bibitem{thimbleby:review}
+Harold Thimbleby.
+\newblock A review of {Donald} {C}. {L}indsay's text file difference utility,
+ {{\em diff}}.
+\newblock {\em Communications of the ACM}, 32(6):752--755, June 1989.
+
+\bibitem{thimbleby:cweb}
+Harold Thimbleby.
+\newblock Experiences of `literate programming' using cweb (a variant of
+ {K}nuth's {WEB}).
+\newblock {\em Computer Journal}, 29(3):201--211, 1986.
+
+\bibitem{guntermann:cweb}
+Klaus Guntermann and Joachim Schrod.
+\newblock {{\tt WEB}} adapted to {C}.
+\newblock {\em {TUG}boat}, 7(3):134--137, October 1986.
+
+\bibitem{levy:cweb}
+Silvio Levy.
+\newblock {\tt WEB} adapted to {C}, another approach.
+\newblock {\em TUGBoat}, 8(1):12--13, 1987.
+
+\bibitem{sewell:mangle}
+Wayne Sewell.
+\newblock How to {{\tt MANGLE}} your software: the {{\tt WEB}} system for
+ {M}odula-2.
+\newblock {\em {TUG}boat}, 8(2):118--128, July 1987.
+
+\bibitem{ramsey:building}
+Norman Ramsey.
+\newblock {L}iterate programming: {\hskip 0pt plus 0.5em}{W}eaving a
+ language-independent {{\tt WEB}}.
+\newblock {\em Communications of the ACM}, 32(9):1051--1055, September 1989.
+
+\bibitem{ramsey:developing}
+Norman Ramsey.
+\newblock Developing formally verified {A}da programs.
+\newblock In {\em Proceedings of the 5th International Workshop on Software
+ Specification and Design}, pages 257--265, Pittsburgh, Pennsylvania, May
+ 1989.
+
+\bibitem{marceau:interactive}
+Carla Marceau and C.~Douglas Harper.
+\newblock An interactive approach to {A}da verification.
+\newblock In {\em Proceedings of the 12th National Computer Security
+ Conference}, pages 28--51, Baltimore, Maryland, October 1989.
+
+\bibitem{guaspari:formal}
+David Guaspari, Carla Marceau, and Wolfgang Polak.
+\newblock Formal verification of {A}da programs.
+\newblock {\em IEEE Transactions on Software Engineering}, 16(9):1058--1075,
+ September 1990.
+
+\bibitem{reps:synthesizer:89}
+Thomas Reps and Tim Teitelbaum.
+\newblock {\em The {S}ynthesizer {G}enerator Reference Manual}.
+\newblock Springer-Verlag, 1989.
+
+\bibitem{reps:generating}
+Thomas Reps.
+\newblock {\em Generating Language-Based Environments}.
+\newblock MIT Press, 1984.
+
+\bibitem{adalrm}
+{US Department of Defense}.
+\newblock {\em The {A}da Programming Language Reference Manual}, 1983.
+\newblock ANSI/MILSTD~1815A.
+
+\bibitem{polak:predicate}
+Wolfgang Polak.
+\newblock Predicate transformer semantics for {A}da.
+\newblock Technical Report 89-39, Odyssey Research Associates, September 1989.
+
+\bibitem{marceau:verified}
+Carla Marceau and Geoffrey Hird.
+\newblock A verified software implementation of an {RS}-232 repeater using
+ {P}enelope.
+\newblock Technical Report 90-12, Odyssey Research Associates, 1990.
+
+\bibitem{weber:beyond}
+D.~G. Weber and Roger~L. Costello.
+\newblock Beyond {A1} using {A}da code verification.
+\newblock Technical Report 89-9, Odyssey Research Associates, April 1989.
+
+\bibitem{anderson:asos}
+Eric~R. Anderson, Ben DiVitto, and Ruth~M. Hart.
+\newblock {ASOS}: Information security for real-time systems.
+\newblock In {\em {AFCEA} West Intelligence Symposium}, 1987.
+
+\bibitem{polak:program}
+Wolfgang Polak.
+\newblock Program verification based on denotational semantics.
+\newblock In {\em ACM Symposium on Principles of Programming Languages}, pages
+ 149--158. Association for Computing Machinery, 1981.
+
+\bibitem{ganzinger:operator}
+H.~Ganzinger and K.~Ripken.
+\newblock Operator identification in {A}da.
+\newblock {\em ACM SIGPLAN Notices}, 15(2):30--42, February 1980.
+
+\bibitem{bentley:more-pearls:graphics}
+Jon Bentley.
+\newblock {\em More Programming Pearls: Confessions of a Coder}, chapter 10 and
+ 11, pages 101--126.
+\newblock Addison-Wesley, 1988.
+
+\bibitem{sedgewick:algorithms}
+Robert Sedgewick.
+\newblock {\em Algorithms}.
+\newblock Addison-Wesley, second edition, 1988.
+
+\bibitem{feldman:make}
+Stuart~I. Feldman.
+\newblock Make---a program for maintaining computer programs.
+\newblock {\em Software---Practice and Experience}, 9:255--265, 1979.
+
+\bibitem{johnson:yacc}
+Steve~C. Johnson.
+\newblock Yacc---yet another compiler compiler.
+\newblock Technical Report~32, Computer Science, AT\&T Bell Laboratories,
+ Murray Hill, New Jersey, 1975.
+
+\bibitem{kernighan:unix}
+Brian~W. Kernighan and Rob Pike.
+\newblock {\em The {UNIX} Programming Environment}.
+\newblock Prentice-Hall, 1984.
+
+\bibitem{ramsey:spiderwebman}
+Norman Ramsey.
+\newblock The {S}pidery {{\tt WEB}} system of structured documentation.
+\newblock Technical Report TR-226-89, Department of Computer Science, Princeton
+ University, August 1989.
+
+\bibitem{parnas:rational}
+David~Lorge Parnas and Paul~C. Clements.
+\newblock A rational design process: How and why to fake it.
+\newblock {\em IEEE Transactions on Software Engineering}, SE-12(2):251--257,
+ February 1986.
+
+\end{thebibliography}
diff --git a/web/spiderweb/doc/spe.tex b/web/spiderweb/doc/spe.tex
new file mode 100644
index 0000000000..4a4dc42416
--- /dev/null
+++ b/web/spiderweb/doc/spe.tex
@@ -0,0 +1,545 @@
+\documentstyle[11pt]{article}
+\title {Literate Programming on a Team Project\thanks{This research
+has been sponsored in part by the USAF, Rome Air Development Center, under
+contract number F30602--86--C--0071.
+The first author gratefully acknowledges the support of the Fannie and
+John Hertz Foundation.
+This paper is reprinted from {\em Software---Practice \& Experience}, 21(7):677--683, July 1991.}}
+\author{Norman Ramsey\thanks{Current address: Department of Computer
+Science, Princeton University, Princeton, New Jersey 08544.}
+ \hskip3pt and Carla Marceau\\\mbox{}\\Odyssey Research Associates\\
+301A Harris B. Dates Drive\\Ithaca, New York 14850}
+\date{February 4, 1991}
+\setcounter{secnumdepth}{0}
+\setcounter{tocdepth}{6}
+\renewcommand{\baselinestretch}{1.33}
+
+\makeatletter
+\def\refno#1{\nocite{#1}\@ifundefined
+ {b@#1}{{\bf ?}\@warning
+ {Reference number `#1' on page \thepage \space undefined}}%
+{\hbox{\csname b@#1\endcsname}}}
+\makeatother
+
+\def\remark#1{\marginpar{\raggedright\hbadness=10000\footnotesize\it #1}}
+% \def\remark#1{\relax}
+\let\logo=\sc
+\font\logo=logo10
+\def\metafont{{\logo METAFONT}}
+
+
+\begin{document} % 1
+\clubpenalty=10000
+\widowpenalty=10000
+\maketitle
+
+\begin{abstract} % 2
+% % We used {\tt WEB} on a group project to write a large program, over
+% % 33,000~lines.
+% % The program was not intended to be published.
+% % We encountered many problems using {\tt WEB}, but we believe we are
+% % better off for having used it.
+% % We describe both the problems and why we believe {\tt WEB} was
+% % beneficial despite them.
+% We used literate programming, with {\tt WEB}, on a group project to
+% write a program of
+% over 33,000~lines.
+% The program, Penelope, was not intended to be published, but the
+% literate source has served as good internal documentation through
+% development and maintenance.
+% Using {\tt WEB} without help from its developer uncovered a number of
+% problems, which are described below.
+% Despite the problems, {\tt WEB} has been effective in helping us
+% document the design and implementation of Penelope.
+We used literate programming on a team project to write a 33,000-line
+program for the Synthesizer Generator. The program, Penelope, was
+written using {\tt WEB}, a tool designed for writing literate
+programs. Unlike other {\tt WEB} programs, many of which have been
+written by {\tt WEB}'s developer or by individuals, Penelope was not
+intended to be published. We used {\tt WEB} in the hope that
+both our team and its final product would benefit from the advantages
+often attributed to literate programming. The {\tt
+WEB} source served as good internal documentation throughout
+development and maintenance, and it continues to document Penelope's
+design and implementation.
+Our experience also uncovered a number of
+problems with {\tt WEB}.
+\end{abstract} % 2
+
+
+\section{Introduction}
+
+Donald Knuth coined the term ``literate programming'' when describing
+{\tt WEB}, the tool he used to build \TeX~\cite{knuth:literate}.
+He believes that ``the time is ripe for significantly better
+documentation of programs, and that we can best achieve this by
+considering programs to be {\em works of literature}.''
+Knuth and others have presented examples of such
+programs~\cite{bentley:lp1,bentley:lp2,cvw:loom,gries:pearls}.
+
+
+Literate programming is usually discussed in the context of
+publishing programs or of publishing books or articles about programs.
+\TeX\ and {\metafont}, the original applications of {\tt WEB},
+have been published as books~\cite{knuth:tex,knuth:metafont}.
+Other published literate programs seem to be primarily for teaching.
+Programs to find random sequences and count common words
+were written to illustrate the power of literate
+programming~\cite{bentley:lp1,bentley:lp2}.
+Another program to count common words
+is a tutorial on how to
+develop and tune a small program~\cite{cvw:loom}.
+Another illustrates formal methods of program
+development and the use of abstract data types~\cite{gries:pearls}.
+
+
+A valedictory assessment points out three common aspects of the published
+literate programs: cosmetics, polish, and verisimilitude, of which
+verisimilitude---the property of using one input to produce both
+compilable program and published document--is deemed
+essential~\cite{cvw:assessment}.
+Additional expectations of a literate
+programming tool include flexible order of elaboration,
+ability to develop program and documentation concurrently in one
+place, cross-references, and indexing~\cite{thimbleby:review}.
+
+{\tt WEB} is the principal tool used for literate programming; a
+number of implementations are
+available~\cite{knuth:literate,thimbleby:cweb,guntermann:cweb,levy:cweb,sewell:mangle,ramsey:building}.
+{\tt WEB} programmers
+ interleave source code and descriptive text in a single document.
+When using {\tt WEB}, a programmer divides the source code into
+small textual units called {\em modules}, and each module carries
+associated documentation.
+In the {\tt WEB} source, different modules may
+be written in any order.
+ The programmer is encouraged to choose an
+order that helps explain the program.
+The modules are like macro definitions; they have
+the form
+\begin{quote} % 2
+\tt@<{\em module name\/}@>={\em body}
+\end{quote} % 2
+where the body contains both code and references to other modules.
+{\tt WEB} programmers can also define and use macros similar to
+C~preprocessor macros.
+ One module is unnamed; its body represents the underlying program.
+
+Two filters process {\tt WEB} source.
+ {\tt TANGLE} reads the {\tt WEB} source and expands the
+unnamed module according to its definition.
+References to named modules are expanded where they occur, and the end
+result is that {\tt TANGLE} extracts the underlying program from the
+{\tt WEB} source.
+This program is formed from the code fragments that the programmer put
+into the module definitions, assembled in the order required by the compiler.
+A second filter, {\tt WEAVE}, reads the {\tt WEB} source and converts
+it to \TeX\ input, with which {\TeX} can produce
+high-quality typeset documentation of the program.
+Examples of {\tt WEB} source and typeset documentation can be found in
+Reference~\refno{knuth:literate}.
+
+
+\section{Using Literate Programming}
+
+ Penelope is a language-based editor intended to help
+programmers develop formally verified Ada
+programs~\cite{ramsey:developing,marceau:interactive,guaspari:formal}.
+It parses annotated Ada programs,
+performs static semantic checking and overload resolution,
+computes weakest preconditions by predicate transformation,
+simplifies the resulting preconditions,
+and
+helps users construct proofs of those preconditions.
+Its source code is
+an editor specification for
+the Synthesizer Generator~\cite{reps:synthesizer:89}.
+The Synthesizer Generator builds an editor of attributed syntax
+trees.
+When a user defines a tree, the editor attributes it.
+When the user changes the tree,
+the editor recomputes only those attribute values that have
+changed~\cite{reps:generating}.
+
+Penelope has two written specifications: the Ada language
+reference manual and a denotational-style definition of Ada predicate
+transformers~\cite{adalrm,polak:predicate}.
+After three years of work, the {\tt WEB} source for the editor
+is over 33,000 lines.
+Over 13,000 of those lines are interleaved documentation.
+The editor has been used to verify a software repeater for an
+asynchronous
+communication line
+and security properties of a part of the
+ASOS operating system
+kernel~\cite{marceau:verified,weber:beyond,anderson:asos}.
+Seven programmers have written {\tt WEB} source,
+but no more than four have worked
+on it at any one time.
+At this writing, the editor is being extended
+to support Ada libraries. % programs that use data abstraction.
+
+We decided to write the editor as a literate program because
+we expected implementing predicate
+transformation to be error-prone.
+To avoid errors, we used {\tt WEB} to juxtapose
+the specification and implementation of
+each predicate transformer.
+We used {\TeX}'s math mode to write the specifications in the notation
+of denotational semantics.~\cite{polak:predicate,polak:program}.
+
+The right model for a literate program that is being maintained and
+extended is not the novel but the car repair manual.
+We began writing new code as an
+explanation or tutorial for our colleagues, but
+as the text grew we treated it more like a reference work.
+As with any document, we revised repeatedly to clarify meaning.
+We often used
+{\tt TANGLE}'s reordering mechanism to make major revisions in the
+{\tt WEB} source without changing the underlying program.
+% Parnas and Clements say this; see {parnas:rational}
+
+
+We divided Penelope into parts according to functionality:
+we wrote chapters on
+abstract syntax,
+concrete syntax,
+predicate transformation,
+static semantic checking,
+proof construction,
+and simplification of terms.
+Each of the first four chapters follows the structure of the Ada
+Language Reference Manual, since each is closely related to
+Ada.
+Only knowledge of the Ada manual is required to navigate this code;
+a reader who knows where to find the
+{\tt exit} statement in the Ada manual can find the predicate
+transformation of the {\tt exit} statement in the corresponding
+section of the predicate transformation chapter.
+We gave the final chapters structures related to the problems of
+simplification and proof construction.
+
+
+Penelope has grown so large that each chapter
+is itself structured like a reference work.
+ Sections within chapters have a different structure.
+They are tutorials that use the traditional approach
+to documentation: begin with a problem statement or specification,
+discuss possible solutions, explain the design of the preferred
+solution, then develop the implementation and its description.
+A short introductory chapter describes the major parts of the program
+the organization used to form the text.
+A ``how to find it'' section helps readers find source code.
+
+We have used the Penelope source
+not only for reference but also to introduce new programmers to the
+project. % ???
+% For example, as a prelude to extending the
+% Ada subset handled by Penelope, a new project member might read Chapter
+% 6 of the Red Dragon Book and also the chapter of Penelope on static
+% semantic checking.
+
+
+
+
+We used some of the cosmetic features of {\tt WEB};
+we found
+tables of variables, functions, and files all useful to describe the
+organization of the code.
+When working on Ada static semantic checking, we found it useful to
+include in the {\tt WEB} source some fragments of relevant documents.
+The fragments included visibility and overloading rules from the Ada reference
+manual~\cite{adalrm} and a presentation of the Ada type system derived
+from Reference~\refno{ganzinger:operator}.
+
+
+\section{Evaluating {\tt WEB}}
+
+ Using {\tt WEB} without help from its developer uncovered a number of
+problems.
+Some problems relate to the criteria in References
+\refno{cvw:assessment}~and~\refno{thimbleby:review}, but others do not.
+
+We had no trouble with
+{\tt WEB}'s fundamental mechanisms, the section and
+the named module.
+They provide verisimilitude and flexible order of elaboration.
+The small size of modules makes it feasible to develop code and
+documentation in one place using an ordinary text editor.
+The order of fragments is the same in the {\tt WEB} source and in the
+published document, which simplifies polishing.
+
+\medskip
+We found some of {\tt WEB}'s cosmetic features inadequate, others
+superfluous.
+Cosmetics should include appropriate media for presenting programs:
+not just math and tables but also diagrams and
+figures~\cite{bentley:more-pearls:graphics,bentley:lp2,sedgewick:algorithms}.
+ Describing data structures was hampered by {\TeX}'s lack of support for
+diagrams and pictures.
+{\TeX} does make it easy to use mathematical notation, which
+ helped considerably in describing
+ predicate transformation,
+ the simplifier, and
+ the proof system used in the proof constructor.
+
+Programmers complained more about prettyprinting than about all other {\tt WEB}
+problems combined.
+{\tt WEAVE} ignores the programmer's choice of indentation
+and line breaks; it breaks and indents lines on the basis of
+the syntactic categories of tokens.
+(Programmers can force line breaks by inserting special control sequences
+like {\tt@/} into their program text, but that's about all.)
+We spent too much time tinkering
+with prettyprinting, trying to make {\tt WEAVE}'s output
+acceptable to everyone.
+We would have been better off with no prettyprinter, or with a
+prettyprinter that changed
+only the typographic treatment of program fragments without changing
+the placement of tokens on the page.
+
+We used the index of identifiers
+ during reviews only, usually to find function definitions
+and to locate code that had been misplaced.
+
+\medskip
+{\tt WEB} formats interleaved documentation using {\TeX}, which some
+programmers already use for writing documents.
+{\tt WEB} and {\TeX} are integrated poorly.
+One cannot lift pieces of {\tt WEAVE}'s output and put them in other
+documents without adjusting the \TeX\ code.
+{\tt WEB} works even less well with \LaTeX; \LaTeX\ constructs cannot
+be used in {\tt WEB} source, and getting {\tt WEAVE} output
+to work in \LaTeX\ documents requires tedious adjustments by hand.
+The other direction is easier;
+we wrote project documents using \LaTeX, and, with some adjustments,
+we could include excerpts from these documents in our code.
+%%%%%%%% Carla wants no more details
+% \remark{I can give more details. For example, the {\tt webmac} macros
+% should make it easy to pull out the {\tt WEAVE} output routine and use
+% a plain \TeX\ or \LaTeX output routine---but they don't.
+% This is a sore point with me.}
+%%%%%%%%%
+ We were accustomed to writing \LaTeX\ documents,
+so it was annoying to be forced to switch to plain
+\TeX\ to write programs.
+
+% \paragraph{Editing {\tt WEB} source}
+\medskip
+
+\TeX's input often looks very different from \TeX's output, especially
+when mathematics is used.
+Similarly, {\tt WEB} source looks very different from the typeset
+document produced by {\tt WEAVE} and {\TeX}.
+When people use \TeX\ to write papers,
+it may be acceptable for the \TeX\ input to be full of
+confusing hieroglyphics, because the {\TeX} input is almost never
+read---only the printed version is read.
+{\tt WEB} source is read frequently because programmers must edit it.
+Both the difficulty of reading the source and the marked difference between
+source and listing complicate editing.
+
+\medskip % \paragraph{Structuring the document}
+
+{\tt WEAVE}'s standard table of contents mechanism is a list of
+section names.
+ (A section is a named group of modules together with their
+interleaved documentation.)
+This flat structure is inadequate for
+describing even a moderate-sized program.
+Extra structure in the form of ``parts'' has been added to
+the book version of {\TeX}; a part contains several
+sections~\cite{knuth:tex}.
+
+
+We changed {\tt WEAVE}'s table of contents mechanism to make
+hierarchical organization possible.
+ The new mechanism supports
+chapters, sections, and two levels of subsections.
+We did so without changing {\tt WEAVE} itself; instead we changed the
+\TeX\ macros that support {\tt WEAVE}.
+The new macros recognize special symbols at the beginnings of section
+names; these symbols indicate which sections are really chapters,
+subsections, and so on.
+Using this hierarchy made the table of contents
+an important guide to the code;
+the only practical way to find a particular part of the editor code
+was to begin with the table of contents.
+
+
+
+
+The {\tt WEAVE} listing of Penelope is over 800~pages;
+its table of contents is about 8~pages.
+We needed to extract and print parts of this document,
+but {\tt WEAVE} processes only complete documents.
+We extracted parts in two ways.
+When we wanted just a few, small, closely related parts, we created a
+special {\tt WEB} file that held just those parts, and printed it.
+For something more general, we used a shell script that
+removed parts of {\tt WEAVE}'s output before passing the rest to {\TeX}.
+This script recognized the special symbols in the section names so that, for
+example, we could include or exclude whole chapters by name,
+without having to
+enumerate their contents.
+It would have been more expensive, and no less awkward, to use
+standard mechanisms for extracting pages from {\TeX}'s output.
+
+Special symbols in section names are an awkward way of indicating
+structure.
+ A more natural way of indicating structure, like the
+{\LaTeX} mechanism, would have been welcome.
+Tools should make it easy to use the
+ structure to help readers extract excerpts from literate
+programs.
+
+\medskip % \paragraph{Fit with configuration management tools}
+
+ {\tt WEB} works poorly with {\tt make}~\cite{feldman:make}.
+ {\tt TANGLE} is designed to read and write a complete program.
+Some {\tt TANGLE}s can write multiple files,
+which can then be compiled separately, but
+those files all get rewritten
+ every time the {\tt WEB} source changes,
+and {\tt make} therefore recompiles them all.
+This problem is familiar;
+other preprocessors, like {\tt yacc}~\cite{johnson:yacc}, can also
+cause excessive recompilation.
+The workaround described on page 265 of
+Reference~\refno{kernighan:unix} works for {\tt TANGLE}.
+%%%%%%%% Carla wants no more details
+% \remark{Workaround doesn't help too much when the output
+% from {\tt TANGLE} includes information about source line numbers?}
+%%%%%%%%%
+
+{\tt WEB} users may be tempted
+to break their {\tt WEB} source into many files and run them through
+{\tt TANGLE} separately.
+Doing so defeats the purpose of writing a literate
+program; separate compilation does not necessarily imply separate
+explanation.
+For example, one would prefer to place a
+unit's specification and implementation in the same {\tt WEB}
+source, even when
+they should be compiled separately.
+
+\medskip % \paragraph{Fit with compilers and debuggers}
+
+Our {\tt TANGLE}~\cite{ramsey:spiderwebman} emits
+the {\tt\#line} directive of the C preprocessor, making
+messages from compilers and debuggers refer to line numbers in
+the {\tt WEB} source instead of to those in {\tt TANGLE}'s output.
+Not all compilers or all {\tt TANGLE}s support such mechanisms.
+Renumbering is essential for large programs.
+
+
+
+
+
+\section{Discussion}
+
+Most literate programming papers refer to programs that are
+polished, publishable ``works of art.''
+Our primary goal in writing Penelope
+was not to write a publishable program, nor to
+evaluate literate programming as a software engineering technique,
+but to build a prototype editor embodying the results
+of research in formal verification.
+Our experience has given us some subjective
+impressions of the benefits of applying literate programming
+to team development, as well as more specific conclusions about
+the difficulties of applying literate programming.
+
+There are few published techniques for writing literate
+programs, especially for writing large ones.
+Most of our programmers complained about the awkward tools and about
+the lack of guidance in their use.
+We were unable to develop precise methods for writing literate
+programs or even clear criteria about what constituted a
+literate program.
+Instead, we relied on peer review of programs, rewriting them
+until the project members understood them.
+These programs were rarely polished to the point necessary for
+publication; less polished presentations were adequate.
+
+One review of a literate program emphasizes the role of
+juxtaposed code and documentation~\cite{thimbleby:review}.
+It cites several benefits of this juxtaposition, including an
+incentive to explain and hence to understand what one is doing.
+During peer reviews of Penelope,
+we insisted that explanations of programs include explanations of design.
+% this insistence mitigated against the
+% tendency of programmers to begin implementing without thinking about
+% design.
+% We found that
+% the juxtaposition reduced the overhead
+% involved in maintenance;
+Juxtaposing design documentation and code reduced the overhead of
+maintenance because maintainers reading the code did not have to look
+elsewhere for design documents.
+
+We cannot say to what extent literate programming can replace
+standard software development methodology. However, putting a
+clear description of design in our source code helped make it possible
+for a changing team of programmers to develop it over a span of three
+years. We were able to apply standard guidelines, like those in
+Reference~\refno{parnas:rational}, to describing Penelope's design.
+
+We believe
+literate programming helped us substantially.
+This belief is based not on measurements but on our subjective
+comparisons of experience on this project to other projects.
+A programmer who has used standard software development systems at an
+international computer manufacturing company reports that a key
+difference in Penelope was that the documentation was {\em used}, precisely
+because of its proximity to the source code.
+The project manager, when at a large software house,
+learned to expect technical staff first to criticize
+implementations
+for drifting away from the original intent, then to
+call for complete rewrites.
+There have been no complaints about the quality of Penelope's
+implementation.
+The programmers have been surprised at how easily they have extended
+and modified one another's work.
+For example, an editor for constructing proofs was implemented by a
+programmer who then left the project.
+The programmer who took over the job of maintaining the proof
+constructor read the program in two hours and found herself well
+prepared to change the code.
+
+We do not ascribe Penelope's success purely to literate programming;
+other factors contributed.
+We began implementation with a clearly defined
+goal and worked from detailed, sometimes formal, specifications.
+We had time to design the system carefully and used a declarative
+programming language.
+We did not have to develop a user interface but used the one provided
+by the Synthesizer Generator~\cite{reps:synthesizer:89}.
+
+
+We will continue to use literate programming
+for Penelope and for future projects.
+{\tt WEB}'s problems are such that we believe it will be
+cost-effective for future projects to develop literate programming
+tools that address some of the criticisms presented here.
+
+
+\section{Acknowledgments}
+Silvio Levy provided his {\tt CWEB} implementation as a base for the
+{\tt WEB} used to implement the Penelope editor.
+The staff of the Ada Verification project at Odyssey Research made
+possible the experience with Penelope on which this paper is based.
+This paper has been much improved by comments from David Hanson and
+from the anonymous referees.
+Stuart Feldman commented on this paper and discussed ideas for better
+tools.
+
+\bibliographystyle{unsrt}
+\bibliography{web,ada,cs,ramsey}
+
+%\newpage
+%\tableofcontents
+
+\end{document} % 1
+
diff --git a/web/spiderweb/doc/spiderman.aux b/web/spiderweb/doc/spiderman.aux
new file mode 100644
index 0000000000..a5db7cabc5
--- /dev/null
+++ b/web/spiderweb/doc/spiderman.aux
@@ -0,0 +1,56 @@
+\relax
+\citation{knuth:literate-programming}
+\citation{levy:cweb}
+\citation{knuth:literate-programming}
+\citation{sewell:weaving}
+\@writefile{toc}{\string\contentsline\space {section}{Introduction}{1}}
+\@writefile{toc}{\string\contentsline\space {paragraph}{Prerequisites}{2}}
+\@writefile{toc}{\string\contentsline\space {paragraph}{Plan of this guide}{2}}
+\@writefile{toc}{\string\contentsline\space {section}{How {\string\ptt\space WEAVE} and {\string\ptt\space TANGLE} see the world}{2}}
+\@writefile{toc}{\string\contentsline\space {paragraph}{Lexical analysis in {{\string\ptt\space WEB}}}{2}}
+\@writefile{toc}{\string\contentsline\space {section}{Using {Spider} to tell {{\string\ptt\space WEB}} how to tokenize}{4}}
+\@writefile{toc}{\string\contentsline\space {section}{Using {Spider} to tell {\string\ptt\space WEAVE} how to reduce scraps}{5}}
+\@writefile{toc}{\string\contentsline\space {section}{Syntax of {\string\ptt\space spider} files}{6}}
+\@writefile{toc}{\string\contentsline\space {paragraph}{Comments and blank lines}{6}}
+\@writefile{toc}{\string\contentsline\space {paragraph}{Fields}{6}}
+\@writefile{toc}{\string\contentsline\space {subsection}{Translations}{7}}
+\@writefile{toc}{\string\contentsline\space {paragraph}{Restricted translations}{8}}
+\@writefile{toc}{\string\contentsline\space {subsection}{{\string\ptt\space token} commands}{8}}
+\@writefile{toc}{\string\contentsline\space {paragraph}{Token descriptions}{8}}
+\@writefile{toc}{\string\contentsline\space {paragraph}{Token designators}{9}}
+\@writefile{toc}{\string\contentsline\space {subsection}{Reserved word tokens}{11}}
+\@writefile{toc}{\string\contentsline\space {section}{Syntax of the prettyprinting grammar}{11}}
+\@writefile{toc}{\string\contentsline\space {paragraph}{Matching the left hand side of a production}{12}}
+\@writefile{toc}{\string\contentsline\space {paragraph}{Firing a production}{13}}
+\@writefile{toc}{\string\contentsline\space {subparagraph}{Side effects of firing a production}{13}}
+\@writefile{toc}{\string\contentsline\space {paragraph}{If no initial subsequence matches any production}{13}}
+\@writefile{toc}{\string\contentsline\space {section}{Examples of {\string\ptt\space WEAVE} grammars}{13}}
+\@writefile{toc}{\string\contentsline\space {paragraph}{Short examples}{14}}
+\@writefile{toc}{\string\contentsline\space {paragraph}{Expressions}{14}}
+\@writefile{toc}{\string\contentsline\space {paragraph}{Conditional statements}{16}}
+\@writefile{toc}{\string\contentsline\space {paragraph}{Handling preprocessor directives in C}{16}}
+\@writefile{toc}{\string\contentsline\space {subsection}{Using context-dependent productions}{17}}
+\@writefile{toc}{\string\contentsline\space {paragraph}{Underlining the index entry for the name of a declared function}{17}}
+\@writefile{toc}{\string\contentsline\space {paragraph}{Conditional expressions}{17}}
+\@writefile{toc}{\string\contentsline\space {subsection}{Debugging a prettyprinting grammar}{18}}
+\@writefile{toc}{\string\contentsline\space {section}{The rest of the {Spider} language}{18}}
+\@writefile{toc}{\string\contentsline\space {subsection}{Naming the target language}{19}}
+\@writefile{toc}{\string\contentsline\space {subsection}{Defining {T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emX} macros}{19}}
+\@writefile{toc}{\string\contentsline\space {subsection}{Setting default token information}{20}}
+\@writefile{toc}{\string\contentsline\space {subsection}{Specifying the treatment of modules}{20}}
+\@writefile{toc}{\string\contentsline\space {subsection}{Determining the at sign}{20}}
+\@writefile{toc}{\string\contentsline\space {paragraph}{Changing control sequences}{21}}
+\@writefile{toc}{\string\contentsline\space {subsection}{Comments in the programming language}{21}}
+\@writefile{toc}{\string\contentsline\space {subsection}{Controlling line numbering}{22}}
+\@writefile{toc}{\string\contentsline\space {subsection}{Showing the date of generation}{22}}
+\@writefile{toc}{\string\contentsline\space {section}{Spider's error messages}{23}}
+\@writefile{toc}{\string\contentsline\space {section}{{Spider}'s output files}{24}}
+\@writefile{toc}{\string\contentsline\space {section}{Using {Spider} to make {{\string\ptt\space WEB}} (the {Spider} tools)}{24}}
+\@writefile{toc}{\string\contentsline\space {section}{Getting your own Spidery {\string\ptt\space WEB}}{29}}
+\@writefile{toc}{\string\contentsline\space {section}{A real {Spider} file}{29}}
+\bibcite{bentley:pearls}{Bentley\penalty \@M \ 87}
+\bibcite{knuth:web}{Knuth\penalty \@M \ 83}
+\bibcite{knuth:literate-programming}{Knuth\penalty \@M \ 84}
+\@writefile{toc}{\string\contentsline\space {section}{Bibliography}{33}}
+\bibcite{levy:cweb}{Levy\penalty \@M \ 87}
+\bibcite{sewell:weaving}{Sewell\penalty \@M \ 89}
diff --git a/web/spiderweb/doc/spiderman.tex b/web/spiderweb/doc/spiderman.tex
new file mode 100644
index 0000000000..e59087373d
--- /dev/null
+++ b/web/spiderweb/doc/spiderman.tex
@@ -0,0 +1,1693 @@
+% Copyright 1989 by Norman Ramsey and Odyssey Research Associates
+% Not to be sold, but may be used freely for any purpose
+% For more information, see file COPYRIGHT in the parent directory
+
+% spiderman.tex, with apologies to Stan Lee
+
+\documentstyle[11pt]{article}
+\setcounter{secnumdepth}{0}
+\newcommand{\syntax}[1]{\mbox{$\langle\hbox{\sl #1\/}\rangle$}}
+\newcommand{\produces}{\mbox{${}::={}$}}
+\newcommand{\opt}[1]{$[$#1$]$}
+\newcommand{\BS}{\relax}
+\chardef\BS=`\\ % backslash in a string
+
+\title{A {Spider} User's Guide}
+\author{Norman Ramsey\\Department of Computer Science\\Princeton University}
+\date{July 1989}
+\newcommand {\WEB}{{\tt WEB}}
+
+\begin{document}
+\maketitle
+
+\section{Introduction}
+Donald Knuth developed the {\tt WEB} system of structured documentation
+as part of the {\TeX} project~\cite{knuth:literate-programming}.
+{\WEB} enables a programmer to divide his or her program into chunks (called
+{\em modules}), to associate text with each chunk, and to present the
+chunks in in any order.
+In Knuth's implementation, the chunks are pieces of PASCAL programs,
+and the chunks are formatted using {\TeX}.
+
+ The {\tt WEB} idea suggests a way of combining {\em any}
+programming language with {\em any} document formatting language,
+but until recently there was no software support for writing anything
+but PASCAL programs using {\tt WEB}.
+In~1987, Silvio Levy rewrote the {\tt WEB} system in C for C,
+while retaining {\TeX} as the formatting language~\cite{levy:cweb}.
+I have has modified Levy's implementation by removing the parts
+that make C the target programming language, and I have
+ added a third tool, {Spider}, which complements {\tt WEAVE}
+and {\tt TANGLE}.
+{Spider} reads a description of a programming language, and writes
+source code for a {\tt WEAVE} and {\tt TANGLE} which support that
+language.
+Using {Spider}, a C~compiler, and an Awk~interpreter, an experienced
+systems programmer can generate a {\tt WEB} system for
+an Algol-like language in a few hours.
+
+This document explains how to use {Spider} to generate a {\WEB}
+system for any programming language.
+(The choice of programming language is limited only by the lexical
+structure built into Spidery {\tt WEB}, as we shall see.)
+You should consult the companion document, ``The Spidery {\WEB} system of
+structured documentation,'' to learn how to use the generated {\WEB} system.
+
+\paragraph{Prerequisites}
+If you are going to use {Spider} to build a {\WEB} system,
+you should be comfortable using {\tt WEB}.
+To get an idea how {\tt WEB} works, you should have read Knuth's
+introductory article
+on {\WEB}~\cite{knuth:literate-programming}, as well as the {\WEB}
+users' manual.
+(The {\WEB} user's manual is pretty heavy going, so you may want to
+consult the Bibliography for more introductory material on {\WEB}.
+Wayne Sewell's {\it Weaving a Program: Literate Programming in {\tt
+WEB}}
+may be helpful~\cite{sewell:weaving}.)
+
+In what follows we will assume that you know what {\tt WEAVE} and {\tt
+TANGLE} are, what input they expect, and what output they produce.
+
+\paragraph{Plan of this guide}
+We'll begin with a review of weaving and tangling, so that we can get
+an idea what is necessary to build a language-independent {\WEB}.
+Then we'll present a discussion of the features of {Spider} that
+tell {\WEB} about the programming language.
+We'll define these in detail and give some examples, and then
+we'll close with a complete description of the {Spider} language
+and tools.
+
+\section{How {\tt WEAVE} and {\tt TANGLE} see the world}
+Both {\tt WEAVE} and {\tt TANGLE} operate on the same input, a {\WEB}
+file.
+{\tt WEAVE} must examine this input and produce a {\TeX} text, while
+{\tt TANGLE} must produce a program text from the same input.
+The input consists of {\TeX} parts, definition parts, and code parts.
+The {\TeX} parts are the easiest to consider: {\tt WEAVE} just copies
+them and {\tt TANGLE} throws them away.
+The definition parts are a bit more complicated: {\tt WEAVE}'s job is
+to typeset them, while {\tt TANGLE} must remember the definitions and
+expand them at the proper time.
+The code parts are the most complex of all: {\tt WEAVE} must
+prettyprint them, and {\tt TANGLE} must rearrange them into a coherent
+program text.
+
+\paragraph{Lexical analysis in {\WEB}}
+Both {\tt WEAVE} and {\tt TANGLE} interpret the code parts as a stream
+of {\em tokens}.
+Since not all programming languages have the same tokens, it is
+{Spider}'s job to tell {\tt WEAVE} and {\tt TANGLE} how to tokenize the
+input.%
+\footnote{%
+The current implementation of {\tt WEB}'s lexical analysis is limited.
+It should be replaced with something using regular
+expressions.%
+}
+A Spidery {\WEB} system can recognize the following kinds of
+tokens:
+\begin{itemize}
+\item identifiers
+\item numeric and string constants
+\item newlines
+\item ``pseudo-semicolons'' (the token {\tt @;})
+\item reserved words
+\item non-alphanumeric tokens
+\end{itemize}
+
+{\tt TANGLE} rearranges these tokens into one long program
+text, then writes out the program text token by token.
+Normally, {\tt TANGLE} puts no white space between tokens, but it
+will put blanks between adjacent identifier, reserved word, and
+numeric constant tokens.
+Thus the input
+\begin{quote}
+\tt if 0 > x-y then z := -1;
+\end{quote}
+will be written out as
+\begin{quote}
+\tt if 0>x-y then z:=-1;
+\end{quote}
+and not
+\begin{quote}
+\tt if0>x-ythenz:=-1;
+\end{quote}
+which wouldn't parse.
+When it is desirable to have {\tt TANGLE} translate
+the tokens differently, each token can be given a {\tt tangleto}
+attribute, which specifies what program text is printed out for that
+token.
+For example,
+the {\tt spider} file used to generate C~{\WEB} forces the {\tt =}
+tokento be printed out as the string {\tt "=\ "}, because in C the string
+{\tt "=-"} can be ambiguous.
+
+{\tt WEAVE} must turn the token stream into a {\TeX} text that will
+cause the code to be prettyprinted.
+It does so in three steps:
+\begin{enumerate}
+\item
+{\tt WEAVE} turns each token into a {\em scrap}.
+A scrap has two important properties: its syntactic
+{\em category} and its {\em translation}.
+The categories are symbols in a prettyprinting grammar; that grammar
+tells {\tt WEAVE} how to combine the scraps
+with prettyprinting instructions.
+The translations are the {\TeX} texts that will tell {\TeX} exactly
+how to print the scraps.
+\item
+{\tt WEAVE} reduces the scrap stream by combining scraps according to
+the productions of its prettyprinting grammar.
+({\tt WEAVE} does a kind of shift-reduce parsing of program fragments.)
+While combining the translations, {\tt WEAVE} adds {\TeX} text that
+will cause indenting, outdenting, line breaking, and so on.
+\item
+Ideally, {\tt WEAVE} keeps reducing scraps until it has a single scrap with
+a very long translation, but perhaps it will end up
+with an irreducible sequence of scraps.
+In any case, after no more reductions can be done, the translations of the
+remaining scraps are output one at a time.
+\end{enumerate}
+
+\section{Using {Spider} to tell {\WEB} how to tokenize}
+{Spider} divides tokens into two classes; reserved words and
+other.
+The reserved words as specified using the {\tt reserved} and {\tt ilk}
+commands; the other tokens are specified using the {\tt token}
+command.
+(This somewhat unusual setup is dictated by the way {\tt
+WEAVE} works; its advantage is that is is easy to define a whole group
+of reserved words that will be treated identically.)
+Here's how it works: the {\tt reserved} command designates
+ a particular identifier as a reserved word, and says
+what {\em ilk} it belongs to.
+The {\tt token} and {\tt ilk} commands tell {\tt WEAVE} and {\tt
+TANGLE} what to do with a particular token, or with all the reserved
+words of a particular ilk.
+For each token or ilk one can specify the {\em tangleto} field, the
+token's {\em mathness} (whether it has to be typeset in math mode), and
+its {\em category} and {\em translation} (for conversion to scraps).
+All but the category can have defaults, set with the {\tt defaults}
+command.
+Choice of category names is up to the user.
+
+We will discuss the tokenization commands more later when we present
+the syntax of {Spider} in detail.
+Meanwhile,
+here are some example tokenization commands from the {\tt spider} file
+for~C:
+\begin{verbatim}
+token + category unorbinop
+token - category unorbinop
+token * category unorbinop
+token = category equals translation <"\\leftarrow"> tangleto <"="-space>
+token ~ category unop translation <"\\TI">
+token & category unorbinop translation <"\\amp">
+token ^ translation <"\\^"> category binop
+token ? translation <"\\?"> category question
+token % translation <"\\%"> category binop
+token # translation <"\\#"> category sharp
+token ! category unop translation <"\\neg">
+token ( category lpar
+token ) category rpar
+token [ category lpar
+token ] category rpar
+token { translation <"\\{"> category lbrace
+token } translation <"\\}"> category rbrace
+token ++ category unop translation <"\\PP">
+token -- category unop translation <"\\MM">
+token != translation <"\\I"> category binop
+token == translation <"\\S"> category binop
+token && translation <"\\W"> category binop
+
+ilk case_like category case
+ilk int_like category int
+
+reserved auto ilk int_like
+reserved break ilk case_like
+reserved case ilk case_like
+reserved char ilk int_like
+\end{verbatim}
+These show the definitions of some of the tokens used in C.
+Notice the {\tt tangleto} option is almost always left to default, and
+the {\tt translation} option is often left to default.
+
+Once the tokens are specified, and each has a {\tt tangleto} string,
+we can almost construct a {\tt TANGLE} for the language.
+ Before we can construct a {\tt WEAVE}, we have to tell it how to
+combine and reduce scraps.
+
+\section{Using {Spider} to tell {\tt WEAVE} how to reduce scraps}
+The most intricate part of {\tt WEAVE} is its mechanism for converting
+programming language code into \TeX\ code.
+{\tt WEAVE} uses a simple bottom-up parsing algorithm, since it
+ must deal with fragmentary
+constructions whose overall ``part of speech'' is not known.
+
+The input is represented as a sequence of {\em scraps},
+where each scrap of information consists
+of two parts, its {\em category} and its {\em translation}.
+The category
+is essentially a syntactic class, and the translation represents
+{\TeX} code.
+Rules of syntax and semantics tell us how to
+combine adjacent scraps into larger ones, and if we are lucky an entire
+program text that starts out as hundreds of small scraps will join
+together into one gigantic scrap whose translation is the desired \TeX\
+code.
+If we are unlucky, we will be left with several scraps that don't
+combine; their translations will simply be output, one by one.
+
+The combination rules are given as context-sensitive productions that are
+applied from left to right. Suppose that we are currently working on the
+sequence of scraps $s_1\,s_2\ldots s_n$. We try first to find the longest
+production that applies to an initial substring $s_1\,s_2\ldots\,$; but if
+no such productions exist, we find to find the longest production
+applicable to the next substring $s_2\,s_3\ldots\,$; and if that fails, we
+try to match $s_3\,s_4\ldots\,$, et cetera.
+
+A production applies if the category codes have a given pattern. For
+example, if one of the productions is
+$$\hbox{\tt open [ math semi <"\BS\BS,"-opt-5> ] -->
+open math}$$
+then it means that three consecutive scraps whose respective categories are
+{\tt open}, {\tt math}, and {\tt semi} are con\-verted to two scraps whose categories
+are {\tt open} and {\tt math}.
+ The {\tt open} scrap has not changed, while the string
+{\tt <"\BS\BS,"-opt-5>}
+indicates that the new {\tt math} scrap
+has a translation composed of the translation of the original
+{\tt math} scrap followed by the translation of the {\tt semi} scrap followed
+by `{\tt \BS,}' followed by `{\tt opt}' followed by `{\tt5}'. (In the \TeX\ file,
+this will specify an additional thin space after the semicolon, followed
+by an optional line break with penalty 50.)
+Translations are enclosed in angle brackets, and may contain quoted
+strings (using the C conventions to escape backslashes and so on), or
+may contain special keywords.
+
+Before giving examples of useful productions, we'll break to give the
+detailed syntax of the {Spider} subset covered so far.
+
+
+
+\section{Syntax of {\tt spider} files}
+
+{Spider} is an Awk program which converts a description of a
+language into C~code for {\tt WEAVE} and {\tt TANGLE}.
+Since {Spider} is an Awk program, its input is a sequence of
+lines, and all {Spider} commands must fit on one line.
+
+\paragraph{Comments and blank lines}
+Because {\em any} character sequence can be a token of a programming
+language, we can't just designate a particular sequence as a ``begin
+comment'' marker.
+So in {Spider} there are no comments, only {\em comment lines}.
+A comment line is one whose first character is ``{\tt \#}''.
+The {Spider} processor ignores comment lines and blank lines.
+
+\paragraph{Fields}
+Each command in the {\tt spider} file consists of a sequence of {\em
+fields}.
+These are just the Awk fields, and they are separated by white space.
+This feature of {Spider} (inherited from Awk) forbids the use of
+white space within a field.
+
+\subsection{Translations}
+Most fields in a {Spider} file are simple identifiers, or perhaps
+strings of non-alphanumeric characters.
+The major exception is {\em translations}.
+Translations are always surrounded by angle brackets ({\tt <>}),
+and consist of a (possibly empty) list of translation pieces.
+The pieces on a list are separated by dashes ({\tt -}).
+A piece is one of:
+\begin{itemize}
+\item A quoted string.
+This string may contain embedded quotes escaped by ``\verb+\+'', but
+it {\em must not} contain embedded white space or an embedded dash.
+\item The ``self'' marker, ``{\tt *}'',
+ refers to the sequence of characters making up the token being
+translated.
+The self marker is permitted only in certain contexts, and its precise
+meaning depends on the context.
+\item A digit.
+\item A key word.
+The key words known to {Spider} are
+\begin{description}
+\item [\tt space] Stands for one space ({\tt "\ "}).
+\item[\tt dash] Stands for a dash ({\tt "-"}).
+\end{description}
+The other key words are passed on to {\tt WEAVE}.
+
+{\tt WEAVE} recognizes the following key words:
+\begin{description}
+\item[\tt break\_space] denotes an optional line break or an en space;
+\item[\tt force] denotes a line break;
+\item[\tt big\_force] denotes a line break with additional vertical space;
+\item[\tt opt] denotes an optional line break (with the continuation
+line indented two ems with respect to the normal starting position)---this
+code is followed by an integer $n$, and the break will occur with penalty
+$10n$;
+\item[\tt backup] denotes a backspace of one em;
+\item[\tt cancel] obliterates any {\tt break\_space} or {\tt force} or
+{\tt big\_force}
+tokens that immediately precede or follow it and also cancels any
+{\tt backup} tokens that follow it;
+\item[\tt indent] causes future lines to be indented one more em;
+\item[\tt outdent] causes future lines to be indented one less em.
+\item[\tt math\_rel] translates to \verb+\mathrel{+
+\item[\tt math\_bin]translates to \verb+\mathbin{+
+\item[\tt math\_op] translates to \verb+\mathop{+
+\end{description}
+The {\em only} key words that will work properly in math mode are {\tt
+indent} and {\tt outdent}, so when you're defining the translations of
+tokens you must use {\tt mathness~no} if your translations contain
+other key words.
+You may use any recognized key words in the translations of a
+production; there the mathness is automatically taken care of for you.
+\end{itemize}
+
+Here are some example translations:
+\begin{verbatim}
+<"\\"-space>
+<indent-force>
+<"{\\let\\\\=\\bf"-space>
+<"}"-indent-"{}"-space>
+\end{verbatim}
+
+\paragraph{Restricted translations}
+In some cases, notably for a {\tt tangleto} description, translations
+are {\em restricted}.
+A restricted translation is never converted to typesetting code,
+but is always converted to an ASCII string, usually for output by {\tt
+TANGLE}, but sometimes for other things.
+A restricted translation may contain only {\em quoted strings} and the
+keywords {\tt space} and {\tt dash}.
+
+
+\subsection{{\tt token} commands}
+The syntax of the {\tt token} command is:
+\begin{quote}
+\tt
+\syntax{command} \produces~token \syntax{token-designator}
+\syntax{token-descriptions}
+\end{quote}
+Where \syntax{token-descriptions} is a (possibly empty) list of token
+descriptions.
+
+\paragraph{Token descriptions}
+The token descriptions are
+\begin{itemize}\parindent=0pt
+\item
+{\tt tangleto \syntax{restricted translation}}
+
+The \syntax{restricted translation} tells {\tt TANGLE} what program
+text to write out for this token.
+The only kinds of translation pieces valid in a restricted translation
+are quoted strings and the special words {\tt space} and {\tt dash}.
+If no {\tt tangleto} description is present, {\tt TANGLE} just writes
+out the sequence of characters that constitute the token.
+
+\item
+{\tt translation \syntax{translation}}
+
+Tells {\tt WEAVE} what translation to assign when making this token into
+a scrap.
+The self
+marker~({\tt*}) stands for the sequence of characters that were read in to
+make up the token.
+The translation often defaults to \verb+translation <*>+; {Spider}
+is set up to have this default initially.
+
+\item
+{\tt category \syntax{category-name}}
+
+Tells {\tt WEAVE} what category to assign when making this token into
+a scrap.
+If you're writing a {Spider} file, you may choose any category
+names you like, subject only to the restriction that they not conflict
+with other names known to {Spider} (e.g.~predefined key words,
+names of ilks, and so on).
+Using category names that are identical to reserved words of the
+target programming language (or reserved words of~C) is not only
+supported, it is strongly encouraged, for clarity.
+Also, when we get to the sample grammars later on, you will see some
+other conventions we use for category names.
+
+\item
+{\tt mathness \syntax{mathness-indicator}}
+
+where \syntax{mathness-indicator} is {\tt yes}, {\tt no}, or {\tt
+maybe}.
+This indicates to {\tt WEAVE} whether the translation for this token
+needs to be typeset in {\TeX}'s math mode or not, or whether it
+doesn't matter.
+When firing productions,
+{\tt WEAVE} will place math shift characters~(\verb+$+) in the {\TeX}
+text that guarantee the placement of tokens in the correct modes.
+Tokens with the {\em empty translation} (\verb+<>+) should always have
+{\tt mathness maybe}, lest they cause {\tt WEAVE} to place two
+consecutive math shift characters.
+
+\item
+{\tt name \syntax{token-name}}
+
+This should only be necessary in debugging {Spider} or {\WEB}.
+It causes the specified name to be attached to the token, so that a
+programmer can search for that name in the C~code generated by
+{Spider}.
+
+\end{itemize}
+
+\paragraph{Token designators}
+{Spider} recognizes the following token designators:
+\begin{description}
+\item[{\tt identifier}]
+A {\tt token} command using this designator tells {\tt WEAVE} and {\tt
+TANGLE} what to do with identifier tokens.
+Unfortunately it is not possible to specify with {Spider} just
+what an identifier is; that definition is hard-wired into {\tt WEAVE}
+and {\tt TANGLE}.
+An identifier is the longest string matching this regular expression%
+\footnote{The reader unfamiliar with the Unix notation for regular
+expressions should consult the {\it ed(1)} man page.}:
+\begin{verbatim}
+[a-zA-Z_][a-zA-Z0-9_]*
+\end{verbatim}
+
+\item[{\tt number}]
+In the current implementation of {Spider} and {\tt WEAVE}, a {\tt token}
+command using this designator covers the treatment of both numeric
+constants and string constants.
+Like the identifiers, the definitions of what constitutes a numeric or
+string constant cannot be changed.
+{\samepage
+A numeric constant is the longest string matching%
+\footnote{There ought to be some kind of {\WEB} control sequence to
+support floating point notation for those languages that have it.}:
+\begin{verbatim}
+[0-9]+(\.[0-9]*)?
+\end{verbatim}
+}
+A string constant is the longest string matching
+\begin{verbatim}
+\"([^"]*\\\")*[^"]*\"|'[^@\]'|'\\.'|'@@'
+\end{verbatim}
+Carriage returns may appear in string constants if escaped by a
+backslash~(\verb+\+).
+
+\item[{\tt newline}]
+A {\tt token} command using this descriptor tells {\tt WEAVE} and {\tt
+TANGLE} how to treat a newline.
+We'll see later how to make {\tt WEAVE} ignore newlines.
+
+\item[{\tt pseudo\_semi}]
+A {\tt token} command using this descriptor tells {\tt WEAVE} what to
+do with the {\WEB} control sequence {\tt @;}.
+This control sequence is always ignored by {\tt TANGLE}.
+
+\item[\syntax{characters}]
+where none of the characters is alphanumeric.
+A {\tt token} command using this descriptor defines the sequence of
+characters as a token, and tells {\tt WEAVE} and {\tt TANGLE} what to
+do with that token.
+A token may be a prefix of another token; {\tt WEAVE} and {\tt TANGLE}
+will prefer the longer token to the shorter.
+Thus, in a C~{\WEB}, \verb+==+ will be read as a single \verb+==+
+token, not as two \verb+=+ tokens.
+\end{description}
+
+
+
+
+\subsection{Reserved word tokens}
+Reserved words are attached to a particular {\em ilk} using the {\tt
+reserved} command.
+\begin{quote}
+\tt reserved \syntax{reserved-word} $[$ilk \syntax{ilk-name}$]$
+\end{quote}
+If you're writing a {Spider} file, you may choose any ilk
+names you like, subject only to the restriction that they not conflict
+with other names known to {Spider} (e.g.~predefined key words,
+names of categories, and so on).
+The convention, however, is to use ilk {\tt with\_like} for a reserved
+word {\tt with}, and so on.%
+\footnote{%
+The existence of this convention seduced me into adding a pernicious
+feature to {Spider}---if you omit the ilk from a {\tt reserved}
+command, {Spider} will make an ilk name by appending {\tt \_like}
+to the name of the reserved word.
+Furthermore, if that ilk doesn't already exist, {Spider} will
+construct one.
+Don't use this feature.
+}
+
+The {\tt ilk} and {\tt token} commands have nearly identical syntax.
+The syntax of the {\tt ilk} command is:
+\begin{quote}\tt
+\syntax{command} \produces~ilk \syntax{ilk-name}
+\syntax{token-descriptions}
+\end{quote}
+In translations that appear in {\tt ilk} commands, the self
+marker~({\tt *}) designates the string of characters making up the
+reserved word, surrounded by \verb+\&{...}+, which makes the reserved
+words appear in bold face.
+
+\section{Syntax of the prettyprinting grammar}
+Defining the tokens of a language is somewhat tedious, but it is
+essentially straightforward, and the definition usually does not need
+fine tuning.
+When developing a new {\WEB} with {Spider}, you will spend most of
+your time writing the grammar that tells {\tt WEAVE} how to reduce
+scraps.
+The grammar is defined as a sequence of context-sensitive productions.
+Each production has the form:
+\begin{quote}
+\tt
+\syntax{left context} [ \syntax{firing instructions} ] \syntax{right context}
+\\\null\qquad
+--> \syntax{left context} \syntax{target category} \syntax{right context}
+\end{quote}
+where the left and right contexts are (possibly empty) sequences of
+scrap designators, the firing instructions are a sequence of scrap
+designators and translations (containing at least one scrap
+designator), and the target category is a category designator.
+If the left and right contexts are both empty, the square brackets
+({\tt []}) can be omitted, and the production is context free.
+The left and right contexts must be the same on both sides of the {\tt
+-->}.
+
+What does the production mean?
+Well, {\tt WEAVE} is trying to reduce a sequence of scraps.
+So what {\tt WEAVE} does is look at the sequence, to find out whether
+the left hand side of some production matches an initial subsequence
+of the scraps.
+{\tt WEAVE} picks the first matching production, and {\em fires} it,
+reducing the scraps described in the firing instructions to a single
+scrap, and it gives the new scrap the {\em target category}.
+The translation of the new scrap is formed by concatenating the
+translations in the {\em firing instructions}, where a scrap
+designator stands for the translation of the designated scrap.
+
+Here is the syntax that describes contexts, firing instructions, scrap
+designators, and so on.
+\begin{quote}
+\tt
+\syntax{left context} \produces~\syntax{scrap designators}\\
+\syntax{right context} \produces~\syntax{scrap designators}\\
+\syntax{firing instruction} \produces \syntax{scrap designator}\\
+\syntax{firing instruction} \produces \syntax{translation}\\
+\syntax{scrap designator} \produces~?\\
+\syntax{scrap designator} \produces~\opt{!}\syntax{category name}\opt{*}\\
+\syntax{scrap designator}
+ \produces~\opt{!}\syntax{category alternatives}\opt{*}\\
+\syntax{category alternatives}
+ \produces~\rlap{(\syntax{optional alternatives}\syntax{category name})}\\
+\syntax{optional alternative} \produces~\syntax{category name}|\\
+\syntax{target category} \produces~\#\syntax{integer}\\
+\syntax{target category} \produces~\syntax{category name}\\
+\end{quote}
+
+\paragraph{Matching the left hand side of a production}
+When does a sequence of scraps match the left hand side of a
+production?
+For matching purposes, we can ignore the translations and the square
+brackets~({\tt []}), and look at the left hand side just as a sequence
+of scrap designators.
+A sequence of scraps matches a sequence of scrap designators if and
+only if each scrap on the sequence matches the corresponding scrap
+designator.
+Here are the rules for matching scrap designators (we can
+ignore starring%
+\footnote{A category name is said to be {\em starred} if it has the
+optional {\tt *}.}%
+):
+\begin{itemize}
+\item
+Every scrap matches the designator {\tt ?}.
+\item
+A scrap matches \syntax{marked category} if and only if its category
+is the same as the category of the designator.
+\item
+A scrap matches {\tt!}\syntax{marked category} if and only if its category
+is {\em not} the same as the category of the designator.
+(The {\tt !} indicates negation.)
+\item
+A scrap matches a list of category alternatives if and only if its
+category is on the list of alternatives.
+\item
+A scrap matches a {\em negated} list of category alternatives if and
+only if its category is {\em not} on the list of alternatives.
+\end{itemize}
+
+\paragraph{Firing a production}
+Once a match is found, {\tt WEAVE} fires the production by replacing
+the subsequence of scraps matching the firing instructions.
+{\tt WEAVE} replaces this subsequence with a new scrap whose category
+is the target category, and whose translation is the concatenation of
+all the translations in the firing instructions.
+(When the new translation is constructed, the
+translations of the old scraps are included at the positions of the
+corresponding scrap designators.)
+If the target category is not given by name, but rather by
+number~({\tt \#$n$}), {\tt WEAVE} will take the category of the $n$th
+scrap in the subsequence that matches the left hand side of the
+production, and make that the target category.
+
+\subparagraph{Side effects of firing a production}
+When a production fires, {\tt WEAVE} will {\em underline the
+index entry} for the first identifier in any {\em starred} scrap.
+
+\paragraph{If no initial subsequence matches any production}
+If the initial subsequence of scraps does not match the left hand side
+of any production, {\tt WEAVE} will try to match the subsequence
+beginning with the second scrap, and so on, until a match is found.
+Once a match is found, {\tt WEAVE} fires the production, changing its
+sequence of scraps.
+It then starts all over again at the beginning of the new sequence,
+looking for a match.%
+\footnote{
+The implementation is better than that; {Spider} figures out just
+how much {\tt WEAVE} must backtrack to get the same effect as
+returning to the beginning.}
+If {\em no} subsequence of the scraps matches any production, then the
+sequence of scraps is irreducible, and {\tt WEAVE} writes out the
+translations of the scraps, one at a time.
+
+\section{Examples of {\tt WEAVE} grammars}
+This all must seem very intimidating, but it's not really.
+In this section we present some grammar fragments and explain what's
+going on.
+
+\paragraph{Short examples}
+\begin{verbatim}
+? ignore_scrap --> #1
+\end{verbatim}
+This production should appear in every grammar, because Spidery {\tt
+WEAVE} expects category \verb+ignore_scrap+ to exist with roughly this
+semantics.
+(For example, all comments generate scraps of category {\tt
+ignore\_scrap}.)
+Any scrap of category \verb+ignore_scrap+ essentially doesn't affect
+the reduction of scraps: it is absorbed into the scrap to its left.
+
+\begin{verbatim}
+token newline category newline translation <>
+newline --> ignore_scrap
+\end{verbatim}
+This token definition and production, combined with the previous
+production, causes {\tt WEAVE} to ignore all newlines.
+
+For this next example, from the C~grammar, you will need to know that
+{\tt math} represents a mathematical expression, {\tt semi} a
+semicolon, and {\tt stmt} a statement or sequence of statements.
+\begin{verbatim}
+math semi --> stmt
+stmt <force> stmt --> stmt
+\end{verbatim}
+The first production says that a mathematical expression, followed by
+a semicolon, should be treated as a statement.
+The second says that two statements can be combined to make a single
+statement by putting a line break between them.
+
+\paragraph{Expressions}
+This more extended example shows the treatment of expressions in Awk.
+This is identical to the treatment of expressions in C and in several
+other languages.
+We will use the following categories:
+\begin{description}
+\item[math] A mathematical expression
+\item[binop] A binary infix operator
+\item[unop] A unary prefix or postfix operator
+\item[unorbinop] An operator that could be binary infix or unary
+prefix
+\end{description}
+To show you how these might be used, here are some sample token
+definitions using these categories:
+\begin{verbatim}
+token + category unorbinop
+token - category unorbinop
+token * category binop
+token / category binop
+token < category binop
+token > category binop
+token , category binop translation <",\\,"-opt-3>
+token = category binop translation <"\\K">
+token != translation <"\\I"> category binop
+token == name eq_eq translation <"\\S"> category binop
+token ++ name gt_gt category unop translation <"\\uparrow">
+token -- name lt_lt category unop translation <"\\downarrow">
+\end{verbatim}
+Notice that the translation for the comma specifies a thin space and
+an optional line break after the comma.
+The translations of {\tt =}, {\tt !=}, and {\tt ==}
+produce~$\leftarrow$, $\ne$, and~$\equiv$.
+
+Here is the grammar for expressions.
+\begin{verbatim}
+math (binop|unorbinop) math --> math
+(unop|unorbinop) math --> math
+math unop --> math
+math <"\\"-space> math --> math
+\end{verbatim}
+In Awk there is no concatenation operator; concatenation is by
+juxtaposition.
+The last production tells {\tt WEAVE} to insert a space between two
+juxtaposed expressions.
+
+So far we haven't dealt with parentheses, but that's easily done:
+\begin{verbatim}
+token ( category open
+token ) category close
+token [ category open
+token ] category close
+open math close --> math
+\end{verbatim}
+
+
+Now this grammar just given doesn't handle the Awk or C {\tt +=}
+feature very well; {\tt x+=1} comes out as~$x+\leftarrow 1$, and {\tt
+x/=2} is irreducible!
+Here's the cure; first, we make a new category for assignment:
+\begin{verbatim}
+token = category equals translation <"\\K">
+\end{verbatim}
+And then we write productions that reduces assignment (possibly
+preceded by another operator) to a binary operator:
+\begin{verbatim}
+<"\\buildrel"> (binop|unorbinop) <"\\over{"> equals <"}"> --> binop
+equals --> binop
+\end{verbatim}
+Notice that, given the rules stated above, the second production can
+fire only if {\tt equals} is {\em not} preceded by an operator.
+On input~{\tt x+=1}, the first production fires, and we have the
+translation~$x\buildrel+\over{\leftarrow} 1$.
+
+\paragraph{Conditional statements}
+Here is the grammar for (possibly nested) conditional statements in
+Awk.
+\begin{verbatim}
+if <"\\"-space> math --> ifmath
+ifmath lbrace --> ifbrace
+ifmath newline --> ifline
+ifbrace <force> stmt --> ifbrace
+ifbrace <outdent-force> close else <"\\"-space> if --> if
+ifbrace <outdent-force> close else lbrace --> ifbrace
+ifbrace <outdent-force> close else newline --> ifline
+ifbrace <outdent-force> close --> stmt
+(ifline|ifmath) <indent-force> stmt <outdent> --> stmt
+\end{verbatim}
+It relies on the following token definitions:
+\begin{verbatim}
+ilk if_like category if
+reserved if
+ilk else_like category else
+reserved else
+token { translation <"\\;\\{"-indent> category lbrace
+token } translation <"\\}\\"-space> category close
+token newline category newline translation <>
+\end{verbatim}
+
+\paragraph{Handling preprocessor directives in C}
+Here is a simplified version of
+the grammar that handles C preprocessor directives.
+It puts the directives on the left hand margin, and correctly handles
+newlines escaped with backslashes.
+(The full version is also able to distinguish {\tt <...>}
+bracketing a file name from the use of the same symbols to mean ``less
+than'' and ``greater than.'')
+{\small\advance\hsize 1in
+\begin{verbatim}
+# control sequence \8 puts things on the left margin
+<"\\8"> sharp <"{\\let\\\\=\\bf"-space> math <"}"-indent-"{}"-space> --> preproc
+preproc backslash <force-"\\8\\hskip1em"-space> newline --> preproc
+<force> preproc <force-outdent> newline --> ignore_scrap
+preproc math --> preproc
+newline --> ignore_scrap
+\end{verbatim}
+}
+The \verb+\let+ in the first production makes the identifier following
+the {\tt \#} come out in bold face.
+
+
+\subsection{Using context-dependent productions}
+So far we've been able to do a lot without using the
+context-dependent features of {Spider} productions.
+(For example, the entire {\tt spider} file for Awk is written using
+only context-free productions.)
+Now we'll show some examples that use the context-dependence.
+
+In the grammar for Ada, a semicolon is used as a terminator for
+statements.
+But semicolons are also used as {\em separators} in parameter
+declarations.
+The first two productions here find the statements, but the third
+production supersedes them when a semicolon is seen in a parenthesized
+list.
+\begin{verbatim}
+semi --> terminator
+math terminator --> stmt
+open [ math semi ] --> open math
+\end{verbatim}
+
+
+\paragraph{Underlining the index entry for the name of a declared
+function}
+In SSL, function declarations begin with the type of the function
+being declared, followed by the name of that function.
+The following production causes the index entry for that function to
+be underlined, so that we can look up the function name in the index
+and easily find the section in which the function is declared:
+\begin{verbatim}
+decl simp [ simp* ] --> decl simp math
+\end{verbatim}
+Where we've relied on
+\begin{verbatim}
+token identifier category simp mathness yes
+\end{verbatim}
+
+
+\paragraph{Conditional expressions}
+Suppose we want to format conditional expressions (for example in C)
+like this:
+\begin{quote}
+\syntax{condition}\\
+\mbox{\qquad}$?$ \syntax{expression}\\
+\mbox{\qquad}$:$ \syntax{expression}
+\end{quote}
+The problem is that it's hard to know when the conditional expression
+ends.
+It's essentially a question of precedence, and what we're going to do
+is look ahead until we see an operator with sufficiently low
+precedence that it terminates a conditional expression.
+In SSL a conditional expression can be terminated by a semicolon, a
+right parenthesis, a comma, or a colon.
+We'll use the {\em right context} to do the lookahead.
+{\small
+\begin{verbatim}
+token ? translation <"\\?"> category question
+token : category colon
+
+<indent-force> question math <force> colon --> condbegin
+[ condbegin math <outdent> ] (semi|close|comma|colon) --> math (semi|close|comma|colon)
+\end{verbatim}
+}
+
+\subsection{Debugging a prettyprinting grammar}
+{\tt WEAVE} has two tracing modes that can help you debug a
+prettyprinting grammar.
+The control sequence {\tt @1} turns on partial tracing, and {\tt @2}
+turns on a full trace.
+{\tt @0} turns tracing back off again.
+In the partial tracing mode, {\tt WEAVE} applies all the productions
+as many times as possible, and then it prints out the irreducible
+scraps that remain.
+If the scraps reduce to a single scrap, no diagnostics are printed.
+
+
+When a scrap is printed, {\tt WEAVE} prints a leading
+{\tt+}~or~{\tt-}, the name of the category of that scrap, and a
+trailing {\tt+}~or~{\tt-}.
+The {\tt+} indicates that {\TeX} should be in math mode, and the
+{\tt-} that {\TeX} should not be in math mode, at the beginning and
+end of the scrap's translation, respectively.
+(You can see the translations by looking at the {\tt.tex} file, since
+that's where they're written out.)
+
+For beginners, the full trace is more helpful.
+It prints out the following information every time a production is
+fired:
+\begin{itemize}
+\item
+The number of the production just fired (from {\tt productions.list});
+\item
+The sequence of scraps {\tt WEAVE} is now trying to reduce;
+\item
+A {\tt*} indicating what subsequence {\tt WEAVE} will try to reduce
+next.
+\end{itemize}
+A good way to understand how prettyprinting grammars work is to take
+a {\tt productions.list} file, and look at a full trace of the
+corresponding {\tt WEAVE}.
+Or, if you prefer, you can simulate by hand the action of {\tt WEAVE}
+on a sequence of scraps.
+
+\section{The rest of the {Spider} language}
+The tokens and the grammar are not quite the whole story.
+Here's the rest of the truth about what you can do with {Spider}.
+
+\subsection{Naming the target language}
+When a Spidery {\tt WEAVE} or {\tt TANGLE} starts up, it prints the
+target language for which it was generated, and the date and time of
+the generation.
+The {\tt language} command is used to identify the language being
+targeted.
+Its syntax is
+\begin{quote}
+\tt language \syntax{language-name}
+\opt{extension \syntax{extension-name}}\\
+\mbox{\qquad\qquad}\opt{version \syntax{version-name}}
+\end{quote}
+The extension name is the extension used (in place of {\tt .web}) by
+{\tt TANGLE} to write out the program text for the unnamed module.
+The extension is also used to construct a language-specific file of
+{\TeX} macros to be used by {\tt WEAVE}, so different languages should
+always have different extensions.
+If the extension is not given it defaults to the language name.
+If the version information is given, it too will be printed out at
+startup.
+
+The {\tt c.spider} file I use for Unix has
+\begin{verbatim}
+language C extension c
+\end{verbatim}
+
+
+\subsection{Defining {\TeX} macros}
+In addition to the ``kernel'' {\WEB} macros stored in {\tt
+webkernel.tex}, you may want to create some {\TeX} macros of your
+own for use in translations.
+Any macro definitions you put between lines saying {\tt macros begin}
+and {\tt macros end} will be included verbatim in the {\TeX} macro
+file for this language.
+That macro file will automatically be \verb+\input+ by every {\TeX}
+file generated by this {\tt WEAVE}.
+
+For example, the C grammar includes productions to handle preprocessor
+directives.
+These directives may include file names that are delimited by angle
+brackets.
+I wanted to use the abbreviations \verb+\LN+ and \verb+\RN+ for left
+and right angle brackets, so I included
+\begin{verbatim}
+macros begin
+\let\LN\langle
+\let\RN\rangle
+macros end
+\end{verbatim}
+in the {\tt c.spider} file.
+
+\subsection{Setting default token information}
+It's possible to set default values for the {\tt translation} and {\tt
+mathness} properties of tokens, so that they don't have to be
+repeated.
+This is done with the {\tt default} command, whose syntax is:
+\begin{quote}
+\tt
+default \syntax{token descriptions}
+\end{quote}
+The initial defaults (when {Spider} begins execution) are {\tt
+translation~<*>} and {\tt mathness~maybe}.
+
+\subsection{Specifying the treatment of modules}
+{\WEB} introduces a new kind of token that isn't in any programming
+language, and that's the module name ({\tt @<...@>} or {\tt @(...@>}).
+{\tt TANGLE}'s job is to convert the module names to program text, and
+when {\tt TANGLE} is finished no module names remain.
+But {\tt WEAVE} has to typeset the module names, and we need to tell
+{\tt WEAVE} what category to give a scrap created from a module name.
+We allow two different categories, one for the definition of the
+module name (at the beginning of a module), and one for a use of a
+module name.
+{\samepage
+The syntax of the {\tt module} command is:
+\begin{quote}
+\tt
+module \opt{definition \syntax{category name}}
+\opt{use \syntax{category name}}
+\end{quote}
+}
+
+The {\tt c.spider} file contains the line
+\begin{verbatim}
+module definition decl use math
+\end{verbatim}
+
+\subsection{Determining the at sign}
+When generating a {\WEB} system with {Spider}, you're not required
+to use ``{\tt @}'' as the ``magic at sign'' that introduces {\WEB}
+control sequences.
+By convention, however, we use ``{\tt @}'' unless that is deemed
+unsuitable.
+If ``{\tt @}'' is unsuitable, we use ``{\tt \#}.''
+Since {Spider} writes C~{\WEB} code for {\tt WEAVE} and {\tt
+TANGLE}, it writes a lot of {\tt @} signs.
+I didn't when to have to escape each one, so I chose
+``{\tt \#}'' for Awk~{\WEB}'s at sign:
+\begin{verbatim}
+at_sign #
+\end{verbatim}
+The at sign defaults to ``{\tt @}'' if left unspecified.
+
+\paragraph{Changing control sequences}
+Changing the at sign changes the meaning of one or two control
+sequences.
+This is more easily illustrated by example than explained.
+Suppose we change the at sign to {\tt\#}.
+Then in the resulting {\WEB} two control sequences have new meanings:
+\begin{description}
+\item[{\tt \#\#}]
+Stands for a {\tt \#} in the input, by analogy with {\tt @@} in normal
+{\WEB}.
+You will need this when defining {\TeX} macros that take parameters.
+\item[{\tt \#@}]
+This is the new name of the control sequence normally represented by
+{\tt@\#}.
+ You would use {\tt\#@} to get a line break followed by vertical
+white space.
+\end{description}
+If you change the at sign to something other than {\tt@}~or~{\tt\#},
+the above will still hold provided you substitute your at sign for
+{\tt\#}.
+
+
+\subsection{Comments in the programming language}
+We have to tell {\tt WEAVE} and {\tt TANGLE} how to recognize
+comments in our target programming language, since comment text is
+treated as {\TeX} text by {\tt WEAVE} and is ignored by {\tt TANGLE}.
+The syntax of the {\tt comment} command is
+\begin{quote}
+\tt
+comment begin \syntax{restricted translation} \\
+\null\qquad end $(\syntax{restricted translation}|{\tt newline})$
+\end{quote}
+The restricted translations can include only quoted
+strings, {\tt space}, and
+{\tt dash}.
+They give the character sequences that begin and end comments.
+If comments end with newlines the correct incantation is {\tt end
+newline}.
+
+If the comment character is the same as the at sign, it has to be
+doubled in the {\WEB} file to have any effect.
+For reasons that I've forgotten, {Spider} is too dumb
+to figure this out and {\em you must double the comment character in
+the {Spider} file}.
+This is not totally unreasonable since any at sign that actually appears in a
+{\WEB} file will have to be double to be interpreted correctly.
+
+{\tt WEAVE} uses the macros \verb+\commentbegin+ and
+\verb+\commentend+ at the beginning and end of comments, so you can
+define these to be whatever you like (using the {\tt macros} command)
+if you don't like {Spider}'s defaults.
+{Spider} is smart enough to escape {\TeX}'s special characters in
+coming up with these defaults.
+
+Here's a real-world ugly example of how things really are, from the
+{\tt spider} file for Awk:
+\begin{verbatim}
+comment begin <"##"> end newline
+macros begin
+\def\commentbegin{\#} % we don't want \#\#
+macros end
+\end{verbatim}
+
+\subsection{Controlling line numbering}
+ A compiler doesn't get to see {\WEB} files directly; it has to
+read the output of {\tt TANGLE}.
+Error messages labelled with line numbers from a tangled file aren't
+very helpful, so Spidery {\tt TANGLE} does something to improve the
+situation: it writes {\tt \#line} directives into its output, in the
+manner of the C~preprocessor.
+({\tt TANGLE} also preserves the line breaking of the {\WEB} source,
+so that the {\tt \#line} information will be useful.)
+For systems like Unix with {\tt cc} and {\tt dbx}, both compile-time
+and run-time debugging can be done in terms of the {\WEB} source, and
+the intermediate programming language source need never be consulted.
+
+Not all compilers support line numbering with {\tt \#line} directives,
+so {Spider} provides a {\tt line} command to change the format of
+the {\tt \#line} directives.
+If your compiler doesn't support {\tt \#line}, you can use the {\tt
+line} command to turn the line number information into a comment.%
+\footnote{%
+There should be a command that turns off line numbering.%
+}
+The syntax is:
+\begin{quote}
+\tt
+line begin \syntax{restricted translation} end \syntax{restricted translation}
+\end{quote}
+The {\tt begin} translation tells what string to put in front of the file
+name and line number information; the {\tt end} translation tells what to
+put afterward.
+The defaults (which are set for C) are
+\begin{verbatim}
+line begin <"#line"> end <"">
+\end{verbatim}
+Here's an example from the Ada~{Spider} file, which makes the line
+number information into an Ada comment:
+\begin{verbatim}
+line begin <"--"-space-"line"> end <"">
+\end{verbatim}
+
+
+
+
+\subsection{Showing the date of generation}
+When Spidery {\tt WEAVE} and {\tt TANGLE} start up, they print the
+date and time at which their {Spider} file was processed.
+This is done through the good offices of {Spider}'s {\tt date}
+command, which is
+\begin{quote}
+\tt
+date \syntax{date}
+\end{quote}
+where \syntax{date} looks like {\tt "Fri Dec 11 11:31:18 EST 1987"} or
+some such.
+Normally you never need to use the {\tt date} command, because one is
+inserted automatically by the {Spider} tools, but if you're
+porting {Spider} to a non-Unix machine you need to know about it.
+
+
+
+
+\section{Spider's error messages}
+{Spider} makes a lot of attempts to detect errors in a
+{Spider} specification.
+{Spider}'s error messages are intended to be self-explanatory, but
+I don't know how well they succeed.
+In case you run into trouble, here are the error
+conditions {Spider} tries to detect:
+\begin{itemize}
+\item
+ Garbled commands, lines with bad fields in them, or commands with
+unused fields.
+Any command with a field {Spider} can't follow or with an extra
+field is ignored from the bad field onward, but the earlier fields may
+have an effect.
+Any production with a bad field or other error is dropped completely.
+\item
+Missing {\tt language} command.
+\item
+{\tt macros} or {\tt comment} command before {\tt language} command.
+{Spider} uses the {\tt extension} information
+from the {\tt language} command to determine the name of the file to
+which the macros will be written, and the {\tt comment} command
+causes {Spider} to write macros telling {\TeX} what to do at the
+beginning and end of comments.
+\item
+Contexts don't match on the left and right sides of a production.
+\item
+A numbered target token doesn't fall in the range defined by the
+left hand side of its production.
+\item
+Some category is never {\em appended}.
+This means there is no way to create a scrap with this category.
+{Spider} only looks to see that each
+category appears at least once as the category of some token or as the
+category of the target token in some production, so {Spider} might
+fail to detect this condition (if there is some production that can
+never fire).
+\item
+Some category is never {\em reduced}.
+This means that the category never appears in a scrap
+designator from the firing instructions of a production.
+If a category is never reduced, {Spider} only issues a warning,
+and does not halt the compilation process with an error.
+
+The append
+and reduce checks will usually catch you if you misspell a category
+name.
+\item
+You defined more tokens than {\tt WEAVE} and {\tt TANGLE} can handle.
+\item
+You forgot token information for identifiers, numeric
+constants, newlines, pseudo-semicolons~({\tt @;}), module definitions,
+or module uses.
+\item
+Some ilk has no translation, or there is some ilk of which there are
+no reserved words.
+\end{itemize}
+
+
+
+
+\section{{Spider}'s output files}
+{Spider} writes many output files, and you may want to look at
+them to figure out what's going on.
+Here is a partial list (you can find a complete list by consulting
+{\tt spider.web}):
+\begin{description}
+\item[\tt cycle.test]
+Used to try to detect potential loops in the grammar.
+Such loops can cause {\tt WEAVE} to run indefinitely (until it runs
+out of memory) on certain inputs.
+Discussed below with the {Spider} tools.
+\item[\tt spider.slog]
+A verbose discussion of everything {Spider} did while it was
+processing your file.
+To be consulted when things go very wrong.
+\item[\tt *web.tex]
+The macros specific to the generated {\WEB}.
+\item[\tt productions.list]
+A numbered list of all the productions.
+This list is invaluable when you are trying to debug a grammar using
+Spidery {\tt WEAVE}'s tracing facilities ({\tt @2}).
+\end{description}
+
+
+
+
+\section{Using {Spider} to make {\WEB} (the {Spider} tools)}
+Many of the {Spider} tools do error checking, like:
+\begin{itemize}
+\item
+Check to see there are no duplicate names among the categories, ilks,
+and translation keywords.
+\item
+Check the translation keywords against a list of those recognized by
+{\tt WEAVE}, and yelps if trouble happens.
+\item
+Try to determine whether there is a ``production cycle'' that could
+cause {\tt WEAVE} to loop infinitely by firing the productions in the
+cycle one after another.
+\end{itemize}
+
+I'm not going to say much about how to do all this, or how to make
+{\tt WEAVE} and {\tt TANGLE}; instead I'm going to show you a {\tt
+Makefile} and comment on it a little bit.
+Since right now Spidery {\tt WEB} is available only on Unix systems,
+chances are you have the {\tt Makefile} and can just type ``{\tt
+make~tangle}'' or ``{\tt make~weave}.''
+If not, reading the Makefile is still your best bet to figure out what
+the tools do.
+
+We assume that you are making {\tt WEAVE} and {\tt TANGLE} in some
+directory, and that the ``master sources'' for Spidery {\WEB} are kept
+in some other directory.
+Some of the {\tt Makefile} macros deserve special mention:
+\begin{description}
+\renewcommand{\makelabel}[1]{{\tt#1}\hfil}
+\item[THETANGLE]
+Name of the {\tt TANGLE} we will generate.
+\item[THEWEAVE]
+Name of the {\tt WEAVE} we will generate.
+\item[SPIDER]
+Name of the {Spider} input file.
+\item[DEST]
+The directory in which the executables defined by \verb+$(TANGLE)+ and
+\verb+$(WEAVE)+ will be placed.
+\item[WEBROOT]
+The directory that is the root of the Spidery {\WEB} distribution.
+\item[MASTER]
+The location of the ``master sources.''
+This should always be different from the directory in which {\tt make}
+is called, or havoc will result.
+\item[CTANGLE]
+The name of the program used to tangle C code.
+\item[AWKTANGLE]
+The name of the program used to tangle Awk code.
+\item[MACROS]
+The name of a directory in which to put {\TeX} macro definitions (a
+{\tt *web.tex} file.
+\end{description}
+
+Usually we will only be interested in two commands: ``\/{\tt
+make~weave}'' and ``\/{\tt make~tangle}.''
+It's safe to use ``\/{\tt make~clean}'' only if you use the current
+directory for nothing exception spidering; ``\/{\tt make~clean}'' is
+really vicious.
+
+The line that's really of interest is the line showing the dependency
+for {\tt grammar.web}.
+First we run {Spider}.
+Then we check for bad translation keywords and for potential cycles in
+the prettyprinting grammar.
+We check for duplicate names, and then finally (if everything else
+works), we put the {\tt *web.tex} file in the right place.
+
+Here's \verb+$(MASTER)/WebMakefile+:
+\begingroup\small
+\begin{verbatim}
+# Copyright 1989 by Norman Ramsey and Odyssey Research Associates.
+# Not to be sold, but may be used freely for any purpose.
+# For more information, see file COPYRIGHT in the parent directory.
+
+HOME=/u/nr# # Make no longer inherits environment vars
+THETANGLE=tangle
+THEWEAVE=weave
+SPIDER=any.spider
+#
+DVI=dvi
+CFLAGS=-DDEBUG -g -DSTAT
+
+# CPUTYPE is a grim hack that attempts to solve the problem of multiple
+# cpus sharing a file system. In my environment I have to have different
+# copies of object and executable for vax, sun3, next, iris, and other
+# cpu types. If you will be using Spidery WEB in a homogeneous processor
+# environment, you can just set CPUTYPE to a constant, or eliminate it
+# entirely.
+#
+# In my environment, the 'cputype' program returns a string that
+# describes the current processor. That means that the easiest thing
+# for you to do is to define a 'cputype' program that does something
+# sensible. A shell script that says 'echo "vax"' is fine.
+
+CPUTYPE=`cputype`
+
+# Change the following three directories to match your installation
+#
+# the odd placement of # is to prevent any trailing spaces from slipping in
+
+WEBROOT=$(HOME)/web/src# # root of the WEB source distribution
+DEST=$(HOME)/bin/$(CPUTYPE)# # place where the executables go
+MACROS=$(HOME)/tex/macros# # place where the macros go
+
+MASTER=$(WEBROOT)/master# # master source directory
+OBDIR=$(MASTER)/$(CPUTYPE)# # common object files
+
+TANGLESRC=tangle
+CTANGLE=ceetangle -I$(MASTER)
+CWEAVE=ceeweave -I$(MASTER)
+AWKTANGLE=awktangle -I$(MASTER)
+COMMONOBJS=$(OBDIR)/common.o $(OBDIR)/pathopen.o
+COMMONC=$(MASTER)/common.c $(MASTER)/pathopen.c
+COMMONSRC=$(COMMONC) $(MASTER)/spider.awk
+
+
+
+# Our purpose is to make tangle and weave
+
+web: tangle weave
+
+tangle: $(COMMONOBJS) $(TANGLESRC).o
+ cc $(CFLAGS) -o $(DEST)/$(THETANGLE) $(COMMONOBJS) $(TANGLESRC).o
+
+weave: $(COMMONOBJS) weave.o
+ cc $(CFLAGS) -o $(DEST)/$(THEWEAVE) $(COMMONOBJS) weave.o
+
+
+source: $(TANGLESRC).c $(COMMONSRC) # make tangle.c and common src, then clean
+ if [ -f WebMakefile ]; then exit 1; fi # don't clean the master!
+ if [ -f spiderman.tex ]; then exit 1; fi # don't clean the manual
+ -rm -f tangle.web weave.* common.* # remove links that may be obsolete
+ -rm -f *.unsorted *.list grammar.web outtoks.web scraps.web
+ -rm -f cycle.test spider.slog
+ -rm -f *.o *.tex *.toc *.dvi *.log *.makelog *~ *.wlog *.printlog
+
+# Here is how we make the common stuff
+
+$(MASTER)/common.c: $(MASTER)/common.web # no change file
+ $(CTANGLE) $(MASTER)/common
+
+$(OBDIR)/common.o: $(MASTER)/common.c
+ cc $(CFLAGS) -c $(MASTER)/common.c
+ mv common.o $(OBDIR)
+
+
+$(MASTER)/pathopen.c: $(MASTER)/pathopen.web # no change file
+ $(CTANGLE) $(MASTER)/pathopen
+ mv pathopen.h $(MASTER)
+
+$(OBDIR)/pathopen.o: $(MASTER)/pathopen.c
+ cc $(CFLAGS) -c $(MASTER)/pathopen.c
+ mv pathopen.o $(OBDIR)
+
+
+## Now we make the tangle and weave source locally
+
+$(TANGLESRC).c: $(MASTER)/$(TANGLESRC).web $(MASTER)/common.h grammar.web
+ -/bin/rm -f $(TANGLESRC).web
+ ln $(MASTER)/$(TANGLESRC).web $(TANGLESRC).web
+# chmod -w $(TANGLESRC).web
+ $(CTANGLE) $(TANGLESRC)
+
+weave.c: $(MASTER)/weave.web $(MASTER)/common.h grammar.web
+ -/bin/rm -f weave.web
+ ln $(MASTER)/weave.web weave.web
+# chmod -w weave.web
+ $(CTANGLE) weave
+
+## Here's where we run SPIDER to create the source
+
+grammar.web: $(MASTER)/cycle.awk $(MASTER)/spider.awk $(SPIDER)
+ echo "date" `date` | cat - $(SPIDER) | awk -f $(MASTER)/spider.awk
+ cat $(MASTER)/transcheck.list trans_keys.unsorted | awk -f $(MASTER)/transcheck.awk
+ awk -f $(MASTER)/cycle.awk < cycle.test
+ sort *.unsorted | awk -f $(MASTER)/nodups.awk
+ mv *web.tex $(MACROS)
+
+## We might have to make spider first.
+
+$(MASTER)/spider.awk: $(MASTER)/spider.web
+ $(AWKTANGLE) $(MASTER)/spider
+ mv cycle.awk nodups.awk transcheck.awk $(MASTER)
+ rm junk.list
+
+
+# $(MASTER)/cycle.awk: $(MASTER)/cycle.web # making spider also makes cycle
+# $(AWKTANGLE) $(MASTER)/cycle
+
+
+# This cleanup applies to every language
+
+clean:
+ if [ -f WebMakefile ]; then exit 1; fi # don't clean the master!
+ if [ -f spiderman.tex ]; then exit 1; fi # don't clean the manual
+ -rm -f tangle.* weave.* common.* # remove links that may be obsolete
+ -rm -f *.unsorted *.list grammar.web outtoks.web scraps.web
+ -rm -f cycle.test spider.slog
+ -rm -f *.c *.o *.tex *.toc *.dvi *.log *.makelog *~ *.wlog *.printlog
+
+
+
+# booting the new distribution
+boot:
+ cd ../master; rm -f *.o; for i in $(COMMONC); do \
+ cc $(CFLAGS) -c $$i; \
+ mv *.o $(OBDIR) ; \
+ done; cd ../c
+ cc $(CFLAGS) -c $(TANGLESRC).c; \
+ cc $(CFLAGS) -o $(DEST)/$(THETANGLE) $(COMMONOBJS) $(TANGLESRC).o
+
+
+\end{verbatim}
+\endgroup
+
+\section{Getting your own Spidery {\tt WEB}}
+At this time, Spidery {\tt WEB} has been tested only on Unix machines.
+It should be easy to port to any machine having a C compiler and an
+Awk interpreter, but undoubtedly some changes will be necessary.
+The full {Spider} distribution, including this manual, is available by
+anonymous {\tt ftp} from {\tt princeton.edu:~ftp/pub/spiderweb.tar.Z}.
+You should pick a directory to install {Spider} in, untar the
+distribution, and follow the directions in the README file.
+The directory you have picked becomes {\tt WEBROOT}.
+
+If the {\tt Makefile} in the distribution differs from the one given
+above, the one in the distribution should be considered the correct
+one.
+
+
+
+
+\section{A real {Spider} file}
+I have tried to use real examples to illustrate the use of {Spider}.
+I include here, as an extended example, the complete {Spider} file for
+the Awk language.
+Those who cannot easily study the distribution may find it useful to
+study this.
+\begingroup\small
+\begin{verbatim}
+# Copyright 1989 by Norman Ramsey and Odyssey Research Associates.
+# Not to be sold, but may be used freely for any purpose.
+# For more information, see file COPYRIGHT in the parent directory.
+
+language AWK extension awk
+
+at_sign #
+
+module definition stmt use stmt
+# use as stmt is unavoidable since tangle introduces line breaks
+
+comment begin <"##"> end newline
+macros begin
+\def\commentbegin{\#} % we don't want \#\#
+macros end
+
+line begin <"#line"> end <"">
+
+default translation <*> mathness yes
+
+token identifier category math mathness yes
+token number category math mathness yes
+token newline category newline translation <> mathness maybe
+token pseudo_semi category ignore_scrap mathness no translation <opt-0>
+
+token \ category backslash translation <> mathness maybe
+token + category unorbinop
+token - category unorbinop
+token * category binop
+token / category binop
+token < category binop
+token > category binop
+token >> category binop translation <"\\GG">
+token = category equals translation <"\\K">
+token ~ category binop translation <"\\TI">
+token !~ category binop translation <"\\not\\TI">
+token & category binop translation <"\\amp">
+token % translation <"\\%"> category binop
+token ( category open
+token [ category lsquare
+token ) category close
+token ] category close
+token { translation <"\\;\\{"-indent> category lbrace
+token } translation <"\\}\\"-space> category close
+token , category binop translation <",\\,"-opt-3>
+
+token ; category semi translation <";"-space-opt-2> mathness no
+# stuff with semi can be empty in for statements
+open semi --> open
+semi semi --> semi
+semi close --> close
+semi --> binop
+
+# token : category colon
+# token | category bar
+token != name not_eq translation <"\\I"> category binop
+token <= name lt_eq translation <"\\L"> category binop
+token >= name gt_eq translation <"\\G"> category binop
+token == name eq_eq translation <"\\S"> category binop
+token && name and_and translation <"\\W"> category binop
+token || name or_or translation <"\\V"> category binop
+# token -> name minus_gt translation <"\\MG"> category binop
+token ++ name gt_gt category unop translation <"\\uparrow">
+token -- name lt_lt category unop translation <"\\downarrow">
+# preunop is for unary operators that are prefix only
+token $ category preunop translation <"\\DO"> mathness yes
+
+default mathness yes translation <*>
+
+ilk pattern_like category math
+reserved BEGIN ilk pattern_like
+reserved END ilk pattern_like
+
+ilk if_like category if
+reserved if
+ilk else_like category else
+reserved else
+
+ilk print_like category math
+# math forces space between this and other math...
+reserved print ilk print_like
+reserved printf ilk print_like
+reserved sprintf ilk print_like
+
+
+ilk functions category unop mathness yes
+reserved length ilk functions
+reserved substr ilk functions
+reserved index ilk functions
+reserved split ilk functions
+reserved sqrt ilk functions
+reserved log ilk functions
+reserved exp ilk functions
+reserved int ilk functions
+
+ilk variables category math mathness yes
+reserved NR ilk variables
+reserved NF ilk variables
+reserved FS ilk variables
+reserved RS ilk variables
+reserved OFS ilk variables
+reserved ORS ilk variables
+
+ilk for_like category for
+reserved for ilk for_like
+reserved while ilk for_like
+
+ilk in_like category binop translation <math_bin-*-"}"> mathness yes
+# translation <"\\"-space-*-"\\"-space>
+reserved in ilk in_like
+
+ilk stmt_like category math
+reserved break ilk stmt_like
+reserved continue ilk stmt_like
+reserved next ilk stmt_like
+reserved exit ilk stmt_like
+
+
+backslash newline --> math
+# The following line must be changed to make a backslash
+backslash <"\\backslash"> --> math
+
+math (binop|unorbinop) math --> math
+<"\\buildrel"> (binop|unorbinop) <"\\over{"> equals <"}"> --> binop
+equals --> binop
+(unop|preunop|unorbinop) math --> math
+# unorbinop can only act like unary op as *prefix*, not postfix
+math unop --> math
+math <"\\"-space> math --> math
+# concatenation
+
+math newline --> stmt
+newline --> ignore_scrap
+
+stmt <force> stmt --> stmt
+
+(open|lsquare) math close --> math
+
+math lbrace --> lbrace
+lbrace <force> stmt --> lbrace
+lbrace <outdent-force> close --> stmt
+
+if <"\\"-space> math --> ifmath
+ifmath lbrace --> ifbrace
+ifmath newline --> ifline
+ifbrace <force> stmt --> ifbrace
+ifbrace <outdent-force> close else <"\\"-space> if --> if
+ifbrace <outdent-force> close else lbrace --> ifbrace
+ifbrace <outdent-force> close else newline --> ifline
+ifbrace <outdent-force> close --> stmt
+(ifline|ifmath) <indent-force> stmt <outdent-force> else <"\\"-space> if --> if
+(ifline|ifmath) <indent-force> stmt <outdent-force> else lbrace --> ifbrace
+(ifline|ifmath) <indent-force> stmt <outdent-force> else newline --> ifline
+(ifline|ifmath) <indent-force> stmt <outdent-force> else --> ifmath
+(ifline|ifmath) <indent-force> stmt <outdent> --> stmt
+
+for <"\\"-space> math --> formath
+formath lbrace --> forbrace
+formath newline --> forline
+forbrace <force> stmt --> forbrace
+forbrace <outdent-force> close --> stmt
+(forline|formath) <indent-force> stmt <outdent> --> stmt
+
+
+? ignore_scrap --> #1
+\end{verbatim}
+\endgroup
+
+
+
+\section{Bibliography}
+\begin{thebibliography}{Knuth~999}
+\bibitem[Bentley~87]{bentley:pearls}
+Jon L. Bentley, ``Programming Pearls,'' {\sl Communications of the
+ACM}~{\bf 29:5}(May 1986), 364--?, and {\bf 29:6}(June 1986),
+471--483.
+Two columns on literate programming.
+The first is an introduction, and the second is an extended example by
+Donald Knuth, with commentary by Douglas MacIlroy.
+\bibitem[Knuth~83]{knuth:web}
+Donald~E. Knuth,
+``The {{\tt WEB}} system of structured documentation''
+ Technical Report 980, Stanford Computer Science, Stanford,
+ California, September 1983.
+The manual for the original {\tt WEB}.
+\bibitem[Knuth~84]{knuth:literate-programming}
+Donald E. Knuth, ``Literate Programming,'' {\sl The Computer Journal}
+{\bf 27:2}(1984), 97--111.
+The original introduction to literate programming with {\WEB}.
+\bibitem[Levy~87]{levy:cweb}
+Silvio Levy, ``Web Adapted to C, Another Approach'' {\sl TUGBoat}
+{\bf 8:2}(1987), 12--13.
+A short note about the C implementation of {\WEB}, from which Spidery
+{\WEB} is descended.
+\bibitem[Sewell~89]{sewell:weaving}
+Wayne Sewell, ``Weaving a program: Literate programming in {\tt
+WEB},''
+Van Nostrand Reinhold, 1989.
+\end{thebibliography}
+
+
+\end{document}
diff --git a/web/spiderweb/doc/spiderwebman.tex b/web/spiderweb/doc/spiderwebman.tex
new file mode 100644
index 0000000000..c512983ee1
--- /dev/null
+++ b/web/spiderweb/doc/spiderwebman.tex
@@ -0,0 +1,2268 @@
+% Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+% Not to be sold, but may be used freely for any purpose
+% For more information, see file COPYRIGHT in the parent directory
+
+\input webkernel % rank bravery; was webmac
+
+% macros for itemized lists
+\newcount\level
+\level=0
+
+\def\enum#1{\ifcase\the#1 x\or i\or ii\or iii\else iv\fi}
+\def\setenum{\edef\theenum{\csname enum\enum\level\endcsname}}
+
+
+\def\itemize{\begingroup\advance\level by1
+ \def\item{\par\noindent
+ \raise2pt\llap{$\scriptstyle\bullet$\ }}%
+ \par\advance\leftskip by2em\advance\rightskip by2em}
+\def\enditemize{\par\endgroup\noindent\ignorespaces}
+% end of stuff for itemized lists
+
+\parskip 0pt plus 1pt
+\def\RA{\char'31 } % right arrow
+\def\hang{\hangindent 4em\ignorespaces}
+\font\ninerm=cmr9
+\font\ninett=cmtt9
+\font\eighttt=cmtt8
+\let\mc=\ninerm % medium caps for names like SAIL
+\def\PASCAL{\newstuff ``X''\endnewstuff}
+\def\PAS{\newstuff X\endnewstuff} % used to mark file extensions
+\def\oP{{\sl \overline X}} % used in table of control sequences
+\font\quoterm=cmssq8
+\font\quoteit=cmssqi8
+\def\pb{\.{|...|}}
+\def\lpile{\def\cr{\hfill\endline}\matrix} % I only use \lpile by
+ % itself
+
+\def\newstuff{\begingroup\sl}
+\def\endnewstuff{\endgroup}
+
+\outer\def\section #1.{\penalty-50\vskip 12pt plus 3pt minus 3pt
+ \noindent{\bf #1.}\quad\ignorespaces}
+
+\def\titlepage{T}
+\def\lheader{\mainfont\the\pageno\hfill\sc\runninghead\hfill}
+\def\rheader{\hfill\sc\runninghead\hfill\mainfont\the\pageno}
+\def\runninghead{SPIDERY {\tentt WEB} USER MANUAL}
+
+% This verbatim mode assumed that no ? appears in the text being copied.
+\def\verbatim{\begingroup
+ \def\do##1{\catcode`##1=12 } \dospecials
+ \parskip 0pt \parindent 0pt
+ \catcode`\ =13 \catcode`\^^M=13
+ \tt \catcode`\?=0 \verbatimdefs \verbatimgobble}
+{\catcode`\^^M=13{\catcode`\ =13\gdef\verbatimdefs{\def^^M{\ \par}\let =\ }} %
+ \gdef\verbatimgobble#1^^M{}}
+
+\centerline{\titlefont The Spidery {\ttitlefont WEB} System
+ of Structured Documentation}
+
+\vskip 15pt plus 3pt minus 3pt
+\noindent
+\newstuff
+This memo describes how to write programs in the \.{WEB} language,
+using \.{WEB} systems generated by {Spider}.
+This class of \.{WEB} systems will be referred to (collectively) as
+``Spidery \.{WEB}.''
+Most of the material is taken verbatim from Donald Knuth's original
+memo introducing \.{WEB}; new material (like this paragraph) appears
+in slant type.
+Knuth's original memo is available as Stanford University CS technical
+ report number 980 (September 1983).
+Unlike Knuth's, this memo is not accompanied by the full \.{WEB}
+documentation for Spidery \.{WEAVE} and \.{TANGLE}, the programs that
+read \.{WEB} input and produce {\TeX} output and code, respectively.
+Nor does it contain the \.{WEB} documentation for {Spider}, the program that
+ generates the
+language-dependent parts of \.{WEAVE} and \.{TANGLE}.
+This memo should be accompanied by ``A {Spider} User's Guide,'' which
+explains how to use {Spider} to build a Spidery \.{WEB} system.
+\endnewstuff
+
+The philosophy behind \.{WEB} is
+that an experienced system programmer, who wants to provide the best
+possible documentation of his or her software products, needs two things
+simultaneously: a language like \TeX\ for formatting, and a language
+for programming.
+\newstuff For convenience, we'll give this programming language a
+name; let's call it the \PASCAL\ programming language.
+\endnewstuff
+Neither type of language can provide the best
+documentation by itself; but when both are appropriately combined, we
+obtain a system that is much more useful than either language
+separately.
+
+
+The structure of a software program may be thought of as a ``web'' that is
+made up of many interconnected pieces.
+To document such a program, we want
+to explain each individual part of the web and how it relates to its
+neighbors.
+The typographic tools provided by \TeX\ give us an opportunity
+to explain the local structure of each part by making that structure
+visible, and the programming tools provided by \PASCAL\ make it possible
+for us to specify the algorithms formally and unambiguously.
+By combining
+the two, we can develop a style of programming that maximizes our ability
+to perceive the structure of a complex piece of software, and at the same
+time the documented programs can be mechanically translated into a working
+software system that matches the documentation.
+
+Since \.{WEB} is an experimental system developed for internal use within
+the \TeX\ project at Stanford, this report is rather terse, and it assumes
+that the reader is an experienced programmer who is highly motivated to
+read a detailed description of \.{WEB}'s rules.
+{\newstuff Spidery \.{WEB} is also an experimental system and
+the same warning applies.\endnewstuff}
+\newstuff
+Before continuing, you may want to read some more introductory
+material on {Spider} and \.{WEB}.
+Here are some references worth looking at:
+\itemize
+\rm
+\item Donald E. Knuth, ``Literate Programming,'' {\sl Computer
+Journal} {\bf 27:2} (1984), 97--111..
+The original introduction of \.{WEB}.
+\item Jon L. Bentley, ``Programming Pearls,'' {\sl Communications of
+the ACM} {\bf 29:5} (May 1986), 364--368 and
+{\bf 29:6} (June 1986), 471--483.
+Two columns on literate programming with \.{WEB}.
+\item Norman Ramsey, ``Building a Language-Independent \.{WEB},''
+{\sl Communications of the ACM}, September 1989.
+An overview of how {Spider} and \.{WEB} work.
+\item
+Wayne Sewell, ``Weaving a program: Literate programming in \.{WEB},''
+Van Nostrand Reinhold, 1989.
+\enditemize
+In addition to these, there is a periodic column in the {\sl
+Communications of the ACM} devoted to literate programming.
+\endnewstuff
+
+Even if a
+less terse manual were to be written, the reader would have to be warned
+in advance that \.{WEB} is not for beginners and it never will be: The
+user of \.{WEB} must be familiar with both \TeX\ and \PASCAL.
+When one
+writes a \.{WEB} description of a software system, it is possible to make
+mistakes by breaking the rules of \.{WEB} and/or the rules of \TeX\ and/or
+the rules of \PASCAL.
+In practice, all three types of errors will occur,
+and you will get different error messages from the different language
+processors.
+In compensation for the sophisticated expertise needed to cope
+with such a variety of languages, however, experience has shown that
+reliable software can be created quite rapidly by working entirely in
+\.{WEB} from the beginning; and the documentation of such programs seems
+to be better than the documentation obtained by any other known method.
+Thus, \.{WEB} users need to be highly qualified, but they can get some
+satisfaction and perhaps even a special feeling of accomplishment when
+they have successfully created a software system with this method.
+
+To use \.{WEB}, you prepare a file called \.{COB.WEB} (say), and then you
+apply a system program called \.{WEAVE} to this file, obtaining an output
+file called \.{COB.TEX}.
+When \TeX\ processes \.{COB.TEX}, your output
+will be a ``pretty printed'' version of \.{COB.WEB} that takes appropriate
+care of typographic details like page layout and the use of indentation,
+italics, boldface, etc.; this output will contain extensive cross-index
+information that is gathered automatically.
+You can also submit the same
+file \.{COB.WEB} to another system program called \.{TANGLE}, which will
+produce a file \.{COB.\PAS} that contains the \PASCAL\ code of your \.{COB}
+program.
+The \PASCAL\ compiler will convert \.{COB.\PAS} into
+machine-language instructions corresponding to the algorithms that were so
+nicely formatted by \.{WEAVE} and \TeX.
+Finally, you can (and should)
+delete the files \.{COB.TEX} and \.{COB.\PAS}, because \.{COB.WEB} contains
+the definitive source code.
+Examples of the behavior of \.{WEAVE} and
+\.{TANGLE} are
+\newstuff
+not
+\endnewstuff
+appended to this manual.
+\newstuff
+The names {\tt WEAVE} and \.{TANGLE} may vary, especially since there
+may be versions for multiple languages.
+My site supports, in addition to the original \.{TANGLE},
+\.{CEETANGLE}, \.{AWKTANGLE}, and \.{ADATANGLE}.
+\endnewstuff
+
+Besides providing a documentation tool, \.{WEB} enhances the \PASCAL\
+language by providing a
+%rudimentary
+ macro capability together with the
+ability to permute pieces of the program text, so that a large system can
+be understood entirely in terms of small modules and their local
+interrelationships.
+The \.{TANGLE} program is so named because it takes a
+given web and moves the modules from their web structure into the order
+required by \PASCAL; the advantage of programming in \.{WEB} is that the
+algorithms can be expressed in ``untangled'' form, with each module
+explained separately.
+The \.{WEAVE} program is so named because it takes
+a given web and intertwines the \TeX\ and \PASCAL\ portions contained in
+each module, then it knits the whole fabric into a structured document.
+(Get it? Wow.)
+Perhaps there is some deep connection here with the fact
+that the German word for ``weave'' is ``{\it web\/}'', and the
+corresponding Latin imperative is ``{\it texe\/}''!
+
+It is impossible to list all of the related work that has influenced the
+design of \.{WEB}, but the key contributions should be mentioned
+here.\quad (1)~Myrtle Kellington, as executive editor for ACM
+publications, developed excellent typographic standards for the
+typesetting of Algol programs during the 1960s, based on the original
+designs of Peter Naur; the subtlety and quality of this influential work
+can be appreciated only by people who have seen what happens when other
+printers try to typeset Algol without the advice of ACM's copy
+editors.\quad(2)~Bill McKeeman introduced a program intended to automate
+some of this task [Algorithm 268, ``Algol~60 reference language editor,''
+{\sl CACM \bf8} (1965), 667--668]; and a considerable flowering of such
+programs has occurred in recent years [see especially Derek Oppen,
+``Prettyprinting,'' {\sl ACM TOPLAS \bf2} (1980), 465--483; G.~A.
+Rose and
+J.
+Welsh, ``Formatted programming languages,'' {\sl SOFTWARE Practice
+\char`\&\ Exper.\ \bf11} (1981), 651--669].\quad(3)~The top-down style of
+exposition encouraged by \.{WEB} was of course chiefly influenced by Edsger
+Dijkstra's essays on structured programming in the late 1960s.
+The less
+well known work of Pierre-Arnoul de Marneffe [``Holon programming: A
+survey,'' Univ.\ de Liege, Service Informatique, Liege, Belgium, 1973; 135
+pp.\null] also had a significant influence on the author as \.{WEB} was
+being formulated.\quad(4)~Edwin Towster has proposed a similar style of
+documentation in which the programmer is supposed to specify the relevant
+data structure environment in the name of each submodule [``A convention
+for explicit declaration of environments and top-down refinement of
+data,'' {\sl IEEE Trans.\ on Software Eng.\ \bf SE--5} (1979), 374--386];
+this requirement seems to make the documentation a bit too verbose,
+although experience with \.{WEB} has shown that any unusual control
+structure or data structure should definitely be incorporated into the
+module names on psychological grounds.\quad(5)~Discussions with Luis
+Trabb~Pardo in the spring of 1979 were extremely helpful for setting up a
+prototype version of \.{WEB} that was called \.{DOC}.\quad (6)~Ignacio
+Zabala's extensive experience with \.{DOC}, in which he created a full
+implementation of \TeX\ in {Pascal} that was successfully transported to
+many different computers, was of immense value while \.{WEB} was taking
+its present form.\quad(7)~David~R.
+Fuchs made several crucial suggestions
+about how to make \.{WEB} more portable; he and Arthur~L.
+Samuel
+coordinated the initial installations of \.{WEB} on dozens of computer
+systems, making changes to the code so that it would be acceptable to
+a wide variety of \.{Pascal} compilers.\quad(8)~The name \.{WEB} itself
+was chosen in honor of my wife's mother, Wilda Ernestine Bates.
+
+\newstuff
+The work on Spidery \.{WEB} would not have been possible without the
+help of Silvio Levy, who first ported \.{WEB} to C.
+The name {Spider} was chosen because (in nature at least) webs are
+built by spiders.
+\endnewstuff
+
+The appendices to this report
+\newstuff
+do not
+\endnewstuff
+contain complete \.{WEB} programs for the
+\newstuff {Spider}, \endnewstuff
+\.{WEAVE}, and \.{TANGLE} processors.
+A study of these examples, together
+with an attempt to write \.{WEB} programs by yourself, is the best way
+to understand why \.{WEB} has come to be like it is.
+
+\section General rules.
+A \.{WEB} file is a long string of text that has been divided into
+individual lines.
+\newstuff
+Unlike original {\tt WEB}, Spidery {\tt WEB} respects the programmer's
+choice of line breaks.
+A newline in code is normally passed along through tangle and will
+appear in the resulting program.
+This is important in languages like awk where line breaks are
+significant.
+In documentation,
+\endnewstuff
+the exact line boundaries are not terribly crucial, and
+a programmer can pretty much chop up the \.{WEB} file in whatever way seems
+to look best as the file is being edited; but string constants and control
+texts must end on the same line on which they begin, since this convention
+helps to keep errors from propagating.
+\newstuff
+The line length of the input is limited and is rather small.
+\endnewstuff
+% The end of a line means
+% the same thing as a blank space.
+
+Two kinds of material go into \.{WEB} files: \TeX\ text and \PASCAL\ text.
+A programmer writing in \.{WEB} should be thinking both of the
+documentation and of the \PASCAL\ program that he or she is creating;
+i.e., the programmer should be instinctively aware of the different
+actions that \.{WEAVE} and \.{TANGLE} will perform on the \.{WEB} file.
+\TeX\ text is essentially copied without change by \.{WEAVE}, and it is
+entirely deleted by \.{TANGLE}, since the \TeX\ text is ``pure
+documentation.''
+\PASCAL\ text, on the other hand, is formatted by
+\.{WEAVE} and it is shuffled around by \.{TANGLE}, according to rules that
+will become clear later.
+For now the important point to keep in mind is
+that there are two kinds of text.
+Writing \.{WEB} programs is something
+like writing \TeX\ documents, but with an additional ``\PAS\ mode''
+that is added to \TeX's horizontal mode, vertical mode, and math mode.
+
+A \.{WEB} file is built up from units called {\sl modules\/} that are more
+or less self-contained.
+Each module has three parts:
+
+\yskip\item{1)} A \TeX\ part, containing explanatory material about what
+is going on in the module.
+
+\item{2)} A definition part, containing macro definitions that serve as
+abbreviations for \PASCAL\ constructions that would be less comprehensible
+if written out in full each time.
+
+\item{3)} An \PASCAL\ part, containing a piece of the program that
+\.{TANGLE} will produce.
+This \PASCAL\ code should ideally be about a
+dozen lines long, so that it is easily comprehensible as a unit and so
+that its structure is readily perceived.
+
+\yskip\noindent The three parts of each module must appear in this order;
+i.e., the \TeX\ commentary must come first, then the definitions, and
+finally the \PASCAL\ code.
+Any of the parts may be empty.
+
+A module begins with the pair of symbols `\.{@\ }' or `\.{@*}', where
+`\.{\ }' denotes a blank space.
+A module ends
+at the beginning of the next module (i.e., at the next
+`\.{@\ }' or `\.{@*}'), or at the end of the file, whichever comes first.
+The \.{WEB} file may also contain material that is not part of any module
+at all, namely the text (if any) that occurs before the first module.
+Such text is said to be ``in limbo''; it is ignored by \.{TANGLE}
+and copied essentially verbatim by \.{WEAVE}, so its function is to
+provide any additional formatting instructions that may be desired in the
+\TeX\ output.
+Indeed, it is customary to begin a \.{WEB} file with
+\TeX\ code in limbo that loads special fonts, defines special macros,
+changes the page sizes, and/or produces a title page.
+
+Modules are numbered consecutively, starting with 1; these numbers appear
+at the beginning of each module of the \TeX\ documentation, and they appear
+as bracketed comments at the beginning of the code generated by that
+module in the \PASCAL\ program.
+
+Fortunately, you never mention these numbers yourself when you are writing
+in \.{WEB}.
+You just say `\.{@\ }' or `\.{@*}' at the beginning of each
+new module, and the numbers are supplied automatically by \.{WEAVE} and
+\.{TANGLE}.
+As far as you are concerned, a module has a
+name instead of a number; such a name is specified by writing
+`\.{@<}' followed by \TeX\ text followed by `\.{@>}'.
+When \.{WEAVE}
+outputs a module name, it replaces the `\.{@<}' and `\.{@>}' by
+angle brackets and inserts the module number in small type.
+Thus, when you
+read the output of \.{WEAVE} it is easy to locate any module that is
+referred to in another module.
+
+\newstuff
+Spidery {\tt WEB} supports a new kind of module called a ``file
+module.''
+File modules open with \.{@(} instead of \.{@<}, and the module name
+ is taken to be the name of a file to which \.{TANGLE} will write the
+contents of the module.
+When \.{WEAVE}
+outputs a file module name, it replaces the `\.{@(}' and `\.{@>}' by
+parentheses and sets the entire name in {\tt typewriter} font.
+\endnewstuff
+
+
+For expository purposes, a module name should be a good description of the
+contents of that module, i.e., it should stand for the abstraction
+represented by the module; then the module can be ``plugged into'' one or
+more other modules so that the unimportant details of its inner workings
+are suppressed.
+A module name therefore ought to be long enough to convey
+the necessary meaning.
+Unfortunately, however, it is laborious to type
+such long names over and over again, and it is also difficult to specify a
+long name twice in exactly the same way so that \.{WEAVE} and \.{TANGLE}
+will be able to match the names to the modules.
+Therefore a module name
+can be abbreviated after its first appearance in the \.{WEB} file, by
+typing `\.{@<$\alpha$...@>}', where $\alpha$ is any string that is a prefix of
+exactly one module name that appears in the file.
+For example, `\.{@<Clear
+the arrays@>}' can be abbreviated to `\.{@<Clear...@>}' if no other module
+name begins with the five letters `\.{Clear}'.
+Module names must otherwise
+match character for character, except that consecutive blank spaces and/or
+tab marks are treated as equivalent to single spaces, and such spaces are
+deleted at the beginning and end of the name.
+Thus, `\.{@< Clear { }the
+arrays @>}' will also match the name in the previous example.
+
+We have said that a module begins with `\.{@\ }' or `\.{@*}', but we
+didn't say how it gets divided up into a \TeX\ part, a definition part,
+and an \PASCAL\ part.
+The definition part begins with the first appearance
+of `\.{@d}' or `\.{@f}' in the module, and the \PASCAL\ part begins with
+the first appearance of `\.{@u}', `\.{@<}',
+\newstuff or `\.{@(}'.\endnewstuff
+The
+%latter
+ options `\.{@<}' \newstuff and `\.{@(}'.\endnewstuff
+stand for the beginning of a module name, which is the name of the module
+itself.
+An equals sign (\.=) must follow the `\.{@>}' at the end of this
+module name; you are saying, in effect, that the module name stands for
+the \PASCAL\ text that follows, so you say `$\langle\,$module
+name$\,\rangle=\null$\PASCAL\ text'.
+Alternatively, if the \PASCAL\ part
+begins with `\.{@u}' instead of a module name, the current module is said
+to be {\sl unnamed}.
+Note that module names cannot appear in the
+definition part of a module, because the first `\.{@<}' \newstuff or
+`\.{@(}'.\endnewstuff in a module
+signals the beginning of its \PASCAL\ part.
+Any number of module names
+might appear in the \PASCAL\ part, however, once it has started.
+
+The general idea of \.{TANGLE} is to make an \PASCAL\ program out of these
+modules in the following way: First all the \PASCAL\ parts of unnamed
+modules are copied down, in order; this constitutes the initial
+approximation $T_0$ to the text of the program.
+(There should be at least
+one unnamed module, otherwise
+\newstuff unless there are file modules \endnewstuff
+there will be no program.) Then all module
+names that appear in the initial text $T_0$ are replaced by the \PASCAL\
+parts of the corresponding modules, and this substitution process
+continues until no module names remain.
+Then all defined macros are
+replaced by their equivalents, according to certain rules that are
+explained later.
+%The resulting \PASCAL\ code is ``sanitized'' so that it
+%will be acceptable to an average garden-variety \PASCAL\ compiler; i.e.,
+%lowercase letters are converted to uppercase, long identifiers are
+%chopped, and the lines of the output file are constrained to be at most 72
+%characters long.
+All comments will have been removed from this \PASCAL\
+program except for the meta-comments delimited by `\.{@\{}' and
+`\.{@\}}', as explained below, and except for the module-number comments
+that point to the source location where each piece of the program text
+originated in the \.{WEB} file.
+\newstuff
+Spidery {\tt WEB} does not support the use of the meta-comments
+ `\.{@\{}' and `\.{@\}}'.
+Their absence can be partially compensated for by clever use of the
+``verbatim'' control sequence `\.{@=...@>}'.
+\endnewstuff
+
+Incidentally, module numbers are automatically inserted
+as meta-comments into the \PASCAL\ program, in order to help correlate the
+outputs of \.{WEAVE} and \.{TANGLE} (see Appendix~C\null).
+\newstuff So are {\tt\#line} directives, the exact workings of which
+are obscure (but see the ``{Spider} User's Guide'' for more information).
+\endnewstuff
+
+If the same name has been given to more than one module, the \PASCAL\ text
+for that name is obtained by putting together all of the \PASCAL\ parts in
+the corresponding modules.
+This feature is useful, for example, in a
+module named `Global variables in the outer block', since one can then
+declare global variables in whatever modules those variables are
+introduced.
+When several modules have the same name, \.{WEAVE} assigns the
+first module number as the number corresponding to that name, and it
+inserts a note at the bottom of that module telling the reader to `See
+also sections so-and-so'; this footnote gives the numbers of all the other
+modules having the same name as the present one.
+The \PASCAL\ text
+corresponding to a module is usually formatted by \.{WEAVE} so that the
+output has an equivalence sign in place of the equals sign in the \.{WEB}
+file; i.e., the output says `$\langle\,$module
+name$\,\rangle\equiv\null$\PASCAL\ text'.
+However, in the case of the second
+and subsequent appearances of a module with the same name, this `$\equiv$'
+sign is replaced by `$\mathrel+\equiv$', as an indication that the \PASCAL\
+text that follows is being appended to the \PASCAL\ text of another
+module.
+
+
+The general idea of \.{WEAVE} is to make a \.{TEX} file from the \.{WEB}
+file in the following way: The first line of the \.{TEX} file will be
+`\.{\\input \PAS web}'; this will cause \TeX\ to read in the macros that
+define \.{WEB}'s documentation conventions
+\newstuff
+for the \PASCAL\ programming language.
+\endnewstuff
+The next lines of the file
+will be copied from whatever \TeX\ text is in limbo before the first
+module.
+Then comes the output for each module in turn, possibly
+interspersed with end-of-page marks.
+Finally, \.{WEAVE} will generate a
+cross-reference index that lists each module number in which each \PASCAL\
+identifier appears, and it will also generate an alphabetized list
+of the module names, as well as a table of contents that
+shows the page and module numbers for each ``starred'' module.
+
+What is a ``starred'' module, you ask?
+A module that begins with `\.{@*}'
+instead of `\.{@\ }' is slightly special in that it denotes a new major
+group of modules.
+The `\.{@*}' should be followed by the title of this
+group, followed by a period.
+Such modules will always start on a new page
+in the \TeX\ output, and the group title will appear as a running headline
+on all subsequent pages until the next starred module.
+The title will also
+appear in the table of contents, and in boldface type at the beginning of
+its module.
+
+\newstuff
+Spidery {\tt WEB} supports a hack that makes the module structure
+appear more hierarchical in the table of contents.
+If the title begins with the special character {\tt =}, or one of the
+digits {\tt 1}~through~{\tt 4}, it will be formatted specially.
+This table shows the effect of the special titles:
+\medskip
+{
+\tabskip=0pt plus 1fil
+\noindent\halign to \hsize{\strut\tt#\hfil
+\tabskip=2em&#\hfil&\hfil #\hfil&#\hfil\tabskip=0pt plus 1fil\cr
+\bf Marker&\bf Level&\bf Page Eject?&\bf Other\cr
+\noalign{\smallskip}
+@*=&chapter&yes&Bold in toc\cr
+@*&section&yes\cr
+@*1&subsection&yes\cr
+@*2&subsection&no\cr
+@*3&subsubsection&yes\cr
+@*4&subsubsection&no\cr
+}
+}
+\medskip
+\endnewstuff
+
+Caution: Do not use \TeX\ control sequences in such titles,
+unless you know that the \.{webmac} macros will do the right thing with
+them.
+The reason is that these titles are converted to uppercase when
+they appear as running heads, and they are converted to boldface when they
+appear at the beginning of their modules, and they are also written out to
+a table-of-contents file used for temporary storage while \TeX\ is
+working; whatever control sequences you use must be meaningful in all
+three of these modes.
+
+\newstuff
+Second caution:
+do not allow the titles to begin with a non-letter, unless the
+non-letter is the control sequence \.{\\relax}.
+The reason is that the first character of the titles is checked to see
+whether it is the special character {\tt =}, or one of the
+digits {\tt 1}~through~{\tt 4}.
+A non-letter that is not one of these will only confuse the formatter.
+\endnewstuff
+
+The \TeX\ output produced by \.{WEAVE} for each module consists of
+the following: First comes the module number (e.g., `\.{\\M123.}'
+at the beginning of module 123, except that `\.{\\N}' appears in place of
+`\.{\\M}' at the beginning of a starred module).
+Then comes the
+\TeX\ part of the module, copied almost verbatim except as noted
+below.
+Then comes the definition part and the \PASCAL\ part, formatted
+so that there will be a little extra space between them if both are
+nonempty.
+The definition and \PASCAL\ parts are obtained by inserting
+a bunch of funny looking \TeX\ macros into the \PASCAL\ program; these
+macros handle typographic details about fonts and proper math spacing,
+as well as line breaks and indentation.
+
+When you are typing \TeX\ text, you will probably want to make frequent
+reference to variables and other quantities in your \PASCAL\ code, and you
+will want those variables to have the same typographic treatment
+when they appear in your text as when they appear in your
+program.
+Therefore the \.{WEB} language allows you to get the effect of
+\PASCAL\ editing within \TeX\ text, if you place `\.|' marks before and
+after the \PASCAL\ material.
+For example, suppose
+\newstuff
+you are writing Pascal code and
+\endnewstuff
+you want to say something
+like this:
+$$\hbox{The characters are placed into \\{buffer}, which is a
+\&{packed} \&{array} $[1\to\|n]$ \&{of} \\{char}.}$$
+The \TeX\ text would look like this in your \.{WEB} file:
+$$\.{The characters are placed into |buffer|, which is a |packed
+array [1..n] of char|.}$$
+And \.{WEAVE} translates this into something you are glad you didn't have
+to type:
+$$\lpile{\.{The characters are placed into \\\\\{buffer\},}\cr
+ \.{which is a \\\&\{packed\}{ }\\\&\{array\}{ }\$
+ [1\\to\\|n]\${ }\\\&\{of\}{ }\\\\\{char\}.}\cr}$$
+Incidentally, the cross-reference index that \.{WEAVE} would make, in
+the presence of a comment like this, would include
+the current module number as one of the index entries for \\{buffer}
+and \\{char}, even though \\{buffer} and \\{char}
+might not appear in the \PASCAL\ part of
+this module.
+Thus, the index covers references to identifiers in
+the explanatory comments as well as in the program itself; you will
+soon learn to appreciate this feature.
+However, the identifiers
+\&{packed} and \&{array} and \|n\ and \&{of\/} would not be indexed,
+because \.{WEAVE} does not make index entries for reserved words or
+single-letter identifiers.
+Such identifiers are felt to be so ubiquitous
+that it would be pointless to mention every place where they occur.
+
+Speaking of identifiers, the author of \.{WEB} thinks that
+\\{IdentifiersSeveralWordsLong} look terribly ugly when they mix
+uppercase and lowercase letters.
+He recommends that
+\\{identifiers\_several\_words\_long} be written with underline characters
+to get a much better effect.
+%The actual identifiers sent to the \PASCAL\
+%compiler by \.{TANGLE} will have such underlines removed, and \.{TANGLE}
+%will check to make sure that two different identifiers do not become
+%identical when this happens.
+%(In fact, \.{TANGLE} even checks that
+%the first seven characters of identifiers are unique, when lowercase
+%letters have been converted to uppercase; the number seven in this
+%constraint is more strict than \PASCAL's eight, and it can
+%be changed if desired.)
+The \.{WEAVE} processor will properly
+alphabetize identifiers that have embedded underlines
+when it makes the index.
+\newstuff
+Using Spidery \.{WEB}, you're out of luck if programming language
+\PASCAL\ doesn't support underlines in identifiers.
+\endnewstuff
+
+Although a module begins with \TeX\ text and ends with \PASCAL\ text, we
+have noted that the dividing line isn't sharp, since \PASCAL\ text can be
+included in \TeX\ text if it is enclosed in `\pb'.
+Conversely, \TeX\ text
+also appears frequently within \PASCAL\ text, because everything in
+\PASCAL\ comments is treated as \TeX\ text.
+Furthermore, a module name consists of \TeX\ text; thus, a \.{WEB} file
+typically involves constructions like `\.{if} \.x \.= \.0 \.{then}
+\.{@<Empty} \.{the} \.{|buffer|} \.{array@>}' where we go back and forth
+between \PASCAL\ and \TeX\ conventions in a natural way.
+
+\section Macros.
+\newstuff
+In the current implementation of Spidery \.{WEB}, a \.{WEB} programmer
+can define two kinds of macros to make the programs shorter and more
+readable.
+
+\yskip\hang`\.{@d} \\{identifier} \.{=} \PASCAL\ text' defines a {\sl
+simple\/} macro, where the identifier will be replaced by the \PASCAL\ text
+when \.{TANGLE} produces its output.
+
+\yskip\hang`\.{@d} \\{identifier} \.{(}\\{formal parameters}\.{)}
+\.{=} \PASCAL\ text' defines a
+{\sl parametric\/} macro, where the identifier will be replaced by the
+\PASCAL\
+text and where occurrences of the \\{formal parameters} in that
+\PASCAL\ text will be replaced by arguments.
+For C programmers, this is similar to the C macro processor, but
+the \.{=} sign is used to avoid the need for bizarre lexical
+requirements.
+Whitespace can appear between a macro name and a list of formal
+paramters, and newlines in macros need not be escaped with
+backslashes.
+A macro definition is terminated by a following \.{@d}, \.{@f},
+\.{@u}, \.{@<}, or \.{@(}.
+\endnewstuff
+
+
+
+
+%A \.{WEB} programmer can define three kinds of macros to make the programs
+%shorter and more readable:
+%
+%\yskip\hang`\.{@d} \\{identifier} \.= \\{constant}' defines a {\sl numeric\/}
+%macro, allowing \.{TANGLE} to do rudimentary arithmetic.
+%
+%\yskip\hang`\.{@d} \\{identifier} \.{==} \PASCAL\ text' defines a {\sl
+%simple\/} macro, where the identifier will be replaced by the \PASCAL\ text
+%when \.{TANGLE} produces its output.
+%
+%\yskip\hang`\.{@d} \\{identifier}\.{(\#) ==} \PASCAL\ text' defines a
+%{\sl parametric\/} macro, where the identifier will be replaced by the \PASCAL\
+%text and where occurrences of \.{\#} in that \PASCAL\ text will be
+%replaced by an argument.
+%
+%\yskip\noindent In all three cases, the identifier must have length greater
+%than one; it must not be a single letter.
+%Furthermore, the identifier must
+%be making its first appearance in the \.{WEB} file; a macro must be defined
+%before it is used.
+%
+%Numeric macros are subject to the following restrictions:\quad
+%(1)~The right-hand side of the numeric definition must be made entirely from
+%integer constants, numeric macros, preprocessed strings (see below), and
+%plus~signs or minus signs.
+%No other operations or symbols are allowed,
+%not even parentheses, except that \PASCAL-like comments (enclosed in
+%braces) can appear.
+%Indeed, comments are recommended, since it is usually
+%wise to give a brief explanation of the significance of each identifier as
+%it is defined.\quad
+%(2)~The numeric value must be less than $2^{15}=32768$ in absolute value.
+%(For larger values, you can use `\.{==}' in place of~`\.=', thus making use
+%of a simple macro instead of a numeric one.
+%Note, however, that simple
+%macros sometimes have a different effect.
+%For example, consider the three
+%definitions `\.{@d n1=2 @d n2=2+n1 @d n3==2+n1}'; then `\.{x-n2}' will
+%expand into `\.{x-4}', while `\.{x-n3}' will expand into `\.{x-2+2}' which
+%is quite different! It is wise to include parentheses in non-numeric
+%macros, e.g., `\.{@d n3==(2+n1)}', to avoid such errors.)
+%
+%When constants are connected by plus signs or minus
+%signs in an \PASCAL\ program, \.{TANGLE} does the arithmetic before putting
+%the constant into the output file.
+%Therefore it is permissible to say, for
+%example, `\&{array} $[0\,.\,.\,\\{size}-1]$' if \\{size} has been declared
+%as a macro; note that \PASCAL\ doesn't allow this kind of compile-time
+%arithmetic if \\{size} is a \&{constant} quantity in the program.
+%Another
+%use of \.{TANGLE}'s arithmetic is to make \&{case} statement labels such
+%as `$\\{flag}+1$' legitimate.
+%Of course, it is improper to change \.{2+2}
+%into \.4 without looking at the surrounding context; many counterexamples
+%exist, such as the phrases `\.{-2+2}', `\.{x/2+2}', and `\.{2+2E5}'.
+%The
+%program for \.{TANGLE}, in the appendix, gives precise details about this
+%conversion, which \.{TANGLE} does only when it is safe.
+%
+%The right-hand sides of simple and parametric macros
+%are required to have balanced parentheses, and the \PASCAL\ texts of
+%modules must have balanced parentheses too.
+%Therefore when the argument
+%to a para\-metric macro appears in parentheses, both parentheses
+%will belong to the same \PASCAL\ text.
+%
+%The appendices to this report contain hundreds of typical examples of the
+%usefulness of \.{WEB} macros, so it is not necessary to dwell on the
+%subject here.
+%However, the reader should know that \.{WEB}'s apparently
+%primitive macro capabilities can actually do a lot of rather surprising
+%things.
+%Here is a construction that sheds further light on what is
+%possible: After making the definitions
+%$$\catcode`\#=12
+%\lpile{\.{@d two\_cases(#)==case j of 1:#(1); 2:#(2); end}\cr
+%\.{@d reset\_file(#)==reset(input\_file@\&#)}\cr}$$
+%one can write `\.{two\_cases(reset\_file)}' and the resulting \PASCAL\
+%output will be
+%$$\.{case j of 1:reset(input\_file1); 2:reset(input\_file2); end}$$
+%(but in uppercase letters and with \.\_'s removed).
+%The `\.{@\&}' operation used here joins together two adjacent tokens
+%into a single token, as explained later; otherwise the \PASCAL\ file would
+%contain a space between \.{input\_file} and the digit that followed it.
+%This trick can be used to provide the effect of an array of files, if you
+%are unfortunate enough to have a \PASCAL\ compiler that doesn't allow such
+%arrays.
+%Incidentally, the cross-reference index made by \.{WEAVE} from
+%this example would contain the identifier \\{input\_file} but it would not
+%contain \\{input\_file1} or \\{input\_file2}.
+%Furthermore, \.{TANGLE}
+%would not catch the error that \.{INPUTFILE1} and \.{INPUTFILE2} both
+%begin with the same nine letters; one should be more careful when using
+%`\.{@\&}'! But such aspects of the construction in this trick are
+%peripheral to our main point, which is that a parametric macro name without
+%arguments can be used as an argument to another parametric macro.
+%
+%Although \.{WEB}'s macros are allowed to have at most one parameter, the
+%following example shows that this is not as much of a restriction as it
+%may seem at first.
+%Let \\{amac} and \\{bmac} be any parametric macros, and
+%suppose that we want to get the effect of
+%$$\catcode`\#=12
+%\.{@d cmac(#1,#2) == amac(#1) bmac(#2)}$$
+%which \.{WEB} doesn't permit.
+%The solution is to make the definitions
+%$$\catcode`\#=12
+%\lpile{\.{@d cmac(#) == amac(#) dmac}\cr
+%\.{@d dmac(#) == bmac(#)}\cr}$$
+%and then to say `\.{cmac(x)(y)}'.
+%
+%There is one restriction in the generality of \.{WEB}'s parametric
+%macros, however: the argument to a para\-metric macro must not come from
+%the expansion of a macro that has not already been ``started.'' For
+%example, here is one of the things \.{WEB} cannot handle:
+%$$\catcode`\#=12
+%\lpile{\.{@d arg == (p)}\cr
+%\.{@d identity(#) == #}\cr
+%\.{@p identity arg}\cr}$$
+%In this case \.{TANGLE} will complain that the \.{identity} macro is not
+%followed by an argument in parentheses.
+
+%The \.{WEB} language has another feature that is somewhat similar to a
+%numeric macro.
+%A {\sl preprocessed string\/} is a string that is like
+%a \PASCAL\ string but delimited by double-quote marks (\.") instead of
+%single-quotes.
+%Double-quote marks inside of such strings are indicated by
+%giving two double-quotes in a row.
+%If a preprocessed string is
+%of length one (e.g., \.{"A"} or \.{""""}), it will be treated by \.{TANGLE}
+%as equivalent to the corresponding ASCII-code integer (e.g., \.{65} or
+%\.{34}).
+%And if a preprocessed string is not of length one, it will be
+%converted into an integer equal to 128 or more.
+%A {\sl string pool\/}
+%containing all such strings will be written out by the \.{TANGLE}
+%processor; this string pool file consists of string 128, then string 129,
+%etc., where each string is followed by an end-of-line and prefixed by two
+%decimal digits that define its length.
+%Thus, for example, the empty string
+%\.{""} would be represented in the string pool file by a line containing
+%the two characters `\.{00}', while the string \.{"""String"""} would be
+%represented by `\.{08"String"}'.
+%A given string appears at most once in
+%the string pool; the use of such a pool makes it easier to cope with
+%\PASCAL's restrictions on string manipulation.
+%The string pool ends with
+%`\.{*nnnnnnnnn}', where \.{nnnnnnnnn} is a decimal number
+%called the {\sl string pool check sum}.
+%If any string changes, the check
+%sum almost surely changes too; thus, the `\.{@\$}' feature
+%described below makes it possible for a program to assure itself that it
+%is reading its own string pool.
+%
+%Here is a simple example that combines numeric macros with preprocessed
+%strings of length one:
+%$$\lpile{\.{@d upper\_case\_Y = "Y"}\cr
+%\.{@d case\_difference = -"y"+upper\_case\_Y}\cr}$$
+%The result is to define
+%$\\{upper\_case\_Y}=89$, $\\{case\_difference}=-32$.
+
+\newstuff
+Spidery \.{WEB} does not support a string pool file.
+Pleas for its restoration will be heard.
+\endnewstuff
+
+\section Control codes.
+We have seen several magic uses of `\.{@}' signs in \.{WEB} files, and it
+is time to make a systematic study of
+these special features.
+A \.{WEB} {\sl control code\/}
+is a two-character combination of which the first is `\.@'.
+\newstuff
+In Spidery \.{WEB} the ``magic at sign'' need not be `\.@'; the person
+who built your \.{WEB} (with {Spider}) may have defined it to be
+something else.
+By convention, people building Spidery {\tt WEB}s
+ use `\.@' as the magic at sign, except when it is
+deemed unsuitable for some reason, in which case
+ cases they use `\.\#'.
+\endnewstuff
+
+Here is a complete list of the legal control codes.
+The letters $L$, $T$,
+$\PAS$, $M$, $C$, and/or $S$ following each code indicate whether or not that
+code is allowable in limbo, in \TeX\ text, in \PASCAL\ text, in module
+names, in comments, and/or in strings.
+A bar over such a letter means
+that the control code terminates the present part of the \.{WEB} file; for
+example, $\overline L$ means that this control code ends the limbo material
+before the first module.
+
+\def\@#1[#2] {\yskip\hangindent 2em\noindent\.{@#1\unskip
+ \spacefactor1000{ }}$[#2]$\quad}
+\def\oT{\overline T}
+
+\@@ [C,L,M,\PAS,S,T] A double \.@ denotes the single character `\.@'.
+This is
+the only control code that is legal in limbo, in comments, and in strings.
+
+\@i [L,T]
+\newstuff
+The \.{@i} control code should always be followed by a file name and a
+newline.
+It causes the file to be included at the current point in the
+\.{WEB} source, just like the C \.{\#include} facility.
+\endnewstuff
+
+\@\ [\overline L,\oP,\oT] This denotes the beginning of a new
+(unstarred) module.
+A tab mark or end-of-line (carriage return)
+is equivalent to a space when it follows an \.@ sign.
+
+\@* [\overline L,\oP,\oT] This denotes the beginning of a new starred
+module, i.e., a module that begins a new major group.
+The title of the new
+group should appear after the \.{@*}, followed by a period.
+\newstuff
+As explained above, the first character of the title should be either
+a letter or the control sequence \.{\\relax}, unless special
+formatting is desired.
+Titles beginning with \.=, \.1, \.2, \.3, or \.4 are formatted
+specially.
+\endnewstuff
+As explained
+above, \TeX\ control sequences should be avoided in such titles unless
+they are quite simple.
+When \.{WEAVE} and \.{TANGLE} read a \.{@*}, they
+print an asterisk followed by the current module number, so that the user
+can see some indication of progress.
+The very first module should be starred.
+
+\@d [\oP,\oT] Macro definitions begin with \.{@d} (or \.{@D}), followed by
+the \PASCAL\ text for one of the three kinds of macros, as explained
+earlier.
+
+\@f [\oP,\oT] Format definitions begin with \.{@f} (or \.{@F}); they cause
+\.{WEAVE} to treat identifiers in a special way when they appear in
+\PASCAL\ text.
+The general form of a format definition is `\.{@f} \|l %\.{=}
+\|r', followed by an optional comment enclosed in braces, where \|l and \|r
+are identifiers; \.{WEAVE} will subsequently treat identifier \|l as it
+currently treats \|r.
+This feature allows a \.{WEB} programmer to invent
+new reserved words and/or to unreserve some of \PASCAL's reserved
+identifiers.
+\newstuff
+It is offensive that the syntax is different from the \.{2d} syntax,
+but it is that way for historical reasons (to avoid invalidating
+existing code.
+\endnewstuff
+The definition part of each module consists of any number of
+macro definitions (beginning with \.{@d}) and format definitions (beginning
+with \.{@f}), intermixed in any order.
+
+
+\@u [\oP,\oT] \newstuff
+The \PASCAL\ part of an unnamed module begins with \.{@u}
+(or \.{@U}).
+\endnewstuff
+This causes \.{TANGLE} to append the following \PASCAL\ code
+to the initial program text $T_0$ as explained above.
+The \.{WEAVE}
+processor does not cause a `\.{@u}' to appear explicitly in the \TeX\
+output, so if you are creating a \.{WEB} file based on a \TeX-printed
+\.{WEB} documentation you have to remember to insert \.{@u} in the
+appropriate places of the unnamed modules.
+
+\@< [\PAS,\oT] A module name begins with \.{@<} followed by \TeX\ text followed
+by \.{@>}; the \TeX\ text should not contain any \.{WEB} control sequences
+except \.{@@}, unless these control sequences appear in \PASCAL\ text that
+is delimited by \pb.
+The module name may be abbreviated, after its first
+appearance in a \.{WEB} file, by giving any unique prefix followed by \.{...},
+where the three dots immediately precede the closing \.{@>}.
+Module names may
+not appear in \PASCAL\ text that is enclosed in \pb, nor may they appear
+in the definition part of a module (since the appearance of a module name
+ends the definition part and begins the \PASCAL\ part).
+
+
+\@( [\PAS,\oT] \newstuff A module beginning
+with \.{@(} is treated like one beginning with \.{@<},
+except that the module name is treated as the name of a file to which
+the module will be written.
+If such modules are used in other modules the results are undefined.
+\endnewstuff
+
+\@\' [\PAS,T] This denotes an octal constant, to be formed from the
+succeeding digits.
+For example, if the \.{WEB} file contains `\.{@\'100}',
+the \.{TANGLE} processor will treat this an equivalent to `\.{64}';
+the constant will be formatted as ``\O{\~100}'' in the \TeX\ output
+produced via \.{WEAVE}.
+You should use octal notation only for positive
+constants; don't try to get, e.g., $-1$ by saying `\.{@\'777777777777}'.
+
+\@" [\PAS,T] A hexadecimal constant; `\.{@"D0D0}' tangles to \.{53456} and
+weaves to `\O{\^D0D0}'.
+
+%\@\$ [\PAS] This denotes the string pool check sum.
+
+%\@\{ [\PAS] The beginning of a ``meta comment,'' i.e., a comment
+%that is supposed to appear in the \PASCAL\ code, is indicated by
+%\.{@\{} in the \.{WEB} file.
+%Such delimiters can be used as
+%isolated symbols in macros or modules, but they should be properly nested
+%in the final \PASCAL\ program.
+%The \.{TANGLE} processor will convert
+%`\.{@\{}' into `\.\{' in the \PASCAL\ output file, unless
+%the output is already part of a meta-comment; in the latter case
+%`\.{@\{}' is converted into `\.[', since
+%we don't assume that \PASCAL\ allows
+%nested comments.
+%Meta-comments
+%can be used to put conditional text into an \PASCAL\ program; this helps to
+%overcome one of the limitations of \.{WEB}, since the simple macro
+%processing routines of \.{TANGLE} do not include the dynamic evaluation of
+%boolean expressions.
+%\newstuff
+%Where is this trick explained, and note that it only works in
+%languages whose comments don't end with newline.
+%\endnewstuff
+%
+%\@\} [\PAS] The end of a ``meta comment'' is indicated by `\.{@\}}'; this is
+%converted either into `\.\}' or `\.{]}' in the \PASCAL\ output, according
+%to the conventions explained for \.{@\{} above.
+
+\@\& [\PAS] The \.{@\&} operation causes whatever is on its left to be
+adjacent to whatever is on its right, in the \PASCAL\ output.
+No spaces or
+line breaks will separate these two items.
+However, the thing on the left
+should not be a semicolon, since a line break might occur after a semicolon.
+
+\@\^ [\PAS,T] The ``control text'' that follows, up to the next
+`\.{@>}', will be entered into the index together with the identifiers of
+the \PASCAL\ program; this text will appear in roman type.
+For example, to
+put the phrase ``system dependencies'' into the index, you can type
+`\.{@\^system dependencies@>}' in each module
+that you want to index as system dependent.
+A control text, like a string,
+must end on the same line of the \.{WEB} file as it began.
+Furthermore,
+no \.{WEB} control sequences are allowed in a control text, not even
+\.{@@}.
+(If you need an \.{@} sign you can get around this restriction by
+typing `\.{\\AT!}'.)
+
+\@.
+[\PAS,T] The ``control text'' that follows will be entered into the index
+in \.{typewriter} \.{type}; see the rules for `\.{@\^}', which is analogous.
+
+\@: [\PAS,T] The ``control text'' that follows will be entered into the index
+in a format controlled by the \TeX\ macro `\.{\\9}', which the user
+should define as desired; see the rules for `\.{@\^}', which is analogous.
+
+\@t [\PAS] The ``control text'' that follows, up to the next `\.{@>}', will
+be put into a \TeX\ \.{\\hbox} and formatted along with the neighboring
+\PASCAL\ program.
+This text is ignored by \.{TANGLE}, but it can be used
+for various purposes within \.{WEAVE}.
+For example, you can make comments
+that mix \PASCAL\ and classical mathematics, as in `$\\{size}<2^{15}$', by
+typing `\.{|size < @t\$2\^\{15\}\$@>|}'.
+A control text must end on the
+same line of the \.{WEB} file as it began, and it may not contain any
+\.{WEB} control codes.
+
+\@= [\PAS] The ``control text'' that follows, up to the next `\.{@>}', will
+be passed verbatim to the \PASCAL\ program.
+
+%%% \@\\ [\PAS] Force end-of-line here in the \PASCAL\ program file.
+
+\@! [\PAS,T] The module number in an index entry will be underlined if `\.{@!}'
+immediately precedes the identifier or control text being indexed.
+This
+convention is used to distinguish the modules where an identifier is
+defined, or where it is explained in some special way, from the modules
+where it is used.
+A~reserved word or an identifier of length one will not
+be indexed except for underlined entries.
+%An `\.{@!}' is implicitly inserted
+%by \.{WEAVE} just after the reserved words \&{function}, \&{procedure},
+%\&{program}, and \&{var}, and just after \.{@d} and \.{@f}.
+%But you should
+%insert your own `\.{@!}' before the definitions of types, constants,
+%variables, parameters, and components of records and enumerated types that
+%are not covered by this implicit convention, if you want to improve the
+%quality of the index that you get.
+\newstuff
+Some Spidery \.{WEAVE}s will insert implicit `\.{@!}' tokens in places
+like function definitions or variable declarations.
+The person who built your Spidery \.{WEB} should have documented these
+places; if not, they can be discovered by examing the {\tt .spider}
+file.
+The automatic definitions work well for some languages, but
+for the best possible index you should insert your own `\.{@!}' token before
+the defining instance of every identifier.
+\endnewstuff
+
+\@?
+[\PAS,T] This cancels an implicit (or explicit) `\.{@!}', so that the next
+index entry will not be underlined.
+\newstuff This is not implemented in the current version of Spidery \.{WEB}.
+\endnewstuff
+
+\@, [\PAS] This control code inserts a thin space in \.{WEAVE}'s output; it is
+ignored by \.{TANGLE}.
+Sometimes you need this extra space if you are using
+macros in an unusual way, e.g., if two identifiers are adjacent.
+
+\@/ [\PAS] This control code causes a line break to occur within an \PASCAL\
+program formatted by \.{WEAVE}; it is ignored by \.{TANGLE}.
+Line breaks
+are chosen automatically by \TeX\ according to a scheme that works 99\%\
+of the time, but sometimes you will prefer to force a line break so that
+the program is segmented according to logical rather than visual criteria.
+\newstuff
+The line following such a line break is indented at the same level as
+the line broken.
+\endnewstuff
+Caution: `\.{@/}' should be used only after statements or clauses, not in
+the middle of an expression; use \.{@|} in the middle of expressions, in
+order to keep \.{WEAVE}'s parser happy.
+
+\@- [\PAS] \newstuff
+This control code makes \.{WEAVE} continue the current
+statement on the next line; it is ignored by \.{TANGLE}.
+If is just like `\.{@/}', except that the following line is indented,
+to show that it is a continuation of the line broken.
+\endnewstuff
+
+\@| [\PAS] This control code specifies an optional line break in the midst of
+an expression.
+For example, if you have a long condition between \&{if} and
+\&{then}, or a long expression on the right-hand side of an assignment
+statement, you can use `\.{@|}' to specify breakpoints more logical than
+the ones that \TeX\ might choose on visual grounds.
+
+\@\# [\PAS] This control code forces a line break, like \.{@/} does,
+and it also causes a little extra white space to appear between the lines at
+this break.
+You might use it, for example, between procedure definitions or
+between groups of macro definitions that are logically separate but within
+the same module.
+
+\@+ [\PAS] This control code cancels a line break that might otherwise be
+inserted by \.{WEAVE}, e.g., before the word `\&{else}', if you want to
+put a short if-then-else construction on a single line.
+It is ignored by
+\.{TANGLE}.
+
+\@; [\PAS] Usually this control code is treated like a semicolon, for
+formatting purposes, except that it is invisible.
+\newstuff
+The person who built your \.{WEB} can redefine it, though, so check
+his documentation to make sure.
+\endnewstuff
+
+You can use it, for example, after
+a module name when the \PASCAL\ text represented by that module name ends
+with a semicolon.
+
+\yskip\noindent
+The last \newstuff seven \endnewstuff
+ control codes (namely `\.{@,}', `\.{@/}', `\.{@-}', `\.{@|}',
+`\.{@\#}', `\.{@+}', and `\.{@;}') have no effect on the \PASCAL\
+program output by \.{TANGLE}; they merely help to improve the readability
+of the \TeX-formatted \PASCAL\ that is output by \.{WEAVE}, in unusual
+circumstances.
+\.{WEAVE}'s built-in formatting method is fairly good, but
+it is incapable of handling all possible cases, because it must deal with
+fragments of text involving macros and module names; these fragments do
+not necessarily obey \PASCAL's syntax.
+Although \.{WEB} allows you to
+override the automatic formatting, your best strategy is not to worry
+about such things until you have seen what \.{WEAVE} produces automatically,
+since you will probably need to make only a few corrections when you are
+touching up your documentation.
+
+Because of the rules by which every module is broken into three parts,
+the control codes `\.{@d}', `\.{@f}', and `\.{@u}' are not allowed to occur
+once the \PASCAL\ part of a module has begun.
+
+\section Additional features and caveats.
+
+%1.
+%The character pairs `\.{(*}', `\.{*)}', `\.{(.}', and `\.{.)}' are
+%converted automatically in \PASCAL\ text as though they were
+%`\.{@\{}', `\.{@\}}', `\.[', and `\.]', respectively, except
+%%of course in strings.
+%Furthermore in certain installations of \.{WEB} that
+%{\def\\#1#2{`{\tentex\char'#1#2}'}%
+%have an extended character set, the characters \\32, \\34, \\35, \\30,
+%\\36, \\04, \\37, \\05, and \\06}
+%can be used as abbreviations for
+%`\.{<>}', `\.{<=}', `\.{>=}', `\.{:=}', `\.{==}', `\.{and}', `\.{or}',
+%`\.{not}', and `\.{in}', respectively.
+%However, the latter abbreviations
+%are not used in the standard versions of \.{WEAVE.WEB} and \.{TANGLE.WEB}
+%that are distributed to people who are installing \.{WEB} on other
+%computers, and the programs are designed to produce only standard ASCII
+%characters as output if the input consists entirely of ASCII characters.
+%
+%2.
+%If you have an extended character set, all of the characters listed
+%in Appendix C of {\sl The \TeX book\/} can be used in strings.
+%But you should
+%stick to standard ASCII characters if you want to write programs that will
+%be useful to the all the poor souls out there who don't have extended
+%character sets.
+
+3.
+The \TeX\ file output by \.{WEAVE} is broken into lines having at most
+80 characters each.
+The algorithm that does this line breaking is unaware
+of \TeX's convention about comments following `\.\%' signs on a line.
+When
+\TeX\ text is being copied, the existing line breaks are copied as well,
+so there is no problem with `\.\%' signs unless the original \.{WEB} file
+contains a line more than eighty characters long or a line with \PASCAL\
+text in \pb\ that expands to more than eighty characters long.
+Such lines
+should not have `\.\%' signs.
+
+4.
+\PASCAL\ text is translated by a ``bottom up'' procedure that
+identifies each token as a ``part of speech'' and combines parts of speech
+into larger and larger phrases as much as possible according to a special
+\newstuff prettyprinting \endnewstuff
+grammar.
+The grammar and the translation process are explained in the
+``Spider User's Guide.''
+It is easy to
+learn the translation scheme for simple constructions like single
+identifiers and short expressions, just by looking at a few examples of
+what \.{WEAVE} does, but the general mechanism is somewhat complex because
+it must handle much more than \PASCAL\ itself.
+Furthermore the output
+contains embedded codes that cause \TeX\ to indent and break lines as
+necessary, depending on the fonts used and the desired page width.
+For
+best results it is wise to adhere to the following restrictions:
+
+\yskip\itemitem{a)}Comments in \PASCAL\ text should appear only after
+statements or clauses; i.e.,
+\newstuff(if \PASCAL\ were PASCAL) \endnewstuff
+after semicolons, after reserved words like
+\&{then} and \&{do}, or before reserved words like \&{end} and \&{else}.
+Otherwise \.{WEAVE}'s parsing method may well get mixed up.
+
+\itemitem{b)}Don't enclose long \PASCAL\ texts in \pb, since the
+indentation and line breaking codes are omitted when the \pb\ text is
+translated from \PASCAL\ to \TeX.
+Stick to simple expressions or
+statements.
+
+\yskip
+5.
+Comments and module names are not permitted in \pb\ text.
+After a `\.|'
+signals the change from \TeX\ text to \PASCAL\ text, the next `\.|' that is
+not part of a string or control text ends the \PASCAL\ text.
+
+6.
+\newstuff
+Spidery {\tt WEB} does not handle nested comments.
+\endnewstuff
+%A comment must have properly nested occurrences of left and right
+% braces, otherwise \.{WEAVE} and \.{TANGLE} will not know where the comment
+% ends.
+%However, the character pairs `\.{\\\{}' and `\.{\\\}}' do not count
+%as left and right braces in comments, and the character pair `\.{\\|}'
+%does not count as a delimiter that begins \PASCAL\ text.
+%(The actual rule
+%is that a character after `\.\\' is ignored; hence in `\.{\\\\\{}' the
+%left brace {\sl does\/} count.) At present, \.{TANGLE} and \.{WEAVE} treat
+%comments in slightly different ways, and it is necessary to satisfy both
+%conventions: \.{TANGLE} ignores `\.|' characters entirely, while \.{WEAVE}
+%uses them to switch between \TeX\ text and \PASCAL\ text.
+%Therefore, a
+%comment that includes a brace in a string in \pb---e.g., `\.{\{{ }look at
+%this |"\{"| \}}'---will be handled correctly by \.{WEAVE}, but \.{TANGLE}
+%will think there is an unmatched left brace.
+%In order to satisfy both
+%processors, one can write `\.{\{{ }look at this \\leftbrace\\{ }\}}', after
+%setting up`\.{\\def\\leftbrace\{|"\{"|\}}'.
+
+7.
+Reserved words of \PASCAL\ must appear entirely in lowercase letters
+in the \.{WEB} file; otherwise their special nature will not be recognized
+by \.{WEAVE}.
+\newstuff
+This could be changed, but the author of Spidery {\tt WEB} does not
+believe in case-insensitivity for programming languages.
+\endnewstuff
+You could, for example, have a macro named \\{END} and it
+would not be confused with \&{end}.
+
+However, you may not want to capitalize macro names just to distinguish them
+from other identifiers.
+Here is a way to unreserve Pascal's reserved word
+`\&{type}' and to substitute another word `\&{mtype}' in the \.{WEB} file.
+$$\vbox{\halign{\tt #\hfil\cr
+@d type(\char'43) = mem[\char'43].t\cr
+@d mtype = t \char'100\char'46{} y \char'100\char'46{} p
+ \char'100\char'46{} e\cr
+@f mtype = type\cr
+@f type = true\cr}}$$
+In the output of \.{TANGLE}, the macro \.{mtype} now produces `\.{TYPE}'
+and the macro \.{type(x)} now produces `\.{MEM[X].T}'.
+In the output of
+\.{WEAVE}, these same inputs produce \&{mtype} and \\{type}(\|x),
+respectively.
+
+8.
+The \.{@f} feature allows you to define one identifier to act like
+another, and these format definitions are carried out sequentially, as the
+example above indicates.
+However, a given identifier has only one printed format
+throughout the entire document (and this format will even be used before
+the \.{@f} that defines it).
+The reason is that \.{WEAVE} operates in two
+passes; it processes \.{@f}'s and cross-references on the first pass and
+does the output on the second.
+
+9.
+You may want some \.{@f} formatting that doesn't correspond to any
+existing reserved word.
+In that case, \.{WEAVE} could be extended
+\newstuff
+by someone who built Spidery {\tt WEB}
+\endnewstuff
+to include new ``reserved words'' in its vocabulary.
+\newstuff
+(The ``\/{Spider} User's Guide'' explains how.)
+\endnewstuff
+
+%The identifier `\&{xclause}' has in fact been included already as a
+%reserved word, so that it can be used to format the `\&{loop}' macro,
+%where `\&{loop}' is defined to be equivalent to `\&{while \\{true} do}'.
+
+10.
+Sometimes it is desirable to insert spacing into \PASCAL\ code that is
+more general than the thin space provided by `\.{@,}'.
+The \.{@t} feature
+can be used for this purpose; e.g., `\.{@t\\hskip 1in@>}' will
+leave one inch of blank space.
+Furthermore, `\.{@t\\4@>}' can be
+used to backspace by one unit of indentation, since the control sequence
+\.{\\4} is defined in \.{webmac} to be such a backspace.
+(This
+control sequence is used, for example, at the beginning of lines that
+contain labeled statements, so that the label will stick out a little at
+the left.)
+
+11.
+\.{WEAVE} and \.{TANGLE} are designed to work with two input files,
+called \\{web\_file} and \\{change\_file}, where \\{change\_file} contains
+data that overrides selected portions of \\{web\_file}.
+The resulting merged
+text is actually what has been called the \.{WEB} file elsewhere in this
+report.
+
+Here's how it works: The change file consists of zero or more ``changes,''
+where a change has the form `\.{@x}$\langle$old lines$\rangle$\.{@y}$\langle$%
+new lines$\rangle$\.{@z}'.
+The special control codes \.{@x}, \.{@y}, \.{@z},
+which are allowed only in change files, must appear at the beginning of a line;
+the remainder of such a line is ignored.
+The $\langle$old lines$\rangle$ represent material that exactly matches
+consecutive lines of the \\{web\_file}; the $\langle$new lines$\rangle$
+represent zero or more lines that are supposed to replace the old.
+Whenever
+the first ``old line'' of a change is found to match a line in the
+\\{web\_file}, all the other lines in that change must match too.
+
+Between changes, before the first change, and after the last change,
+the change file can have any number of lines that do not begin with
+`\.{@x}', `\.{@y}', or~`\.{@z}'.
+Such lines are bypassed and not used for
+matching purposes.
+
+This dual-input feature is useful when working with a master \.{WEB} file
+that has been received from elsewhere (e.g., \.{TANGLE.WEB} or
+\.{WEAVE.WEB} or \.{TEX.WEB}), when changes are desirable to customize the
+program for your local computer system.
+You will be able to debug your
+system-dependent changes without clobbering the master web file; and once
+your changes are working, you will be able to incorporate them readily
+into new releases of the master web file that you might receive from time
+to time.
+
+\newstuff
+There are several multiple-changefile tools in the {\TeX} community;
+check back issues of TUGboat for more information.
+\endnewstuff
+
+\section Appendices.
+% The basic ideas of \.{WEB} can be understood most easily by looking at
+% examples of ``real'' programs.
+% Appendix~A shows the \.{WEB} input that
+% generated modules 55--59 of the \.{WEAVE} program; Appendix~B shows the
+% corresponding \TeX\ code output by \.{WEAVE}; and Appendix~C shows excerpts
+% from the corresponding \PASCAL\ code output by \.{TANGLE}.
+%
+% The complete webs for \.{WEAVE} and \.{TANGLE} appear as the bulk of this
+% report, in Appendices D and~E.
+% The reader should first compare Appendix~A
+% to the corresponding portion of Appendix~D; then the same material should
+% be compared to Appendices B and~C.
+% Finally, if time permits, the reader may
+% enjoy studying the complete programs in Appendices D and~E, since \.{WEAVE}
+% and \.{TANGLE} contain several interesting aspects, and since an attempt
+% has been made in these appendices to evolve a style of programming that
+% makes good use of the \.{WEB} language.
+%
+% Finally, Appendix F is the `\.{webkernel}' file that sets \TeX\ up to accept
+% the output of \.{WEAVE}; Appendix~G discusses how to use some of its macros
+% to vary the output formats; and Appendix~H discusses what needs to be done
+% when \.{WEAVE} and \.{TANGLE} are installed in a new operating environment.
+%
+% \section Performance statistics.
+% The programs in Appendices D and E will optionally keep statistics on
+% how much memory they require.
+% Here is what they printed out when
+% processing themselves:
+%
+% \def\pstat#1#2#3
+% #4{\yskip\noindent\.{#1} applied to \.{#2} (cpu time #3 sec)\par
+% \halign{\quad\tt##\hfil\cr#4}}
+%
+% \pstat{TANGLE}{TANGLE}{15}
+% {Memory usage statistics:\cr
+% 456 names, 215 replacement texts;\cr
+% 3396+3361 bytes, 6685+7329+5805 tokens.\cr}
+%
+% \pstat{TANGLE}{WEAVE}{30}
+% {Memory usage statistics:\cr
+% 692 names, 339 replacement texts;\cr
+% 4576+4294 bytes, 10184+9875+9150 tokens.\cr}
+%
+% \pstat{WEAVE}{TANGLE}{45}
+% {Memory usage statistics: 478 names, 2045 cross references, 4159+3729 bytes;\cr
+% parsing required 684 scraps, 1300 texts, 3766 tokens, 119 levels;\cr
+% sorting required 34 levels.\cr}
+%
+% \pstat{WEAVE}{WEAVE}{65}
+% {Memory usage statistics: 737 names, 3306 cross references, 4896+4962 bytes;\cr
+% parsing required 684 scraps, 1300 texts, 3766 tokens, 119 levels;\cr
+% sorting required 73 levels.\cr}
+%
+% \yskip\noindent The cpu time for \PASCAL\ to process \.{TANGLE.PAS} was
+% approximately 13 seconds, and \.{WEAVE.PAS} took approximately 26 seconds;
+% thus the tangling time was slightly more than the compiling time.
+% The cpu
+% time for \TeX\ to process \.{TANGLE.TEX} was approximately 500 seconds,
+% and \.{WEAVE.TEX} took approximately 750 seconds (i.e., about 7
+% seconds per printed page, where these pages are substantially larger than
+% the pages in a normal book).
+% All cpu times quoted are for a DECsystem-10.
+%
+% \def\K{{\mc K}}
+% The file \.{TANGLE.WEB} is about 125\K\ characters long; \.{TANGLE}
+% reduces it to a file \.{TANGLE.PAS} whose size is about 42\K\ characters,
+% while \.{WEAVE} expands it to a file \.{TANGLE.TEX} of about 185\K\null.
+% The corresponding file sizes for \.{WEAVE.WEB}, \.{WEAVE.PAS}, and
+% \.{WEAVE.TEX} are 180\K, 89\K, and 265\K.
+%
+% The much larger file \.{TEX.WEB} led to the following numbers:
+%
+% \pstat{TANGLE}{TEX}{110}
+% {Memory usage statistics:\cr
+% 3750 names, 1768 replacement texts;\cr
+% 41895+41053 bytes, 42378+45074+41091 tokens.\cr}
+%
+% \pstat{WEAVE}{TEX}{270}
+% {Memory usage statistics: 3412 names, 19699 cross references,
+% 37900+40232 bytes;\cr
+% parsing required 685 scraps, 1303 texts, 3784 tokens, 104 levels;\cr
+% sorting required 52 levels.\cr}
+%
+% \yskip\noindent
+% \PASCAL\ did \.{TEX.PAS} in about 75 seconds; \TeX\ did \.{TEX.TEX}
+% in about 3600.
+%
+% % Here is a quotation that could not really be omitted
+%
+% \vfill
+%
+% {\baselineskip9pt
+% \halign to\hsize{\hfil\quoteit#\tabskip 0pt plus 100pt&
+% \hfil\quoteit#\tabskip 0pt\cr
+% O, what a tangled web we weave&
+% O, what a tangled WEB we weave\cr
+% When first we practise to deceive!&
+% When \TeX\ we practise to conceive!\cr
+% \noalign{\vskip 2pt}
+% \quoterm ---SIR WALTER SCOTT, {\quoteit Marmion} 6:17 (1808)&
+% \quoterm ---RICHARD PALAIS (1982)\cr
+% }}
+% \eject
+%
+% \def\runninghead{APPENDIX A --- {\tentt WEB} FILE FORMAT}
+% \section Appendix A.
+% This excerpt from \.{WEAVE.WEB} produced modules 55--59 in Appendix~D.
+% Note that some of the lines are indented to show the program structure.
+% The indentation is ignored by \.{WEAVE} and \.{TANGLE}, but users find
+% that \.{WEB} files are quite readable if they have some such indentation.
+%
+% \vskip 6pt
+% \begingroup \def\tt{\eighttt} \baselineskip9pt
+% % Note to myself: I had to remove SAIL characters from the file here!
+% % Also tabs replaced by double-space.
+% The changes were made in WEAVE source.
+% \verbatim
+% @* Searching for identifiers.
+% The hash table described above is updated by the |id_lookup| procedure,
+% which finds a given identifier and returns a pointer to its index in
+% |byte_start|.
+% The identifier is supposed to match character by character
+% and it is also supposed to have a given |ilk| code; the same name may be
+% present more than once if it is supposed to appear in the index with
+% different typesetting conventions.
+% If the identifier was not already present, it is inserted into the table.
+%
+% Because of the way \.{WEAVE}'s scanning mechanism works, it is most convenient
+% to let |id_lookup| search for an identifier that is present in the |buffer|
+% array.
+% Two other global variables specify its position in the buffer: the
+% first character is |buffer[id_first]|, and the last is |buffer[id_loc-1]|.
+%
+% @<Glob...@>=
+% @!id_first:0..long_buf_size; {where the current identifier begins in the buffer}
+% @!id_loc:0..long_buf_size; {just after the current identifier in the buffer}
+% @#
+% @!hash:array [0..hash_size] of sixteen_bits; {heads of hash lists}
+%
+% @ Initially all the hash lists are empty.
+%
+% @<Local variables for init...@>=
+% @!h:0..hash_size; {index into hash-head array}
+%
+% @ @<Set init...@>=
+% for h:=0 to hash_size-1 do hash[h]:=0;
+%
+% @ Here now is the main procedure for finding identifiers (and index
+% entries).
+% The parameter |t| is set to the desired |ilk| code.
+% The
+% identifier must either have |ilk=t|, or we must have
+% |t=normal| and the identifier must be a reserved word.
+%
+% @p function id_lookup(@!t:eight_bits):name_pointer; {finds current identifier}
+% label found;
+% var i:0..long_buf_size; {index into |buffer|}
+% @!h:0..hash_size; {hash code}
+% @!k:0..max_bytes; {index into |byte_mem|}
+% @!w:0..ww-1; {row of |byte_mem|}
+% @!l:0..long_buf_size; {length of the given identifier}
+% @!p:name_pointer; {where the identifier is being sought}
+% begin l:=id_loc-id_first; {compute the length}
+% @<Compute the hash code |h|@>;
+% @<Compute the name location |p|@>;
+% if p=name_ptr then @<Enter a new name into the table at position |p|@>;
+% id_lookup:=p;
+% end;
+%
+% @ A simple hash code is used: If the sequence of
+% ASCII codes is $c_1c_2\ldots c_m$, its hash value will be
+% $$(2^{n-1}c_1+2^{n-2}c_2+\cdots+c_n)\,\bmod\,|hash_size|.$$
+%
+% @<Compute the hash...@>=
+% h:=buffer[id_first]; i:=id_first+1;
+% while i<id_loc do
+% begin h:=(h+h+buffer[i]) mod hash_size; incr(i);
+% end
+% ?endgroup % end of verbatim mode
+% \endgroup
+% \vfill\eject
+%
+% \def\runninghead{APPENDIX B --- TRANSLATION BY {\tentt WEAVE}}
+% \section Appendix B.
+% This excerpt from \.{WEAVE.TEX} corresponds to Appendix A.
+%
+% % I've inserted \vfill's here at the blank lines, to squeeze this on one page!
+% \begingroup \def\tt{\eighttt} \baselineskip9pt
+% \verbatim
+% ?vfill?verbatimgobble
+% \N55.
+% Searching for identifiers.
+% The hash table described above is updated by the \\{id\_lookup} procedure,
+% which finds a given identifier and returns a pointer to its index in
+% \\{byte\_start}.
+% The identifier is supposed to match character by character
+% and it is also supposed to have a given \\{ilk} code; the same name may be
+% present more than once if it is supposed to appear in the index with
+% different typesetting conventions.
+% If the identifier was not already present, it is inserted into the table.
+% ?vfill?verbatimgobble
+% Because of the way \.{WEAVE}'s scanning mechanism works, it is most convenient
+% to let \\{id\_lookup} search for an identifier that is present in the %
+% \\{buffer}
+% array.
+% Two other global variables specify its position in the buffer: the
+% first character is $\\{buffer}[\\{id\_first}]$, and the last is $\\{buffer}[%
+% \\{id\_loc}-1]$.
+% ?vfill?verbatimgobble
+% \Y\P$\4\X9:Globals in the outer block\X\mathrel{+}\S$\6
+% \4\\{id\_first}: \37$0\to\\{long\_buf\_size}$;\C{where the current identifier
+% begins in the buffer}\6
+% \4\\{id\_loc}: \37$0\to\\{long\_buf\_size}$;\C{just after the current
+% identifier in the buffer}\7
+% \4\\{hash}: \37\&{array} $[0\to\\{hash\_size}]$ \1\&{of}\5
+% \\{sixteen\_bits};\C{heads of hash lists}\2\par
+% \fi
+% ?vfill?verbatimgobble
+% \M56.
+% Initially all the hash lists are empty.
+% ?vfill?verbatimgobble
+% \Y\P$\4\X16:Local variables for initialization\X\mathrel{+}\S$\6
+% \4\|h: \37$0\to\\{hash\_size}$;\C{index into hash-head array}\par
+% \fi
+% ?vfill?verbatimgobble
+% \M57.
+% \P$\X10:Set initial values\X\mathrel{+}\S$\6
+% \&{for} $\|h\K0\mathrel{\&{to}}\\{hash\_size}-1$ \1\&{do}\5
+% $\\{hash}[\|h]\K0$;\2\par
+% \fi
+% ?vfill?verbatimgobble
+% \M58.
+% Here now is the main procedure for finding identifiers (and index
+% entries).
+% The parameter \|t is set to the desired \\{ilk} code.
+% The
+% identifier must either have $\\{ilk}=\|t$, or we must have
+% $\|t=\\{normal}$ and the identifier must be a reserved word.
+% ?vfill?verbatimgobble
+% \Y\P\4\&{function}\1\ \37$\\{id\_lookup}(\|t:\\{eight\_bits})$: \37\\{name%
+% \_pointer};\C{finds current identifier}\6
+% \4\&{label} \37\\{found};\6
+% \4\&{var} \37\|i: \37$0\to\\{long\_buf\_size}$;\C{index into \\{buffer}}\6
+% \|h: \37$0\to\\{hash\_size}$;\C{hash code}\6
+% \|k: \37$0\to\\{max\_bytes}$;\C{index into \\{byte\_mem}}\6
+% \|w: \37$0\to\\{ww}-1$;\C{row of \\{byte\_mem}}\6
+% \|l: \37$0\to\\{long\_buf\_size}$;\C{length of the given identifier}\6
+% \|p: \37\\{name\_pointer};\C{where the identifier is being sought}\2\6
+% \&{begin} \37$\|l\K\\{id\_loc}-\\{id\_first}$;\C{compute the length}\6
+% \X59:Compute the hash code \|h\X;\6
+% \X60:Compute the name location \|p\X;\6
+% \&{if} $\|p=\\{name\_ptr}$ \1\&{then}\5
+% \X62:Enter a new name into the table at position \|p\X;\2\6
+% $\\{id\_lookup}\K\|p$;\6
+% \&{end};\par
+% \fi
+% ?vfill?verbatimgobble
+% \M59.
+% A simple hash code is used: If the sequence of
+% ASCII codes is $c_1c_2\ldots c_m$, its hash value will be
+% $$(2^{n-1}c_1+2^{n-2}c_2+\cdots+c_n)\,\bmod\,\\{hash\_size}.$$
+% ?vfill?verbatimgobble
+% \Y\P$\4\X59:Compute the hash code \|h\X\S$\6
+% $\|h\K\\{buffer}[\\{id\_first}]$;\5
+% $\|i\K\\{id\_first}+1$;\6
+% \&{while} $\|i<\\{id\_loc}$ \1\&{do}\6
+% \&{begin} \37$\|h\K(\|h+\|h+\\{buffer}[\|i])\mathbin{\&{mod}}\\{hash\_size}$;\5
+% $\\{incr}(\|i)$;\6
+% \&{end}\2\par
+% \U section~58.\fi
+% ?endgroup
+% \endgroup
+% \eject
+%
+% \def\runninghead{APPENDIX C --- TRANSLATION BY {\tentt TANGLE}}
+% \section Appendix C.
+% The \.{TANGLE} processor converts \.{WEAVE.WEB} into a syntactically
+% correct (but not very pretty) \PASCAL\ program \.{WEAVE.PAS}.
+% The first three and last two lines of output are shown here, together with the
+% lines of code generated by modules 55--62 and the environments of
+% those lines.
+% There are 1559 lines in all; the notation
+% `\.. \\.
+% \\.' stands for portions that are not shown.
+%
+% Note that, for example, the code corresponding to
+% module 55 begins with `\.{\{55:\}}' and ends with `\.{\{:55\}}';
+% the code from modules 59--62 has been tangled into the code from module 58.
+%
+% \vskip6pt
+% \verbatim
+% {2:}{4:}{$C-,A+,D-}{[$C+,D+]}{:4}
+% PROGRAM WEAVE(WEBFILE,CHANGEFILE,TEXFILE);LABEL 9999;CONST{8:}
+% MAXBYTES=45000;MAXNAMES=5000;MAXMODULES=2000;HASHSIZE=353;BUFSIZE=100;
+% .
+% . .
+% TOKPTR:0..MAXTOKS;{MAXTOKPTR,MAXTXTPTR:0..MAXTOKS;}{:53}{55:}
+% IDFIRST:0..LONGBUFSIZE;IDLOC:0..LONGBUFSIZE;
+% HASH:ARRAY[0..HASHSIZE]OF SIXTEENBITS;{:55}{63:}CURNAME:NAMEPOINTER;
+% .
+% . .
+% PROCEDURE INITIALIZE;VAR{16:}I:0..127;{:16}{40:}WI:0..1;{:40}{56:}
+% H:0..HASHSIZE;{:56}{247:}C:ASCIICODE;{:247}BEGIN{10:}HISTORY:=0;{:10}
+% .
+% . .
+% TOKPTR:=1;TEXTPTR:=1;TOKSTART[0]:=1;TOKSTART[1]:=1;{MAXTOKPTR:=1;
+% MAXTXTPTR:=1;}{:54}{57:}FOR H:=0 TO HASHSIZE-1 DO HASH[H]:=0;{:57}{94:}
+% SCANNINGHEX:=FALSE;{:94}{102:}MODTEXT[0]:=32;{:102}{124:}OUTPTR:=1;
+% .
+% . .
+% IF R=0 THEN XREF[P]:=XREFPTR ELSE XMEM[R].XLINKFIELD:=XREFPTR;END;{:51}
+% {58:}FUNCTION IDLOOKUP(T:EIGHTBITS):NAMEPOINTER;LABEL 31;
+% VAR I:0..LONGBUFSIZE;H:0..HASHSIZE;K:0..MAXBYTES;W:0..1;
+% L:0..LONGBUFSIZE;P:NAMEPOINTER;BEGIN L:=IDLOC-IDFIRST;{59:}
+% H:=BUFFER[IDFIRST];I:=IDFIRST+1;
+% WHILE I<IDLOC DO BEGIN H:=(H+H+BUFFER[I])MOD HASHSIZE;I:=I+1;END{:59};
+% {60:}P:=HASH[H];
+% WHILE P<>0 DO BEGIN IF(BYTESTART[P+2]-BYTESTART[P]=L)AND((ILK[P]=T)OR((T
+% =0)AND(ILK[P]>3)))THEN{61:}BEGIN I:=IDFIRST;K:=BYTESTART[P];W:=P MOD 2;
+% WHILE(I<IDLOC)AND(BUFFER[I]=BYTEMEM[W,K])DO BEGIN I:=I+1;K:=K+1;END;
+% IF I=IDLOC THEN GOTO 31;END{:61};P:=LINK[P];END;P:=NAMEPTR;
+% LINK[P]:=HASH[H];HASH[H]:=P;31:{:60};IF P=NAMEPTR THEN{62:}
+% BEGIN W:=NAMEPTR MOD 2;
+% IF BYTEPTR[W]+L>MAXBYTES THEN BEGIN WRITELN(TERMOUT);
+% WRITE(TERMOUT,'! Sorry, ','byte memory',' capacity exceeded');ERROR;
+% HISTORY:=3;JUMPOUT;END;
+% IF NAMEPTR+2>MAXNAMES THEN BEGIN WRITELN(TERMOUT);
+% WRITE(TERMOUT,'! Sorry, ','name',' capacity exceeded');ERROR;HISTORY:=3;
+% JUMPOUT;END;I:=IDFIRST;K:=BYTEPTR[W];
+% WHILE I<IDLOC DO BEGIN BYTEMEM[W,K]:=BUFFER[I];K:=K+1;I:=I+1;END;
+% BYTEPTR[W]:=K;BYTESTART[NAMEPTR+2]:=K;NAMEPTR:=NAMEPTR+1;ILK[P]:=T;
+% XREF[P]:=0;END{:62};IDLOOKUP:=P;END;{:58}{66:}
+% FUNCTION MODLOOKUP(L:SIXTEENBITS):NAMEPOINTER;LABEL 31;VAR C:0..4;
+% .
+% . .
+% WRITE(TERMOUT,'(That was a fatal error, my friend.)');END;END{:263};
+% END.{:261}
+% ?endgroup
+% \vfill\eject
+%
+% \pageno=199 % take account of the page numbers for App's D and E.
+%
+% \def\runninghead{APPENDIX F --- MACROS FOR FORMATTING}
+% \section Appendix F: The \.{webmac.tex} file.
+% This is the file that extends ``plain \TeX'' format in order to support the
+% features needed by the output of \.{WEAVE}.
+%
+% \vskip6pt
+% \verbatim
+% % standard macros for WEB listings (in addition to PLAIN.TEX)
+% \xdef\fmtversion{\fmtversion+WEBMAC1.3} % identifies current set of macros
+% \parskip 0pt % no stretch between paragraphs
+% \parindent 1em % for paragraphs and for the first line of Pascal text
+%
+% \font\eightrm=cmr8
+% \let\sc=\eightrm \let\mainfont=\tenrm
+% \font\titlefont=cmr7 scaled\magstep4 % title on the contents page
+% \font\ttitlefont=cmtt10 scaled\magstep2 % typewriter type in title
+% \font\tentex=cmtex10 % TeX extended character set (used in strings)
+%
+% \def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+% \def\|#1{\hbox{$#1$}} % one-letter identifiers look a bit better this way
+% \def\&#1{\hbox{\bf#1\/}} % boldface type for reserved words
+% \def\.#1{\hbox{\tentex % typewriter type for strings
+% \let\\=\BS % backslash in a string
+% \let\'=\RQ % right quote in a string
+% \let\`=\LQ % left quote in a string
+% \let\{=\LB % left brace in a string
+% \let\}=\RB % right brace in a string
+% \let\~=\TL % tilde in a string
+% \let\ =\SP % space in a string
+% \let\_=\UL % underline in a string
+% \let\&=\AM % ampersand in a string
+% #1}}
+% \def\#{\hbox{\tt\char`\#}} % parameter sign
+% \def\${\hbox{\tt\char`\$}} % dollar sign
+% \def\%{\hbox{\tt\char`\%}} % percent sign
+% \def\^{\ifmmode\mathchar"222 \else\char`^ \fi} % pointer or hat
+% % circumflex accents can be obtained from \^^D instead of \^
+% \def\AT!{@} % at sign for control text
+%
+% \chardef\AM=`\& % ampersand character in a string
+% \chardef\BS=`\\ % backslash in a string
+% \chardef\LB=`\{ % left brace in a string
+% \def\LQ{{\tt\char'22}} % left quote in a string
+% \chardef\RB=`\} % right brace in a string
+% \def\RQ{{\tt\char'23}} % right quote in a string
+% \def\SP{{\tt\char`\ }} % (visible) space in a string
+% \chardef\TL=`\~ % tilde in a string
+% \chardef\UL=`\_ % underline character in a string
+%
+% \newbox\bak \setbox\bak=\hbox to -1em{} % backspace one em
+% \newbox\bakk\setbox\bakk=\hbox to -2em{} % backspace two ems
+%
+% \newcount\ind % current indentation in ems
+% \def\1{\global\advance\ind by1\hangindent\ind em} % indent one more notch
+% \def\2{\global\advance\ind by-1} % indent one less notch
+% \def\3#1{\hfil\penalty#10\hfilneg} % optional break within a statement
+% \def\4{\copy\bak} % backspace one notch
+% \def\5{\hfil\penalty-1\hfilneg\kern2.5em\copy\bakk\ignorespaces}% optional break
+% \def\6{\ifmmode\else\par % forced break
+% \hangindent\ind em\noindent\kern\ind em\copy\bakk\ignorespaces\fi}
+% \def\7{\Y\6} % forced break and a little extra space
+%
+% \let\yskip=\smallskip
+% \def\to{\mathrel{.\,.}} % double dot, used only in math mode
+% \def\note#1#2.{\Y\noindent{\hangindent2em\baselineskip10pt\eightrm#1 #2.\par}}
+% \def\lapstar{\rlap{*}}
+% \def\startsection{\Q\noindent{\let\*=\lapstar\bf\modstar.\quad}}
+% \def\defin#1{\global\advance\ind by 2 \1\&{#1 }} % begin `define' or `format'
+% \def\A{\note{See also}} % cross-reference for multiply defined section names
+% \def\B{\mathopen{\.{@\{}}} % begin controlled comment
+% \def\C#1{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % Pascal comments
+% \XX\hfil\penalty-1\hfilneg\quad$\{\,$#1$\,\}$\XX}
+% \def\D{\defin{define}} % macro definition
+% \def\E{\cdot10^} % exponent in floating point constant
+% \def\F{\defin{format}} % format definition
+% \let\G=\ge % greater than or equal sign
+% \def\H#1{\hbox{\rm\char"7D\tt#1}} % hexadecimal constant
+% \let\I=\ne % unequal sign
+% \def\J{\.{@\&}} % TANGLE's join operation
+% \let\K=\gets % left arrow
+% \let\L=\le % less than or equal sign
+% \outer\def\M#1.{\MN#1.\ifon\vfil\penalty-100\vfilneg % beginning of section
+% \vskip12ptminus3pt\startsection\ignorespaces}
+% \outer\def\N#1.#2.{\MN#1.\vfil\eject % beginning of starred section
+% \def\rhead{\uppercase{\ignorespaces#2}} % define running headline
+% \message{*\modno} % progress report
+% \edef\next{\write\cont{\Z{#2}{\modno}{\the\pageno}}}\next % to contents file
+% \ifon\startsection{\bf\ignorespaces#2.\quad}\ignorespaces}
+% \def\MN#1.{\par % common code for \M, \N
+% {\xdef\modstar{#1}\let\*=\empty\xdef\modno{#1}}
+% \ifx\modno\modstar \onmaybe \else\ontrue \fi \mark{\modno}}
+% \def\O#1{\hbox{\rm\char'23\kern-.2em\it#1\/\kern.05em}} % octal constant
+% \def\P{\rightskip=0pt plus 100pt minus 10pt % go into Pascal mode
+% \sfcode`;=3000
+% \pretolerance 10000
+% \hyphenpenalty 10000 \exhyphenpenalty 10000
+% \global\ind=2 \1\ \unskip}
+% \def\Q{\rightskip=0pt % get out of Pascal mode
+% \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50 }
+% \let\R=\lnot % logical not
+% \let\S=\equiv % equivalence sign
+% \def\T{\mathclose{\.{@\}}}} % terminate controlled comment
+% \def\U{\note{This code is used in}} % cross-reference for uses of sections
+% \let\V=\lor % logical or
+% \let\W=\land % logical and
+% \def\X#1:#2\X{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % section name
+% \XX$\langle\,$#2{\eightrm\kern.5em#1}$\,\rangle$\XX}
+% \def\Y{\par\yskip}
+% \let\Z=\let % now you can \send the control sequence \Z
+% \def\){\hbox{\.{@\$}}} % sign for string pool check sum
+% \def\]{\hbox{\.{@\\}}} % sign for forced line break
+% \def\=#1{\kern2pt\hbox{\vrule\vtop{\vbox{\hrule
+% \hbox{\strut\kern2pt\.{#1}\kern2pt}}
+% \hrule}\vrule}\kern2pt} % verbatim string
+% \let\~=\ignorespaces
+% \let\*=*
+%
+% \def\onmaybe{\let\ifon=\maybe} \let\maybe=\iftrue
+% \newif\ifon \newif\iftitle \newif\ifpagesaved
+% \def\lheader{\mainfont\the\pageno\eightrm\qquad\rhead\hfill\title\qquad
+% \tensy x\mainfont\topmark} % top line on left-hand pages
+% \def\rheader{\tensy x\mainfont\topmark\eightrm\qquad\title\hfill\rhead
+% \qquad\mainfont\the\pageno} % top line on right-hand pages
+% \def\page{\box255 }
+% \def\normaloutput#1#2#3{\ifodd\pageno\hoffset=\pageshift\fi
+% \shipout\vbox{
+% \vbox to\fullpageheight{
+% \iftitle\global\titlefalse
+% \else\hbox to\pagewidth{\vbox to10pt{}\ifodd\pageno #3\else#2\fi}\fi
+% \vfill#1}} % parameter #1 is the page itself
+% \global\advance\pageno by1}
+%
+% \def\rhead{\.{WEB} OUTPUT} % this running head is reset by starred sections
+% \def\title{} % an optional title can be set by the user
+% \def\topofcontents{\centerline{\titlefont\title}
+% \vfill} % this material will start the table of contents page
+% \def\botofcontents{\vfill} % this material will end the table of contents page
+% \def\contentspagenumber{0} % default page number for table of contents
+% \newdimen\pagewidth \pagewidth=6.5in % the width of each page
+% \newdimen\pageheight \pageheight=8.7in % the height of each page
+% \newdimen\fullpageheight \fullpageheight=9in % page height including headlines
+% \newdimen\pageshift \pageshift=0in % shift righthand pages wrt lefthand ones
+% \def\magnify#1{\mag=#1\pagewidth=6.5truein\pageheight=8.7truein
+% \fullpageheight=9truein\setpage}
+% \def\setpage{\hsize\pagewidth\vsize\pageheight} % use after changing page size
+% \def\contentsfile{CONTENTS} % file that gets table of contents info
+% \def\readcontents{\input CONTENTS}
+%
+% \newwrite\cont
+% \output{\setbox0=\page % the first page is garbage
+% \openout\cont=\contentsfile
+% \global\output{\normaloutput\page\lheader\rheader}}
+% \setpage
+% \vbox to \vsize{} % the first \topmark won't be null
+%
+% \def\ch{\note{The following sections were changed by the change file:}
+% \let\*=\relax}
+% \newbox\sbox % saved box preceding the index
+% \newbox\lbox % lefthand column in the index
+% \def\inx{\par\vskip6pt plus 1fil % we are beginning the index
+% \write\cont{} % ensure that the contents file isn't empty
+% \closeout\cont % the contents information has been fully gathered
+% \output{\ifpagesaved\normaloutput{\box\sbox}\lheader\rheader\fi
+% \global\setbox\sbox=\page \global\pagesavedtrue}
+% \pagesavedfalse \eject % eject the page-so-far and predecessors
+% \setbox\sbox\vbox{\unvbox\sbox} % take it out of its box
+% \vsize=\pageheight \advance\vsize by -\ht\sbox % the remaining height
+% \hsize=.5\pagewidth \advance\hsize by -10pt
+% % column width for the index (20pt between cols)
+% \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines
+% \def\lr{L} % this tells whether the left or right column is next
+% \output{\if L\lr\global\setbox\lbox=\page \gdef\lr{R}
+% \else\normaloutput{\vbox to\pageheight{\box\sbox\vss
+% \hbox to\pagewidth{\box\lbox\hfil\page}}}\lheader\rheader
+% \global\vsize\pageheight\gdef\lr{L}\global\pagesavedfalse\fi}
+% \message{Index:}
+% \parskip 0pt plus .5pt
+% \outer\def\:##1, {\par\hangindent2em\noindent##1:\kern1em} % index entry
+% \def\[##1]{$\underline{##1}$} % underlined index item
+% \rm \rightskip0pt plus 2.5em \tolerance 10000 \let\*=\lapstar
+% \hyphenpenalty 10000 \parindent0pt}
+% \def\fin{\par\vfill\eject % this is done when we are ending the index
+% \ifpagesaved\null\vfill\eject\fi % output a null index column
+% \if L\lr\else\null\vfill\eject\fi % finish the current page
+% \parfillskip 0pt plus 1fil
+% \def\rhead{NAMES OF THE SECTIONS}
+% \message{Section names:}
+% \output{\normaloutput\page\lheader\rheader}
+% \setpage
+% \def\note##1##2.{\hfil\penalty-1\hfilneg\quad{\eightrm##1 ##2.}}
+% \linepenalty=10 % try to conserve lines
+% \def\U{\note{Used in}} % cross-reference for uses of sections
+% \def\:{\par\hangindent 2em}\let\*=*}
+% \def\con{\par\vfill\eject % finish the section names
+% \rightskip 0pt \hyphenpenalty 50 \tolerance 200
+% \setpage
+% \output{\normaloutput\page\lheader\rheader}
+% \titletrue % prepare to output the table of contents
+% \pageno=\contentspagenumber \def\rhead{TABLE OF CONTENTS}
+% \message{Table of contents:}
+% \topofcontents
+% \line{\hfil Section\hbox to3em{\hss Page}}
+% \def\Z##1##2##3{\line{\ignorespaces##1
+% \leaders\hbox to .5em{.\hfil}\hfil\ ##2\hbox to3em{\hss##3}}}
+% \readcontents\relax % read the contents info
+% \botofcontents \end} % print the contents page(s) and terminate
+% ?endgroup
+% \vfill\eject
+%
+\def\runninghead{APPENDIX G --- NOTES ON FORMATTING}
+\section Appendix G: How to use \.{WEB} macros.
+The macros in \.{webkernel} make it possible to produce a variety of formats
+without editing the output of \.{WEAVE}, and the purpose of this appendix
+is to explain some of the possibilities.
+
+\def\point#1.{\yskip\indent#1.\quad\ignorespaces}
+
+\point 1.
+Three fonts have been declared in addition to the standard fonts of
+\.{PLAIN} format: You can say `\.{\{\\sc stuff\}}' to get {\sc stuff}
+in small caps; and you can select the largish fonts \.{\\titlefont}
+and \.{\\ttitlefont} in the title of your document, where \.{\\ttitlefont}
+is a typewriter style of type.
+
+\point 2.
+When you mention an identifier in \TeX\ text, you normally call
+it `\.{|identifier|}'.
+But you can also say `\.{\\\\\{identifier\}}'.
+The
+output will look the same in both cases, but the second alternative
+doesn't put \\{identifier} into the index, since
+it bypasses \.{WEAVE}'s translation from \PASCAL\ mode.
+
+\point 3.
+To get typewriter-like type, as when referring to `\.{WEB}', you
+can use the `\.{\\.}' macro (e.g., `\.{\\.\{WEB\}}').
+In the argument to
+this macro you should insert an additional backslash before the symbols
+listed as `special string characters' in the index to \.{WEAVE}, i.e.,
+before backslashes and dollar signs and the like.
+A `\.{\\\ }' here will result in the visible space symbol; to get an
+invisible space following a control sequence you can say `\.{\{\ \}}'.
+
+\point 4.
+The three control sequences \.{\\pagewidth}, \.{\\pageheight},
+and \.{\\fullpageheight} can be redefined in the limbo section at the
+beginning of your \.{WEB} file, to change the dimensions of each page.
+The standard settings
+$$\lpile{\.{\\pagewidth=6.5in}\cr
+ \.{\\pageheight=8.7in}\cr
+ \.{\\fullpageheight=9in}\cr}$$
+were used to prepare the present report; \.{\\fullpageheight} is
+\.{\\pageheight} plus room for the additional heading and page numbers at
+the top of each page.
+If you change any of these quantities, you should
+call the macro \.{\\setpage} immediately after making the change.
+
+\point 5.
+The \.{\\pageshift} macro defines an amount by which right-hand
+pages (i.e., odd-numbered pages) are shifted right with respect to
+left-hand (even-numbered) ones.
+By adjusting this amount you may be
+able to get two-sided output in which the page numbers line up on
+opposite sides of each sheet.
+
+\point 6.
+The \.{\\title} macro will appear at the top of each page
+in small caps.
+For example, Appendix~D was produced after saying
+`\.{\\def\\title\{WEAVE\}}'.
+\newstuff
+(Appendix~D was omitted from this document; see Don Knuth's original {\tt WEB}
+technical report for all the appendices.)
+\endnewstuff
+
+\point 7.
+The first page usually is number 1; if you want some other
+starting page, just set \.{\\pageno} to the desired number.
+For example,
+the initial limbo section for Appendix~D included the command
+`\.{\\pageno=16}'.
+
+\point 8.
+The macro \.{\\iftitle} will suppress the header line if it is
+defined by `\.{\\titletrue}'.
+The normal value is \.{\\titlefalse}
+except for the table of contents; thus, the contents
+page is usually unnumbered.
+If your program is so long that the table of
+contents doesn't fit on a single page, or if you want a number to appear
+on the contents page, you should reset \.{\\pageno} when you begin the
+table of contents.
+
+Two macros are provided to give flexibility to the table of
+contents: \.{\\topofcontents} is invoked just before the contents
+info is read, and \.{\\botofcontents} is invoked just after.
+For example, Appendix~D
+was produced with the following definitions:
+$$\lpile{\.{\\def\\topofcontents\{\\null\\vfill}\cr
+ \.{ { }\\titlefalse \% include headline on the contents page}\cr
+ \.{ { }\\def\\rheader\{\\mainfont Appendix D\\hfil 15\}}\cr
+ \.{ { }\\centerline\{\\titlefont The \{\\ttitlefont WEAVE\}{ }processor\}}\cr
+ \.{ { }\\vskip 15pt \\centerline\{(Version 2.5)\}{ }\\vfill\}}\cr}$$
+Redefining \.{\\rheader}, which is the headline for right-hand pages,
+suffices in this case to put the desired information at the top of the page.
+
+\point 9.
+Data for the table of contents is written to a file that
+is read after the indexes have been \TeX ed; there's one line of data
+for every starred module.
+For example, when Appendix~D was being generated,
+a file
+% \.{CONTENTS.TEX}
+containing
+$$\lpile{\.{\\Z \{{ }Introduction\}\{1\}\{16\}}\cr
+ \.{\\Z \{{ }The character set\}\{11\}\{19\}}\cr}$$
+and similar lines was created.
+The \.{\\topofcontents} macro could
+redefine \.{\\Z} so that the information appears in another format.
+
+\point 10.
+Sometimes it is necessary or desirable to divide the output of
+\.{WEAVE} into subfiles that can be processed separately.
+For example,
+the listing of \TeX\ runs to more than 500 pages, and that is enough to
+exceed the capacity of many printing devices and/or their software.
+When an extremely large job isn't cut into smaller pieces, the entire
+process might be spoiled by a single error of some sort, making it
+necessary to start everything over.
+
+Here's a safe way to break a woven file into three parts:
+Say the pieces are $\alpha$,
+$\beta$, and $\gamma$, where each piece begins with a starred module.
+All macros should be defined in the opening limbo section of $\alpha$,
+and copies of this \TeX\ code should be placed at the
+beginning of $\beta$ and of $\gamma$.
+In order to process the parts
+separately, we need to take care of two things: The starting page
+numbers of $\beta$ and $\gamma$ need to be set up properly, and
+the table of contents data from all three runs needs to be
+accumulated.
+
+The \.{webmac} macros include two control sequences \.{\\contentsfile} and
+\.{\\readcontents} that facilitate the necessary processing.
+We include
+`\.{\\def\\contentsfile\{CONT1\}}' in the limbo section of $\alpha$, and
+we include `\.{\\def\\contentsfile\{CONT2\}}' in the limbo section of
+$\beta$; this causes \TeX\ to write the contents data for $\alpha$ and $\beta$
+into \.{CONT1.TEX} and \.{CONT2.TEX}.
+Now in $\gamma$ we say
+$$\.{\\def\\readcontents\{\\input CONT1 \\input CONT2 \\input CONTENTS\}};$$
+this brings in the data from all three pieces, in the proper order.
+
+\newstuff
+Warning: life is a little different in Spidery {\tt WEB}.
+{\TeX} hackers should go straight to the source.
+\endnewstuff
+
+However, we still need to solve the page-numbering problem.
+One way to
+do it is to include the following in the limbo material for $\beta$:
+$$\lpile{\.{\\message\{Please type the last page number of part 1: \}}\cr
+ \.{\\read-1to\\\\ \\pageno=\\\\ \\advance\\pageno by 1}\cr}$$
+Then you simply provide the necessary data when \TeX\ requests
+it; a similar construction is used at the beginning of $\gamma$.
+
+This method can, of course, be used to divide a woven file into
+any number of pieces.
+
+\point 11.
+Sometimes it is nice to include things in the index that are
+typeset in a special way.
+For example, we might want to have an
+index entry for `\TeX'.
+\.{WEAVE} provides only two standard ways to
+typeset an index entry (unless the entry is an identifier or a reserved word):
+`\.{@\^}' gives roman type, and `\.{@.}' gives typewriter type.
+But if we try to typeset `\TeX' in roman type by saying, e.g.,
+`\.{@\^\\TeX@>}', the backslash character gets in the way,
+and this entry wouldn't appear in the index with the T's.
+
+The solution is to use the `\.{@:}' feature, declaring a macro that
+simply removes a sort key as follows:
+$$\.{\\def\\9\#1\{\}}$$
+Now you can say, e.g., `\.{@:TeX\}\{\\TeX@>}' in your \.{WEB} file; \.{WEAVE}
+puts it into the index alphabetically, based on the sort key, and
+produces the macro call `\.{\\9\{TeX\}\{\\TeX\}}' which will ensure that
+the sort key isn't printed.
+
+A similar idea can be used to insert hidden material into module
+names so that they are alphabetized in whatever way you might wish.
+Some people call these tricks ``special refinements''; others call
+them ``kludges''.
+
+\point 12.
+The control sequence \.{\\modno} is set to the number of the
+module being typeset.
+
+\point 13.
+If you want to list only the modules that have changed,
+together with the index, put the command `\.{\\let\\maybe=\\iffalse}' in
+the limbo section before the first module of your \.{WEB} file.
+It's
+customary to make this the first change in your change file.
+
+\vfill
+
+\eject
+%
+% \def\runninghead{APPENDIX H --- GETTING STARTED}
+% \section Appendix H: Installing the \.{WEB} system.
+% Suppose you want to use the \.{WEB} programs on your computer, and suppose
+% that you can't simply borrow them from somebody else who has the same
+% kind of machine.
+% Here's what to do:
+%
+% \yskip
+% \def\step(#1){\par\hangindent 2em\noindent\hbox to 2em{\hfil(#1) }\ignorespaces}
+% \step(1) Get a tape that contains the files \.{WEAVE.WEB}, \.{TANGLE.WEB},
+% \.{TANGLE.PAS}, and \.{WEBMAC.TEX}.
+% The tape will probably also contain an
+% example change file \.{TANGLE.CH}.
+% \step(2) Look at the sections of \.{TANGLE} that are listed under ``system
+% dependencies'' in the index of Appendix~E above, and figure out what changes
+% (if any) will be needed for your system.
+% \step(3) Make a change file \.{TANGLE.CH} that contains the changes of~(2);
+% do not change your copy of \.{TANGLE.WEB}, leave it intact.
+% (The
+% rules for change files are explained at the end of the manual just before
+% the appendices; you may want to look at the example change file that
+% arrived with your copy of \.{TANGLE.WEB}.
+% It's also a good idea to
+% define all the ``switches'' like \&{debug} and \&{gubed} to be null in your
+% first change files; then you can sure that your compiler will handle
+% all of the code.)
+% \step(4) Make the changes of (2) in your copy of \.{TANGLE.PAS}.
+% (If these
+% changes are extensive, you might be better off finding some computer that
+% that already has \.{TANGLE} running, and making the new \.{TANGLE.PAS}
+% from \.{TANGLE.WEB} and your \.{TANGLE.CH}.)
+% \step(5) Use your \PASCAL\ compiler to convert your copy of \.{TANGLE.PAS}
+% to a running program \.{TANGLE}.
+% \step(6) Check your changes as follows: Run \.{TANGLE} on \.{TANGLE.WEB}
+% and your \.{TANGLE.CH}, yielding $\.{TANGLE.PAS}'$; make a running
+% program $\.{TANGLE}'$ by applying \PASCAL\ to
+% $\.{TANGLE.PAS}'$; run $\.{TANGLE}'$ on \.{TANGLE.WEB} and
+% your \.{TANGLE.CH}, yielding $\.{TANGLE.PAS}''$; and check
+% that $\.{TANGLE.PAS}''$ is identical to
+% $\.{TANGLE.PAS}'$.
+% Once this test has been passed, you have got a
+% working \.{TANGLE} program.
+% \step(7) Make a change file \.{WEAVE.CH} analogous to (3), but this time
+% consider the system-dependent parts of \.{WEAVE} that are listed in
+% the index to Appendix~D.
+% \step(8) Run \.{TANGLE} on \.{WEAVE.WEB} and your \.{WEAVE.CH}, obtaining
+% \.{WEAVE.PAS}.
+% \step(9) Use \PASCAL\ on \.{WEAVE.PAS} to make a running \.{WEAVE} program.
+% \step(10) Run \.{WEAVE} on \.{TANGLE.WEB} and \.{TANGLE.CH} to produce
+% \.{TANGLE.TEX}.
+% \step(11) Run \TeX\ on \.{TANGLE.TEX}, obtaining a listing analogous to
+% Appendix~E.
+% This listing will incorporate your changes.
+% \step(12) Run \.{WEAVE} on \.{WEAVE.WEB} and your \.{WEAVE.CH} to produce
+% \.{WEAVE.TEX}.
+% \step(13) Run \TeX\ on \.{WEAVE.TEX}, obtaining a listing analogous to
+% Appendix~D that incorporates your changes.
+%
+% \yskip\noindent
+% This description assumes that you already have a working \TeX82 system.
+% But what if you don't have \TeX82?
+% Then you start with a tape that also
+% contains \.{TEX.WEB} and \.{plain.tex}, and you refer to a hardcopy
+% listing of the \TeX82 program corresponding to \.{TEX.WEB}.
+% Between steps
+% (10) and (11) you do the following:
+%
+% \yskip
+% \def\substep(10.#1){\par\hangindent 4em\noindent
+% \hbox to 4em{\hfil(10.#1) }\ignorespaces}
+% \substep(10.1) Make a change file \.{TEX.CH} to fix the system dependent
+% portions of \.{TEX.WEB}, in a manner analogous to step~(2).
+% Since \TeX\ is
+% a much more complex program than \.{WEAVE} or \.{TANGLE}, there are more
+% system-dependent features to think about, but by now you will be good at
+% making such modifications.
+% Do not make any changes to \.{TEX.WEB}.
+% \substep(10.2) Make an almost-copy of your \.{TEX.CH} called \.{INITEX.CH};
+% this one will have the `\&{init}' and `\&{tini}' macros redefined in order
+% to make the initialization version of \TeX.
+% It also might have smaller
+% font memory and dynamic memory areas, since \.{INITEX} doesn't need as
+% much memory for such things; by setting the memory smaller in \.{INITEX},
+% you guarantee that the production system will have a ``cushion.''
+% \substep(10.3) Run \.{TANGLE} on \.{TEX.WEB} and \.{INITEX.CH}, obtaining
+% \.{INITEX.PAS} and \.{TEX.POOL}.
+% \substep(10.4) Run \PASCAL\ on \.{INITEX.PAS}, obtaining \.{INITEX}.
+% \substep(10.5) Run \.{INITEX} on \.{TEX.POOL}, during which run you type
+% `\.{plain}' and `\.{\\dump}'.
+% This will produce a file \.{plain.fmt}
+% containing the data needed to initialize \TeX's memory.
+% \substep(10.6) Run \.{TANGLE} on \.{TEX.WEB} and the \.{TEX.CH} of (10.1),
+% obtaining \.{TEX.PAS}.
+% \substep(10.7) Run \PASCAL\ on \.{TEX.PAS}, obtaining \.{VIRTEX}.
+% \substep(10.8) If your operating system supports programs whose core images
+% have been saved, run \.{VIRTEX}, type `\.{\&plain}', then save the core image
+% and call it \TeX.
+% Otherwise, \.{VIRTEX} will be your \TeX, and it will
+% read `\.{plain.fmt}' (or some other \.{fmt} file) each time you run.
+%
+% \yskip
+% This 21-step process may seem long, but it is actually an oversimplification,
+% since you also need fonts and a way to print the device-independent files
+% that \TeX\ spews out.
+% On the other hand, the total number of steps is not
+% quite so large when you consider that \.{TANGLE}-followed-by-\PASCAL\ and
+% \.{WEAVE}-followed-by-\TeX\ may be regarded as single operations.
+%
+% If you have only the present report, not a tape, you will have to prepare
+% files \.{WEAVE.WEB} and \.{TANGLE.WEB} by hand, typing them into the
+% computer by following Appendices D and E.
+% Then you have to simulate the
+% behavior of \.{TANGLE} by converting \.{TANGLE.WEB} manually into
+% \.{TANGLE.PAS}; with a good text editor this takes about six hours.
+% Then
+% you have to correct errors that were made in all this hand work; but still
+% the whole project is not impossibly difficult, because in fact the entire
+% development of \.{WEAVE} and \.{TANGLE} (including the writing of the
+% programs and the manual) took less than two months of work.
+%
+% \vfill
+
+\end
+
diff --git a/web/spiderweb/doc/spiderwebman.toc b/web/spiderweb/doc/spiderwebman.toc
new file mode 100644
index 0000000000..66f7f67ff5
--- /dev/null
+++ b/web/spiderweb/doc/spiderwebman.toc
@@ -0,0 +1 @@
+\catcode`\@=11
diff --git a/web/spiderweb/fixes-to-be-applied/changes b/web/spiderweb/fixes-to-be-applied/changes
new file mode 100644
index 0000000000..aab863bc4f
--- /dev/null
+++ b/web/spiderweb/fixes-to-be-applied/changes
@@ -0,0 +1,641 @@
+From fubinf!thull Mon Mar 12 09:01:53 1990
+Received: by cs.Princeton.EDU (5.57/1.98)
+ id AA22774; Mon, 12 Mar 90 09:01:50 EST
+Received: from [129.217.64.60] by Princeton.EDU (5.58+++/2.32/mailrelay)
+ id AA20280; Mon, 12 Mar 90 08:59:12 EST
+Received: from fubinf.uucp
+ by unido.informatik.uni-dortmund.de with uucp via EUnet (UNIDO-2.0.1.d)
+ for princeton.edu
+ id AO16211; Mon, 12 Mar 90 14:57:27 +0100
+Received: by fubinf.uucp (4.0/SMI-4.0)
+ id AA01394; Sat, 3 Nov 90 15:19:31 +0100
+Date: Sat, 3 Nov 90 15:19:31 +0100
+From: fubinf!thull (Klaus Thull)
+Message-Id: <9011031419.AA01394@fubinf.uucp>
+To: nr@Princeton.EDU
+Subject: spider.fixes
+Status: R
+
+These changes made spider operational on several suns, one old
+16bitter 68000 pcs cadmus, one 32bittter 68020 same,
+the sony news 68030, and the sony risc.
+please note that these changes refer to a version that came to me
+out of its own accord one day last summer and without bearing an exact date.
+please note that there is the issue of awk versions. I constantly
+have to take along one awk source to be sure to compile spider.
+please note that there is one extension as well: there is a symbolic
+printout in weave which has, in the case of knuths pascal-web,
+proven very handy.
+::::::::::::::
+common.ch
+::::::::::::::
+module 19
+
+@d buf_size = 200 /* for \.{WEAVE} and \.{TANGLE} */
+@d long_buf_size = 500 /* for \.{WEAVE} */
+
+
+module 26
+
+@d max_modules = 2000 /* number of identifiers, strings, module names;
+ must be less than 10240 */
+
+
+de-linting...
+@x module 29
+@ @<Add path name from {\tt -I} to search path@>=
+ pathaddname(*argv+2);
+@ @<Other...@>=
+@y
+@ @<Add path name from {\tt -I} to search path@>=
+ pathaddname(*argv+2);
+@ @<Other...@>=
+extern char* getenv();
+@z
+
+
+de-linting...
+@x module 33
+@ The included file name should only contain visible ASCII characters,
+@y
+@ The included file name should only contain visible ASCII characters,
+@z
+
+@x
+ if ((cur_file=pathopen(cur_file_name,"r"))==NULL) {
+@y
+ if ((cur_file=pathopen(cur_file_name))==NULL) {
+@z
+
+
+@d max_bytes = 90000 /* the number of bytes in identifiers,
+ index entries, and module names */
+@d max_names = 4000 /* number of identifiers, strings, module names;
+ must be less than 10240 */
+
+module 42
+
+@d hash_size = 353 /* should be prime */
+
+
+@x module 62
+@ Some implementations may wish to pass the |history| value to the
+@y
+@ Some implementations may wish to pass the |history| value to the
+@z
+
+activate stats
+@x
+ @<Print the job |history|@>;
+@y
+#ifdef STAT
+ print_stats();
+#endif
+ @<Print the job |history|@>;
+@z
+
+de-linting...
+@x
+fatal("! Usage: tangle webfile[.web] [changefile[.ch]] [-Ipathname ...]\n",0)@;
+else
+fatal("! Usage: weave webfile[.web] [changefile[.ch]] [-x] [-Ipathname ...]\n",
+ 0);
+@y
+fatal("! Usage: tangle webfile[.web] [changefile[.ch]] [-Ipathname ...]\n",
+ "")@;
+else
+fatal("! Usage: weave webfile[.web] [changefile[.ch]] [-x] [-Ipathname ...]\n",
+ "");
+@z
+::::::::::::::
+spider.ch
+::::::::::::::
+
+escape backslash...
+(and put titles right)
+#x module 11
+# We write tokens out to two files: |scrapfile| for \.{WEAVE}, and
+#y
+# We write tokens out to two files: |scrapfile| for \.{WEAVE}, and
+#z
+
+|ttokfile| for \.{TANGLE}.
+#<Set init...#>=
+ scrapfile = "scraps.web"
+#x
+ print "@*Scrap code generated by {\tt SPIDER}." > scrapfile
+ ttokfile = "outtoks.web"
+ print "@*Token code generated by {\tt SPIDER}." > scrapfile
+#y
+ print "@*Scrap code generated by {\\tt SPIDER}." > scrapfile
+ ttokfile = "outtoks.web"
+ print "@*Token code generated by {\\tt SPIDER}." > ttokfile
+#z
+
+escape backslash...
+#x module 16
+# We use a special file to write grammar information:
+#<Set init...#>=
+ grammarfile = "grammar.web"
+ print "@*Grammar code generated by {\tt SPIDER}." > grammarfile
+#y
+# We use a special file to write grammar information:
+#<Set init...#>=
+ grammarfile = "grammar.web"
+ print "@*Grammar code generated by {\\tt SPIDER}." > grammarfile
+#z
+
+escape backslash...
+#x module 62
+# This is how we write out the string or constant scrap, at the end.
+#y
+# This is how we write out the string or constant scrap, at the end.
+#z
+
+#x
+ " and \TeX\ strings are identified." > scrapfile
+#y
+ " and \\TeX\\ strings are identified." > scrapfile
+#z
+
+#x module 72
+# We use an ugly trick to get the token numbers different for
+#y
+# We use an ugly trick to get the token numbers different for
+#z
+
+#x
+ temp = temp + #'37 - highesttoken ## hackety hack!
+#y
+ temp = temp + #'37 + 3 - highesttoken ## hackety hack!
+ ## +3 because three highest are already defined!
+#z
+
+
+#x module 126
+# It's desirable to put the production in a comment, but we have to
+get rid of the confusing \vert, or \.{WEAVE} will think it introduces
+code.
+#<Remove \vert\ from |inputline[n]| and put results in |this_string|#>=
+ this_string = inputline[n]
+ tempi = index(this_string,"|")
+ while (tempi != 0) {
+ tempa = substr(this_string,1,tempi-1)
+ tempb = substr(this_string,tempi+1)
+ this_string = tempa "\\vert " tempb
+ tempi = index(this_string,"|")
+ }
+#y
+# It's desirable to put the production in a comment, but we have to
+get rid of the confusing \vert, or \.{WEAVE} will think it introduces
+code. And of other things as well\dots
+#<Remove \vert\ from |inputline[n]| and put results in |this_string|#>=
+ tempb = inputline[n]
+ tempa = ""
+ tempi = index(tempb,"\\")
+ while (tempi != 0) {
+ tempa = tempa substr(tempb,1,tempi-1) "\\BS "
+ tempb = substr(tempb,tempi+1)
+ tempi = index(tempb,"\\")
+ }
+ this_string = tempa tempb
+ tempb = this_string
+ tempa = ""
+ tempi = index(tempb,"##")
+ while (tempi != 0) {
+ tempa = tempa substr(tempb,1,tempi-1) "\\##"
+ tempb = substr(tempb,tempi+1)
+ tempi = index(tempb,"##")
+ }
+ this_string = tempa tempb
+ tempb = this_string
+ tempa = ""
+ tempi = index(tempb,"$")
+ while (tempi != 0) {
+ tempa = tempa substr(tempb,1,tempi-1) "\\$"
+ tempb = substr(tempb,tempi+1)
+ tempi = index(tempb,"$")
+ }
+ this_string = tempa tempb
+ tempb = this_string
+ tempa = ""
+ tempi = index(tempb,"%")
+ while (tempi != 0) {
+ tempa = tempa substr(tempb,1,tempi-1) "\\%"
+ tempb = substr(tempb,tempi+1)
+ tempi = index(tempb,"%")
+ }
+ this_string = tempa tempb
+ tempb = this_string
+ tempa = ""
+ tempi = index(tempb,"^")
+ while (tempi != 0) {
+ tempa = tempa substr(tempb,1,tempi-1) "\\^"
+ tempb = substr(tempb,tempi+1)
+ tempi = index(tempb,"^")
+ }
+ this_string = tempa tempb
+ tempb = this_string
+ tempa = ""
+ tempi = index(tempb,"@")
+ while (tempi != 0) {
+ tempa = tempa substr(tempb,1,tempi-1) "\\@@"
+ tempb = substr(tempb,tempi+1)
+ tempi = index(tempb,"@")
+ }
+ this_string = tempa tempb
+ tempi = index(this_string,"|")
+ while (tempi != 0) {
+ tempa = substr(this_string,1,tempi-1)
+ tempb = substr(this_string,tempi+1)
+ this_string = tempa "\\vert " tempb
+ tempi = index(this_string,"|")
+ }
+ tempi = index(this_string,"'")
+ while (tempi != 0) {
+ tempa = substr(this_string,1,tempi-1)
+ tempb = substr(this_string,tempi+1)
+ this_string = tempa "\\RQ " tempb
+ tempi = index(this_string,"'")
+ }
+ tempi = index(this_string,"`")
+ while (tempi != 0) {
+ tempa = substr(this_string,1,tempi-1)
+ tempb = substr(this_string,tempi+1)
+ this_string = tempa "\\LQ " tempb
+ tempi = index(this_string,"`")
+ }
+ tempi = index(this_string,"{")
+ while (tempi != 0) {
+ tempa = substr(this_string,1,tempi-1)
+ tempb = substr(this_string,tempi+1)
+ this_string = tempa "\\LB " tempb
+ tempi = index(this_string,"{")
+ }
+ tempi = index(this_string,"}")
+ while (tempi != 0) {
+ tempa = substr(this_string,1,tempi-1)
+ tempb = substr(this_string,tempi+1)
+ this_string = tempa "\\RB " tempb
+ tempi = index(this_string,"}")
+ }
+ tempi = index(this_string,"~")
+ while (tempi != 0) {
+ tempa = substr(this_string,1,tempi-1)
+ tempb = substr(this_string,tempi+1)
+ this_string = tempa "\\TL " tempb
+ tempi = index(this_string,"~")
+ }
+ tempi = index(this_string,"_")
+ while (tempi != 0) {
+ tempa = substr(this_string,1,tempi-1)
+ tempb = substr(this_string,tempi+1)
+ this_string = tempa "\\UL " tempb
+ tempi = index(this_string,"_")
+ }
+ tempi = index(this_string,"&")
+ while (tempi != 0) {
+ tempa = substr(this_string,1,tempi-1)
+ tempb = substr(this_string,tempi+1)
+ this_string = tempa "\\AM " tempb
+ tempi = index(this_string,"&")
+ }
+#z
+
+
+activate this if year is field no 8
+
+ x module 151
+#*1Tracking the generation date.
+ y
+#*1Tracking the generation date.
+ z
+
+ x
+ year = $7
+ y
+ year = $8
+ z
+
+::::::::::::::
+tangle.ch
+::::::::::::::
+
+@ The following parameters were sufficient in the original \.{TANGLE} to
+handle \TeX, so they should be sufficient for most applications of \.{TANGLE}.
+
+If you change |max_bytes|, |max_names| or |hash_size| you should also
+change them in the file |"common.web"|.
+
+@d max_bytes = 90000 /* the number of bytes in identifiers,
+ index entries, and module names; used in |"common.web"| */
+@d max_toks = 150000 /* number of bytes in compressed \cee\ code */
+@d max_names = 4000 /* number of identifiers, strings, module names;
+ must be less than 10240; used in |"common.web"| */
+@d max_texts = 2000 /* number of replacement texts, must be less than 10240 */
+@d hash_size = 353 /* should be prime; used in |"common.web"| */
+@d longest_name = 400 /* module names shouldn't be longer than this */
+@d stack_size = 50 /* number of simultaneous levels of macro expansion */
+@d buf_size = 100 /* for \.{WEAVE} and \.{TANGLE} */
+
+de-linting...
+@x
+@ Here's the procedure that decides whether a name of length |l|
+starting at position |first| equals the identifier pointed to by |p|:
+
+@u
+names_match(p,first,l)
+name_pointer p; /* points to the proposed match */
+ASCII *first; /* position of first character of string */
+int l; /* length of identifier */
+@y
+@ Here's the procedure that decides whether a name of length |l|
+starting at position |first| equals the identifier pointed to by |p|:
+
+@u
+names_match(p,first,l,t)
+name_pointer p; /* points to the proposed match */
+ASCII *first; /* position of first character of string */
+int l; /* length of identifier */
+eight_bits t; /* which is a dummy but lint complains */
+ /* it will still complain \dots */
+@z
+
+
+
+12-char significance
+@x module 110
+@ We use macros with zero or more parameters, and we give the parameters names.
+@y
+@ We use macros with zero or more parameters, and we give the parameters names.
+@z
+
+@x
+@d max_param_name_texts = 256
+@y
+
+Identifier conflict with PCS C\dots
+
+@d param_name_texts_end = p_nm_txts_end
+@d next_param_name_text = next_p_nm_txt
+@#
+@d max_param_name_texts = 256
+@z
+
+de-linting
+@x
+@ This function prints out a decimal constant using |app_repl|.
+@u
+app_decimal(c)
+ int c; /* on entry require |c>=0| */
+{int power;
+@y
+@ This function prints out a decimal constant using |app_repl|.
+This casting trick is due to Tim Morgan's WEB-C.
+
+@d app_decimal(x) = zapp_decimal((long)(x))
+
+@u
+zapp_decimal(c)
+ long c; /* on entry require |c>=0| */
+{long power;
+@z
+::::::::::::::
+weave.ch
+::::::::::::::
+
+@x module 1
+#ifdef STAT
+ @<Print statistics about memory usage@>;
+#endif STAT
+@y
+@z
+
+module 2
+@ The following parameters were sufficient in the original \.{WEAVE} to
+handle \TeX, so they should be sufficient for most applications of \.{CWEAVE}.
+
+@d max_bytes = 90000 /* the number of bytes in identifiers,
+ index entries, and module names */
+@d max_names = 4000 /* number of identifiers, strings, module names;
+ must be less than 10240 */
+@d max_modules = 2000 /* greater than the total number of modules */
+@d hash_size = 353 /* should be prime */
+@d buf_size = 100 /* maximum length of input line, plus one */
+@d longest_name = 400 /* module names and strings shouldn't be longer than this */
+@d long_buf_size = 500 /* |buf_size+longest_name| */
+@d line_length = 80 /* lines of \TeX\ output have at most this many characters;
+ should be less than 256 */
+@d max_refs = 20000 /* number of cross-references; must be less than 65536 */
+@d max_toks = 20000 /* number of symbols in \cee\ texts being parsed;
+ must be less than 65536 */
+@x
+@d max_texts = 2000 /* number of phrases in \cee\ texts being parsed;
+ must be less than 10240 */
+@d max_scraps = 1000 /* number of tokens in \cee\ texts being parsed */
+@y
+@d max_texts = 4000 /* number of phrases in \cee\ texts being parsed;
+ must be less than 10240 */
+@d max_scraps = 4000 /* number of tokens in \cee\ texts being parsed */
+@z
+@d stack_size = 400 /* number of simultaneous output levels */
+
+@x
+/* identifier =200 or octal @'310 */
+@y
+/* identifier =200 or octal |@'310| */
+@z
+
+@x module 57
+@ In the \TeX\ part of a module, cross-reference entries are made only for
+@y
+@ In the \TeX\ part of a module, cross-reference entries are made only for
+@z
+
+@x doesn't belong here
+#ifdef DEBUG
+ case trace: tracing=next_control-'0'; continue;
+#endif DEBUG
+@y
+@z
+
+
+Print symbolically the entire tree
+
+@x module 87
+@ Token lists in |@!tok_mem| are composed of the following kinds of
+@y
+@ Token lists in |@!tok_mem| are composed of the following kinds of
+@z
+
+
+@u
+#ifdef DEBUG
+@x
+print_text(p) /* prints a token list */
+text_pointer p;
+@y
+print_text(p,ind) /* prints a token list */
+text_pointer p;
+int ind;
+@z
+{
+ token_pointer j; /* index into |tok_mem| */
+ sixteen_bits r; /* remainder of token after the flag has been stripped off */
+ if (p>=text_ptr) printf("BAD");
+ if (p>=text_ptr) printf("BAD");
+ else for (j=*p; j<*(p+1); j++) {
+ r=*j%id_flag;
+ r=*j%id_flag;
+ switch (*j/id_flag) {
+ case 1: printf("\\{"); print_id((name_dir+r)); printf("}"); break;
+ /* |id_flag| */
+ case 2: printf("\&{"); print_id((name_dir+r)); printf("}"); break;
+ /* |res_flag| */
+ case 3: printf("<"); print_id((name_dir+r)); printf(">"); break;
+ /* |mod_flag| */
+@x
+ case 4: printf("[[%d]]",r); break; /* |tok_flag| */
+ case 5: printf("|[[%d]]|",r); break; /* |inner_tok_flag| */
+@y
+ case 4: /* we make this a recursive prettyprinting here */
+ printf("@@/\n");
+ { int i; for (i=0; i<ind; i++) printf(" "); }
+ printf("[[%d:",r);
+ print_text(r+tok_start,ind+1);
+ printf("]]");
+ break; /* |tok_flag| */
+ case 5:
+ printf("@@/\n");
+ { int i; for (i=0; i<ind; i++) printf(" "); }
+ printf("|[[%d:",r);
+ print_text(r+tok_start,ind+1);
+ printf("]]|");
+ break; /* |inner_tok_flag| */
+@z
+ default: @<Print token |r| in symbolic form@>;
+ }
+ }
+}
+#endif DEBUG
+
+@x module 106
+@ @<If semi-tracing, show the irreducible scraps@>=
+#ifdef DEBUG
+@y
+@ @<If semi-tracing, show the irreducible scraps@>=
+#ifdef DEBUG
+ if (tracing==2)
+ {
+ scrap_pointer k;
+ printf("\nafter...\n");
+ for (k=scrap_base; k<=lo_ptr; k++)
+ { print_cat(k->cat); printf(", %ld:<",(long)(k->trans-tok_start));
+ print_text(k->trans,0); printf(">");
+ }
+ new_line;
+ }
+@z
+if (lo_ptr>scrap_base && tracing==1) {
+ printf("\nIrreducible scrap sequence in section %d:",module_count);
+ mark_harmless;
+ for (j=scrap_base; j<=lo_ptr; j++) {
+ printf(" "); print_cat(j->cat);
+ }
+}
+#endif DEBUG
+
+@x module 107
+@ @<If tracing,...@>=
+#ifdef DEBUG
+if (tracing==2) {
+ printf("\nTracing after l. %d:\n",cur_line); mark_harmless;
+ if (loc>buffer+50) {
+ printf("...");
+ ASCII_write(loc-51,51);
+ }
+ else ASCII_write(buffer+1,loc-buffer);
+}
+#endif DEBUG
+@y
+@ @<If tracing,...@>=
+#ifdef DEBUG
+if (tracing==2) {
+ scrap_pointer k;
+ printf("\nTracing after l. %d:\n",cur_line); mark_harmless;
+ if (loc>buffer+50) {
+ printf("...");
+ ASCII_write(loc-51,51);
+ }
+ else ASCII_write(buffer,loc-buffer);
+ printf("\nbefore...\n");
+ for (k=scrap_base; k<scrap_ptr; k++)
+ { print_cat(k->cat); printf(", %ld:<",(long)(k->trans-tok_start));
+ print_text(k->trans,0); printf(">\n");
+ }
+ new_line;
+}
+#endif DEBUG
+@z
+
+@x module 144
+@ In the \TeX\ part of a module, we simply copy the source text, except that
+@y
+@ In the \TeX\ part of a module, we simply copy the source text, except that
+@z
+
+@x
+ case vertical_bar: /* surround vertical bar with \.{\\CD...\\DC} */
+@y
+#ifdef DEBUG
+ case trace: tracing=*(loc-1)-'0'; continue;
+#endif DEBUG
+ case vertical_bar: /* surround vertical bar with \.{\\CD...\\DC} */
+@z
+
+
+
+@x module 262
+@ @<Print statistics about memory usage@>=
+printf(
+"\nMemory usage statistics: %d of %d names, %d of %d cross-references,\n",
+ name_ptr-name_dir, name_dir_end-name_dir,
+ xref_ptr-xmem, xmem_end-xmem);
+printf("\t %d of %d bytes;",byte_ptr-byte_mem,byte_mem_end-byte_mem);
+printf("\nParsing required %d of %d(%d) scraps, %d of %d(%d) texts,\n",
+ max_scr_ptr-scrap_info, max_scraps, max_scraps-SCRAP_SLACK,
+ max_text_ptr-tok_start, max_texts, max_texts-TEXT_SLACK
+ );
+printf("\t %d of %d(%d) tokens, %d of %d levels;\n",
+ max_tok_ptr-tok_mem, max_toks, max_toks-TOK_SLACK,
+ max_stack_ptr-stack, stack_end-stack
+ );
+printf("\nSorting required %d levels\n", max_sort_ptr-scrap_info);
+@y
+@ @u print_stats() {
+#ifdef STAT
+printf(
+"\nMemory usage statistics: %d of %d names, %d of %d cross-references,\n",
+ name_ptr-name_dir, name_dir_end-name_dir,
+ xref_ptr-xmem, xmem_end-xmem);
+printf("\t %d of %d bytes;",byte_ptr-byte_mem,byte_mem_end-byte_mem);
+printf("\nParsing required %d of %d(%d) scraps, %d of %d(%d) texts,\n",
+ max_scr_ptr-scrap_info, max_scraps, max_scraps-SCRAP_SLACK,
+ max_text_ptr-tok_start, max_texts, max_texts-TEXT_SLACK
+ );
+printf("\t %d of %d(%d) tokens, %d of %d levels;\n",
+ max_tok_ptr-tok_mem, max_toks, max_toks-TOK_SLACK,
+ max_stack_ptr-stack, stack_end-stack
+ );
+printf("\nSorting required %d levels\n", max_sort_ptr-scrap_info);
+#endif
+}
+@z
+
+@x
+#ifdef STAT
+ @<Print statistics about memory usage@>;
+#endif STAT
+@y
+@z
+
diff --git a/web/spiderweb/fixes-to-be-applied/dnn.web b/web/spiderweb/fixes-to-be-applied/dnn.web
new file mode 100644
index 0000000000..a9c4d033cd
--- /dev/null
+++ b/web/spiderweb/fixes-to-be-applied/dnn.web
@@ -0,0 +1,125 @@
+%<$DNN GRAMMAR Condenser - Ver DN-1A(2) - [PQN-OTFA]$>
+% Copyright 1989--1990 by David Ness
+% Not to be sold, but may be used freely for any purpose or for any purposes of
+% Norman Ramsey
+
+\let\RA\rightarrow
+
+\def\vert{{\tt\char'174}}
+\def\pb{$\.|\ldots\.|$} % C brackets (|...|)
+
+\def\title{DNN GRAMMAR Condenser}
+
+\def\topofcontents{\null\vfill
+ \titlefalse % include headline on the contents page
+ \def\rheader{\hfil}
+ \centerline{\titlefont The {\ttitlefont DNN GRAMMAR} Condenser}
+ \vfill}
+
+
+\def\syntax##1{\leavevmode\hbox{$\langle\hbox{\sl ##1\/}\rangle$}}
+\def\produces{\leavevmode\hbox{${}::={}$}}
+\def\opt##1{$[$##1$]$}
+
+#*=The {\tt SPIDER} grammar condenser.
+#*Introduction.
+This is an \.{AWK} program designed to read a description of a grammar and to
+produce calls on |squash| instead of |reduce| where it can.
+
+This might not look very important, but the grammar of {\tt C} is such that
+MicroSoft C 5.1 can't handle the \.{WEB} for \.{WEAVE} because the |translate|
+function turns out to be too large. By good luck, the condensation done here
+manages to (just) avoid that!
+
+The philosophy here is very simple. We are only `interested' in lines
+which begin with |app1| or |reduce|. When they begin with |app1(pp+n...| we
+table |n| in the array |data| and don't generate anything. When they begin
+with |reduce| we check
+and see if the |reduce| is consistent with the |app1|s. If so then we just
+generate one |squash| for the whole mess.
+
+In all other cases (an inconsistent |reduce| or neither an |app1| or
+|reduce|) we generate all of the lines (if there were any) that got swallowed
+into the |data| array.
+
+#d banner = "DNN GRAMMAR.WEB Condenser -> OUT.TMP Ver DN-1A(2)"
+#u#1
+BEGIN {
+#<Say Hello#>
+#<Set initial values#>
+}
+#@
+#<Define Functions#>
+#<Pattern-action statements#>
+#@
+END {
+#<Do final things#>
+}
+
+
+# #<Set init...#>=
+out = "out.tmp"
+Base = 0
+
+# |dumparray()| dumps any |app1(pp+...)|'s that have been accumulated so far.
+It is called when we get anything other than a |reduce| or |app1|, or if we
+get a |reduce| but it isn't {\it the right stuff!}
+#<Define Functions#>=
+function dumparray()
+{
+ if (Base != 0)
+ {
+ for (i = 0; i < Base; ++i) print "\tapp1(pp+" data[i] ");" >out
+ delete data
+ Base = 0
+ }
+ print $0 >out
+ return
+}
+
+# If we have an |app1(pp+n)| enter |n| into the table and keep going
+#<Pattern-action statements#>=
+#=/app1\(pp\+/#> {
+match($0,"app1\\(pp\\+.*\\)")
+val = substr($0,RSTART+8,RLENGTH-9)
+data[Base++] = val
+}
+
+# If we hit a |reduce(...)|, see if we should process it.
+#<Pattern-action statements#>=
+#=/reduce/#> {
+ match($0,"reduce\\(pp\\+[0-9]*\\,")
+ val = substr($0,RSTART+10,RLENGTH-11)
+ if (data[0] == val)
+ #<|reduce| starts where first |app1| started#>#;
+ else {dumparray()}
+}
+
+# #<|reduce| starts where first |app1| started#>=
+{
+ match($0,",[0-9]+,")
+ val = substr($0,RSTART+1,RLENGTH-2)
+ if (val == (1+data[Base-1]-data[0]))
+ #<|reduce| condenses right number of elements#>#;
+ else {dumparray()}
+}
+
+# #<|reduce| condenses right number of elements#>=
+{
+ match($0,"\\(.*\\);")
+ print "\tsquash" substr($0,RSTART,RLENGTH) >out
+ delete data
+ Base = 0
+}
+
+# When we encounter an `uninteresting' statement, dump anything that we might
+have accumulated.
+#<Pattern-action statements#>=
+#=$0 !~ /app1|reduce/#> {dumparray()}
+
+# #<Say Hello#>=print banner
+
+# #<Do final...#>=
+
+#*=Index.
+ \ No newline at end of file
diff --git a/web/spiderweb/fixes-to-be-applied/fixes b/web/spiderweb/fixes-to-be-applied/fixes
new file mode 100644
index 0000000000..e751557ded
--- /dev/null
+++ b/web/spiderweb/fixes-to-be-applied/fixes
@@ -0,0 +1,139 @@
+From patrick%cs.kuleuven.ac.be@princeton.edu Thu Aug 29 01:20:59 1991
+Return-Path: <patrick%cs.kuleuven.ac.be@princeton.edu>
+Received: from alpha.xerox.com by palain.PARC (4.1/SMI-4.1)
+ id AA13556; Thu, 29 Aug 91 01:20:57 PDT
+Received: from Minos.PARC.Xerox.xns by alpha.xerox.com via XNS id <11523>; Thu, 29 Aug 1991 01:20:32 PDT
+Received: from Princeton.EDU ([128.112.128.1]) by alpha.xerox.com with SMTP id <11523>; Thu, 29 Aug 1991 01:20:05 PDT
+Received: from fs.Princeton.EDU by Princeton.EDU (5.65b/2.80/princeton)
+ id AA15585; Thu, 29 Aug 91 04:19:59 -0400
+Received: from Princeton.EDU (Princeton.EDU.) by fs.Princeton.EDU (4.0/1.105)
+ id AA08885; Thu, 29 Aug 91 04:19:57 EDT
+Received: from n-kulcs.cs.kuleuven.ac.be by Princeton.EDU (5.65b/2.80/princeton)
+ id AA15582; Thu, 29 Aug 91 04:19:49 -0400
+Received: from medusa.cs.kuleuven.ac.be by n-kulcs.cs.kuleuven.ac.be (5.64+/n_kulcs1.1)
+ id AA02072; Thu, 29 Aug 91 10:20:48 +0200
+Received: by medusa.cs.kuleuven.ac.be (5.65b/cs_kuleuven.02)
+ id AA08766; Thu, 29 Aug 91 10:21:14 +0200
+X-Ns-Transport-Id: 08002008D0FD000FC327
+Date: Thu, 29 Aug 1991 01:21:14 PDT
+From: patrick%cs.kuleuven.ac.be@princeton.edu (Patrick Weemeeuw)
+Subject: Spidery Web
+To: nr@princeton.edu
+Message-Id: <9108290821.AA08766@medusa.cs.kuleuven.ac.be>
+Status: RO
+
+Hello,
+I'm trying to develop a web system for Prolog.
+
+One of the difficulties I had is recognizing tokens containing
+backslashes. I changed master/spider.web such that it now correctly
+handles tokens like:
+token \\== category ....
+generating the C string "\\==" but checking for a string with lenght *3*
+instead of 4.
+
+The context diff is included below.
+
+Patrick.
+--
+Patrick Weemeeuw mail: Katholieke Universiteit Leuven
+Tel: +32 16 200656 x 3544 Dept. of Computer Science
+e-mail: patrick@cs.kuleuven.ac.be Celestijnenlaan 200 A
+Fax: +32 16 205308 B-3001 Leuven (Belgium)
+======================================================================
+
+
+*** spider.web Wed Aug 28 19:32:01 1991
+--- spider.web.orig Wed Aug 28 17:47:57 1991
+***************
+*** 794,800
+ tokenname[$2]="SP_gen_token_" tokennumber
+ tokennumbers[$2]=tokennumber
+ tokennumber--
+- #<Find real length of |$2| and put it in |tokenlength[$2]|#>
+ ## figure out how to recognize the token
+ temp = sprintf( "strncmp(\"%s\",loc-1,%d)==0", $2, tokenlength[$2])
+ tokentest[$2]=temp
+
+--- 794,799 -----
+ tokenname[$2]="SP_gen_token_" tokennumber
+ tokennumbers[$2]=tokennumber
+ tokennumber--
+ ## figure out how to recognize the token
+ temp = sprintf( "strncmp(\"%s\",loc-1,%d)==0", $2, length($2))
+ tokentest[$2]=temp
+***************
+*** 796,802
+ tokennumber--
+ #<Find real length of |$2| and put it in |tokenlength[$2]|#>
+ ## figure out how to recognize the token
+! temp = sprintf( "strncmp(\"%s\",loc-1,%d)==0", $2, tokenlength[$2])
+ tokentest[$2]=temp
+
+ # To find the length of a string considered as a C~string, we scan it looking
+
+--- 795,801 -----
+ tokennumbers[$2]=tokennumber
+ tokennumber--
+ ## figure out how to recognize the token
+! temp = sprintf( "strncmp(\"%s\",loc-1,%d)==0", $2, length($2))
+ tokentest[$2]=temp
+ tokenlength[$2]=length($2)
+
+***************
+*** 798,803
+ ## figure out how to recognize the token
+ temp = sprintf( "strncmp(\"%s\",loc-1,%d)==0", $2, tokenlength[$2])
+ tokentest[$2]=temp
+
+ # To find the length of a string considered as a C~string, we scan it looking
+ for occurrences of the \.{\\} character. We initialize |templ| with
+
+--- 797,803 -----
+ ## figure out how to recognize the token
+ temp = sprintf( "strncmp(\"%s\",loc-1,%d)==0", $2, length($2))
+ tokentest[$2]=temp
++ tokenlength[$2]=length($2)
+
+
+ # The setting of attributes is as for all tokens:
+***************
+*** 799,827
+ temp = sprintf( "strncmp(\"%s\",loc-1,%d)==0", $2, tokenlength[$2])
+ tokentest[$2]=temp
+
+- # To find the length of a string considered as a C~string, we scan it looking
+- for occurrences of the \.{\\} character. We initialize |templ| with
+- |length($2)|, and each time we find a legitimate escape sequence, we decrement
+- |templ|. Remark that, given the current lexical analysis, \.{\\f}, \.{\\n} etc.
+- cannot occur in a token.
+- #<Find real length of |$2| and put it in |tokenlength[$2]|#>=
+- templ=length($2)
+- i=1 #/
+- while(i<=length($2)) { #/
+- if(substr($2,i,1)=="\\") { #/
+- if(i<length($2)) {
+- tempc=substr($2,i+1,1) #/
+- if((tempc=="a") || (tempc=="b") || (tempc=="\\") || (tempc=="?") || (tempc=="'")) {
+- templ--
+- i++
+- } else { #/
+- i++ #/
+- } #/
+- } #/
+- } #/
+- i++ #/
+- } #/
+- tokenlength[$2]=templ
+
+ # The setting of attributes is as for all tokens:
+ #<Set attributes of token |$2|#>=
+
+--- 799,804 -----
+ tokentest[$2]=temp
+ tokenlength[$2]=length($2)
+
+
+ # The setting of attributes is as for all tokens:
+ #<Set attributes of token |$2|#>=
+
diff --git a/web/spiderweb/fixes-to-be-applied/latex/README b/web/spiderweb/fixes-to-be-applied/latex/README
new file mode 100644
index 0000000000..e237cf9dbe
--- /dev/null
+++ b/web/spiderweb/fixes-to-be-applied/latex/README
@@ -0,0 +1,66 @@
+This is a collection of files to enable you to use Spidery Web with
+LaTeX as the formatter rather than plain TeX. It is copyright D.Love,
+SERC Daresbury Laboratory 1991 under the same conditions as the Spider
+distribution.
+
+--------------------------------------------------------------------
+#include <disclaimer.h>
+Snail mail: | JANET: d.love@uk.ac.dl
+Dr. David Love, | modern BIT/INTERNET: d.love@dl.ac.uk
+SERC Daresbury Laboratory, | old UUCP: ...!ukc!daresbury!d.love
+Warrington WA4 4AD, | alternative BITNET: d.love%dl@ukacrl
+UK | alternative ARPA: d.love%dl@nsfnet-relay.ac.uk
+ 'Phone: (+44/0)925 603573, Telex: ...925 629609, FAX: ...925 603173
+
+
+Here is a contents list. You will need to copy the files to the
+correct sub-directories of the spider source (once you are sure you
+want to) and invoke, for instance, `make weave' in the C directory to
+make a LaTeX version of weave. See web.doc for definitive information
+on the TeX aspect of things.
+
+* README.LaTeX This file;
+
+* latexweb.tex A short LaTeX document describing this stuff,
+ intended for submission to TUGboat;
+
+* weave.ltx A change file for $MASTER/weave.web which
+ inserts #defines to allow it to be compiled
+ for LaTeX-compatible output;
+
+* tangle.ltx Trivial change file for $MASTER/tangle.web to
+ allow woven output from it to be printed with
+ either LaTeX or plain;
+
+* spider.ltx Change file for $MASTER/spider.web to allow it
+ to produce output for a plain or LaTeX weave;
+
+* WebMakefile Changed version of $MASTER/WebMakefile
+ to cope with the change files above and the
+ different possible versions (also with my
+ filenames wired in);
+
+* web.doc Self-documenting LaTeX sub-style for use
+ instead of webkernel.tex. Probably needs
+ Mittelbach's newdoc.sty, v1.6d or later to
+ produce documentation -- instructions at the
+ front of it;
+
+* web.sty web.doc with comments stripped;
+
+* cmake Changed version of $SPIDER/c/make to produce
+ LaTeX ceeweave;
+
+* awkmake Changed version of $SPIDER/awk/make to produce
+ LaTeX awkweave;
+
+* cspider.dif Trivial diff from $SPIDER/c/c.spider to allow
+ it to work with LaTeX or plain;
+
+* tie.web Translation of the TIE processor to spidery
+ C-web. This allows you to merge change files
+ with the original or with other change files,
+ which may be useful for combining the LaTeX
+ changes with any you already have;
+
+* tiedoc.tex Explanation of the above.
diff --git a/web/spiderweb/fixes-to-be-applied/latex/WebMakefile b/web/spiderweb/fixes-to-be-applied/latex/WebMakefile
new file mode 100644
index 0000000000..4e948515af
--- /dev/null
+++ b/web/spiderweb/fixes-to-be-applied/latex/WebMakefile
@@ -0,0 +1,172 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+# Modified by Dave Love, Daresbury Lab (d.love@daresbury.ac.uk) for local
+# setup and to incorporate change files, particularly for LaTeX mods.
+# To make LaTeX versions of weave, set WEAVECHANGEFILE=$(MASTER)/weave.ltx
+# and include -DLaTeX in CFLAGS. To get a version of spider.awk usable for
+# LaTeX or plain, define SPIDERCHANGEFILE=$(MASTER)/spider.ltx and define
+# LaTeX=1 so that spider.awk generates LaTeX-compatible webs. I'm sure all
+# this could be tidied up.
+
+#HOME=/home/users0/fx# # Make no longer inherits environment vars
+# (it does inherit env vars on my system!)
+THETANGLE=tangle
+THEWEAVE=weave
+SPIDER=any.spider
+WEAVECHANGEFILE=
+TANGLECHANGEFILE=
+SPIDERCHANGEFILE=
+
+#
+DVI=dvi
+CFLAGS=-DDEBUG -DSTAT
+
+# CPUTYPE is a grim hack that attempts to solve the problem of multiple
+# cpus sharing a file system. In my environment I have to have different
+# copies of object and executable for vax, sun3, next, iris, and other
+# cpu types. If you will be using Spidery WEB in a homogenous processor
+# environment, you can just set CPUTYPE to a constant, or eliminate it
+# entirely.
+#
+# In my environment, the 'cputype' program returns a string that
+# describes the current processor. That means that the easiest thing
+# for you to do is to define a 'cputype' program that does something
+# sensible. A shell script that says 'echo "vax"' is fine.
+
+#CPUTYPE=`cputype`
+CPUTYPE=`arch`
+
+# Change the following three directories to match your installation
+#
+# the odd placement of # is to prevent any trailing spaces from slipping in
+
+WEBROOT=$(HOME)/ltxspiderweb# # root of the WEB source distribution
+DEST=$(HOME)/bin# # place where the executables go
+MACROS=$(HOME)/tex/inputs# # place where the macros go
+
+MASTER=$(WEBROOT)/master# # master source directory
+OBDIR=$(MASTER)/$(CPUTYPE)# # common object files
+
+TANGLESRC=tangle
+CTANGLE=ceetangle -I$(MASTER)
+CWEAVE=ceeweave -I$(MASTER)
+AWKTANGLE=awktangle -I$(MASTER)
+COMMONOBJS=$(OBDIR)/common.o $(OBDIR)/pathopen.o
+COMMONC=$(MASTER)/common.c $(MASTER)/pathopen.c
+COMMONSRC=$(COMMONC) $(MASTER)/spider.awk
+
+
+
+# Our purpose is to make tangle and weave
+
+web: tangle weave
+
+tangle: $(COMMONOBJS) $(TANGLESRC).o
+ cc $(CFLAGS) -o $(DEST)/$(THETANGLE) $(COMMONOBJS) $(TANGLESRC).o
+
+weave: $(COMMONOBJS) weave.o
+ cc $(CFLAGS) -o $(DEST)/$(THEWEAVE) $(COMMONOBJS) weave.o
+
+
+source: $(TANGLESRC).c $(COMMONSRC) # make tangle.c and common src, then clean
+ if [ -f WebMakefile ]; then exit 1; fi # don't clean the master!
+ if [ -f spiderman.tex ]; then exit 1; fi # don't clean the manual
+ -rm -f tangle.web weave.* common.* # remove links that may be obsolete
+ -rm -f *.unsorted *.list grammar.web outtoks.web scraps.web
+ -rm -f cycle.test spider.slog
+ -rm -f *.o *.tex *.toc *.dvi *.log *.makelog *~ *.wlog *.printlog
+
+# Here is how we make the common stuff
+
+$(MASTER)/common.c: $(MASTER)/common.web $(MASTER)/common.ch
+ $(CTANGLE) $(MASTER)/common $(MASTER)/common
+
+$(OBDIR)/common.o: $(MASTER)/common.c
+ cc $(CFLAGS) -c $(MASTER)/common.c
+ mv common.o $(OBDIR)
+
+
+$(MASTER)/pathopen.c: $(MASTER)/pathopen.web $(MASTER)/pathopen.ch
+ $(CTANGLE) $(MASTER)/pathopen $(MASTER)/pathopen
+ mv pathopen.h $(MASTER)
+
+$(OBDIR)/pathopen.o: $(MASTER)/pathopen.c
+ cc $(CFLAGS) -c $(MASTER)/pathopen.c
+ mv pathopen.o $(OBDIR)
+
+
+## Now we make the tangle and weave source locally
+
+$(TANGLESRC).c: $(MASTER)/$(TANGLESRC).web $(MASTER)/common.h grammar.web \
+ $(TANGLECHANGEFILE)
+ -/bin/rm -f $(TANGLESRC).web
+ ln $(MASTER)/$(TANGLESRC).web $(TANGLESRC).web
+# chmod -w $(TANGLESRC).web
+ $(CTANGLE) $(TANGLESRC) $(TANGLECHANGEFILE)
+
+weave.c: $(MASTER)/weave.web $(MASTER)/common.h grammar.web $(WEAVECHANGEFILE)
+ -/bin/rm -f weave.web
+ ln $(MASTER)/weave.web weave.web
+# chmod -w weave.web
+ $(CTANGLE) weave $(WEAVECHANGEFILE)
+
+## Here's where we run SPIDER to create the source
+
+grammar.web: $(MASTER)/cycle.awk $(MASTER)/spider.awk $(SPIDER)
+ echo "date" `date` | cat - $(SPIDER) | awk -f $(MASTER)/spider.awk \
+ LaTeX=$(LaTeX) -
+ cat $(MASTER)/transcheck.list trans_keys.unsorted | awk -f \
+ $(MASTER)/transcheck.awk
+ awk -f $(MASTER)/cycle.awk < cycle.test
+ sort *.unsorted | awk -f $(MASTER)/nodups.awk
+ mv *web.tex $(MACROS)
+
+## We might have to make spider first.
+
+$(MASTER)/spider.awk: $(MASTER)/spider.web $(SPIDERCHANGEFILE)
+ $(AWKTANGLE) $(MASTER)/spider $(SPIDERCHANGEFILE)
+ mv cycle.awk nodups.awk transcheck.awk $(MASTER)
+ rm junk.list
+
+# $(MASTER)/cycle.awk: $(MASTER)/cycle.web # making spider also makes cycle
+# $(AWKTANGLE) $(MASTER)/cycle
+
+# Weaving:
+
+weave.tex: $(MASTER)/weave.web grammar.web $(WEAVECHANGEFILE)
+ ceeweave -I$(MASTER) $(MASTER)/weave.web $(WEAVECHANGEFILE)
+ mv $(MASTER)/weave.tex .
+
+tangle.tex: $(MASTER)/tangle.web $(TANGLECHANGEFILE)
+ ceeweave -I$(MASTER) $(MASTER)/tangle.web $(TANGLECHANGEFILE)
+ mv $(MASTER)/tangle.tex .
+
+spider.tex: $(MASTER)/spider.web $(SPIDERCHANGEFILE)
+ awkweave -I$(MASTER) $(MASTER)/spider.web $(SPIDERCHANGEFILE)
+ mv $(MASTER)/spider.tex .
+
+# This cleanup applies to every language
+
+clean:
+ if [ -f WebMakefile ]; then exit 1; fi # don't clean the master!
+ if [ -f spiderman.tex ]; then exit 1; fi # don't clean the manual
+ -rm -f tangle.web weave.web common.* # remove links that may be obsolete
+ -rm -f *.unsorted *.list grammar.web outtoks.web scraps.web
+ -rm -f cycle.test spider.slog
+# vital bootstrap files are kept as SAVE..., hence only remove .c files whose
+# names start with lower case
+ -rm -f [a-z]*.c *.o *.tex *.toc *.dvi *.log *.makelog *~ *.wlog *.printlog
+
+
+
+# booting the new distribution
+boot:
+ cd ../master; rm -f *.o; for i in $(COMMONC); do \
+ cc $(CFLAGS) -c $$i; \
+ mv *.o $(OBDIR) ; \
+ done; cd ../c
+ cc $(CFLAGS) -c $(TANGLESRC).c; \
+ cc $(CFLAGS) -o $(DEST)/$(THETANGLE) $(COMMONOBJS) $(TANGLESRC).o
+
+
diff --git a/web/spiderweb/fixes-to-be-applied/latex/awkmake b/web/spiderweb/fixes-to-be-applied/latex/awkmake
new file mode 100644
index 0000000000..02cc270328
--- /dev/null
+++ b/web/spiderweb/fixes-to-be-applied/latex/awkmake
@@ -0,0 +1,5 @@
+/bin/make -f ../master/WebMakefile CPUTYPE=`cputype`\
+ THETANGLE=awktangle THEWEAVE=awkweave SPIDER=awk.spider \
+SPIDERCHANGEFILE=../master/spider.ltx WEAVECHANGEFILE=../master/weave.ltx \
+TANGLECHANGEFILE=../master/tangle.ltx \
+CFLAGS='-O1 -DC_FLOATING_POINT -DLaTeX' LaTeX=1 $*
diff --git a/web/spiderweb/fixes-to-be-applied/latex/cmake b/web/spiderweb/fixes-to-be-applied/latex/cmake
new file mode 100644
index 0000000000..d2853dbaa1
--- /dev/null
+++ b/web/spiderweb/fixes-to-be-applied/latex/cmake
@@ -0,0 +1,5 @@
+#!/bin/csh -f
+/bin/make -f ../master/WebMakefile CPUTYPE=`cputype`\
+CFLAGS="-O1 -DC_FLOATING_POINT -DLaTeX" LaTeX=1 THETANGLE=ceetangle \
+THEWEAVE=ceeweave SPIDER=c.spider TANGLECHANGEFILE=../master/tangle.ltx \
+WEAVECHANGEFILE=../master/weave.ltx SPIDERCHANGEFILE=../master/spider.ltx $*
diff --git a/web/spiderweb/fixes-to-be-applied/latex/cspider.dif b/web/spiderweb/fixes-to-be-applied/latex/cspider.dif
new file mode 100644
index 0000000000..1ed829d428
--- /dev/null
+++ b/web/spiderweb/fixes-to-be-applied/latex/cspider.dif
@@ -0,0 +1,17 @@
+*** c/c.spider Mon Feb 19 03:47:06 1990
+--- /home/users0/fx/ltxspiderweb/c/c.spider Wed Mar 13 11:58:35 1991
+***************
+*** 326,330 ****
+
+ # control sequence \8 puts things on the left margin
+! <force-"\\8"> sharp <"{\\let\\\\=\\bf"-space> (simp|if|else) <"}"-indent-"{}"-space> --> preproc
+ preproc backslash <force-"\\8\\hskip1em"-space> newline --> preproc
+ preproc <force-outdent> newline --> ignore_scrap
+--- 326,332 ----
+
+ # control sequence \8 puts things on the left margin
+! #<force-"\\8"> sharp <"{\\let\\\\=\\bf"-space> (simp|if|else) <"}"-indent-"{}"-space> --> preproc
+! # changed to work with LaTeX as well:
+! <force-"\\8"> sharp <"{\\let\\idfont=\\reservedfont"-space> (simp|if|else) <"}"-indent-"{}"-space> --> preproc
+ preproc backslash <force-"\\8\\hskip1em"-space> newline --> preproc
+ preproc <force-outdent> newline --> ignore_scrap
diff --git a/web/spiderweb/fixes-to-be-applied/latex/latexweb.tex b/web/spiderweb/fixes-to-be-applied/latex/latexweb.tex
new file mode 100644
index 0000000000..63219a188d
--- /dev/null
+++ b/web/spiderweb/fixes-to-be-applied/latex/latexweb.tex
@@ -0,0 +1,81 @@
+\documentstyle[ltugboat]{article}
+
+\let\tensl=\sl
+\title{\WEB{} Adapted to \LaTeX{} --- a First Attempt}
+\author{David Love}
+\netaddress{d.love@daresbury.ac.uk}
+\begin{document}
+\maketitle
+\noindent
+Following Knuth's original Pascal/TeX{} \WEB{} system a number of
+\WEB-like systems have been developed. Mostly these use the same
+plain \TeX{} formatting system and differ in the languages supported
+(although Thimbleby's CWEB system uses Troff and there are non-\WEB{}
+literate programming systems like Scheme\TeX{} and {\tt doc.sty} that
+use \LaTeX)\footnote{For a \WEB{} bibliography, see Lisa M. C. Smith
+and Mansur Samadzadeh, {\sl SIGPLAN Notices\/} {\bf 26} (1991)}\@.
+There are two advantages to using \LaTeX{} rather than plain \TeX{}
+for formatting:
+\begin{itemize}
+\item greater accessibility for many (familiarity and ease of use)
+which may encourage more people to use it;
+\item the availability of extra intrinsic \LaTeX{} facilities and
+especially style options. These might, for instance, support setting
+your formal specification material as well as the code refined from
+it, and in non-CM fonts.
+\end{itemize}
+This note describes a first attempt at integrating \LaTeX{} with
+\WEB\ (actually Ramsey's Spider system for
+`language-independent' \WEB s\footnote{Sometimes Spider doesn't do the
+whole job for you: non-Algol-like languages may need the lexing
+routines hacking. This gives the complication of
+amalgamating the basic \WEAVE{} change file for \LaTeX{} formatting
+with changes for the lexical routines etc.}).
+
+I have made minimal changes necessary for Spidery \WEB s to work with
+\LaTeX\@. These take the form of change files for the base {\tt
+weave.web}, {\tt tangle.web} and {\tt spider.web} (which generates the
+language-dependent parts), conversion of the {\tt webkernel.tex} macro
+file to a \LaTeX{} sub-style and trivial updates to the make files. A
+trivial change to the {\tt c.spider} file that describes the
+prettyprinting grammar for C was also necessary. The result of
+merging the change files with the original webs would be a {\tt
+weave.web} that can be built for use with either plain \TeX\ or
+\LaTeX\ using a makefile flag and a {\tt spider.web} that produces a
+{\tt spider.awk} with a run-time switch to determine the formatter.
+(\WEAVE\ cannot change the formatter assumed at run time, although it
+would not be difficult to make it do so.) \WEB\ files can be woven
+with either a plain or \LaTeX\ \WEAVE\ if they avoid using
+incompatible macros or define them appropriately in limbo
+according to whether the \LaTeX\ macros are present.
+
+The changes to {\tt spider.web} are minor; changes to {\tt weave.web}
+and the macros are more extensive. Many of the original \WEB{} macros
+clash with \LaTeX{} names or conventions and have been changed
+appropriately, but only where necessary. The formatting style is
+essentially unchanged apart from the use of the \LaTeX\ page headers
+and contents list. {\tt web.sty} is documented with {\tt doc.sty}
+since it is a pity not to use literate techniques to build literate
+programming tools---the bulk of the work! There are some remaining
+infelicities, such as floats being disrupted by the way the sectioning
+code avoids page breaks and a lot of messiness due to the assumptions
+of existing Spider descriptions.
+
+This hack could be developed in other directions, for instance:
+\begin{itemize}
+\item proper parameterisation of the formatting commands, perhaps
+modelled after {\tt makeindex};
+\item adapting the formatting macros more to the \LaTeX{} style;
+\item inclusion of a proper multi-level sectioning scheme. I think
+the extra structure would be helpful in large webs, but implementing
+it would require considerable attention to the guts of \TANGLE{} and
+\WEAVE\@. (It affects \TANGLE{} through the comments it writes in the
+code);
+\item replacing the index processing with {\tt makeindex}.
+\end{itemize}
+
+The changes should be available from the Aston archive as {\tt
+[.web.spiderweb]latexmods.shar}.
+
+\makesignature
+\end{document}
diff --git a/web/spiderweb/fixes-to-be-applied/latex/spider.ltx b/web/spiderweb/fixes-to-be-applied/latex/spider.ltx
new file mode 100644
index 0000000000..6e26a5304e
--- /dev/null
+++ b/web/spiderweb/fixes-to-be-applied/latex/spider.ltx
@@ -0,0 +1,107 @@
+% this is spider.ch $Header: /home/users0/fx/ltxspiderweb/master/spider.ltx,v 1.3 91/03/22 11:19:54 fx Exp $
+% for a LaTeX version of spider
+% d.love@daresbury.ac.uk
+
+l 5 (don't want batchmode for debugging; only print changes; for
+ LaTeX: want \documentstyle and fix use of \. and \title)
+#x
+\message{OK, entering \string\batchmode...}
+\batchmode
+#y
+\ifx\enddocument\undefined \else % check for LaTeX
+ \documentstyle[web]{article}
+ \let\maybe\iffalse
+ \let\.=\str
+ \def\LaTeX{{\rm L\kern-.36em\raise.3ex\hbox{\sc a}\kern-.15em
+ T\kern-.1667em\lower.7ex\hbox{E}\kern-.125emX}}
+\fi
+#z
+
+l 13 (change title page stuff)
+#x
+\def\title{SPIDER}
+
+\def\topofcontents{\null\vfill
+ \titlefalse % include headline on the contents page
+ \def\rheader{\hfil}
+ \centerline{\titlefont The {\ttitlefont SPIDER} processor}
+ \vfill}
+#y
+\ifx\enddocument\undefined % check for LaTeX
+\def\title{SPIDER}
+
+\def\topofcontents{\null\vfill
+ \titlefalse % include headline on the contents page
+ \def\rheader{\hfil}
+ \centerline{\titlefont The {\ttitlefont SPIDER} processor}
+ \vfill}
+\else
+ \title{The {\tt SPIDER} processor} \date{}
+\fi
+#z
+
+l 39
+#x
+The unusual lexical requirements of FORTRAN are probably beyond it, at
+least until the lexical analysis is modernized.)
+#y
+The unusual lexical requirements of FORTRAN are probably beyond it, at
+least until the lexical analysis is modernized.)
+
+This version of Spider has been changed to be able to produce a
+\.{WEAVE} suitable for use with \LaTeX{} rather than plain \TeX{}.
+The changes are minor and can be found by looking up ``LaTeX'' in the
+index. You get the \LaTeX{} version by defining |LaTeX=1| or
+something (the variable |LaTeX| should be non-null) on
+the \.{awk} command line when you run Spider. The limbo part will sort
+itself out for \LaTeX{} or plain when you weave this file.
+#z
+
+l 188 (bug fix)
+#x
+#<Set init...#>=
+ scrapfile = "scraps.web"
+ print "@*Scrap code generated by {\tt SPIDER}." > scrapfile
+ ttokfile = "outtoks.web"
+ print "@*Token code generated by {\tt SPIDER}." > scrapfile
+#y
+#<Set init...#>=
+ scrapfile = "scraps.web"
+ print "@*Scrap code generated by {\\tt SPIDER}." > scrapfile
+ ttokfile = "outtoks.web"
+ print "@*Token code generated by {\\tt SPIDER}." > scrapfile
+#z
+
+l 211 (bug fix)
+#x
+ grammarfile = "grammar.web"
+ print "@*Grammar code generated by {\tt SPIDER}." > grammarfile
+#y
+ grammarfile = "grammar.web"
+ print "@*Grammar code generated by {\\tt SPIDER}." > grammarfile
+#z
+
+l 2108 (change for LaTeX)
+#x
+ printf "*out_ptr='x'; tex_printf(\"\\\\input %sweb.te\");\n", \
+ extension > wlang
+#y
+ if (LaTeX=="") { #^LaTeX#>
+ printf "*out_ptr='x'; tex_printf(\"\\\\input %sweb.te\");\n", \
+ extension > wlang
+ }else{
+ printf "*out_ptr='}'; tex_printf(\"\\\\def\\\\webmacs{%sweb.tex\");\n", \
+ extension > wlang
+ }
+#z
+
+l 2121 (change for LaTeX)
+#x
+#<Write the first line of the macro file#>=
+ macrofile = extension "web.tex"
+ print "\\input webkernel.tex" > macrofile
+#y
+#<Write the first line of the macro file#>=
+ macrofile = extension "web.tex"
+ if (LaTeX=="") print "\\input webkernel.tex" > macrofile #^LaTeX#>
+#z
diff --git a/web/spiderweb/fixes-to-be-applied/latex/tangle.ltx b/web/spiderweb/fixes-to-be-applied/latex/tangle.ltx
new file mode 100644
index 0000000000..c7c054c5a2
--- /dev/null
+++ b/web/spiderweb/fixes-to-be-applied/latex/tangle.ltx
@@ -0,0 +1,79 @@
+this is tangle.latex-ch to fix tangle.web so that it can be woven with
+the LaTeX version of weave
+$Header: /home/users0/fx/ltxspiderweb/master/tangle.ltx,v 1.1 91/03/22 11:32:59 fx Exp $
+d.love@daresbury.ac.uk
+
+l 12 (fix for use with LaTeX or plain)
+@x
+% Here is TeX material that gets inserted after \input webmac
+
+\message{OK, entering \string\batchmode...}
+\batchmode
+
+\def\hang{\hangindent 3em\indent\ignorespaces}
+\font\ninerm=cmr9
+\let\mc=\ninerm % medium caps
+\def\cee{C}
+\def\pb{$\.|\ldots\.|$} % C brackets (|...|)
+\def\v{\char'174} % vertical (|) in typewriter font
+\def\ceeref{{\it The C Reference Manual}}
+\mathchardef\RA="3221 % right arrow
+\mathchardef\BA="3224 % double arrow
+
+\def\title{Spidery TANGLE}
+\def\contentspagenumber{1} % should be odd
+\def\topofcontents{\null\vfill
+ \titlefalse % include headline on the contents page
+ \def\rheader{\hfil}
+ \centerline{\titlefont The {\ttitlefont Spidery TANGLE} processor}
+ \vfill
+}
+@y
+% Here is TeX material that gets inserted after \documentstyle
+
+% \message{OK, entering \string\batchmode...}
+% \batchmode
+
+\ifx\enddocument\undefined % LaTeX?
+\font\ninerm=cmr9 % no...
+\let\mc=\ninerm % medium caps (not actually used)
+\def\title{Spidery TANGLE}
+\def\contentspagenumber{1} % should be odd
+\def\topofcontents{\null\vfill
+ \titlefalse % include headline on the contents page
+ \def\rheader{\hfil}
+ \centerline{\titlefont The {\ttitlefont Spidery TANGLE} processor}
+ \vfill
+}
+\else % yes...
+\documentstyle[web]{article}
+\title{Spidery TANGLE}\date{}
+\let\.=\str
+\fi
+
+\def\hang{\hangindent 3em\indent\ignorespaces}
+\def\cee{C}
+\def\pb{$\.|\ldots\.|$} % C brackets (|...|)
+\def\v{\char'174} % vertical (|) in typewriter font
+\def\ceeref{{\it The C Reference Manual}}
+\mathchardef\RA="3221 % right arrow
+\mathchardef\BA="3224 % double arrow
+@z
+
+l 1296 (fix \item)
+@x
+\yskip \item{a)}Module names are not allowed in macros;
+in fact, the appearance of a module name terminates such macros and denotes
+the name of the current module.
+
+\item{b)}The symbols \.{@@d} and \.{@@f} and \.{@@u} are not allowed after
+module names, while they terminate macro definitions.
+@y
+\begin{itemize}
+ \item[a)]Module names are not allowed in macros;
+in fact, the appearance of a module name terminates such macros and denotes
+the name of the current module.
+\item[b)]The symbols \.{@@d} and \.{@@f} and \.{@@u} are not allowed after
+module names, while they terminate macro definitions.
+\end{itemize}
+@z
diff --git a/web/spiderweb/fixes-to-be-applied/latex/tie.web b/web/spiderweb/fixes-to-be-applied/latex/tie.web
new file mode 100644
index 0000000000..3739558e19
--- /dev/null
+++ b/web/spiderweb/fixes-to-be-applied/latex/tie.web
@@ -0,0 +1,1276 @@
+% This is TIE.CWB as of 25 Oct 89
+%---------------------------------------------------------
+% (c) 1989 by THD/ITI. Put into the public domain.
+
+%
+% Version 1.7 was built alike TIE.WEB Version 1.6 (89-01-27)
+% but used a command line interface only
+% Version 2.0 was revised to include optional tab expansion (89-02-01)
+% Version 2.1 deleted WEB relicts. (-js) (89-10-25)
+%
+
+% Converted to spidery web Dave Love Feb 91 & bug fixed at line 990
+% and took out a couple of `@+' after `*' which break spidery weave
+
+% Here is TeX material that gets inserted after \input cwebmac
+
+\def\hang{\hangindent 3em\indent\ignorespaces}
+\font\mc=cmr9
+\def\PASCAL{Pascal}
+\def\Cl{{\rm C}}
+\def\ASCII{{\mc ASCII}}
+
+\def\title{TIE}
+\def\topofcontents{\null\vfill
+ \centerline{\titlefont The {\ttitlefont TIE} processor}
+ \vskip 15pt
+ \centerline{(CWEB Version 2.1)}
+ \vfill}
+\def\botofcontents{
+\null\vfill
+\item{$\copyright$}1989
+ by Technische Hochschule Darmstadt,\hfill\break
+Fachbereich Informatik, Institut f\"ur Theoretische Informatik\hfill\break
+All rights reserved.\hfill\break
+This program is put into the public domain and may be used freely
+for any non commercial purposes.
+}
+
+
+
+
+
+@* Introduction.
+
+\noindent Whenever a programmer wants to change a given
+\.{WEB} or \.{CWEB} program (referred to as a \.{WEB} program throughout
+this program) because of system dependencies, he will
+create a new change file. In addition there may be a second
+change file to modify system independent modules of the
+program. But the \.{WEB} file cannot be tangled and weaved
+with more than one change file simultaneously. Therefore,
+we introduce the present program to merge a \.{WEB} file and
+several change files producing a new \.{WEB} file. Since
+the input files are tied together, the program is called
+\.{TIE}. Furthermore, the program can be used to merge
+several change files giving a new single change file. This
+method seems to be more important because it doesn't modify
+the original source file. The use of \.{TIE} can be
+expanded to other programming languages since this processor
+only knows about the structure of change files and does not
+interpret the master file at all.
+
+The program \.{TIE} has to read lines from several input
+files to bring them in some special ordering. For this
+purpose an algorithm is used which looks a little bit
+complicated. But the method used only needs one buffer line
+for each input file. Thus the storage requirement of
+\.{TIE} does not depend on the input data.
+
+The program is written in \Cl\ and uses only few features of a
+particular environment that may need to be changed in other
+installations.
+E.g.\ it will not use the |enum| type declarations.
+The changes needed may refer to the access of the command line
+if this can be not supported by any \Cl\ compiler.
+
+The ``banner line'' defined here should be changed whenever
+\.{TIE} is modified. This program is put into the public
+domain. Nevertheless the copyright notice must not be
+replaced or modified.
+
+@d banner="This is TIE, CWEB Version 2.1."
+@d copyright=
+ "Copyright (c) 1989 by THD/ITI. All rights reserved."
+
+
+@ The main outline of the program is given in the next section.
+This can be used more or less for any \Cl\ program.
+@c
+@<Global |#include|s@>
+@<Global constants@>
+@<Global types@>
+@<Global variables@>
+@<Error handling functions@>
+@<Internal functions@>
+@<The main function@>
+
+@ Here are some macros for common programming idioms.
+
+@d incr(a) = a+=1 /* increase a variable by unity */
+@d decr(a) = a-=1 /* decrease a variable by unity */
+@d loop = @+ while (1)@+ /* repeat over and over until a |break| happens */
+@d do_nothing = /* empty statement */
+@f loop repeat
+
+
+@ Furthermore we include the additional types |boolean| and |string|.
+
+@<Global types@>=
+#define @!false 0
+#define @!true 1
+typedef int @!boolean;
+typedef char* string;
+
+
+@ The following parameters should be sufficient for most
+applications of \.{TIE}.
+@^system dependencies@>
+
+@<Global constants@>=
+#define @!buf_size 512 /* maximum length of one input line */
+#define @!max_file_index 9
+/* we don't think that anyone needs more than 9 change files,
+ but \dots\ just change it */
+
+
+@ We introduce a history variable that allows us to set a
+return code if the operating system can use it.
+First we introduce the coded values for the history.
+This variable must be initialized.
+(We do this even if the value given may be the default for
+variables, just to document the need for the initial value.)
+@d spotless=0
+@d troublesome=1
+@d fatal=2
+
+@<Global variables@>=
+int @!history=spotless;
+
+
+
+@* The character set.
+
+\noindent One of the main goals in the design of \.{TIE} has
+been to make it readily portable between a wide variety of
+computers. Yet \.{TIE} by its very nature must use a
+greater variety of characters than most computer programs
+deal with, and character encoding is one of the areas in
+which existing machines differ most widely from each other.
+
+To resolve this problem, all input to \.{TIE} is converted to an
+internal seven-bit code that is essentially standard \ASCII{}, the
+``American Standard Code for Information Interchange.'' The conversion
+is done immediately when each character is read in. Conversely,
+characters are converted from \ASCII{} to the user's external
+representation just before they are output. But the algorithm is
+prepared for the usage of eight-bit data.
+
+\noindent Here is a table of the standard visible \ASCII{} codes:
+$$\def\:{\char\count255\global\advance\count255 by 1}
+\count255='40
+\vbox{
+\hbox{\hbox to 40pt{\it\hfill0\/\hfill}%
+\hbox to 40pt{\it\hfill1\/\hfill}%
+\hbox to 40pt{\it\hfill2\/\hfill}%
+\hbox to 40pt{\it\hfill3\/\hfill}%
+\hbox to 40pt{\it\hfill4\/\hfill}%
+\hbox to 40pt{\it\hfill5\/\hfill}%
+\hbox to 40pt{\it\hfill6\/\hfill}%
+\hbox to 40pt{\it\hfill7\/\hfill}}
+\vskip 4pt
+\hrule
+\def\^{\vrule height 10.5pt depth 4.5pt}
+\halign{\hbox to 0pt{\hskip -24pt\O{#0}\hfill}&\^
+\hbox to 40pt{\tt\hfill#\hfill\^}&
+&\hbox to 40pt{\tt\hfill#\hfill\^}\cr
+04&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+05&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+06&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+07&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+10&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+11&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+12&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+13&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+14&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+15&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+16&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+17&\:&\:&\:&\:&\:&\:&\:\cr}
+\hrule width 280pt}$$
+(Actually, of course, code @'040 is an invisible blank space.) Code @'136
+was once an upward arrow (\.{\char'13}), and code @'137 was
+once a left arrow (\.^^X), in olden times when the first draft
+of ASCII code was prepared; but \.{TIE} works with today's standard
+ASCII in which those codes represent circumflex and underline as shown.
+The maximum value used is also defined, it must be changed if an
+extended \ASCII{} is used.
+
+If the \Cl\ compiler is not able to process \&{unsigned char}'s, you
+should define |ASCII_Code| as \&{short}.
+@^system dependencies@>
+
+@<Global types@>=
+#define max_ASCII @`~'+1
+typedef unsigned char @!ASCII_Code;
+ /* eight-bit numbers, a subrange of the integers */
+
+
+@ \Cl\ was first implemented on a machine that uses the
+\ASCII{} representation for characters. But to make it readily
+available also for other machines (big brother is watching?)\
+we add a conversion that may be undone for most installations.
+\.{TIE} assumes that it is being used
+with a character set that contains at least the
+characters of standard \ASCII{} as listed above.
+
+In order to accommodate this difference, we shall use the
+name |text_char| to stand for the data type of the
+characters in the input and output files. We shall also
+assume that |text_char| consists of the elements
+|first_text_char| through |last_text_char|,
+inclusive. The following definitions should be adjusted if
+necessary.
+@^system dependencies@>
+
+@d text_char = @+ unsigned char /* the data type of characters in text files */
+@d first_text_char=0 /* ordinal number of the smallest element of |text_char|*/
+@d last_text_char=255 /* ordinal number of the largest element of |text_char|*/
+@f FILE int
+
+@<Global types@>=
+typedef FILE* @!text_file;
+
+
+@ The \.{TIE} processor converts between \ASCII{} code and
+the user's external character set by means of arrays |xord|
+and |xchr| that are analogous to \PASCAL's |ord| and |chr|
+functions.
+
+The mapping may be disabled by changing the following macro
+definitions to just a cast. If your \Cl\ compiler does not support
+\&{unsigned char}'s, you should incorporate a binary and with @"ff.
+@^system dependencies@>
+
+@d map_xchr(a)=xchr[a]
+ /* change this to |(text_char)(a)| on \ASCII{} machines */
+@d map_xord(a)=xord[a]
+ /* change this to |(ASCII_Code)(a)| on \ASCII{} machines */
+
+@<Global variables@>=
+ASCII_Code @!xord[last_text_char+1];
+ /* specifies conversion of input characters */
+text_char @!xchr[max_ASCII+1];
+ /* specifies conversion of output characters */
+
+
+@ If we assume that every system using \.{WEB} is able to
+read and write the visible characters of standard \ASCII{}
+(although not necessarily using the \ASCII{} codes to
+represent them), the following assignment statements
+initialize most of the |xchr| array properly, without
+needing any system-dependent changes. For example, the
+statement |xchr[@`A']='A'| that appears in the present
+\.{WEB} file might be encoded in, say, {\mc EBCDIC} code on
+the external medium on which it resides, but \.{CTANGLE} will
+convert from this external code to \ASCII{} and back again.
+Therefore the assignment statement |xchr[65]='A'| will
+appear in the corresponding \Cl\ file, and \Cl\ will
+compile this statement so that |xchr[65]| receives the
+character \.A in the external code. Note that it
+would be quite incorrect to say |xchr[@`A']=@`A'|, because
+|@`A'| is a constant of type |int| not \&{char}, and
+because we have |@`A'==65| regardless of the external
+character set.
+
+@<Set initial values@>=
+xchr[@` ']=' ';
+xchr[@`!']='!';
+xchr[@`"']='"';
+xchr[@`#']='#';@/
+xchr[@`$']='$';
+xchr[@`%']='%';
+xchr[@`&']='&';
+xchr[@`'']='\'';@/
+xchr[@`(']='(';
+xchr[@`)']=')';
+xchr[@`*']='*';
+xchr[@`+']='+';@/
+xchr[@`,']=',';
+xchr[@`-']='-';
+xchr[@`.']='.';
+xchr[@`/']='/';@/
+xchr[@`0']='0';
+xchr[@`1']='1';
+xchr[@`2']='2';
+xchr[@`3']='3';@/
+xchr[@`4']='4';
+xchr[@`5']='5';
+xchr[@`6']='6';
+xchr[@`7']='7';@/
+xchr[@`8']='8';
+xchr[@`9']='9';
+xchr[@`:']=':';
+xchr[@`;']=';';@/
+xchr[@`<']='<';
+xchr[@`=']='=';
+xchr[@`>']='>';
+xchr[@`?']='?';@/
+xchr[@`@@']='@@';
+xchr[@`A']='A';
+xchr[@`B']='B';
+xchr[@`C']='C';@/
+xchr[@`D']='D';
+xchr[@`E']='E';
+xchr[@`F']='F';
+xchr[@`G']='G';@/
+xchr[@`H']='H';
+xchr[@`I']='I';
+xchr[@`J']='J';
+xchr[@`K']='K';@/
+xchr[@`L']='L';
+xchr[@`M']='M';
+xchr[@`N']='N';
+xchr[@`O']='O';@/
+xchr[@`P']='P';
+xchr[@`Q']='Q';
+xchr[@`R']='R';
+xchr[@`S']='S';@/
+xchr[@`T']='T';
+xchr[@`U']='U';
+xchr[@`V']='V';
+xchr[@`W']='W';@/
+xchr[@`X']='X';
+xchr[@`Y']='Y';
+xchr[@`Z']='Z';
+xchr[@`[']='[';@/
+xchr[@`\\']='\\';
+xchr[@`]']=']';
+xchr[@`^']='^';
+xchr[@`_']='_';@/
+xchr[@`'']='`';
+xchr[@`a']='a';
+xchr[@`b']='b';
+xchr[@`c']='c';@/
+xchr[@`d']='d';
+xchr[@`e']='e';
+xchr[@`f']='f';
+xchr[@`g']='g';@/
+xchr[@`h']='h';
+xchr[@`i']='i';
+xchr[@`j']='j';
+xchr[@`k']='k';@/
+xchr[@`l']='l';
+xchr[@`m']='m';
+xchr[@`n']='n';
+xchr[@`o']='o';@/
+xchr[@`p']='p';
+xchr[@`q']='q';
+xchr[@`r']='r';
+xchr[@`s']='s';@/
+xchr[@`t']='t';
+xchr[@`u']='u';
+xchr[@`v']='v';
+xchr[@`w']='w';@/
+xchr[@`x']='x';
+xchr[@`y']='y';
+xchr[@`z']='z';
+xchr[@`{']='{';@/
+xchr[@`|']='|';
+xchr[@`}']='}';
+xchr[@`~']='~';@/
+xchr[0]=' '; xchr[@"7F]=' '; /* these \ASCII{} codes are not used */
+
+
+@ Some of the \ASCII{} codes below @"20 have been given a
+symbolic name in \.{TIE} because they are used with a special
+meaning.
+
+@d tab_mark = @"09 /* \ASCII{} code used as tab-skip */
+@d nl_mark = @"0A /* \ASCII{} code used as line end marker */
+@d form_feed = @"0C /* \ASCII{} code used as page eject */
+
+
+@ When we initialize the |xord| array and the remaining
+parts of |xchr|, it will be convenient to make use of an
+index variable, |i|.
+
+@<Local variables for initialisation@>=
+int i;
+
+
+@ Here now is the system-dependent part of the character
+set. If \.{TIE} is being implemented on a garden-variety
+\Cl\ for which only standard \ASCII{} codes will appear
+in the input and output files, you don't need to make any
+changes here.
+@^system dependencies@>
+
+Changes to the present module will make \.{TIE} more
+friendly on computers that have an extended character set,
+so that one can type things like \.^^Z. If you have an
+extended set of characters that are easily incorporated into
+text files, you can assign codes arbitrarily here, giving an
+|xchr| equivalent to whatever characters the users of
+\.{TIE} are allowed to have in their input files, provided
+that unsuitable characters do not correspond to special
+codes like |tab_mark| that are listed above.
+
+@<Set init...@>=
+for (i=1;i<@` ';xchr[i++]=' ');
+xchr[tab_mark]='\t';
+xchr[form_feed]='\f';
+xchr[nl_mark]='\n';
+
+
+@ The following system-independent code makes the |xord|
+array contain a suitable inverse to the information in
+|xchr|.
+
+@<Set init...@>=
+for ( i=first_text_char ; i<=last_text_char ; xord[i++]=@` ' ) do_nothing;
+for ( i=1 ; i<=@`~' ; i++ ) xord[xchr[i]] = i;
+
+
+
+
+
+@* Input and output.
+
+\noindent Output for the user is done by writing on file |term_out|,
+which is assumed to consist of characters of type \&{text\_char}. It
+should be linked to |stdout| usually. Terminal input is not needed in
+this version of \.{TIE}. |stdin| and |stdout| are predefined if we
+include the \.{stdio.h} definitions. Although I/O redirection for
+|stdout| is usually available you may lead output to another file if
+you change the definition of |term_out|. Also we define some macros
+for terminating an output line and writing strings to the user. These
+distinguish the number of parameters used to ease translation with a
+\.{CWEB} like Sylvio Levy's that does not support a variable number of
+parameters for macros.
+
+@^system dependencies@>
+@d term_out=stdout
+@d print(a)=fprintf(term_out,a) /* `|print|' means write on the terminal */
+@d print2(a)=fprintf(term_out,a) /* same with two arguments */
+@d print3(a)=fprintf(term_out,a) /* same with three arguments */
+@d print_c(a)=fputc(a,term_out); /* print a single character */
+@d new_line(a)=fputc('\n',a) /* start new line */
+@d term_new_line=new_line(term_out) /* start new line of the terminal */
+@d print_ln(a)={fprintf(term_out,a);term_new_line;}
+ /* `|print|' and then start new line */
+@d print2_ln(a)={print2(a);term_new_line;} /* same with two arguments */
+@d print3_ln(a)={print3(a);term_new_line;} /* same with three arguments */
+@d print_nl(a)= /* print information starting on a new line */
+ {term_new_line; print(a);}
+@d print2_nl(a)= /* same for two arguments */
+ {term_new_line; print2(a);}
+
+@<Global |#include|s@>=
+#include <stdio.h>
+
+
+@ And we need dynamic memory allocation.
+This should cause no trouble in any \Cl\ program.
+@^system dependencies@>
+
+@<Global |#include|s@>=
+extern char *malloc();
+
+
+@ The |update_terminal| function is called when we want to
+make sure that everything we have output to the terminal so
+far has actually left the computer's internal buffers and
+been sent.
+@^system dependencies@>
+
+@d update_terminal = fflush(term_out) /* empty the terminal output buffer */
+
+
+
+
+
+@* Data structures.
+
+\noindent The multiple input files (master file and change
+files) are treated the same way. To organize the
+simultaneous usage of several input files, we introduce the
+data type \&{in\_file\_modes}.
+
+The mode |search| indicates that \.{TIE} searches for a
+match of the input line with any line of an input file in
+|reading| mode. |test| is used whenever a match is found
+and it has to be tested if the next input lines do match
+also. |reading| describes that the lines can be read without
+any check for matching other lines. |ignore| denotes
+that the file cannot be used. This may happen because an
+error has been detected or because the end of the file has
+been found.
+
+\leavevmode |file_types| is used to describe whether a file
+is a master file or a change file. The value |unknown| is added
+to this type to set an initial mode for the output file.
+This enables us to check whether any option was used to select
+the kind of output. (this would even be necessary if we
+would assume a default action for missing options.)
+
+@<Global types@>=
+#define search 0
+#define test 1
+#define reading 2
+#define ignore 3
+typedef int @!in_file_modes; /* should be |enum(search,test,reading,ignore)| */
+#define unknown 0
+#define master 1
+#define chf 2
+typedef int @!file_types; /* should be |enum(unknown,master,chf)| */
+
+
+@ A variable of type |out_md_type| will tell us in what state the output
+change file is during processing. |normal| will be the state, when we
+did not yet start a change, |pre| will be set when we write the lines
+to be changes and |post| will indicate that the replacement lines are
+written.
+
+@<Global types@>=
+#define normal 0
+#define pre 1
+#define post 2
+typedef int @!out_md_type; /* should be |enum(normal,pre,post)| */
+
+
+@ Two more types will indicate variables used as an index into either
+the file buffer or the file table.
+
+@<Global types@>=
+typedef int @!buffer_index; /* |-1..buf_size| */
+typedef int @!file_index; /* |-1..max_file_index+1| */
+
+
+@ The following data structure joins all informations needed to use
+these input files.
+
+@<Global types@>=
+typedef struct _idsc{
+ string @!name_of_file;
+ ASCII_Code @!buffer[buf_size];
+ in_file_modes @!mode;
+ long @!line;
+ file_types @!type_of_file;
+ buffer_index @!limit;
+ text_file the_file;
+ } @!input_description;
+
+
+@ These data types are used in the global variable section.
+They refer to the files in action, the number of change files,
+the mode of operation and the current output state.
+
+@<Global variables@>=
+file_index @!actual_input,@!test_input,@!no_ch;
+file_types @!prod_chf=unknown;
+out_md_type @!out_mode;
+
+
+@ All input files (including the master file) are recorded
+in the following structure.
+Mostly the components are accessed through a local pointer variable.
+This corresponds to \PASCAL's \&{with}-statement
+and results in a one-time-computation of the index expression.
+
+@f input_description int
+
+@<Global variables@>=
+input_description *@!input_organization[max_file_index+1];
+
+
+
+
+
+@* File I/O.
+
+\noindent The basic function |get_line| can be used to get a line from
+an input file. The line is stored in the |buffer| part of the
+descriptor. The components |limit| and |line| are updated. If the
+end of the file is reached |mode| is set to |ignore|. On some systems
+it might be useful to replace tab characters by a proper number of
+spaces since several editors used to create change files insert tab
+characters into a source file not under control of the user. So it
+might be a problem to create a matching change file.
+@^tab character expansion@>
+
+We define |get_line| to read a line from a file specified by
+the corresponding file descriptor.
+
+@<Internal functions@>=
+@h void get_line(i)
+ file_index i;
+{register input_description *inp_desc=input_organization[i];
+ if (inp_desc->mode==ignore) return;
+ if (feof(inp_desc->the_file))
+ @<Handle end of file and return@>;
+ @<Get line into buffer@>;
+}
+
+
+@ End of file is special if this file is the master file.
+Then we set the global flag variable |input_has_ended|.
+
+@<Handle end of file ...@>=
+{
+ inp_desc->mode=ignore;
+ inp_desc->limit=-1; /* mark end-of-file */
+ if (inp_desc->type_of_file==master) input_has_ended=true;
+ return;
+}
+
+
+@ This variable must be declared for global access.
+
+@<Global variables@>=
+static boolean input_has_ended=false;
+
+
+@ Lines must fit into the buffer completely.
+We read all characters sequentially until an end of line is found
+(but do not forget to check for |EOF|!).
+Too long input lines will be truncated.
+This will result in a damaged output if they occur in the
+replacement part of a change file, or in an incomplerte check if the
+matching part is concerned.
+Tab character expansion might be done here.
+@^tab character expansion@>
+
+@<Get line into buffer@>=
+{int final_limit; /* used to delete trailing spaces */
+ int c; /* the actual character read */
+ @<Increment the line number and print a progess report at
+ certain times@>
+ inp_desc->limit=final_limit=0;
+ while (inp_desc->limit<buf_size) {
+ c=fgetc(inp_desc->the_file);
+ @<Check |c| for |EOF|, |return| if line was empty, otherwise
+ |break| to process last line@>
+ inp_desc->buffer[inp_desc->limit++]=c=map_xord(c);
+ if (c==nl_mark) break; /* end of line found */
+ if (c!=@` ' && c!=tab_mark)
+ final_limit=inp_desc->limit;
+ }
+ @<Test for truncated line, skip to end of line@>
+ inp_desc->limit=final_limit;
+}
+
+
+@ This section does what its name says. Every 100 lines
+in the master file we print a dot, every 500 lines the number
+of lines is shown.
+
+@<Increment the line number and print ...@>=
+incr(inp_desc->line);
+if (inp_desc->type_of_file==master && inp_desc->line % 100==0) {
+ if (inp_desc->line % 500 == 0) print2("%ld",inp_desc->line);
+ else print_c('.');
+ update_terminal;
+}
+
+
+@ There may be incomplete lines of the editor used does
+not make sure that the last character before end of file
+is an end of line. In such a case we must process the
+final line. Of the current line is empty, we just can \&{return}.
+Note that this test must be done {\sl before} the character read
+is translated.
+@^system dependencies@>
+
+@<Check |c| for |EOF|...@>=
+ if (c==EOF) {
+ if (inp_desc->limit<=0) {
+ inp_desc->mode=ignore;
+ inp_desc->limit=-1; /* mark end-of-file */
+ if (inp_desc->type_of_file==master) input_has_ended=true;
+ return;
+ } else { /* add end of line mark */
+ c=nl_mark;
+ break;
+ }
+ }
+
+
+@ If the line is truncated we must skip the rest
+(and still watch for |EOF|!).
+@<Test for truncated line, skip to end of line@>=
+if (c!=nl_mark) {
+ err_print("! Input line too long")(i);
+@.Input line too long@>
+ while ( (c=fgetc(inp_desc->the_file)) != EOF && map_xord(c) != nl_mark )
+ do_nothing; /* skip to end */
+ }
+
+
+
+
+
+@* Reporting errors to the user.
+
+\noindent There may be errors if a line in a given change
+file does not match a line in the master file or a
+replacement in a previous change file. Such errors are
+reported to the user by saying
+$$
+ \hbox{|err_print("! Error message")(file_no)|;}
+$$
+where |file_no| is the number of the file which is concerned by the
+error. Please note that no trailing dot is supplied by the error
+message because it is appended by |err_print|.
+
+This function is implemented as a macro. It gives a message and an
+indication of the offending file. The actions to determine the error
+location are provided by a function called |err_loc|.
+
+@d error_loc(a) = err_loc(a); history=troublesome; @+ }
+@d err_print(a) = { @+ print_nl(a); error_loc
+
+@<Error handling...@>=
+@h void err_loc(i) /* prints location of error */
+ int i;
+{
+ print3_ln(" (file %s, l.%ld).",
+ input_organization[i]->name_of_file,
+ input_organization[i]->line);
+}
+
+
+@ Non recoverable errors are handled by calling |fatal_error| that
+outputs a message and then calls `|jump_out|'. |err_print| will print
+the error message followed by an indication of where the error was
+spotted in the source files. |fatal_error| cannot state any files
+because the problem is usually to access these.
+
+@d fatal_error(a) = {
+ print(a); print_c('.'); history=fatal;
+ term_new_line; jump_out();
+ }
+
+
+@ |jump_out| just cuts across all active procedure levels and jumps
+out of the program. It is used when no recovery from a particular
+error has been provided. The return code from this program should be
+regarded by the caller.
+
+@d jump_out(a) = exit(1)
+
+
+
+
+
+@* Handling multiple change files.
+
+\noindent In the standard version we take the name of the
+files from the command line.
+It is assumed that filenames can be used as given in the
+command line without changes.
+
+First there are some sections to open all files.
+If a file is not accessible, the run will be aborted.
+Otherwise the name of the open file will be displayed.
+
+@<Prepare the output file@>=
+{
+ out_file=fopen(out_name,"w");
+ if (out_file==NULL) {
+ fatal_error("! Could not open/create output file");
+@.Could not open/create output file@>
+ }
+}
+
+
+@ The name of the file and the file desciptor are stored in
+global variables.
+
+@<Global variables@>=
+text_file @!out_file;
+string @!out_name;
+
+
+@ For the master file we start just reading its first line
+into the buffer, if we could open it.
+
+@<Get the master file started@>=
+{ input_organization[0]->the_file=
+ fopen(input_organization[0]->name_of_file,"r");
+ if (input_organization[0]->the_file==NULL)
+ fatal_error("! Could not open master file");
+@.Could not open master file@>
+ print2("(%s)",input_organization[0]->name_of_file);
+ term_new_line;
+ input_organization[0]->type_of_file=master;
+ get_line(0);
+}
+
+@ For the change files we must skip the comment part and
+see, whether we can find any change in it.
+This is done by |init_change_file|.
+
+@<Prepare the change files@>=
+{file_index i;
+ i=1;
+ while (i<no_ch) {
+ input_organization[i]->the_file=
+ fopen(input_organization[i]->name_of_file,"r");
+ if (input_organization[i]->the_file==NULL)
+ fatal_error("!Could not open change file");
+@.Could not open change file@>
+ print2("(%s)",input_organization[i]->name_of_file);
+ term_new_line;
+ init_change_file(i,true);
+ incr(i);
+ }
+}
+
+
+
+
+
+@*Input/output organization.
+
+\noindent Here's a simple function that checks if two lines
+are different.
+
+@<Internal functions@>=
+@h boolean lines_dont_match(i,j)
+ file_index i,j;
+{
+ buffer_index k,lmt;
+ if (input_organization[i]->limit != input_organization[j]->limit)
+ return(true);
+ lmt=input_organization[i]->limit;
+ for ( k=0 ; k<lmt ; k++ )
+ if (input_organization[i]->buffer[k] != input_organization[j]->buffer[k])
+ return(true);
+ return(false);
+}
+
+
+@ Function |init_change_file(i,b)| is used to ignore all
+lines of the input file with index |i| until the next change
+module is found. The boolean parameter |b| indicates
+whether we do not want to see \.{@@x} or \.{@@y} entries during
+our skip.
+
+@<Internal functions@>=
+@h void init_change_file(i,b)
+ file_index i; boolean b;
+{register input_description *inp_desc=input_organization[i];
+ @<Skip over comment lines; |return| if end of file@>;
+ @<Skip to the next nonblank line; |return| if end of file@>;
+}
+
+
+@ While looking for a line that begins with \.{@@x} in the
+change file, we allow lines that begin with \.{@@}, as long
+as they don't begin with \.{@@y} or \.{@@z} (which would
+probably indicate that the change file is fouled up).
+
+@<Skip over comment lines...@>=
+loop@+ {ASCII_Code c;
+ get_line(i);
+ if (inp_desc->mode==ignore) return;
+ if (inp_desc->limit<2) continue;
+ if (inp_desc->buffer[0] != @`@@') continue;
+ c=inp_desc->buffer[1];
+ if (c>=@`X' && c<=@`Z')
+ c+=@`z'-@`Z'; /*lowercasify*/
+ if (c==@`x') break;
+ if (c==@`y' || c==@`z')
+ if (b) /* scanning for start of change */
+ err_print("! Where is the matching @@x?")(i);
+@.Where is the match...@>
+}
+
+
+@ Here we are looking at lines following the \.{@@x}.
+
+@<Skip to the next nonblank line...@>=
+do{
+ get_line(i);
+ if (inp_desc->mode==ignore) {
+ err_print("! Change file ended after @@x")(i);
+@.Change file ended...@>
+ return;
+ }
+} while (inp_desc->limit<=0);
+
+
+@ The |put_line| function is used to write a line from
+input buffer |j| to the output file.
+
+@<Internal functions@>=
+@h void put_line(j)
+ file_index j;
+{buffer_index i; /* index into the buffer */
+ buffer_index lmt; /* line length */
+ string p; /* output pointer */
+ lmt=input_organization[j]->limit;
+ p=input_organization[j]->buffer;
+ for (i=0;i<lmt;i++) fputc(map_xchr(*p++),out_file);
+ new_line(out_file);
+}
+
+
+@ The function |e_of_ch_module| returns true if the input
+line from file |i| starts with \.{@@z}.
+
+@<Internal functions@>=
+@h boolean e_of_ch_module(i)
+ file_index i;
+{register input_description *inp_desc=input_organization[i];
+ if (inp_desc->limit<0) {
+ print_nl("! At the end of change file missing @@z ");
+@.At the end of change file...@>
+ print2("%s",input_organization[i]->name_of_file);
+ term_new_line;
+ return(true);
+ } else if (inp_desc->limit>=2) if (inp_desc->buffer[0]==@`@@' &&
+ (inp_desc->buffer[1]==@`Z' || inp_desc->buffer[1]==@`z'))
+ return(true);
+ return(false);
+}
+
+
+@ The function |e_of_ch_preamble| returns |true| if the input
+line from file |i| starts with \.{@@y}.
+
+@<Internal functions@>=
+@h boolean e_of_ch_preamble(i)
+ file_index i;
+{register input_description *inp_desc=input_organization[i];
+ if (inp_desc->limit>=2 && inp_desc->buffer[0]==@`@@')
+ if (inp_desc->buffer[1]==@`Y'||inp_desc->buffer[1]==@`y') return(true);
+ return(false);
+}
+
+
+
+@ To process the input file the next section
+reads a line of the actual input file and updates the
+|input_organization| for all files with index |test_file| greater
+|actual_input|.
+
+@<Process a line, |break| when end of source reached@>=
+{file_index test_file;
+ @<Check the current files for any ends of changes@>
+ if (input_has_ended && actual_input==0) break; /* all done */
+ @<Scan all other files for changes to be done@>
+ @<Handle output@>
+ @<Step to next line@>
+}
+
+
+@ Any of the current change files may have reached the end of change.
+In such a case intermediate lines must be skipped and the next start
+of change is to be found. This may make a change file inactive if
+it reaches end of file.
+
+@<Check the...@>=
+{register input_description *inp_desc;
+while (e_of_ch_module(actual_input)) {
+ inp_desc=input_organization[actual_input];
+ if (inp_desc->type_of_file==master) {
+ /* emergency exit, everything mixed up!*/
+ fatal_error("! This can't happen: change file is master file");
+@.This can't happen...@>
+ }
+ inp_desc->mode=search;
+ init_change_file(actual_input,true);
+ while ((input_organization[actual_input]->mode!=reading
+ && actual_input>0)) decr(actual_input);
+}
+}
+
+
+@ Now we will set |test_input| to the file that has another match
+for the current line. This depends on the state of the other
+change files. If no other file matches, |actual_input| refers to
+a line to write and |test_input| ist set to |none|.
+
+@d none = (max_file_index+1)
+
+@<Scan all other files...@>=
+test_input=none;
+test_file=actual_input;
+while (test_input==none && test_file</*no\_ch*/no_ch-1) { /* bug fix DL */
+ incr(test_file);
+ switch (input_organization[test_file]->mode) {
+ case search: if (lines_dont_match(actual_input,test_file)==false) {
+ input_organization[test_file]->mode=test;
+ test_input=test_file;
+ }
+ break;
+ case test: if (lines_dont_match(actual_input, test_file)==true) {
+ /* error, sections do not match */
+ input_organization[test_file]->mode=search;
+ err_print("! Sections do not match")(actual_input);
+@.Sections do not match@>
+ err_loc(test_file);
+ init_change_file(test_file,false);
+ } else test_input=test_file;
+ break;
+ case reading: do_nothing; /* this can't happen */
+ break;
+ case ignore: do_nothing; /* nothing to do */
+ break;
+ }
+}
+
+
+@ For the output we must distinguish whether we create a new change
+file or a new master file. The change file creation needs some closer
+inspection because we may be before a change, in the pattern part or
+in the replacement part. For a master file we have to write the line
+from the current actual input.
+
+@<Handle output@>=
+if (prod_chf==chf) {
+ loop @+ {
+ @<Test for normal, |break| when done@>
+ @<Test for pre, |break| when done@>
+ @<Test for post, |break| when done@>
+ }
+} else
+if (test_input==none) put_line(actual_input);
+
+
+@ Check whether we have to start a change file entry.
+Without a match nothing must be done.
+
+@<Test for normal...@>=
+if (out_mode==normal) {
+ if (test_input!=none) {
+ fputc(map_xchr(@`@@'),out_file); fputc(map_xchr(@`x'),out_file);
+ new_line(out_file);
+ out_mode=pre;
+ } else break;
+}
+
+
+@ Check whether we have to start the replacement text.
+This is the case when we have no more matching line.
+Otherwise the master file source line must be copied to the
+change file.
+@<Test for pre...@>=
+
+ if (out_mode==pre) {
+ if (test_input==none) {
+ fputc(map_xchr(@`@@'),out_file); fputc(map_xchr(@`y'),out_file);
+ new_line(out_file);
+ out_mode=post;
+ } else {
+ if (input_organization[actual_input]->type_of_file==master)
+ put_line(actual_input);
+ break;
+ }
+ }
+
+
+@ Check whether an entry from a change file is complete.
+If the current change was a change for a change file in effect,
+then this change file line must be written.
+If the actual input has been reset to the master file we
+can finish this change.
+
+@<Test for post...@>=
+ if (out_mode==post) {
+ if (input_organization[actual_input]->type_of_file==chf) {
+ if (test_input==none) put_line(actual_input);
+ break;
+ } else {
+ fputc(map_xchr(@`@@'),out_file); fputc(map_xchr(@`z'),out_file);
+ new_line(out_file);
+ new_line(out_file);
+ out_mode=normal;
+ }
+ }
+
+
+@ If we had a change, we must proceed in the actual file
+to be changed and in the change file in effect.
+
+@<Step to next line@>=
+get_line(actual_input);
+if (test_input!=none) {
+ get_line(test_input);
+ if (e_of_ch_preamble(test_input)==true) {
+ get_line(test_input); /* update current changing file */
+ input_organization[test_input]->mode=reading;
+ actual_input=test_input;
+ test_input=none;
+ }
+}
+
+
+@ To create the new output file we have to scan the whole
+master file and all changes in effect when it ends.
+At the very end it is wise to check for all changes
+to have completed--in case the last line of the master file
+was to be changed.
+
+@<Process the input@>=
+actual_input=0;
+input_has_ended=false;
+while (input_has_ended==false||actual_input!=0)
+ @<Process a line...@>
+if (out_mode==post) { /* last line has been changed */
+ fputc(map_xchr(@`@@'),out_file); fputc(map_xchr(@`z'),out_file);
+ new_line(out_file);
+ }
+
+
+@ At the end of the program, we will tell the user if the
+change file had a line that didn't match any relevant line
+in the master file or any of the change files.
+
+@<Check that all changes have been read@>=
+{file_index i;
+for (i=1;i<no_ch;i++) {/* all change files */
+ if (input_organization[i]->mode!=ignore)
+ err_print("! Change file entry did not match")(i);
+@.Change file entry ...@>
+ }
+}
+
+
+@ We want to tell the user about our command line options. This is
+done by the |usage()| function. It contains merely the necessary
+print statement and exits afterwards.
+
+@<Intern...@>=
+@h void usage()
+{
+ print("Usage: tie -[mc] outfile master changefile(s)");
+ term_new_line;
+ jump_out();
+}
+
+
+@ We must scan through the list of parameters, given in |argv|. The
+number is in |argc|. We must pay attention to the flag parameter. We
+need at least 5~parameters and can handle up to |max_file_index|
+change files. The names fo the file parameters will be inserted into
+the structure of |input_organization|. The first file is special. It
+indicates the output file. When we allow flags at any position, we
+must find out which name is for what purpose. The master file is
+already part of the |input_organization| structure (index~0). As long
+as the number of files found (counted in |no_ch|) is |-1| we have not
+yet found the output file name.
+
+@<Scan the parameters@>=
+{int act_arg,act_orgpart;
+ if ( argc < 5 || argc > max_file_index+4-1 ) usage();
+ no_ch = -1; /* fill this part of |input_organization| */
+ for ( act_arg=1 ; act_arg<argc ; act_arg++ ) {
+ if (argv[act_arg][0]=='-') @<Set a flag@>
+ else @<Get a file name@>
+ }
+ if (no_ch<=0|| prod_chf==unknown) usage();
+}
+
+
+@ The flag is about to determine the processing mode.
+We must make sure that this flag has not been set before.
+Further flags might be introduced to avoid/force overwriting of
+output files.
+Currently we just have to set the processing flag properly.
+
+@<Set a flag@>=
+if (prod_chf!=unknown) usage();
+else
+ switch (argv[act_arg][1]) {
+ case 'c':
+ case 'C': prod_chf=chf; break;
+ case 'm':
+ case 'M': prod_chf=master; break;
+ default: usage();
+ }
+
+
+@ We have to distinguish whether this is the very first file name
+(known if |no_ch==(-1)|) or if the next element of |input_organization|
+must be filled.
+
+@<Get a file name@>=
+{ if (no_ch==(-1)) {
+ out_name=argv[act_arg];
+ } else { register input_description *inp_desc;
+ inp_desc=(input_description *)
+ malloc(sizeof(input_description));
+ if (inp_desc==NULL)
+ fatal_error("! No memory for descriptor");
+@.No memory for descriptor@>
+ inp_desc->mode=search;
+ inp_desc->line=0;
+ inp_desc->type_of_file=chf;
+ inp_desc->limit=0;
+ inp_desc->name_of_file=argv[act_arg];
+ input_organization[no_ch]=inp_desc;
+ }
+ incr(no_ch);
+}
+
+
+@* The main program.
+
+\noindent Here is where \.{TIE} starts, and where it ends.
+
+@<The main function@>=
+@h main(argc,argv)
+ int argc; string *argv;
+{{@<Local variables for initialisation@>
+ @<Set initial...@>
+ }
+ print_ln(banner); /* print a ``banner line'' */
+ print_ln(copyright); /* include the copyright notice */
+ actual_input=0;
+ out_mode=normal;
+ @<Scan the parameters@>
+ @<Prepare the output file@>
+ @<Get the master file started@>;
+ @<Prepare the change files@>
+ @<Process the input@>;
+ @<Check that all changes have been read@>;
+ @<Print the job |history|@>;
+}
+
+@ We want to pass the |history| value to the operating system so that
+it can be used to govern whether or not other programs are started.
+Additionaly we report the history to the user, although this may not
+be ``{\mc UNIX}'' style---but we are in best companion: \.{WEB} and
+\TeX{} do the same.
+@^system dependencies@>
+
+@<Print the job |history|@>=
+{string msg;
+ switch (history) {
+ case spotless: msg="No errors were found"; break;
+ case troublesome: msg="Pardon me, but I think I spotted something wrong.";
+ break;
+ case fatal: msg="That was a fatal error, my friend"; break;
+ } /* there are no other cases */
+ print2_nl("(%s.)",msg); term_new_line;
+ exit ( history == spotless ? 0 : 1 );
+}
+
+
+
+
+
+@* System-dependent changes.
+
+\noindent This section should be replaced, if necessary, by
+changes to the program that are necessary to make \.{TIE}
+work at a particular installation. It is usually best to
+design your change file so that all changes to previous
+modules preserve the module numbering; then everybody's
+version will be consistent with the printed program. More
+extensive changes, which introduce new modules, can be
+inserted here; then only the index itself will get a new
+module number.
+@^system dependencies@>
+
+
+
+
+
+@* Index.
+
+\noindent Here is the cross-reference table for the \.{TIE}
+processor.
+
diff --git a/web/spiderweb/fixes-to-be-applied/latex/tiedoc.tex b/web/spiderweb/fixes-to-be-applied/latex/tiedoc.tex
new file mode 100644
index 0000000000..525ae60b4e
--- /dev/null
+++ b/web/spiderweb/fixes-to-be-applied/latex/tiedoc.tex
@@ -0,0 +1,138 @@
+% tiedoc.tex 25 Oct 89
+
+% adapted to CWEB by J.Schrod on 89-10-25
+
+\documentstyle[a4]{article}
+\font\mc=cmcsc10
+\def\TANGLE{{\tt TANGLE}}
+\def\TIE{{\tt TIE}}
+\def\WEAVE{{\tt WEAVE}}
+\def\WEB{{\tt WEB}}
+\def\CWEB{{\mc cweb}}
+\def\PASCAL{{\mc Pascal}}
+\title{The TIE Processor}
+\author{Klaus Guntermann\\
+TH Darmstadt\\
+Fachbereich Informatik\\
+Institut f\"ur Theoretische Informatik}
+
+\date{October 1989}
+\begin{document}
+\maketitle
+\section{Introduction}
+
+To install a program on a computer usually
+system dependent changes are needed.
+The \WEB\ system allows to describe these changes in a
+so called change file.
+To incorporate the changes into the program \TANGLE\ processes
+the original source file and inserts the changes into the proper places.
+
+Sometimes it is good practice to develop a set of change files to be able to
+distinguish between different changes like
+program enhancements, bug fixes, system dependent changes
+and output device dependent modifications.
+Additionally this allows combinations of changes that can be used with a set of
+programs that share some common features.
+
+The processors \TANGLE\ and \WEAVE\ can handle only one change file.
+The combination of change files is done best in another preprocessing step.
+\TIE\ is able to create either a new master file or a single change file that
+comprises the effect of all change files.
+
+Since \TIE\ does not know anything about \WEB\ programs but only about the
+structure of change files, it is possible to use this program for other
+programming languages as well.
+You just pretend that you want to create a new master file and \TIE\ will go
+and insert all the changes from your change files.
+
+
+
+\section{Application}
+
+The current version of \TIE\ accepts a master file and up to 9 change files.
+Because in general it is important to use the changes in their proper sequence
+the order of the files must be chosen carefully.
+
+The CWEB version of \TIE{} may be called with the following command
+line interface:
+%
+\begin{verbatim}
+ tie -[mc] output_file master_file changefile(s)
+\end{verbatim}
+%
+The option \verb|-m| results in the creation of a new master file,
+\verb|-c| yields a new changefile. Usually wildcards may be used for
+the filenames.
+
+The multiple change files are used as if the single change files were merged
+into the master files step by step.
+Thus more than 9 change files might be incorporated by repeated application of
+\TIE.
+
+Please note that even when multiple change files are processed each of the
+files is read only once.
+For each of the change files and for the master file there is only one line in
+memory at a time (neglecting operating system buffering).
+Thus the storage requirement of \TIE\ does not depend on the size of the change
+files or the size of a single changed section.
+
+\vfill\eject
+\def\eof{$\langle$EOF$\rangle$}
+\section{Example}
+
+To illustrate the actions \TIE\ performs you may inspect the following example
+that exercises some of the border line cases.
+
+$$\vbox{
+\halign{#\hfill\qquad\quad&#\hfill\qquad\quad&#\hfill\qquad\quad&#\hfill\cr
+``master'' &{\tt CF1} &{\tt CF2} &{\tt CF3}\cr
+line 1 &@x &@x &@x\cr
+line 2 &line 2 &line 1 &changed line 4\cr
+line 3 &line 3 &changed line 2 &@y\cr
+line 4 &@y &changed line 3 &final line 4\cr
+line 5 &changed line 2 &inserted line &@z\cr
+line 6 &changed line 3 &line 4 &\eof\cr
+line 7 &inserted line &@y\cr
+line 8 &@z &final line 2\cr
+line 9 & &final line 3\cr
+line 10 &@x &changed line 4\cr
+\eof &line 7 &@z\cr
+ &@y\cr
+ &changed line 7 &@x\cr
+ &@z &changed line 7\cr
+ &\eof &line 8\cr
+ & &@y\cr
+ & &final line 7\cr
+ & &final line 8\cr
+ & &@z\cr
+ & &\eof\cr}
+}$$
+\vfill\eject
+Using these input files and running \TIE\ twice to create a new master file
+and a new change file will result in the following output files:
+
+$$\vbox{
+\halign{#\hfill\qquad\quad&&#\hfill\qquad\quad\cr
+``master'' &``change''\cr
+final line 2 &@x\cr
+final line 3 &line 1\cr
+final line 4 &line 2\cr
+line 5 &line 3\cr
+line 6 &line 4\cr
+final line 7 &@y\cr
+final line 8 &final line 2\cr
+line 9 &final line 3\cr
+line 10 &final line 4\cr
+\eof &@z\cr
+ &\cr
+ &@x\cr
+ &line 7\cr
+ &line 8\cr
+ &@y\cr
+ &final line 7\cr
+ &final line 8\cr
+ &@z\cr
+ &\eof\cr}
+}$$
+\end{document}
diff --git a/web/spiderweb/fixes-to-be-applied/latex/weave.ltx b/web/spiderweb/fixes-to-be-applied/latex/weave.ltx
new file mode 100644
index 0000000000..7b5454fee6
--- /dev/null
+++ b/web/spiderweb/fixes-to-be-applied/latex/weave.ltx
@@ -0,0 +1,700 @@
+% This is `weave.ltx' to fix spidery weave for LaTeX. See
+% `web.doc' for some comments about how it works.
+
+% changes copyright D.Love, SERC Daresbury Laboratory
+% (d.love@daresbury.ac.uk) under the same conditions as the Spider
+% distribution.
+
+%$Header: /home/users0/fx/ltxspiderweb/master/weave.ltx,v 1.4 91/03/22 11:24:35 fx Exp $
+
+ l 11 (remove \batchmode so we can see what's happening)
+@x
+% Here is TeX material that gets inserted after \input webmac
+
+\message{Entering \string\batchmode...}
+\batchmode
+@y
+% Here is TeX material that gets inserted after \documentstyle[web]...
+
+% we turn off batch mode for debugging purposes
+
+%\message{Entering \string\batchmode...}
+%\batchmode
+@z
+
+ l 16 (swicth for LaTeX or plain)
+@x
+\def\hang{\hangindent 3em\indent\ignorespaces}
+\font\ninerm=cmr9
+\let\mc=\ninerm % medium caps
+\def\cee{C}
+\def\Pascal{Pascal}
+\def\PASCAL{Ada}
+\def\pb{$\.|\ldots\.|$} % C brackets (|...|)
+\def\v{\.{\char'174}} % vertical (|) in typewriter font
+\def\dleft{[\![} \def\dright{]\!]} % double brackets
+\mathchardef\RA="3221 % right arrow
+\mathchardef\BA="3224 % double arrow
+\def\({} % kludge for alphabetizing certain module names
+
+\def\title{Spidery WEAVE}
+\def\contentspagenumber{1} % should be odd
+\def\topofcontents{\null\vfill
+ \titlefalse % include headline on the contents page
+ \def\rheader{\hfil}
+ \centerline{\titlefont The {\ttitlefont Spidery WEAVE} processor}
+ \vfill}
+\pageno=\contentspagenumber \advance\pageno by 1
+\let\maybe=\iftrue
+@y
+\ifx \enddocument\undefined % are we using LaTeX?
+ \font\ninerm=cmr9 % no...
+ \let\mc=\ninerm % medium caps
+
+\def\title{Spidery WEAVE}
+\def\contentspagenumber{1} % should be odd
+\def\topofcontents{\null\vfill
+ \titlefalse % include headline on the contents page
+ \def\rheader{\hfil}
+ \centerline{\titlefont The {\ttitlefont Spidery WEAVE} processor}
+ \vfill}
+ \pageno=\contentspagenumber \advance\pageno by 1
+\def\LaTeX{{\rm L\kern-.36em\raise.3ex\hbox{\sc a}\kern-.15em
+ T\kern-.1667em\lower.7ex\hbox{E}\kern-.125emX}}%
+\else % yes...
+ \documentstyle[web]{article}
+ \let\.=\str % new name
+ \title{Spidery WEAVE} \date{}
+\fi
+
+\def\hang{\hangindent 3em\indent\ignorespaces}
+\def\cee{C}
+\def\Pascal{Pascal}
+\def\PASCAL{Ada}
+\def\pb{$\.|\ldots\.|$} % C brackets (|...|)
+\def\v{\.{\char'174}} % vertical (|) in typewriter font
+\def\dleft{[\![} \def\dright{]\!]} % double brackets
+\mathchardef\RA="3221 % right arrow
+\mathchardef\BA="3224 % double arrow
+\def\({} % kludge for alphabetizing certain module names
+
+\let\maybe=\iffalse % only changed sections -- perhaps you
+ % want to change this if you're
+ % weaving WEAVE for the first time
+
+@z
+
+ l 39
+@x
+@* Introduction.
+\.{CWEAVE} has a fairly straightforward outline. It operates in
+three phases: first it inputs the source file and stores cross-reference
+data, then it inputs the source once again and produces the \TeX\ output
+file, and finally it sorts and outputs the index. It can be compiled
+with certain optional flags, |DEBUG| and |STAT|, the latter being used
+to keep track of how much of \.{WEAVE}'s resources were actually used.
+@y
+@* Introduction.
+\.{CWEAVE} has a fairly straightforward outline. It operates in
+three phases: first it inputs the source file and stores cross-reference
+data, then it inputs the source once again and produces the \TeX\ output
+file, and finally it sorts and outputs the index. It can be compiled
+with certain optional flags, |DEBUG| and |STAT|, the latter being used
+to keep track of how much of \.{WEAVE}'s resources were actually used.
+
+This version has changes to make it work with \LaTeX{} as the
+formatter, rather than plain \TeX\@@. The sections which are changed
+for \LaTeX{} are indicated by |#ifdef LaTeX|, so you can define the
+|LaTeX| switch when you compile it. You could generate a new
+\.{weave.web} using \.{wmerge} or \.{tie} which you could use for
+either plain or \LaTeX, since the limbo section will check for the
+existence of \.{\\enddocument} (which presumably indicates \LaTeX).
+@z
+
+ l 361
+@x
+@d underline = @'176 /* this code will be intercepted without confusion */
+@d param = @'177 /* ASCII delete will not appear */
+/* identifier =200 or octal @'310 */
+@#/* following three must be conseccutive for indexing to work */
+@d xref_roman = (identifier+roman) /* control code for `\.{@@\^}' */
+@y
+@d underline = @'176 /* this code will be intercepted without confusion */
+@d param = @'177 /* ASCII delete will not appear */
+/* identifier =200 or octal |@'310| */
+@#/* following three must be consecutive for indexing to work */
+@d xref_roman = (identifier+roman) /* control code for `\.{@@\^}' */
+@z
+
+ l 1140
+@x
+ for (k=p->byte_start; k<k_end; k++) {
+ if (*k=='$') {out('\\'); out('D'); out('O'); out(' ');}
+ else if (*k=='&') {out('\\'); out('a'); out('m'); out('p');}
+ else {
+ if (*k=='_' || *k=='%' || *k=='#' || *k=='^' || *k=='{' || *k=='}')
+@y
+ for (k=p->byte_start; k<k_end; k++) {
+ if (*k=='$') {out('\\'); out('D'); out('O'); out(' ');}
+ else if (*k=='&') {out('\\'); out('a'); out('m'); out('p'); out(' ');}
+ else {
+ if (*k=='_' || *k=='%' || *k=='#' || *k=='^' || *k=='{' || *k=='}')
+@z
+
+ l 1159
+@x
+No `\.{@@}' signs should occur in such material except in `\.{@@@@}'
+pairs; such pairs are replaced by singletons.
+
+@u copy_limbo()
+@y
+No `\.{@@}' signs should occur in such material except in `\.{@@@@}'
+pairs; such pairs are replaced by singletons.
+For \LaTeX{} we have to introduce the start of the {\tt document}
+environment.@^LaTeX{}@>
+
+@u copy_limbo()
+@z
+
+ l 1172
+@x
+ if (c!='z' && c!='Z') {
+ out(at_sign);
+ if (c!=at_sign) err_print("! Double @@ required outside of sections");
+@.Double \AT! required...@>
+ }
+ }
+ }
+}
+@y
+ if (c!='z' && c!='Z') {
+ out(at_sign);
+ if (c!=at_sign) err_print("! Double @@ required outside of sections");
+@.Double \AT! required...@>
+ }
+ }
+ }
+#ifdef LaTeX
+ out_str("\n\\begin{document}\\maketitle\n");
+#endif LaTeX
+}
+@z
+
+ l 1368
+@x
+\.{\\mathrel\{} and \.{\\mathbin\{}, respectively.
+Also |math_op| to \.{\\mathop\{}.
+Other control sequences in the \TeX\ output will be `\.{\\\\\{}$\,\ldots\,$\.\}'
+surrounding identifiers, `\.{\\\&\{}$\,\ldots\,$\.\}' surrounding
+reserved words, `\.{\\.\{}$\,\ldots\,$\.\}' surrounding strings,
+@y
+\.{\\mathrel\{} and \.{\\mathbin\{}, respectively.
+Also |math_op| to \.{\\mathop\{}.
+Other control sequences in the plain \TeX\ output will be `\.{\\\\\{}$\,\ldots\,$\.\}'
+surrounding identifiers, `\.{\\\&\{}$\,\ldots\,$\.\}' surrounding
+reserved words, `\.{\\.\{}$\,\ldots\,$\.\}' surrounding strings,
+@z
+
+ l 1374
+@x
+`\.{\\X$n$:}$\,\ldots\,$\.{\\X}' surrounding module names, where
+|n| is the module number.
+
+@d math_bin = @'205 /* should these be octal or decimal? */
+@y
+`\.{\\X$n$:}$\,\ldots\,$\.{\\X}' surrounding module names, where
+|n| is the module number.
+@^\LaTeX{}@>
+In the \LaTeX\ output we'll have `\.{\\id\{}$\,\ldots\,$\.\}'
+surrounding identifiers, `\.{\\res\{}$\,\ldots\,$\.\}' surrounding
+reserved words, `\.{\\str\{}$\,\ldots\,$\.\}' surrounding strings,
+`\.{\\cee\{}$\,\ldots\,$\.\}$\,$|force|' surrounding comments, and
+`\.{\\X$n$:}$\,\ldots\,$\.{\\X}' surrounding module names, where
+|n| is the module number.
+@.\\id@>@.\\res@>@.\\str@>
+
+@d math_bin = @'205 /* should these be octal or decimal? */
+@z
+
+ l 1472
+@x
+\yskip\item{$\bullet$}ASCII codes and special codes like |force| and
+|math_rel| represent themselves;
+
+\item{$\bullet$}|id_flag+p| represents \.{\\\\\{{\rm identifier $p$}\}};
+
+\item{$\bullet$}|res_flag+p| represents \.{\\\&\{{\rm identifier $p$}\}};
+
+\item{$\bullet$}|mod_flag+p| represents module name |p|;
+
+\item{$\bullet$}|tok_flag+p| represents token list number |p|;
+
+\item{$\bullet$}|inner_tok_flag+p| represents token list number |p|, to be
+translated without line-break controls.
+@y
+\begin{itemize}
+\item ASCII codes and special codes like |force| and
+|math_rel| represent themselves;
+
+\item |id_flag+p| represents \.{\\\\\{{\rm identifier $p$}\}} in the
+plain \TeX\ version or \.{\\str\{{\rm identifier $p$}\}} in the \LaTeX\
+version;
+
+\item |res_flag+p| represents \.{\\\&\{{\rm identifier $p$}\}} in
+plain or \.{\\id\{{\rm identifier $p$}\}};
+
+\item |mod_flag+p| represents module name |p|;
+
+\item |tok_flag+p| represents token list number |p|;
+
+\item |inner_tok_flag+p| represents token list number |p|, to be
+translated without line-break controls.
+\end{itemize}
+@z
+
+ l 1501
+@x
+ else for (j=*p; j<*(p+1); j++) {
+ r=*j%id_flag;
+ switch (*j/id_flag) {
+ case 1: printf("\\{"); print_id((name_dir+r)); printf("}"); break;
+ /* |id_flag| */
+@y
+ else for (j=*p; j<*(p+1); j++) {
+ r=*j%id_flag;
+#ifdef LaTeX
+ switch (*j/id_flag) {
+ case 1: printf("\id{"); print_id((name_dir+r)); printf("}"); break;
+ /* |id_flag| */
+ case 2: printf("\res{"); print_id((name_dir+r)); printf("}"); break;
+ /* |res_flag| */
+ case 3: printf("<"); print_id((name_dir+r)); printf(">"); break;
+ /* |mod_flag| */
+ case 4: printf("[[%d]]",r); break; /* |tok_flag| */
+ case 5: printf("|[[%d]]|",r); break; /* |inner_tok_flag| */
+ default: @<Print token |r| in symbolic form@>;
+ }
+@.\\id@>@.\\res@>
+#else
+ switch (*j/id_flag) {
+ case 1: printf("\\{"); print_id((name_dir+r)); printf("}"); break;
+ /* |id_flag| */
+@z
+
+ l 1512
+@x
+ default: @<Print token |r| in symbolic form@>;
+ }
+ }
+}
+@y
+ default: @<Print token |r| in symbolic form@>;
+ }
+#endif LaTeX
+ }
+}
+@z
+
+ l 2075
+@x
+
+@<Append a string or...@>=
+if (next_control==constant) app_str("\\O{");
+@.\\O@>
+@y
+
+@<Append a string or...@>=
+#ifdef LaTeX
+if (next_control==constant) app_str("\\const{");
+@.\\const@>
+else if (next_control==string) app_str("\\str{");
+@.\\str@>
+else app_str("\\vstr{");
+@.\\vstr@>
+#else
+if (next_control==constant) app_str("\\O{");
+@.\\O@>
+@z
+
+ l 2079
+@x
+@.\\.@>
+else app_str("\\={");
+@.\\=@>
+while (id_first<id_loc) {
+ if (*id_first==at_sign) {
+@y
+@.\\.@>
+else app_str("\\={");
+@.\\=@> /* verbatim string */
+#endif LaTeX
+while (id_first<id_loc) {
+ if (*id_first==at_sign) {
+@z
+
+ l 2197
+@x
+breaks are inserted after the result of tokens like |break_space| and
+|force|. (d) The final line break should be suppressed, and there should
+be no |force| token output immediately after `\.{\\Y\\P}'.
+
+@ The output process uses a stack to keep track of what is going on at
+@y
+breaks are inserted after the result of tokens like |break_space| and
+|force|. (d) The final line break should be suppressed, and there should
+be no |force| token output immediately after `\.{\\Y\\P}' (or `\.{\\Y\\code}'
+with \LaTeX{}).@^\LaTeX@>
+
+@ The output process uses a stack to keep track of what is going on at
+@z
+
+ l 2394
+@x
+looks slightly better if set in a math-italic font instead of a (slightly
+narrower) text-italic font. Thus we output `\.{\\\char'174a}' but
+`\.{\\\\\{aa\}}'.
+
+@<Output an identifier@>=
+out('\\');
+if (a==identifier)
+ if (length(cur_name)==1) out('|')@;
+@.\\|@>
+@y
+looks slightly better if set in a math-italic font instead of a (slightly
+narrower) text-italic font. Thus we output `\.{\\\char'174a}' but
+`\.{\\\\\{aa\}}'. In \LaTeX\ we use `\.{\\ida a}' and `\.{\\id\{aa\}}'.
+@^\LaTeX{}@>
+
+@<Output an identifier@>=
+#ifdef LaTeX
+out('\\');
+if (a==identifier)
+ if (length(cur_name)==1) out_str("ida ");
+@.\\ida@>
+ else out_str("id");
+@.\\id@>
+else out_str("res"); /* |a==res_word| */
+@.\\res@>
+#else
+out('\\');
+if (a==identifier)
+ if (length(cur_name)==1) out('|')@;
+@.\\|@>
+@z
+
+ l 2045
+@x
+else out('&')@; /* |a==res_word| */
+@.\\\&@>
+if (length(cur_name)==1) out((cur_name->byte_start)[0])@;
+else out_name(cur_name);
+@y
+else out('&')@; /* |a==res_word| */
+@.\\\&@>
+#endif LaTeX
+if (length(cur_name)==1) out((cur_name->byte_start)[0])@;
+else out_name(cur_name);
+@z
+
+ l 2430
+@x
+the largest one is used. A line break also occurs in the output file,
+except at the very end of the translation. The very first line break
+is suppressed (i.e., a line break that follows `\.{\\Y\\P}').
+
+@<Look ahead for st...@>= {
+@y
+the largest one is used. A line break also occurs in the output file,
+except at the very end of the translation. The very first line break
+is suppressed (i.e., a line break that follows `\.{\\Y\\code}').
+@^\LaTeX{}@>
+
+@<Look ahead for st...@>= {
+@z
+
+ l 2442
+@x
+ if ((a!=' ' && a<indent) || a==backup || a>big_force) {
+ if (save_mode==outer) {
+ if (out_ptr>out_buf+3 && strncmp(out_ptr-3,"\\Y\\P",4)==0)
+ goto reswitch;
+ @<Output saved |indent| or |outdent| tokens@>;
+@y
+ if ((a!=' ' && a<indent) || a==backup || a>big_force) {
+ if (save_mode==outer) {
+#ifdef LaTeX
+ if (out_ptr>out_buf+3 && strncmp(out_ptr-3,"\\Y\\code",4)==0)@^\LaTeX{}@>@.\\code@>
+#else
+ if (out_ptr>out_buf+3 && strncmp(out_ptr-3,"\\Y\\P",4)==0)
+#endif LaTeX
+ goto reswitch;
+ @<Output saved |indent| or |outdent| tokens@>;
+@z
+
+ l 2632
+@x
+
+@ @<Translate an octal constant appearing in \TeX\ text@>= {
+out_str("\\O{\\~");
+ while ('0'<=*loc && *loc<'8') out(*loc++);
+out('}');
+@y
+
+@ @<Translate an octal constant appearing in \TeX\ text@>= {
+#ifdef LaTeX
+out_str("\\code{\\~"); /* this occurrence of \.{\~} is OK for \LaTeX\ since
+the control sequence is only defined within the scope of the \.{\\code}
+macro */@^\LaTeX{}@>@.\\code@>
+#else
+out_str("\\O{\\~");
+#endif LaTeX
+ while ('0'<=*loc && *loc<'8') out(*loc++);
+out('}');
+@z
+
+ l 2638
+@x
+
+@ @<Translate a hex constant appearing in \TeX\ text@>= {
+out_str("\\O{\\^");
+ while (isxdigit(*loc)) {
+ out(islower(*loc) ? toupper(*loc):*loc);
+@y
+
+@ @<Translate a hex constant appearing in \TeX\ text@>= {
+#ifdef LaTeX
+out_str("\\code{\\^"); /* OK for \LaTeX{} as above */
+@^\LaTeX{}@>@.\\code@>
+#else
+out_str("\\O{\\^");
+#endif LaTeX
+ while (isxdigit(*loc)) {
+ out(islower(*loc) ? toupper(*loc):*loc);
+@z
+
+ l 2662
+@x
+
+@ The |finish_C| procedure outputs the translation of the current
+scraps, preceded by the control sequence `\.{\\P}' and followed by the
+control sequence `\.{\\par}'. It also restores the token and scrap
+memories to their initial empty state.
+@y
+
+@ The |finish_C| procedure outputs the translation of the current
+scraps, preceded by the control sequence `\.{\\P}' (`\.{\\code}' in
+\LaTeX{}) and followed by the@^\LaTeX{}@>
+control sequence `\.{\\par}'. It also restores the token and scrap
+memories to their initial empty state.
+@z
+
+ l 2674
+@x
+{
+ text_pointer p; /* translation of the scraps */
+ out_str("\\P"); app_tok(force); app_scrap(SP_ignore_scrap,no_math);
+ p=translate();
+@.\\P@>
+@y
+{
+ text_pointer p; /* translation of the scraps */
+#ifdef LaTeX
+ out_str("\\code"); app_tok(force); app_scrap(SP_ignore_scrap,no_math);
+@.\\code@>@^\LaTeX{}@>
+#else
+ out_str("\\P"); app_tok(force); app_scrap(SP_ignore_scrap,no_math);
+#endif LaTeX
+ p=translate();
+@.\\P@>
+@z
+
+ l 2710
+@x
+ token following the parameter list@>;
+ if (next_control==@`=') {
+ small_app('\\'); small_app('S'); /* equivalence sign */
+ @<Set |next_control| to the first non-newline token@>@;
+ } else {
+@y
+ token following the parameter list@>;
+ if (next_control==@`=') {
+#ifdef LaTeX
+@^\LaTeX{}@>@.\\equiv@>
+ small_app('\\'); app_str("equiv");
+#else
+ small_app('\\'); small_app('S'); /* equivalence sign */
+#endif LaTeX
+ @<Set |next_control| to the first non-newline token@>@;
+ } else {
+@z
+
+ l 2823
+@x
+ this_module=name_dir; /*so we won't give cross-reference info here*/
+}
+app_str("\\S"); /* output an equivalence sign */
+@.\\S@>
+app_str("{}$");
+small_app(force);
+@y
+ this_module=name_dir; /*so we won't give cross-reference info here*/
+}
+#ifdef LaTeX
+app_str("\\equiv");@^\LaTeX{}@>@.\\equiv@>
+#else
+app_str("\\S"); /* output an equivalence sign */
+@.\\S@>
+#endif LaTeX
+app_str("{}$");
+small_app(force);
+@z
+
+ l 2950
+@x
+if (no_xref) {
+ finish_line();
+ out_str("\\vfill\\end");
+ finish_line();
+}
+@y
+if (no_xref) {
+ finish_line();
+#ifdef LaTeX
+ out_str("\\end{document}");@^\LaTeX{}@>@.\\end{document}@>
+#else
+ out_str("\\vfill\\end");
+#endif LaTeX
+ finish_line();
+}
+@z
+
+ l 2958
+@x
+ finish_line(); @<Tell about changed modules@>;
+ }
+ finish_line(); out_str("\\inx"); finish_line();
+@.\\inx@>
+ @<Do the first pass of sorting@>;
+ @<Sort and output the index@>;
+ out_str("\\fin"); finish_line();
+@.\\fin@>
+ @<Output all the module names@>;
+ out_str("\\con"); finish_line();
+@.\\con@>
+}
+@y
+ finish_line(); @<Tell about changed modules@>;
+ }
+#if 0
+ finish_line(); out_str("\\begin{theindex}"); finish_line();
+#endif
+ finish_line(); out_str("\\inx"); finish_line();
+@.\\inx@>
+ @<Do the first pass of sorting@>;
+ @<Sort and output the index@>;
+#if 0
+ out_str("\\end{theindex}\\fin"); finish_line();
+#endif
+ out_str("\\fin"); finish_line();
+@.\\fin@>
+ @<Output all the module names@>;
+ out_str("\\con\\end{document}"); finish_line();
+@.\\con@>
+}
+@z
+
+ l 3137
+@x
+@ @<Output the name...@>=
+switch (cur_name->ilk) {
+ case normal: if (length(cur_name)==1) out_str("\\|");
+ else out_str("\\\\"); break;
+@y
+@ @<Output the name...@>=
+switch (cur_name->ilk) {
+#ifdef LaTeX#
+ case normal: if (length(cur_name)==1) out_str("\\ida ");
+ else out_str("\\id"); break;
+@^\LaTeX{}@>@.\\ida@>@.\\id@>
+#else
+ case normal: if (length(cur_name)==1) out_str("\\|");
+ else out_str("\\\\"); break;
+@z
+
+ l 3141
+@x
+@.\\|@>
+@.\\\\@>
+ case roman: break;
+ case wildcard: out_str("\\9"); break;
+@.\\9@>
+ case typewriter: out_str("\\."); break;
+@.\\.@>
+@y
+@.\\|@>
+@.\\\\@>
+#endif LaTeX
+ case roman: break;
+ case wildcard: out_str("\\9"); break;
+@.\\9@>
+#ifdef LaTeX
+ case typewriter: out_str("\\str"); break;
+@.\\str@>
+ default: out_str("\\res");
+@.\\res@>@^\LaTeX{}@>
+#else
+ case typewriter: out_str("\\."); break;
+@.\\.@>
+@z
+
+ l 3148
+@x
+ default: out_str("\\&");
+@.\\\&@>
+}
+out_name(cur_name);
+@y
+ default: out_str("\\&");
+@.\\\&@>
+#endif LaTeX
+}
+out_name(cur_name);
+@z
+
+ l 3152
+@x
+
+@ Section numbers that are to be underlined are enclosed in
+`\.{\\[}$\,\ldots\,$\.]'.
+
+@<Output the cross-references...@>=
+@y
+
+@ Section numbers that are to be underlined are enclosed in
+`\.{\\[}$\,\ldots\,$\.]' or `\.{\\underline}$\,\ldots\,$\.\}' in \LaTeX{}.
+@^\LaTeX{}@>
+
+@<Output the cross-references...@>=
+@z
+
+ l 3159
+@x
+ out_str(", "); cur_val=cur_xref->num;
+ if (cur_val<def_flag) out_mod(cur_val);
+ else {out_str("\\["); out_mod(cur_val%def_flag); out(']');}
+@.\\[@>
+ cur_xref=cur_xref->xlink;
+} while (cur_xref!=xmem);
+@y
+ out_str(", "); cur_val=cur_xref->num;
+ if (cur_val<def_flag) out_mod(cur_val);
+#ifdef LaTeX
+ else {out_str("\\underline{"); out_mod(cur_val%def_flag); out('}');}
+@.\\underline@>@^\LaTeX{}@>
+#else
+ else {out_str("\\["); out_mod(cur_val%def_flag); out(']');}
+@.\\[@>
+#endif LaTeX
+ cur_xref=cur_xref->xlink;
+} while (cur_xref!=xmem);
+@z
diff --git a/web/spiderweb/fixes-to-be-applied/latex/web.doc b/web/spiderweb/fixes-to-be-applied/latex/web.doc
new file mode 100644
index 0000000000..e3e2615a4e
--- /dev/null
+++ b/web/spiderweb/fixes-to-be-applied/latex/web.doc
@@ -0,0 +1,945 @@
+\iffalse
+
+%% Copyright D.Love, SERC Daresbury Laboratory, 1991
+%% The `doc' version of this style is re-distributable and usuable
+%% under conditions of the GNU copyleft, but please mark any changes,
+%% list them here and report any major enhancements to the author.
+
+% This is a self-documenting style. To produce the documentation you
+% might use a driver file like this:
+% \def\webmacs{null} \documentstyle[a4,makeidx,newdoc,web]{article}
+% \EnableCrossrefs \CodelineIndex
+% \begin{document} \DocInput{web.sty} \PrintIndex
+% \end{document}
+% and run `makeindex -s gind.ist doc' in between passes. You need
+% Mittelbach's newdoc.sty at v1.6d or later.
+
+% To produce the .sty file use `latex docstrip' to remove most of the
+% comments. Please don't distribute the .sty file without the .doc
+% file.
+\fi
+
+\iffalse % hack RCS info into a sensible form:
+\fi
+\def\next$#1: #2/#3/#4 #5 ${\def\filedate{#4/#3/#2}\def\filetime{#5}}
+\next$Date: 91/03/06 15:27:01 $
+
+\def\next$#1: #2 ${\def\fileversion{#2}}
+\next$Revision: 1.3 $
+
+% \title{A a \web{} style file for \LaTeX{}\thanks{This file is version
+% \fileversion\ of \filedate}}
+% \author{David Love\\[2ex]{\it SERC Daresbury Laboratory, Warrington
+% WA4 4AD, UK}\\ \tt d.love@daresbury.ac.uk}
+% \date{}
+%
+% \newcommand{\web}{{\tt WEB}}
+% \newcommand{\weave}{{\tt WEAVE}}
+% \newcommand{\tangle}{{\tt tangle}}
+% \newcommand{\spider}{Spider}
+% \MakeShortVerb{\"}
+
+% \DoNotIndex{\/,\@date,\@ifundefined,\@makefnmark,\@starttoc}
+% \DoNotIndex{\@topnum,\addpenalty,addvspace,\advance,aftergroup}
+% \DoNotIndex{\begin,\begingroup,\bgroup,\char,\def,\egroup,\else,\end}
+% \DoNotIndex{\endgroup,\fi,\fnsymbol,\hfil,\hfill,\hfilneg,\hss,\kern}
+% \DoNotIndex{\let,\lineskip,\newcommand,\protect,\qquad,\quad,\relax}
+% \DoNotIndex{\thanks,\thefootnote,\z@,\@M,\@thanks,\@thefnmark,\hbox}
+% \DoNotIndex{\empty,\mbox}
+
+% \maketitle
+%
+% \begin{abstract} \noindent
+% This style file is for use with a version of the Spidery \weave\ system
+% that has been adapted to use \LaTeX\ rather than plain \TeX\ for the
+% formatting. It is a first attempt.
+% \end{abstract}
+%
+% \section{Assumptions of \weave{} and the {\tt .web} file}
+%
+% We assume we're using the version of Spidery \weave{} \cite{spider}
+% changed for \LaTeX\@. This will write out
+% \begin{quote}"\def\webmacs{"\meta{ext}"web.tex}",\end{quote}
+% (where \meta{ext} is
+% the \spider{} {\tt extension}), then the limbo section, then
+% \begin{quote}"\begin{document}\maketitle" \end{quote}
+% the latter to stop you forgetting it. The "\webmacs" file will be
+% included at the end of this style.
+% After the index (if any), we get
+% "\end{document}". The user thus has to put the "\documentstyle"
+% command in the limbo part and include "web" in the style options to
+% get this stuff and can use other options as appropriate. You're
+% meant to use the "article" main style, although I think "report"
+% would work too.
+%
+% \section{Strategy}
+%
+% The idea was to change the original \spider{} \TeX{} stuff as little
+% as possible, although it has actually been changed quite
+% substantially. Changes are forced where there is a clash of macro
+% names; most of the original one-character control sequences are
+% already used by \LaTeX, for instance. Some features have been
+% converted to a \LaTeX{} equivalent,
+% notably the table of contents mechanism, the title page, running
+% header and double-columning for the index. For safety, "\def"s have
+% been replaced by "\newcommands" where possible since there are
+% probably plenty of possibilities for name clashes.
+% User-visible differences from the plain version are given in
+% appendix~\ref{changes}.
+%
+% \section{Use with old webs}
+%
+% Examples of the use of this style with old webs using the plain
+% conventions can be found in the accompanying changes files for
+% {\tt weave.web} and {\tt spider.web}. You can use the limbo section
+% to check whether the generated ".tex" file is being run through
+% \LaTeX\ or plain \TeX\ by doing something like this:
+% \begin{quote}
+% \begin{verbatim}
+% \ifx\enddocument\undefined
+% % plain things
+% \else
+% % LaTeX things
+% \fi
+% \end{verbatim}
+% \end{quote}
+%
+% \section{Bugs}
+%
+% Floats
+% don't always come out where you'd expect due to interaction with
+% \web's attempts to keep all of a module on one page if possible.
+% "\str" and "\vstr", which
+% might well get used in a moving argument, are
+% fragile. Module titles (after "@*") are moving arguments. I think
+% if you use \web's "|"\dots"|" construction in a
+% moving argument it will break and there's not much you can do about
+% it.
+%
+% \section{Code}
+% \subsection{Preliminaries --- page layout}
+%
+% Let's announce ourselves as usual:
+% \begin{macrocode}
+\typeout{Sub-style `web', version \fileversion\space of \filedate}
+% \end{macrocode}
+% We don't want stretch between paragraphs.
+% \begin{macrocode}
+\parskip \z@
+% \end{macrocode}
+% \begin{macro}{\textwidth}\begin{macro}{\textheight}
+% \begin{macro}{\oddsidemargin} \begin{macro}{\evensidemargin}
+% The default page width should be large for \web\@. This is for
+% non-Americans (A4)---if you want to alter the page dimensions with a
+% suitable style option put it {\em after\/} "web" in the
+% "\documentstyle" list. The width here is too big for decently
+% readable text, but is
+% still less than the $6.5''$ of the original. Note that there's no
+% point in trying to use "\marginpar" at
+% this width since the margins have disappeared! The "twoside" option
+% will work sensibly if you care to use it.\DescribeMacro{twoside} We
+% want to avoid doing this when typesetting the documenttation, hence
+% the test for "\DocInput".
+% \begin{macrocode}
+\ifx\DocInput\undefined
+\ifcase \@ptsize
+ \textheight = 53 \baselineskip
+\or
+ \textheight = 47 \baselineskip
+\or
+ \textheight = 43 \baselineskip
+\fi \advance \textheight by \topskip
+\textwidth=6.27in \oddsidemargin=\z@ \evensidemargin=\z@
+\fi
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}\end{macro}
+% We use the "myheadings" page style with headings containing section
+% information (see below).
+% \begin{macrocode}
+\pagestyle{myheadings}
+% \end{macrocode}
+% If we start off with a "\sectionmark" we won't miss the running
+% header off the first page where it should appear.
+% \begin{macrocode}
+\ifx\DocInput\undefined \sectionmark{1} \fi
+% \end{macrocode}
+%
+% \subsubsection{Font selection}
+%
+% \begin{macro}{\normal@font}
+% We have to check whether we're in the old or new font selection scheme
+% and set up appropriately. "\normal@font" is invoked before the font
+% changes for identifiers, reserved words and strings to make sure
+% that they use the default series and shape in the new scheme. This
+% is actually only necessary if "\id", "\res" or "\str" is used in
+% \TeX\ text that is being set in a different shape or series, not
+% normally in the code. If you use the new selection scheme you can
+% do things like using Concrete or PostScript fonts easily.
+% \begin{macrocode}
+\@ifundefined{selectfont}{%
+ \let\normal@font=\relax} % old scheme
+ {% new scheme
+ \def\normal@font{\series \mediumseriesdefault
+ \shape \normalshapedefault}}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Front matter}
+%
+% We depart from the plain version here. The first page (or pages, if
+% the contents are very long) is produced with the "titlepage"
+% environment. The "\author", "\date" and
+% "\title" \DescribeMacro{\title} can be specified
+% as usual in \LaTeX\@. Note that you now say
+% "\title{"\meta{title}"}" rather than "\def\title{"\meta{title}"}" as
+% in the plain version and this title will be used in the running
+% header.
+%
+% \begin{macro}{\@maketitle}
+% We'll re-define "\@maketitle" to include the "\topofcontents" and
+% "\botofcontents" information, with the contents information in the
+% middle. The normal title, author and date will be put automatically
+% at the top---"\topofcontents" is extra. You get the titling and
+% contents information automatically, since "\maketitle" is inserted
+% by \weave{} immediately after "\begin{document}". If you want to
+% suppress it, "\let\maketitle=\relax" in the limbo part.
+%
+% Of course, you have to make two
+% passes to get the contents printed, unlike the original plain
+% system. This should not be much hardship as one usually reckons on
+% running \LaTeX{} at least twice. (Putting the titlepage at the back
+% won't help, since the ".toc" file only exists after the ".aux" file
+% has been read on the secind pass. One could change the standard
+% behaviour so that the ".toc" file was created at the end of the
+% first pass, I guess.)
+% We first test for "\DocInput" as above to
+% avoid messing things up when typesetting the documentation.
+% \begin{macrocode}
+\ifx\DocInput\undefined
+\def\@maketitle{%
+ \newpage \thispagestyle{empty} \null
+ \begin{center}
+ {\LARGE \@title \par} \vskip 1.5em
+ {\large \lineskip .5em
+ \begin{tabular}[t]{c} \@author \end{tabular} \par}
+ \vskip 1em {\large \@date}
+ \end{center}
+ \par \vskip 1.5em
+ \topofcontents \tableofcontents \par \botofcontents \newpage }
+\fi
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\maketitle}
+% We change "\maketitle" to avoid the "\thispagestyle{plain}" that it
+% otherwise contains, to set the page number to 1 at the end and to
+% avoid losing the definitions of "\@title" and "\@author".
+% ("\@title" is used in the running header.)
+% \begin{macrocode}
+\ifx\DocInput\undefined
+\def\maketitle{%
+ \par \begingroup
+ \def\thefootnote{\fnsymbol{footnote}}
+ \def\@makefnmark{\hbox to \z@ {$^{\@thefnmark}$\hss}}
+ \if@twocolumn \twocolumn[\@maketitle]
+ \else \newpage \global\@topnum\z@ \@maketitle \fi
+ \@thanks
+ \endgroup
+ \setcounter{footnote}{0} \setcounter{page}{1}
+ \let\maketitle\relax \let\@maketitle\relax
+ \gdef\@thanks{}\let\thanks\relax}
+\fi
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@title} \begin{macro}{\@author}
+% We better define these in case they're not supplied:
+% \begin{macrocode}
+\let\@title=\empty \let\@author=\empty
+% \end{macrocode}
+% \end{macro} \end{macro}
+% \begin{macro}{\tableofcontents}
+% "\tableofcontents" is re-defined to produce a header saying
+% ``Section'' and ``Page'' a bit like the plain version, although the
+% section number is at the left.
+% \begin{macrocode}
+\def\tableofcontents{%
+ \noindent Section \hfill Page \par \@starttoc{toc}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\topofcontents} \begin{macro}{\botofcontents}
+% The "\topofcontents" material that comes between the title\slash author
+% information and the contents list and the "\botofcontents" stuff
+% that comes after the contents list are empty initially. I'm not
+% sure it's worth preserving them.
+% \begin{macrocode}
+\def\topofcontents{} \def\botofcontents{}
+% \end{macrocode}
+% \end{macro} \end{macro}
+% \begin{macro}{\ttitlefont} \begin{macro}{\titlefont}
+% These are just for compatibility with the plain version---they
+% should probably go.
+% \begin{macrocode}
+\let\ttitlefont=\tt \let\titlefont=\rm
+% \end{macrocode}
+% \end{macro} \end{macro}
+%
+% \subsection{Prettyprinting stuff}
+% \subsubsection{Identifiers, reserved words and strings}
+%
+% \begin{macro}{\id}\begin{macro}{\ida}\begin{macro}{\idfont}
+% Multi-letter identifiers are set by the macro "\id" in font "\idfont",
+% which is italic by default i.e., \id{identifier}.
+% One-letter identifiers are
+% actually set by "\ida" in math italic as they are supposed to look
+% better that way (\ida{a} rather than \id{a}).
+% \begin{macrocode}
+\newcommand{\id}[1]{\mbox{\idfont #1\/\kern.05em}}
+\newcommand{\ida}[1]{\mbox{$ #1 $}}
+\newcommand{\idfont}{\normal@font \it}
+% \end{macrocode}
+% \end{macro} \end{macro} \end{macro}
+% \begin{macro}{\reservedfont}\begin{macro}{\res}
+% Reserved words are set by macro "\res", using "\reservedfont" which
+% is bold by default i.e., \res{reserved}.
+% \begin{macrocode}
+\newcommand{\reservedfont}{\normal@font \bf}
+\newcommand{\res}[1]{\mbox{\reservedfont#1\/}}
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \begin{macro}{\str}
+% Typewriter type is used for strings, set by "\str" i.e.,
+% \str{string}. The definitions of the escaped characters
+% are given below. I don't understand why the ampersand is treated
+% like this, since "\&" is defined anyway, but quotes and "^" are
+% escaped to avoid
+% ligatures.\footnote{{\tt \char`\^} and {\tt \char`\~} form ligatures
+% in PostScript virtual fonts as well as "'".} It's necessary to do a
+% "\def" of "\^" rather than just
+% "\let\^\CF" to avoid an error with the use of "\^" not matching its
+% definition. Note the use of "\@tempa" below rather than "\XX" as
+% used in the same situation elsewhere---using "\XX", "\str" breaks if
+% it is used in, say, a comment.
+% \begin{macrocode}
+\def\str#1{%
+ \ifmmode \gdef\@tempa{\null$\null}\else \gdef\@tempa{}\fi
+ \@tempa {%
+ \let\\=\BS \let\'=\RQ \let\`=\LQ \let\{=\LB \let\}=\RB
+ \let\~=\TL \let\ =\SP \let\&=\AM \def\^{{\tt \char`\^}}%
+ \leavevmode \normal@font\tt #1}\@tempa}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\AM} \begin{macro}{\BS} \begin{macro}{\LB}
+% \begin{macro}{\LQ} \begin{macro}{\RB} \begin{macro}{\UL}
+% \begin{macro}{\TL}
+% Here are the definitions of the control sequences for strings. The
+% plain version redefined "\#", "\$", "\%" and "\^" globally. "\$"
+% isn't used by awk or C \web s, and has been removed. The others are
+% done only in code, using "\startcodehook" (below).
+% \begin{macrocode}
+\chardef\AM=`\& % ampersand
+\chardef\BS=`\\ % backslash
+\chardef\LB=`\{ % left brace
+\def\LQ{{\tt\char'22}} % left quote
+\chardef\RB=`\} % right brace
+\def\RQ{{\tt\char'23}} % right quote
+\def\UL{{\tt\char`\_}} % underline character in a string
+\def\TL{{\tt\char`\~}} % tilde
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}\end{macro}
+% \end{macro}
+% \begin{macro}{\SP}
+% Strings may be rather long and we want some way of breaking
+% them, so
+% "\SP" produces a visible space (\str{\SP}) and also adds a discretionary
+% break afterwords. If a break occurs, the line is ended with a
+% backslash. Spaces are probably the most sensible place to break
+% strings, especially if they are messages, but one could consider
+% doing the same thing for other of the macros above e.g., "\BS" might
+% check if the next character was "n" and insert a discretionary break
+% after that.
+% \begin{macrocode}
+\newcommand{\SP}{\char`\ \discretionary{\hbox{\char`\\}}{}{}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\vstr}
+% This does a verbatim string (from "@=") using the existing \LaTeX
+% nology rather than the original definition to put a frame around it
+% (\vstr{string}).
+% \begin{macrocode}
+\newcommand{\vstr}[1]{\kern 2pt \fbox{\str{#1}}\kern 2pt}
+\setlength{\fboxsep}{2pt}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\const}
+% This looks after setting octal, hex or decimal constants. The first
+% thing in its argument may be one of the control sequences in the
+% example on the left,
+% producing the result in the middle:
+% \[\begin{tabular}{lll}
+% "\const{\$10}" & $\const{\$10}$ & (long) \\
+% "\const{\_10}" & $\const{\_10}$ & (power of ten)\\
+% "\const{\~10}" & $\const{\~10}$ & (octal) \\
+% "\const{\^AB10}" & $\const{\^AB10}$ & (hex) \\
+% \end{tabular}\]
+% \DeleteShortVerb{\"}
+% \begin{macrocode}
+\def\const#1{{%
+ \def\?{\kern.2em}%
+ \def\${\ell}% long
+ \def\_{\RealConstFormat{\aftergroup}}% power of ten
+ \def\~{\hbox{\rm \char'23\kern-.2em \it \aftergroup\?\aftergroup}}% octal
+% \end{macrocode}
+% The \verb+"+ here was originally \verb+\char'175+ which,
+% unfortunately, is different in PostScript virtual fonts and Computer
+% Modern:
+% \begin{macrocode}
+ \def\^{\hbox{\rm "\tt \aftergroup}}% hex
+ #1}} % (\def{\const})
+% \end{macrocode}
+% \end{macro}
+% \MakeShortVerb{\"}
+% \begin{macro}{\RealConstFormat}
+% I prefer to re-define the decimal style
+% to print as the more code-like `$\mbox{\rm e}10$'. You can
+% do this by using the hook "\RealConstFormat" in your Spider "macros"
+% section:
+% \begin{quote} "\newcommand{\RealConstFormat}{\mbox{\rm e}}" .\end{quote}
+% For a go at a Fortran web, I hacked the lexing so that an "e" or "d" in
+% a real or double-precision constant was transmitted verbatim into the
+% argument of "\const" instead of "\_" and re-defined "\const" to ensure
+% this was set in roman.
+% \begin{macrocode}
+\newcommand{\RealConstFormat}{\cdot 10^}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Indentation and breaks}
+%
+% \begin{macro}{\ind}
+% This counter stores the current indentation in ems.
+% \begin{macrocode}
+\newcount\ind
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\bak} \begin{macro}{\bakk}
+% These backspace one and two ems respectively.
+% \begin{macrocode}
+\newbox\bak \setbox\bak=\hbox to \m@ne em{}
+\newbox\bakk \setbox\bakk=\hbox to -2em{}
+% \end{macrocode}
+% \end{macro}\end{macro}
+% \begin{macro}{\0}
+% A forced break, as from "@/":
+% \begin{macrocode}
+\def\0{%
+ \ifmmode
+ \ifinner$\par\hangindent\ind em\noindent\kern\ind em\ignorespaces$\fi
+ \else
+ \par\hangindent\ind em\noindent \kern\ind em\ignorespaces
+ \fi}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\1}
+% Indent one more notch:
+% \begin{macrocode}
+\newcommand{\1}{\global\advance\ind by 1 \hangindent\ind em}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\2}
+% Indent one less notch:
+% \begin{macrocode}
+\newcommand{\2}{\global\advance\ind by \m@ne }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\3}
+% An optional break within a statement, as from "@|":
+% \begin{macrocode}
+\newcommand{\3}[1]{\hfil \penalty#10 \hfilneg}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\4}
+% Backspace one notch:
+% \begin{macrocode}
+\newcommand{\4}{\copy\bak}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\5}
+% Optional break:
+% \begin{macrocode}
+\newcommand{\5}{\hfil \penalty \m@ne \hfilneg \kern 2.5em \copy\bakk
+ \ignorespaces}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\6}
+% A forced break with no indentation:
+% \begin{macrocode}
+\def\6{\ifmmode \else \par
+ \hangindent\ind em\startline \ignorespaces \fi}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\startline}
+% This is used by "\code" as well as "\6" above.
+% \begin{macrocode}
+\def\startline{\noindent \count255=\ind \advance\count255 by -2
+ \hskip\count255 em}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\7}
+% A forced break and a little extra vertical space, as from "@#":
+% \begin{macrocode}
+\newcommand{\7}{\Y\6}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\8}
+% No indentation. It works only in code, not in "|"\dots"|".
+% \begin{macrocode}
+\newcommand{\8}{\unskip}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\J}
+% \tangle's join operation ("@&"):
+% \begin{macrocode}
+\newcommand{\J}{\str{@\&}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\C}
+% This looks after comments. The hooks are inserted because comments
+% aren't code (see below).
+% \begin{macrocode}
+\def\C#1{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi
+ \XX \hfil \penalty \m@ne\hfilneg\quad % original spider
+ $\commentbegin\,$\endcodehook{#1}\startcodehook$\,
+ \commentend$\XX}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Modules}
+%
+% \begin{macro}{\onmaybe} \begin{macro}{\maybe} \begin{macro}{\ifon}
+% These switches are concerned with only printing changed sections if
+% so desired.
+% \begin{macrocode}
+\def\onmaybe{\let\ifon=\maybe} \let\maybe=\iftrue \newif\ifon
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}
+% \begin{macro}{\M}
+% Beginning of an un-starred section:
+% \begin{macrocode}
+\outer\def\M#1.{%
+ \MN#1.\ifon\vfil\penalty-100\vfilneg
+ \vskip12ptminus3pt \startsection \ignorespaces}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\startsection} \begin{macro}{\lapstar}
+% Some auxilliary definitions:
+% \begin{macrocode}
+\def\startsection{\Q \noindent {\let\*=\lapstar \bf \modstar.\quad }}
+\newcommand{\lapstar}{\rlap{*}}
+% \end{macrocode}
+% \end{macro} \end{macro}
+% \begin{macro}{\N}
+% This introduces a starred section (where "#2" is the title). We
+% have to check the title with "\headcheck" for a leading
+% character indicating a subsection. Then we write a contents entry,
+% change the running header and set the title in bold. "\old@S" is
+% used in the header rather than "\S" since "\S" is probably
+% wrongly-defined at this point (see below).
+% \begin{macrocode}
+\outer\def\N#1.#2.{%
+ \MN#1.\headcheck#2\headcheck
+ \typeout{*\modno} % progress report
+ \addcontentsline{toc}{\headcheck@type}
+ {\hbox to 2em{\modno\hfill} \quad \theopen \relax \themodtitle}
+ \markboth{% running headline
+ {\protect\small \qquad\uppercase{\ignorespaces\themodtitle}}
+ \hfill {\protect\small \@title}\qquad{\rm \old@S \modno}}
+ {\rm \old@S \modno\qquad {\protect\small \@title}\hfill
+ {\protect\small \uppercase{\ignorespaces\themodtitle\qquad}}}
+ \ifon\startsection {\bf \ignorespaces \themodtitle.\quad }\ignorespaces}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\MN}
+% Here is some common code for "\M" and "\N"\@. Like the normal \LaTeX{}
+% "\section", it looks after setting a
+% "\sectionmark" and advancing the section counter using
+% "\refstepcounter" so that it can be cross-referenced as usual. It
+% looks after the decision about whether or not to set this module if it
+% is not starred.
+% \begin{macrocode}
+\def\MN#1.{%
+ \par {\xdef\modstar{#1}\let\*=\empty\xdef\modno{#1}}%
+ \ifx\modno\modstar \onmaybe \else \ontrue \fi
+ \sectionmark{\modno} \refstepcounter{section}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\note} \begin{macro}{\A}
+% Auxilliary macros. "\A" is for cross-references for multiply
+% defined section names.
+% \begin{macrocode}
+\def\note#1#2.{\Y \noindent {\hangindent 2em \footnotesize
+ \baselineskip 10pt#1 #2.\par}}
+\newcommand{\A}{\note{See also}}
+% \end{macrocode}
+% \end{macro} \end{macro}
+%
+% \subsubsection{Processing special section headings}
+%
+% This complicated stuff, introduced with \spider{} and modified for the
+% \LaTeX{} version, is to allow an inital =, 1, 2, 3 or 4 in
+% starred module titles to indicate a hierarchy. Their effect is as follows:
+% \[ \begin{tabular}{c|c|c}
+% Introduction & Page eject? & Indentation in contents\\ \hline
+% "@*=" & yes & 0 \\
+% "@*1" & yes & 2 em \\
+% "@*2" & no & 2 em \\
+% "@*3" & yes & 4 em \\
+% "@*4" & no & 4 em \\
+% \end{tabular} \]
+% "@*=" also suppresses a following page eject and emboldens the
+% table of contents entry and puts some extra vertical space before
+% it. Normal starred sections have no indentation in the contents and
+% don't do anything special about page breaks.
+%
+% \begin{macro}{\l@part} \begin{macro}{\l@norm} \begin{macro}{\l@num}
+% Two new sorts of contents entry are defined here and the `part'
+% type re-defined. (See "latex.tex" for details of how this works.)
+% "\l@part" determines the t.o.c.\ entry for a "@*=" section,
+% "\l@norm" the entry for a normal starred section and "\l@num" that
+% for a numbered section. Some penalties are inserted (the normal
+% values for the main style) in case the t.o.c.\ extends over more
+% than one page. The "\headcheck@type" definition is used in the
+% sectioning commands to write the t.o.c.\ entry.
+% \begin{macrocode}
+\def\l@part{\addpenalty{\@secpenalty}
+ \addvspace{3pt plus 1pt} % space above part line
+ \@dottedtocline{0}{\z@ }{4em}}
+\def\l@norm{\addpenalty{\@secpenalty}
+ \@dottedtocline{0}{\z@ }{4em}}
+\def\l@num{\@dottedtocline{0}{0em}{4em}}
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}
+% \begin{macro}{\ifcancel} \begin{macro}{\ifnextchar}
+% \begin{macro}{\ifnch} \begin{macro}{\makethechar}
+% Here's the tricky stuff, presented without further comment!
+% \begin{macrocode}
+\newif\ifcancel \cancelfalse
+\def\ifnextchar#1#2#3{%
+ \let\@tempe=#1\def\@tempa{#2}\def\@tempb{#3}\@ifnch}
+\def\@ifnch{%
+ \ifx \@tempc \@tempe\let\@tempd\@tempa
+ \else \let\@tempd\@tempb
+ \fi
+ \@tempd}
+\def\makethechar#1{\let\@tempc=#1}
+% \end{macrocode}
+% \end{macro} \end{macro} \end{macro} \end{macro}
+% \begin{macro}{\headcheck}
+% ~
+% \begin{macrocode}
+\def\headcheck#1#2\headcheck{%
+ \makethechar{#1}%
+ \def\theskipper{\vfil\penalty-100 % skip before new module
+ \vfilneg\vskip12ptminus3pt}%
+ \def\theopen{}% opening skip in toc entry
+ \def\thetocskip{}% vertical skip before toc entry
+ \def\themodtitle{{#2}}%
+ \def\headcheck@type{num}%
+ \ifnextchar={%
+ \def\theskipper{\newpage} \canceltrue
+ \def\headcheck@type{part} \def\theopen{\bf}%
+ \def\thetocskip{\vskip 3pt plus 1in \penalty-100
+ \vskip \z@ plus -1in}%
+ }{\ifnextchar1{%
+ \cancelfalse \def\theskipper{\newpage}%
+ \def\theopen{\hskip2em}%
+ }{\ifnextchar2{%
+ \cancelfalse \def\theopen{\hskip2em}%
+ }{\ifnextchar3{%
+ \cancelfalse \def\theskipper{\newpage}%
+ \def\theopen{\hskip4em}%
+ }{\ifnextchar4{%
+ \cancelfalse \def\theopen{\hskip4em}%
+ }{% else
+ \ifcancel\else \def\theskipper{\newpage}\fi
+ \cancelfalse \def\headcheck@type{norm}%
+ \def\themodtitle{#1{#2}}%
+ }}}}}%
+ \theskipper }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Starting and ending code sections}
+%
+% \begin{macro}{\code}
+% This takes us into code mode. The old version used infinite hyphen
+% penalty which stopped the discretionary breaks in strings. Extra
+% space is put after ";" with the "\sfcode".
+% \begin{macrocode}
+\newcommand{\code}{%
+ \rightskip=\z@ plus 100pt minus 10pt
+ \sfcode`;=3000 \pretolerance \@M
+ \hyphenpenalty 9999 \exhyphenpenalty \@M
+ \global\ind=2 \1 \startline
+% \end{macrocode}
+% \DescribeMacro{\@}
+% The original says that every web must define "\?", where "?" is the
+% at-sign. Since "\@" is used for end-of-sentence space in \LaTeX, we
+% make sure this is only done in code mode. We need the old and new
+% definitions, "\old@" and "\code@", between which to switch.
+% \spider{} unfortunately uses "\S" instead of "\equiv" and the awk
+% and C \web s assume that "\%" and "\#" translate to typewriter
+% versions, so we have to define these properly in code mode too.
+% \DescribeMacro{\startcodehook} \DescribeMacro{\endcodehook}
+% For convenience, we define token registers
+% "\startcodehook" and "\endcodehook" for this sort of purpose when we
+% go into and out of code mode. These might be altered by the
+% \spider\ description if appropriate.
+% \begin{macrocode}
+ \startcodehook} % \def\code
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\old@}\begin{macro}{\code@}\begin{macro}{\old@S}
+% \begin{macro}{\old@percent} \begin{macro}{\old@hash}
+% Let's store the original definitions of these:
+% \begin{macrocode}
+\let\old@=\@ \let\old@S=\S \let\old@percent=\%
+\let\old@hash=\#
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}
+% \begin{macro}{\code@}\begin{macro}{\tt@percent}\begin{macro}{\tt@hash}
+% And here are replacements for use in code mode.
+% \begin{macrocode}
+\chardef\code@=`\@
+\def\tt@percent{\hbox{\tt\char`\%}} \def\tt@hash{\hbox{\tt\char`\#}}
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}
+% \begin{macro}{\startcodehook}\begin{macro}{\endcodehook}
+% Here are the hooks. Should these be token registers?
+% \begin{macrocode}
+\def\startcodehook{\let\@=\code@ \let\S=\equiv \let\%=\tt@percent
+ \let\#=\tt@hash \def\^{\hbox{\tt\char`\^}}}
+\def\endcodehook{\let\@=\old@ \let\S=\old@S \let\%=\old@percent
+ \let\#=\old@hash \def\^##1{{\accent94 ##1}}}
+% \end{macrocode}
+% \end{macro}\end{macro}
+% \begin{macro}{\Q}
+% This gets us out of code mode, setting things back to normal.
+% \begin{macrocode}
+\def\Q{\rightskip=\z@ \sfcode`;=1500 \pretolerance 200
+ \endcodehook}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\CD} \begin{macro}{\DC}
+% Web text in "|"\dots"|" is woven into text surrounded by
+% "\CD"\dots"\DC"\@. The original definition didn't bother with the
+% grouping if not in math mode, but it's convenient now that the hooks
+% need to be added.
+% \begin{macrocode}
+\def\DC{\endcodehook \egroup}
+\def\CD{\relax
+ \ifmmode \hbox\fi \bgroup \startcodehook}
+% \end{macrocode}
+% \end{macro}\end{macro}
+% \begin{macro}{\U}
+% This provides a cross-reference for uses of sections.
+% \begin{macrocode}
+\newcommand{\U}{\note{This code is used in}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\X}
+% This does modules which introduce the code. Note the usage:
+% "\X"\meta{module number}":"\meta{module name}"\X".
+% \begin{macrocode}
+\def\X#1:#2\X{%
+ \ifmmode \gdef\XX{\null$\null}\else \gdef\XX{}\fi
+ \XX$\langle\,$#2{\footnotesize \kern.5em #1}$\,\rangle$\XX }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\XF}
+% This is for a file module (from "@("):
+% \begin{macrocode}
+\def\XF#1:#2\XF{%
+ \ifmmode \gdef\XX{\null$\null}\else \gdef\XX{}\fi
+ \XX {\tt (#2{\footnotesize \kern.5em #1})}\XX}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\Y} \begin{macro}{\yskip}
+% This does a vertical skip by "\yskip", used in "\note" and "\7".
+% \begin{macrocode}
+\newcommand{\Y}{\par\yskip}
+\let\yskip=\smallskip
+% \end{macrocode}
+% \end{macro}\end{macro}
+%
+% \subsection{Definitions and formats}
+%
+% \begin{macro}{\D} \begin{macro}{\F} \begin{macro}{\defin}
+% "\D" and "\F" deal with macro and format definitions from "@d" and
+% "@f" respectively.
+% \begin{macrocode}
+\newcommand{\D}{\defin{define}} % macro definition
+\newcommand{\F}{\defin{format}} % format definition
+\newcommand{\defin}[1]{\global\advance\ind by 2 \1\res{#1 }}
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}
+%
+% \subsection{Miscellaneous symbols}
+%
+% \begin{macro}{\DO} \begin{macro}{\G} \begin{macro}{\I}
+% \begin{macro}{\K} \begin{macro}{\L} \begin{macro}{\R}
+% \begin{macro}{\TI} \begin{macro}{\V} \begin{macro}{\W}
+% Here are some miscellaneous symbols. I think these should really be
+% defined in the \spider\ descriptions that need them, but they are
+% assumed by the current webs.
+% \begin{macrocode}
+\newcommand{\DO}{\hbox{\sl\char'044}} % slant dollar sign (used by awkweb)
+\let\G=\ge % greater than or equal sign
+\let\I=\ne % unequal sign
+\let\K=\gets % left arrow
+\let\L=\le % less than or equal sign
+\let\R=\lnot % logical not
+\let\TI=\sim % tilde
+\let\V=\lor % logical or
+\let\W=\land % logical and
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}\end{macro}
+% \end{macro}\end{macro}\end{macro}
+% \begin{macro}{\vert} \begin{macro}{\amp} \begin{macro}{\PP}
+% \begin{macro}{\*}
+% And some more: (n.b., the plain \TeX{} definitions of "\vert"
+% and "\*" are over-written, as expected by spidery \weave---maybe this
+% should be changed).
+% \begin{macrocode}
+\def\vert{|} \let\amp=\& \let\PP=\P \let\*=*
+% \end{macrocode}
+% \end{macro}\end{macro}\end{macro}\end{macro}
+% \begin{macro}{\AT}
+% This is the `at sign in control
+% text'. In the plain version it says "\def\AT!{@}" which I presume
+% is a mistake.
+% \begin{macrocode}
+\def\AT{@}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Indexing}
+%
+% \begin{macro}{\ch}
+% This is used trivially at the start of the index in the case of
+% changes:
+% \begin{macrocode}
+\def\ch{\note{The following sections were changed by the change file:}
+ \let\*=\relax}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\inx} \begin{macro}{\:}
+% The index is set in two-column mode.
+% Each item in each index is introduced by "\:". This is a \LaTeX{}
+% macro but is unlikely to get used in the index and so is preserved
+% from the original.
+% \begin{macrocode}
+\def\inx{%
+ \typeout{Index:}
+ \begin{multicols}{2}
+ \parskip \z@ plus .5pt
+ \parfillskip \z@ plus .6\hsize % try to avoid almost empty lines
+ \outer\def\:##1, {\par\hangindent2em\noindent##1:\kern1em} % index entry
+ \rm \tolerance \@M \let\*=\lapstar
+ \hyphenpenalty \@M \parindent=\z@ }
+% \end{macrocode}
+% \end{macro}\end{macro}
+% \begin{macro}{\fin}
+% This finishes off the name index and starts off the module index.
+% "\:" acts as in "\inx". The modules may be
+% qualified with "\U", which cross-references section uses. The page
+% header is changed appropriately.
+% \begin{macrocode}
+\def\fin{%
+ \end{multicols} \newpage
+ \parfillskip \z@ plus 1fil
+ \markboth{{\protect\small NAMES OF THE SECTIONS}\hfill
+ {\protect\small\@title}}
+ {{\protect\small\@title}\hfill
+ {\protect\small NAMES OF THE SECTIONS}}
+ \typeout{Section names:}
+ \def\note##1##2.{\quad{\footnotesize##1 ##2.}}
+ \def\U{\note{Used in}}%
+ \def\:{\par\hangindent 2em}\let\*=*}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\con}
+% This finishes everything off, rather trivially. (It used to make
+% the contents page.)
+% \begin{macrocode}
+\newcommand{\con}{\end{document}}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Including other files}
+%
+% \DescribeEnv{multicols}
+% We need the {\tt multicols} environment to make a two-column index
+% without a forced page break.
+% \begin{macrocode}
+\input{multicol.sty}
+% \end{macrocode}
+% \DescribeMacro{\webmacs}
+% Finally we include the macros defined by \spider. Doing things this way
+% means that \spider{} can override things done in this file for the
+% \web{} system of a particular language (like the
+% definition of "\res", for instance) and the limbo section can do
+% further overriding for a particular web file. If we're using this
+% file to document itself, "\webmacs" should have been defined in the
+% driver file to be "null"!
+% \begin{macrocode}
+\input{\webmacs}
+% \end{macrocode}
+% "\webmacs" is no further use and we might as well save the space.
+% \begin{macrocode}
+\let\webmacs=\empty
+% \end{macrocode}
+%
+% \appendix
+% \section{Changes from the plain version}\label{changes}
+%
+% \begin{description}
+% \item[{\tt \BS.}] becomes "\str";
+% \item[{\tt \BS\char`\^}] has been removed from the global
+% definitions (where it was assumed by the "c.spider" translation for
+% "^") and put in limbo in "weave.ch";
+% \item[{\tt \BS\%}, {\tt \BS\#} and {\tt \BS\$}] also removed from global
+% definitions and put in "\startcodehook";
+% \item[{\tt \BS AT!}] becomes "\AT" on the assumption that
+% the original was an error;
+% \item[{\tt \BS\char`\~}] removed globally since it doesn't seem to be used;
+% \item[{\tt \BS\BS} and {\tt \BS|}] become "\id" and "\ida" respectively;
+% \item[{\tt \BS\&}] becomes "\res";
+% \item[{\tt \BS B} and {\tt \BS T}] (for controlled comments) removed
+% since no controlled comments in \spider;
+% \item[{\tt \BS)}] (string pool check sum) removed;
+% \item[{\tt \BS]}] (sign for forced line break) appears not be be
+% used, so removed;
+% \item[{\tt \BS=}] becomes "\vstr";
+% \item[{\tt \BS H}] (hat) removed since it seems not to be used and
+% clashes with \LaTeX;
+% \item[{\tt \BS Z}] replaced by \LaTeX{} contents stuff;
+% \item[{\tt \BS lheader} and {\tt \BS rheader}] replaced by \LaTeX{} marks;
+% \item[output routine stuff] all gone;
+% \item[{\tt \BS rhead}] no longer relevant---use the \LaTeX{} mark
+% mechanism;
+% \item[{\tt \BS title}] should be called as a macro with the title as
+% its argument rather than "\def"ed;
+% \item[{\tt \BS contentspagenumber}, {\tt \BS contentsfile} and {\tt
+% \BS readcontents}] no longer relevant;
+% \item[{\tt \BS pagewidth}, {\tt \BS pageheight} and {\tt \BS
+% fullpageheight}] no longer relevant---use the \LaTeX\ equivalents;
+% \item[{\tt \BS pageshift}] no longer relevant---use "twoside" option;
+% \item[verbatim macros] no longer relevant;
+% \item[{\tt \BS iftitle}] removed---use "\pagestyle{empty}" to
+% suppress page header.
+% \end{description}
+%
+% \begin{thebibliography}{1}
+% \bibitem{spider} N. Ramsey, {\sl Comm. ACM}, {\bf 32} (1989) 1051
+% \end{thebibliography}
diff --git a/web/spiderweb/fixes-to-be-applied/latex/web.sty b/web/spiderweb/fixes-to-be-applied/latex/web.sty
new file mode 100644
index 0000000000..d30acf397e
--- /dev/null
+++ b/web/spiderweb/fixes-to-be-applied/latex/web.sty
@@ -0,0 +1,271 @@
+%%
+%% This is file `web.sty' generated
+%% on <1991/3/25> with the docstrip utility (v1.1k).
+%%
+%% The original source file was `web.doc'.
+%%
+%% You are not allowed to distribute this file without the corresponding
+%% `.doc' version containing the documentation.
+%%
+\iffalse
+
+%% Copyright D.Love, SERC Daresbury Laboratory, 1991
+%% The `doc' version of this style is re-distributable and usuable
+%% under conditions of the GNU copyleft, but please mark any changes,
+%% list them here and report any major enhancements to the author.
+
+
+\fi
+
+\iffalse % hack RCS info into a sensible form:
+\fi
+\def\next$#1: #2/#3/#4 #5 ${\def\filedate{#4/#3/#2}\def\filetime{#5}}
+\next$Date: 91/03/06 15:27:01 $
+
+\def\next$#1: #2 ${\def\fileversion{#2}}
+\next$Revision: 1.3 $
+
+
+
+\typeout{Sub-style `web', version \fileversion\space of \filedate}
+\parskip \z@
+\ifx\DocInput\undefined
+\ifcase \@ptsize
+ \textheight = 53 \baselineskip
+\or
+ \textheight = 47 \baselineskip
+\or
+ \textheight = 43 \baselineskip
+\fi \advance \textheight by \topskip
+\textwidth=6.27in \oddsidemargin=\z@ \evensidemargin=\z@
+\fi
+\pagestyle{myheadings}
+\ifx\DocInput\undefined \sectionmark{1} \fi
+\@ifundefined{selectfont}{%
+ \let\normal@font=\relax} % old scheme
+ {% new scheme
+ \def\normal@font{\series \mediumseriesdefault
+ \shape \normalshapedefault}}
+\ifx\DocInput\undefined
+\def\@maketitle{%
+ \newpage \thispagestyle{empty} \null
+ \begin{center}
+ {\LARGE \@title \par} \vskip 1.5em
+ {\large \lineskip .5em
+ \begin{tabular}[t]{c} \@author \end{tabular} \par}
+ \vskip 1em {\large \@date}
+ \end{center}
+ \par \vskip 1.5em
+ \topofcontents \tableofcontents \par \botofcontents \newpage }
+\fi
+\ifx\DocInput\undefined
+\def\maketitle{%
+ \par \begingroup
+ \def\thefootnote{\fnsymbol{footnote}}
+ \def\@makefnmark{\hbox to \z@ {$^{\@thefnmark}$\hss}}
+ \if@twocolumn \twocolumn[\@maketitle]
+ \else \newpage \global\@topnum\z@ \@maketitle \fi
+ \@thanks
+ \endgroup
+ \setcounter{footnote}{0} \setcounter{page}{1}
+ \let\maketitle\relax \let\@maketitle\relax
+ \gdef\@thanks{}\let\thanks\relax}
+\fi
+\let\@title=\empty \let\@author=\empty
+\def\tableofcontents{%
+ \noindent Section \hfill Page \par \@starttoc{toc}}
+\def\topofcontents{} \def\botofcontents{}
+\let\ttitlefont=\tt \let\titlefont=\rm
+\newcommand{\id}[1]{\mbox{\idfont #1\/\kern.05em}}
+\newcommand{\ida}[1]{\mbox{$ #1 $}}
+\newcommand{\idfont}{\normal@font \it}
+\newcommand{\reservedfont}{\normal@font \bf}
+\newcommand{\res}[1]{\mbox{\reservedfont#1\/}}
+\def\str#1{%
+ \ifmmode \gdef\@tempa{\null$\null}\else \gdef\@tempa{}\fi
+ \@tempa {%
+ \let\\=\BS \let\'=\RQ \let\`=\LQ \let\{=\LB \let\}=\RB
+ \let\~=\TL \let\ =\SP \let\&=\AM \def\^{{\tt \char`\^}}%
+ \leavevmode \normal@font\tt #1}\@tempa}
+\chardef\AM=`\& % ampersand
+\chardef\BS=`\\ % backslash
+\chardef\LB=`\{ % left brace
+\def\LQ{{\tt\char'22}} % left quote
+\chardef\RB=`\} % right brace
+\def\RQ{{\tt\char'23}} % right quote
+\def\UL{{\tt\char`\_}} % underline character in a string
+\def\TL{{\tt\char`\~}} % tilde
+\newcommand{\SP}{\char`\ \discretionary{\hbox{\char`\\}}{}{}}
+\newcommand{\vstr}[1]{\kern 2pt \fbox{\str{#1}}\kern 2pt}
+\setlength{\fboxsep}{2pt}
+\def\const#1{{%
+ \def\?{\kern.2em}%
+ \def\${\ell}% long
+ \def\_{\RealConstFormat{\aftergroup}}% power of ten
+ \def\~{\hbox{\rm \char'23\kern-.2em \it \aftergroup\?\aftergroup}}% octal
+ \def\^{\hbox{\rm "\tt \aftergroup}}% hex
+ #1}} % (\def{\const})
+\newcommand{\RealConstFormat}{\cdot 10^}
+\newcount\ind
+\newbox\bak \setbox\bak=\hbox to \m@ne em{}
+\newbox\bakk \setbox\bakk=\hbox to -2em{}
+\def\0{%
+ \ifmmode
+ \ifinner$\par\hangindent\ind em\noindent\kern\ind em\ignorespaces$\fi
+ \else
+ \par\hangindent\ind em\noindent \kern\ind em\ignorespaces
+ \fi}
+\newcommand{\1}{\global\advance\ind by 1 \hangindent\ind em}
+\newcommand{\2}{\global\advance\ind by \m@ne }
+\newcommand{\3}[1]{\hfil \penalty#10 \hfilneg}
+\newcommand{\4}{\copy\bak}
+\newcommand{\5}{\hfil \penalty \m@ne \hfilneg \kern 2.5em \copy\bakk
+ \ignorespaces}
+\def\6{\ifmmode \else \par
+ \hangindent\ind em\startline \ignorespaces \fi}
+\def\startline{\noindent \count255=\ind \advance\count255 by -2
+ \hskip\count255 em}
+\newcommand{\7}{\Y\6}
+\newcommand{\8}{\unskip}
+\newcommand{\J}{\str{@\&}}
+\def\C#1{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi
+ \XX \hfil \penalty \m@ne\hfilneg\quad % original spider
+ $\commentbegin\,$\endcodehook{#1}\startcodehook$\,
+ \commentend$\XX}
+\def\onmaybe{\let\ifon=\maybe} \let\maybe=\iftrue \newif\ifon
+\outer\def\M#1.{%
+ \MN#1.\ifon\vfil\penalty-100\vfilneg
+ \vskip12ptminus3pt \startsection \ignorespaces}
+\def\startsection{\Q \noindent {\let\*=\lapstar \bf \modstar.\quad }}
+\newcommand{\lapstar}{\rlap{*}}
+\outer\def\N#1.#2.{%
+ \MN#1.\headcheck#2\headcheck
+ \typeout{*\modno} % progress report
+ \addcontentsline{toc}{\headcheck@type}
+ {\hbox to 2em{\modno\hfill} \quad \theopen \relax \themodtitle}
+ \markboth{% running headline
+ {\protect\small \qquad\uppercase{\ignorespaces\themodtitle}}
+ \hfill {\protect\small \@title}\qquad{\rm \old@S \modno}}
+ {\rm \old@S \modno\qquad {\protect\small \@title}\hfill
+ {\protect\small \uppercase{\ignorespaces\themodtitle\qquad}}}
+ \ifon\startsection {\bf \ignorespaces \themodtitle.\quad }\ignorespaces}
+\def\MN#1.{%
+ \par {\xdef\modstar{#1}\let\*=\empty\xdef\modno{#1}}%
+ \ifx\modno\modstar \onmaybe \else \ontrue \fi
+ \sectionmark{\modno} \refstepcounter{section}}
+\def\note#1#2.{\Y \noindent {\hangindent 2em \footnotesize
+ \baselineskip 10pt#1 #2.\par}}
+\newcommand{\A}{\note{See also}}
+\def\l@part{\addpenalty{\@secpenalty}
+ \addvspace{3pt plus 1pt} % space above part line
+ \@dottedtocline{0}{\z@ }{4em}}
+\def\l@norm{\addpenalty{\@secpenalty}
+ \@dottedtocline{0}{\z@ }{4em}}
+\def\l@num{\@dottedtocline{0}{0em}{4em}}
+\newif\ifcancel \cancelfalse
+\def\ifnextchar#1#2#3{%
+ \let\@tempe=#1\def\@tempa{#2}\def\@tempb{#3}\@ifnch}
+\def\@ifnch{%
+ \ifx \@tempc \@tempe\let\@tempd\@tempa
+ \else \let\@tempd\@tempb
+ \fi
+ \@tempd}
+\def\makethechar#1{\let\@tempc=#1}
+\def\headcheck#1#2\headcheck{%
+ \makethechar{#1}%
+ \def\theskipper{\vfil\penalty-100 % skip before new module
+ \vfilneg\vskip12ptminus3pt}%
+ \def\theopen{}% opening skip in toc entry
+ \def\thetocskip{}% vertical skip before toc entry
+ \def\themodtitle{{#2}}%
+ \def\headcheck@type{num}%
+ \ifnextchar={%
+ \def\theskipper{\newpage} \canceltrue
+ \def\headcheck@type{part} \def\theopen{\bf}%
+ \def\thetocskip{\vskip 3pt plus 1in \penalty-100
+ \vskip \z@ plus -1in}%
+ }{\ifnextchar1{%
+ \cancelfalse \def\theskipper{\newpage}%
+ \def\theopen{\hskip2em}%
+ }{\ifnextchar2{%
+ \cancelfalse \def\theopen{\hskip2em}%
+ }{\ifnextchar3{%
+ \cancelfalse \def\theskipper{\newpage}%
+ \def\theopen{\hskip4em}%
+ }{\ifnextchar4{%
+ \cancelfalse \def\theopen{\hskip4em}%
+ }{% else
+ \ifcancel\else \def\theskipper{\newpage}\fi
+ \cancelfalse \def\headcheck@type{norm}%
+ \def\themodtitle{#1{#2}}%
+ }}}}}%
+ \theskipper }
+\newcommand{\code}{%
+ \rightskip=\z@ plus 100pt minus 10pt
+ \sfcode`;=3000 \pretolerance \@M
+ \hyphenpenalty 9999 \exhyphenpenalty \@M
+ \global\ind=2 \1 \startline
+ \startcodehook} % \def\code
+\let\old@=\@ \let\old@S=\S \let\old@percent=\%
+\let\old@hash=\#
+\chardef\code@=`\@
+\def\tt@percent{\hbox{\tt\char`\%}} \def\tt@hash{\hbox{\tt\char`\#}}
+\def\startcodehook{\let\@=\code@ \let\S=\equiv \let\%=\tt@percent
+ \let\#=\tt@hash \def\^{\hbox{\tt\char`\^}}}
+\def\endcodehook{\let\@=\old@ \let\S=\old@S \let\%=\old@percent
+ \let\#=\old@hash \def\^##1{{\accent94 ##1}}}
+\def\Q{\rightskip=\z@ \sfcode`;=1500 \pretolerance 200
+ \endcodehook}
+\def\DC{\endcodehook \egroup}
+\def\CD{\relax
+ \ifmmode \hbox\fi \bgroup \startcodehook}
+\newcommand{\U}{\note{This code is used in}}
+\def\X#1:#2\X{%
+ \ifmmode \gdef\XX{\null$\null}\else \gdef\XX{}\fi
+ \XX$\langle\,$#2{\footnotesize \kern.5em #1}$\,\rangle$\XX }
+\def\XF#1:#2\XF{%
+ \ifmmode \gdef\XX{\null$\null}\else \gdef\XX{}\fi
+ \XX {\tt (#2{\footnotesize \kern.5em #1})}\XX}
+\newcommand{\Y}{\par\yskip}
+\let\yskip=\smallskip
+\newcommand{\D}{\defin{define}} % macro definition
+\newcommand{\F}{\defin{format}} % format definition
+\newcommand{\defin}[1]{\global\advance\ind by 2 \1\res{#1 }}
+\newcommand{\DO}{\hbox{\sl\char'044}} % slant dollar sign (used by awkweb)
+\let\G=\ge % greater than or equal sign
+\let\I=\ne % unequal sign
+\let\K=\gets % left arrow
+\let\L=\le % less than or equal sign
+\let\R=\lnot % logical not
+\let\TI=\sim % tilde
+\let\V=\lor % logical or
+\let\W=\land % logical and
+\def\vert{|} \let\amp=\& \let\PP=\P \let\*=*
+\def\AT{@}
+\def\ch{\note{The following sections were changed by the change file:}
+ \let\*=\relax}
+\def\inx{%
+ \typeout{Index:}
+ \begin{multicols}{2}
+ \parskip \z@ plus .5pt
+ \parfillskip \z@ plus .6\hsize % try to avoid almost empty lines
+ \outer\def\:##1, {\par\hangindent2em\noindent##1:\kern1em} % index entry
+ \rm \tolerance \@M \let\*=\lapstar
+ \hyphenpenalty \@M \parindent=\z@ }
+\def\fin{%
+ \end{multicols} \newpage
+ \parfillskip \z@ plus 1fil
+ \markboth{{\protect\small NAMES OF THE SECTIONS}\hfill
+ {\protect\small\@title}}
+ {{\protect\small\@title}\hfill
+ {\protect\small NAMES OF THE SECTIONS}}
+ \typeout{Section names:}
+ \def\note##1##2.{\quad{\footnotesize##1 ##2.}}
+ \def\U{\note{Used in}}%
+ \def\:{\par\hangindent 2em}\let\*=*}
+\newcommand{\con}{\end{document}}
+\input{multicol.sty}
+\input{\webmacs}
+\let\webmacs=\empty
+
+%% \endinput
diff --git a/web/spiderweb/mac/MPW_SpiderWEB_21Mar93.sit.bin b/web/spiderweb/mac/MPW_SpiderWEB_21Mar93.sit.bin
new file mode 100644
index 0000000000..89be0ccde1
--- /dev/null
+++ b/web/spiderweb/mac/MPW_SpiderWEB_21Mar93.sit.bin
@@ -0,0 +1,1796 @@
+MPW_SpiderWEB_21Mar93.sitSITDSIT!1?F€€P€€€S€€€B€SIT!1?rLau1 SpiderWEB €ourcG€
+€€€Q€€Q€ €UN!!untitled folder1Mar93.sit@€-d0€_€€€Q€€Qpɛ SpiderWEB€€UYf€€€€€€g€€Ce I€K€€€ ada.unix(€€,_€€€€€€€€h€€j€H*€€€
+ada.spider€f
+WfTEXTMPS €m5
+€m5
+!€€€€ €O€@€€lڹ€q€;2€zk€€€p€s€E€0<',€€s€Å¿€€€n€€€€€€€O€€Z€€€€€€&€€€&€€9ٔ€*€e€#ϵ€€€€€/~€€€€€y€Nx€€€>€Ɵ'€€€€Dpí²gI€<€S€8€€b€€D€l€4€9$€t€€0s€|€Pi€d€€€RE€,€Me €€7€€ɋ€_ z€€
+s-€€€R /Uzc€˩€0€W€€€HR€€WBG<€ş'€€,€3€€€€€€TD €d€€€€€7€€E€w€*?Ͼ€€H€ X€€)€>8€€€€O€ €1€yr:€c&"€E€] #€€€€*1€7€€€€€€MS6€€˜p€€[c€€€€€€€€€€)K5€€€€€F{c€9€D€€9€€Iՙ€€€€5FC3r9€€€€€|>€e€€'€-€1s.AH€€€€<^€e1rʬ€8€€€$"€ €pE€zPu€€€'€?_fi€~/JX€€~Y€€H€s€q]€/{T€T ߭€q)€Xb€n€€fe€*e€€€€Nc€u€w€*N€€€G2€€l€€€=i€[€€:y€€<€&1€ €€€:€x<€€€€d€€€JV €€H€€€`€e€s€ w\k€€€€€€€A€€vpqpp€€€€פ|=&€U€€€ۻ,€O€(l€OK€g€-€$`€€€| €a/{€h [€p9|"€b€€,€à€€D€€oM.€€€€€;KX€€€>€^mPb€nm€€€8€€€€m€ZT €€/€A€v€I h€€_޺€:S€0€€€€€B€€S&€3B€ 䙨€ Ia€Ç€€Dl€€V^€€l€V
+€A)€n€Zs€p€X3 €€+€€€(€/€Z€[G€ބZ€€hU€€€€5€^€€€€€€€$A€€€X€d€€€€€cU€D`G€€Z9€€rÚ¨m€w€L€Po€/€q7€€!€y+€€€€ €€4€€€T€z&"€€Gr€֨Uj€€9€ h€oWG€c€I€LH€J€€|&:€€@€€G-~€€p€1€€€ €€€8R&QWҬ߶€ €Jib€t€€ۖ€n €m€ €€ /[€€€5€€۽k€€€€ӷ€€<€gv€v5€v v€€€€\€€€i€J€€Շ€€€ €c€€ZK3m€€ê·Â€Â€\€€€i€€€S€€d€€€c€€&€<€ZLy€m(€i€Pe€€+€)^€@€€€i<c^K€€€€C€€;€€€€L`€Pk€€€[€ש*h{€,€7p€[€€PJ€€€֨€€€o€.€€€d43€b4m€€€]{€€c{€Z€€~L€ VQZ€d€.€ ٔ€ޣ€€STў€€€e€€'€€€Cl€€cX€€€€ʛ,€€V€€
+[E €0:;€€F€€€8Ei€I€ V€ {"€e€^OR€8U€€a€b€€<€pP€qo-€€dfѳz€B€E€€yby€6€€h0€,ZL€C€€€l€v4€r€€€€€U€€0@v€€€O €€€€ €€8`€€ P€€€€5€€€.€*€€€s€€€dw€{mr|t€€i'€€5€=€8~€ w€Jc^O€Si?€€4.^>€€€4삋€e€i €V€€€€k~P`€€ €)€€€€€€ ^€€€(€I€€@G€p86Onz iPv;€€€*€W€S€l€k&"k€CG€Ū0€ZV
+€Z€La€'Ԙ€'#€€€f~V€t€€€ wLx€T嬙n€€Q€ڢ€4^TՖ€€[€€€€+€& €{€€eRUu€n€€Xf€€€€ €y€€8€I€€€q€€W€n€Y0€€€7q€€€D€€€"G?€yukw€s€€€€_€€} 9@€€€€l€€€'8d@Î’ÒŸC€€۶A_€,b€€vL€€€piO\€€R €}|_€€€Q€q€€k€€5€Q€A{€€€€€€€€€W"€vS€€8€€P€E€X€[d€4€€€€ €€€JÝ€€€7F€ܯմP€:}€€:€p€] €
+€VBcc]"€€7€-N€5€€€€,€€€:€€:€€Ӭ€€i€€K-|m€T€̈́ €€€€€dd€Q€€n€€=/S€N€€€׷<.€kO}?^*€€€€_€€€€b=̪~€€^g}€ĵ€€F€€€,€€D€€€€n>#7€)€€€=Äž{J€(€9,€€€tfC€€€€HE'€\€NzK€N€iL€L€7€*€€€€€c€€€:s€€<l€€bF€€=€€€u/€€€:€X榞€€׻€,_€€ޣp€€€+€g'€€K€€€€@Y€€€€ makespider€€€ 0fTEXTMPS €m5 €m5 €i€ÐQ€j*€€!€'€y€0€6p|€€€€ı):€ҭ$€€€>€wtpuq€€€€€f}€€ €€€ѥ€€€€€€n€efN€€€9€€€€€4€€`t€w=€€€>jK€€
+new.spider€€
+W€fTEXTMPS €m5
+€m5 '(
+I€~€) N9y€ Bo€M€R€€€q€€l€Jh7an€€€€&€€€€€€^€€€€u€s€$€G,pߠ€€€€y€u€mr€€~r€l2€d€€V€Iv€€{€€€€i€€€€€€€ €€g€/-(€E€w€ǵ*€m5€€€€mo€€€)€@€€*)€€~Ì·i€}€€€€€^€XÅ>€€4€ꃚU€n€€o€€wvj€€ڣ€J€€R€€o€€€€€€B{)
+€N€ش6€+€nW€WJk€JsI€g€€7€do^€~W€o[€€#k€j=€Q€,€ݪݿ€€nm€ 4Õ»UtesuW€€€€@1€€an>L~޺€`€V€€€€۬€p"o€Q€7€€ ok$O€€€€-%€fY&K€€{€€€ 컔€€€w!M€HH7 j6€8l>€€€€<^€}€€!€>€€€U€O€$=Z€S€۵j€V€€€u+€€v€Z-€€€b1€€€Ο€6€8€w€€@;€0$a$€€q]Q܉z€€.€|€PA1€5€'€€a€W$5€€€2€€TH€}`€€€d~€€€€P%€!€0€9T€`€x€}€zG!€€G€*€€€ƒHO€€:€€€Kx%%€>€;Rr€A%пḣTS€X$$A$.€€€w€€€€צ€GB€lKJq€€€~€€€^€z€€€€~€& =\€hØ=W&M€€A€u€€iH} €!€€€€€€Av"€€€.€€2€€ €€€!ȳ€€wh€h:DUÔŸ€€M€€€̧€#€€Ò€6€iǼqv€C\€€€€€ €€#€.€U€l€€k.-€=$rC
+€KW€7€Z€s€ä€}€
+€1€1€€U4€!€=ȋ€€€<€€ИÍ€΂IÉŠy€€€€^Ú‚c_€h€8€H9€€€+SU€€gË¥a€€-€KNGYZ€Ϩ€<c 1í·™Â€€y€€R€M€€e€€ed<€€€€€l€X€[˵ۀ,€€ €€€n€€€€K€€€Ē€B€5€€`k€c€€<ycG/Ud@l€M€€€€L€€l€!€€€hzÌ€b€˽@€ '€w€y€€€OJ;i€€"3%€ufY€€v+€\+R>€ f €€€€S€F€9k€I€€€II€ €€5!{9'kN€^/Èš€€€.€P7€€5€bd€€€#J€€€€
+€€€+bKh€xeC€€6€€C€[A€$€9€-€u€€€U$$Cc9o;€€z€€/i]y€€KB€€
+X`€€"€€=֔€]vL€`€€0Ƀj€40Ä€€ €€d€€€
+
+€QP€_ € P€.i€Б€8€ST€h€€€z€ª€€}€ח€€]€€Pp€V€݅€€€z,€€€€F1€qÔ€T,€&`€-€q€€ U€€€€€€٠f€&?-€l€€€€F€€€€€€Q€
+fk8€h€xL€€ (€€GG€c €I"€€3€€|&:S€.€)€€€!€€jnj€€^€g\Mc€€D]@€Ŵ€€€ €€!v[b>€x46€€c€ٺ o Hϛ€=€ €€€뷒€€ԉ€€;(€€€T€€ؚ 0T7aRi€J€7€,€€€}sia$Ì€€V€ѹ/€Oa€€€€€€€2IM€XpD€€€%€D€|€
+vT€X€€€€€V=€k€j€y =I$€€€€€W€ J€&€€{ϺA~Ѱ€€€l};€A€€&
+5O€As€
+€€€5€€pC€ZS6€dßµV€€€ը€.lR€+-€w>€€€€€ٔυF€k€€€.€E€W€2€5lw€ջ€e€鵬€€j€€UÞ¥"€€€€κط€F.x€€IK€€IQh€t.€€披ނ€ €3€_ €€%f€€Ø€€€[#Rn23€Y €€D€ €ςÏ€|€6€€€€hδ€,€€€Jkx1)>€hŖ€ €€PhRZNZ€€)
+Հ€k.€€ €2n€€b€ €€'€€€ueE/€$€U{€ú%€deezm€€{€f]V€€sy€€€Pb€€7m5€€s=€€€€a€€ܨx€€L€€a€5€ӧ€€h꽗O€€€CF€0J€n€€B€€€L`<€€?€€€€€]qV*-sr€€Q0-g€.€€-|O!?€SV5a€'€€2'Azi9€€e€€€U€€ġB€>ѷ
+i€€Q#%€€€€ '+ sV€;D€T€€ZR€€xZUK€_ €€€€€€€d€ @€&ꀀNx:F€1€€/€D€y€*A€J€€*€€€€.€L9€€€4q€w#'€€"€€~M€€€€€€2€*€w€€%j:€!J€€€€`\€ €3€€Cz€}€6€€wc€€GNg€€c€2^q€UG€jh€€Çi{^5€€€ €€€S€Ki€€R€?u€€€:#r8€€J€I€€€ա(€€j.€o€=€1f€F€€€=€"€€€B€€€€€ Px€0€O€€g€€cSt€€€H(d€HG€€€€€€€=€€V€b|€MN3&Ku€)"}€iFy€Oc€€K|g€€j€S>€€€[2€€ Í¡[&Ǽ'e*€)*=_€[€۱€V}?o*€€€€_€€€C€€€a€€Y\g€D€R€`" €8*€€€€J1€o€|6#t€€€€+I€€ɤ+P€€t€€Ig&€_€€€)€€C_'Hß’Lb€€S€€<
+€;€6€€€€€y€€f€a€€€€€€+€/€|l/€€2€€l€€€]Yq€n|{€€˵€+€€€'€€€P_t€Y€k_~€€9t|8c€}"!A{+p€p€G€€.€€^€XM}€€>€€_
+)€^O}€€€€[€€€€€q€€ e$€€N€€ߺ8"€€€€\-€]€Q}€ϸ€X€af€€k!€€Q7€zxȀڬ€€ߺ€<€€J€J€€€7€€€€
+old.spider*8 0fTEXTMPS €m5 €m5 €€€€ͯ €O€@€€pzɩqŸ €€€€G €€ӎ€€p€€€€X=€ €P€€€€€€€ήo€'m€Uz€G€€€qr€ɀ€1#|%€
+d€€!€"K>:N€€|€ €ÉB€4"G4Tl€E€c€S€J€€€)%<N€€y*Ȁ€T1€ €$2€ĩ€€b€€(€€B2€#€€4€"€"€12€#€€€€€€€€€€'€1#1€,J€€%€!€N@€QJG€€€€€ӄE
+,€Sǡ€ €G€€qB€€€€gCqm€€$L€€€>vO€€v6`#€€€€:€€?}€"€D€u€#€€ԓB€€€€rQqv€& €v€€yF€€htm€€€ek€_om€€8€€€ABI#`Ho€€€€Rd €rq€"€}p͇€I€A€F€€€€€€Ң4€$m€rÌœ €€€By€€€€LÆ‚N€€+€€€€b!€€€+€€*€€€=r% €€,K€= x€&€€}Z€H€sZs]€/€(`"€€Vv€€y,€L€Yz€€€
+Y
+€J€n€€€€[k]'ݯ€€t[3€K€€/e;€u€€_&o>€€k]S€€P€€g€€€€€R6 €T€€6€!€a€X€€0)€B€€w€y€€J)^€6€€€€oW€€a€g€€€9o€€€bF€€@y€€YPw€€€;€€€€€Æ¿Lm;X€z Ø£€[€f4€:`A>€€b€a€Ҝ!a€€&gHÓ»:€€N€Y€"€€s€€XAM€zrGb}€WC€{X€6F€€:€$:€t€€U€€˔ €qt€€€€€Ò€ €€ "_€€M€
+€€€€J€y,6€X
+€Q€€w€€`%€€h)€€€RR€o€X3 (€s€)€Z€_*€€W€<
+€Ik€€J+"€P(חl€y€z€€o€<h' ℮€|ēU€|€J€J €(€€€€31Vj€F€_+ݦ€€g€z7€]€€€Z€W€€Ǖw€4€rS€€€€€€€[€€€G€€&€€]y€€€&€6o€€€g€€€ ly€€J-€u̺j€€1€€€€€@%&UͲ€€v€
+3€ €€€€€Wr€€D€
+7€€}Úº p,€(\€€X€W0t €o5Ax€O€€m J€€&l€AC€€€C}€&€€S€W€€€€oe-I€Y4oÕ¯ k€€@G€€€€€d€€zm€t€€€€Ä*Xq€<€M#€6k€]€€€e€€C€€2€Ϙ€€י%€€€€€;0€ތ`€PjOíª›Â€×™Â€Â€Â€Â€Y€o€€7i€W€9EJKT€G€:!"*€€Ȁ€€€€?€wmv€€€€jVe€1i€€€z7'€vQ€€€e€.5"c€€€Ƈ€vG<€€i€W€€€€€€0€MÛ¶L€Þ€€-k€-G!'€€-I#€€o€€€Ȳ €% €€i€ja€b€€\€€Iˤ8€4Aެ€€€ €̼g€<€@Vޓ€̿ݢ€€a'×€€1T€€€€kL;1€0€€€\€g€q€IÈ€B^€ē!€€€u€€)W$€€ €€€€€d}€yr€€€aw €€1€>e8|€€€€€\c€7€Cn?>97.€€€}€;€?€€a €€€€iFÍžH8N^€H€ z#w€P€€€j$JmJ1€5€€€€€€+€S€/ҳ€ €|3}@r€EO[05€€8xY€€
+€€d€€€R€T€lB€ |Ô€€€€ϪfN€€ €€ ω€9€€;U€€€€€h}€€€d€€h€€€€_.޳€€L볃€€&€€€€€€€ €€€['Nq€€Ce€€j€€€V€̙€г€€>H€€CS€€o5€f€.A€€QÖ€s€€€fC€KS€?08€ €€3U€s€}€/€೹E€€3U<€]Ú³Ó¯>j€€n€€7y_€g€!€€빲Do€m€v€€x€_€€€€h=!4€€€D€€€€ei€€€€<€€€1[lç«™O€€PcÔµ^h€M€ʴ€it>€(€€€€€€€€€€j€€€€d4€€Z€y;Cbvʆ1€BT€e€€CMqP)€όë³™p€sӂ€x€€Fi^€v€€€.[C€綠eq€Y€€€€€€&e€X€bZ/]€͢}€1/€€k€€$d€ާ%€€€@€€€*€fL€<a1€€€€7€"€€g€€a?€Q€=€€墛\#̧[`!€O€€'W€a€€Lx€ؾ€€€€€€o€€€v€G&€€€c€€7€€
+stacks.webGE€+€fTEXTMPS €m5
+€m5
+'€ }= €€ N)y€ N€€0€GO€qr€ èµ²MoS€€)€€€"€#\€{€€-€€€€€€€^€€O € €€7賳€/€€}€w€€M~€€€€€mF6€U=€€€zoF€€€g€ڦ€€.€€€€€3€?€d€n€€U€Yu€€€$ɋ€€N€€€tZlPLln& €€€€€€€[€€€u€w]€D€€ËA€hj€€€€{€€€€€€[€€€s€!€v4)t€%}€€ܴ€€€€€6q€€€€€Ð€€€€n4&ϳ€H\H€ّ€€M€m_?
+€€L€P€\€Ã€€o€€c€€€€€€v€ib'€|[€t@/€9T€€ €l€W€€ €y€€€€VO€€€€~k€€X€ܸ€€Y€V€i~[ͬ.€€p€€c€5!€®~j€n8€Y€7€€)€€^6€k€!€€Y
+€€=€&€€€€€4€
+€€€T€€f2i€%*Y€€@mz€€€€€a€€U.^€€€J€1€\€b)L€€€N€€439d#cU/EW€Ir;€9€O€9-B+TÛŠ€€K&€€0̰€€€$Ѧ€;€M€€SdQ€C €€€€'€z€.€EvNC€ €€m€€ €€ €€{ €€€€rmJ €€€€€0€}]€'I6€$€W€€G€I@€0€€ s€0WAKW€&i6€€)9€€€*€€€0MB€€€9€Q€r€B>€ €€<€ȸ׫€8€z€5€B€€y!UR€Œ€€€\€g€€R€€a€M€[:{1€€ѯ=€€€€q€€$€I|€€n%€K€€€D€€€€ Úƒ€€bX[}€€€?€@?€@E6€€Y/q#6€GL€h€€;€€T€"T€PQ€1u€€C€4I€€F€I*N€9€r€A€/€€2€€rk
+,K€N!W€€fqZU€OQF€#€,€A€Y:€€€H]€€
+,€€€€€r)€}K€&€€e€Z€dH
+x4#€
+/BR€(2€ރ€€€w€X€€|€:HSNn€€ ZnEâ–½,K€Ia€€€€€I€S:€€€1€€E#€zBb€Q€€Ԅ"7€€€€€€݃:€%€1[m€€ ;€€;€n€hÛº@y€O€€};%e1€V=€€€N€a€T€B3(€€€€(4€€€€Â]€€€2M€€€x€€o?€\0€6€€?`€€r€€€Ok€+9€,t€T €X€€€€X€€^c秨€€<L]Å<€m€cP€€'€,€6€9M€[€UZ€x+MW€€/$€€FR€€€€€N€Wm€€€€€€?€h €8€@)€(i€x€€A/€F€˭A€€X=€f€€l€€ í£@8€/<×» :€?(€€€€e€'€R€€€ €g**€€4ۋ€Bm%cPQ€€€>€K€^QiU3o?€€€€€G€?,€G€؎U|€€€-Y€€jɦ|€€€€€cj€8t*Z€€€€€:M3q€€€€€8UcB€€Èu€€O€I€-€ € €€{€€€€ €€€€Q€€"€€€J€€€9€߾€q-V€€?€€y€&€€€i€AZ€//{€
+e1,€€€)E€֓|d~€
+P!&€DR€g5[Oj€€€€€^€€ ^€5€Z€W€€ €*€2 €€$v€:dgc€({=€€€E&W( \€R€
+YT€€€€€YE€€Lb@,A€€€€€€2]€€€€ß€ €-€€*C b;€€b€g€h€€€{j(#€-€€€}gY€€€€#€;€FR85U€€q€ 52j7€2€gQo{H: €J€€€Ǥ€f€tLT€3€v€€€$;€€.7B€€€€X€€Z€€2€VI€€*P€H,S €€^€€€€P?^ €u€S€€. L€€€f€€€/€€€Щ€€w€B€ Z€bw=P=;ri|€€Z€RS€€€€€ci€€€l?€\ Þ…"m€=€€dog€€8
++€XE€.eQ€€ A€€2A^€€€€€#€(#H&€\€€€,€€u€€€€ID€ €€€€€z€€€W€€8+C^€€€L€`€€l]€€€€€€ €PP=€ =€€,..^€€i€€k€€)~C€€€ݻ€ʇl€€€n'&€€'2€q;Q€€€+N*Q€€€€ €€€e€j€]€lw€7€€€8€€€€€le€€O€kZ€%L:€€1.Gz€P€€€€€ T€€Cq€|€DZ-€€€€51€:€€€@3K#€ט€€<€އM_€T€*.€Η8|fF€€€5€€€€@€Ā€€€€€`€€:Nn])€€€s/€€€€€-ky€NZ€Ŕ€ز€,v@^`€r€7&t€€€€€N€E€€>€€c €€ €I€€€€€B€€l(r€o€(€'€€€4€€H€€/\Ԕ€€@€/€$€€3eT€;€e€*€€`€Ǒ€+#€€€€€€€€E€@ ozЛrRy"€€€x€"€y€u€€w+€€€€)1v€d€€6ƒ€€clMK€y€ €gÃŒ)€}t]x€€n€8M€N€€€Y€k€€€€k^ M€€32}€€€ <*€4€€~€€;€€€ߞo€€]€|€€~€j€€€a€}€€oZpm€'€6€€,{0/€€ι€€Y€V
+x{€<€ g€
+€p€€€€?€€€a#€€€Gi
+€*€1€€{€c€€£€z=€
+p€"€€q€3Bè€.€€X€ D/e€ IU⤇€suBG€n€'H*w€Ԝ&€js€{€€NϺ)$€+@U*2b5CÌ€JZ€{€€r€RJÏ€€T€€€|s€:B9€€€€X€z{€%c€€1€€€V)€€?Y€[€}kW€˷ZhT€'€1€€;€€Uq€K€ ,I€€€€U€€hx-€-€6€,€|h€5€'P>€Q€€€€€=[M€€'] P:2o€€€G}v21hD€J€€~€€@€pA€م€€7€€0E*%€€€€€€E$t€<
+€A€€ (#b€M€€/ €€€P=€€€˜€
+E€€5€€€q W%€w€<€€-€r€ m€=13Oa€'€€|-€*€€€t€dD3>€qܸ€hd`EHȅ€J€€€€.q€€~€€xKv€@€€€0€Û€4€o@€€€€€€I€i€€€d€€€!h €n€€€€€€2€"€€€€X€(€⥪a€€A€€J€€ƣ€€(F€D4€/KU€€Q$€rH€W€0€c€V€€Jf.€E€{s€QP€€€€
+DO,€q'€€(x€lgÜ€€`n€€€€k€_€€€€1€€X€€(t%(€/|D€€€€AL€^?€€c€i€€G8€€N€€Ւ€€€€€>P€#twÉ„%"L€€€€g€€'€+€€€~]€>€€€u^€€L@.2€߶;F€Z\€€€d€€ϫ€S[8 €€u€€v€J€W€7€€€€€ˈ~#€€€€€:€p€€€€€Bh€!€€€QG/€t €q$"€€=€€Y€€s€[K€=€FzP€R€€€9€€E)y€€މU€TX€€€h€€z€R€G€S€C€€Ԯ_TR
+H é¿‹Z€€K€!€€€R€€€€F€3€€oÑ–8€€€*i€+€€hWW~€€1
+€ǽ€$€€€€Ï^€^€€P߀€A€Bd~€€€9€%€Y€€(Y9GR€4€#Us€€€€F€€€E^/€j€€H€2€6t2€€€1t$€€l€€ €€Ȍ€(€JL€Z€&€€€20c~;v€€€€
+€-€€e o€m€€€S€€€ €N€€u€€ƚ€€w€Z,€#€€ԑ€7n֦q€€Vg€n€€n€ €€€€€S€€S€5€€€t€€€
+,-p€v€g"`€€z€#2€;€€1M€2/I€€#P-€€!€5T€Qn&ҫ€€IlwN]€€6€€€€€4€h€!! SpiderWEB €ourcG€
+f€€€Q€€Q€H*€6€ ansic{d.€€fAE€,€€€€€€CC€€€C€9€v€* c.spider Files€Y,_<E,_@TEXTMPS €CC€€Z€ 44E €ή€8€€€CW€p€r€[€€€€€€€€€€(€:€€j€r€€2€€0€q>-€g€b€Zj2€€€€Z€~ €n'k F%€€€€€q2€€€t€z{€€d€AL€ք1.1II€QۄÌ8€2€€€€€€€€4€€2€fJ€³€Î€€€8JE.2h€€€€€€L€+€€^€Shf&L2€€N€€u€€|€€q€zJ=€iY&&€V1€!€Qu€€€€-€( s€€=*€"€€€J€ c€€#€`€Q3x€%€~€H
+€" r:€€€€€ O€Y€}€.€ P€I€€@ÙLy€€t€€€tH € €€(€€€€Øs€b€€J€€€€m€hÇ€€ݧ€ N9€€'€`?o€€"<2€€€m ÛžO6€€dK6ax%x€€/€€t€€€€{€6A?Z€€]€ €k`O8€€~InKn€}€€€ߔlJ€ :€V€5gqP€w€€}€7€T6€R€4€r€!w€9>€€2€Q€€€\uâ¨y€*€)€'E€ˮ€€Ld€dTf#€€\€4€€#€€*€"N€3€€X€"€R€€D€;€€€€€€€€€/€€€(€i!€q&;€€€A€€2€€J€€ €€ :A€y€O€€€C"Ý“}€€Z€€€€#d€ŧ€+;AЕ€€L
+QdQ€'€€€€#`€ €y.€€4(Ô¾LE܅€€€Lt€u€<€2€J€€^€C€<€ €S€€,€q €1€i€ώ!€€€€€\€€€€%€Jf2€>'€€€[b€0qkx^ ^-€:€€+S€€ũh€5t€:€b€~€€,0ȉ,€€€GQG€W0€€€[€€Tq ê¾”x
+qc€Ȼ€€uUa@[€€€€s€€I€€ħ€϶瑟€Q2€€AJd€€€L€\\€^ik'_€€€67O\€€lrC€€€c@€€€wC€€p€?]€?€yND=€€W€€K€k€€2'€a{g€€ι€€%€jM€€€R]y3!€€;€€Jm€€M>X:€€myZ5€€€5€€$€3€€€;{€€ €€j€di€d€€€0*ǵ+€pII€€€g€6*€€€9€F€r>€j€€Aݬ$n€€7Q€h€€<q€€M68€z€€q]€^€€€^€€€#€€\;G\wϹ€€€>>€€zu€€€€€.€€x€€F€XLÉ…a;Gdw/ȶ€€€€bl67€\";€€@Fݥ€IRd€€T€!;&€;w&!H€€€€€€€C€€€n[€G€€C=y€(€u'ׯ;T€u€q=|€€€m€€€ڞ€€G€€€€€l'€€cqx€Vxe€€€U€€(/€€€€€€W€JH€€€L€pä€+€ԡ0{€0Af€@€ )€€ €o€€€€b1€w2 €€€_V€€Lr€vx;€ņ€€Vz c€€(o;€nD> Å¡](`Λ€6€€ €A€€c €r7€€€€€ €Ui^€€g€j}G3€€/|€€€€ €Eɳ€€:{sd€€84]s €"gn€Ҹ<€€T 5 b|€€€€€ b€A\t €i|1I€€€€€.
+€ €^/{€€/*€y4€€€{€W0 €{0A.€€k'€€€€ €€qZ^€€€€€K3€5€€CS€€Z €€E€€J`€]€j€.>€€<C€x€t/Q€xDM€k€o<€€€€€€Xo€
+€€€€N4€3€(€;Qr€^€€€S€€€€(€€GV€€y€€€v€€j{V€{€s!€€'€€€Z€€€d€_€ov€&€€€g(SZ€KT€€€b-p€x
+=Pu>|4€€€(zQ€€€2(€€%€€,€€€>€€>€s€€h€€Fk€€[€QB€€€V€L;:`€€€M€€€€€ €u€€€€€€€€+€€UÑ‹€€%\@ €€€€€w€y'€Fh€v€€€@€n€F€€ €€L9€€^J€йbU`<€Q€sE€_€€?€€Ç€=€/€€€€€€ €€€8Q€€*€cZ€4)€&€€$P€€Rf€€fW~€€n`#€€Q€€4€€A:z€D€6€€2Ñž* ZN@€h€€€€€o€€)aÖ¸[#€J?DK€9S€€€€€€€€pK€€€€€€Z!€p€€€B`€€,inm
+€€ a€€€€*$A€u€€4,[€p
+k€€€€E €€€UӤz€€i€€9k€Y€€K€n)€€O€€ F€€€1€€&€€Գ€€€€J€*s€
+$c€M€€b€€€]g€ >€p-€]€ €€-€i|€€R
+Z€€3€€€€k€€€?€g€to€€w<€€€€w0€€€-€€€€Ä*€5€€€4H€(€V€€€
+€8€€€€(€€€S€"€€€B€G8€p€€[€z€nj€^€€j.l€€̞!X€tXI€͓€+€€€]€|€yH€€€Z€sÒµA€mC€€€G€ygD€€\€€€€@O€^@3{€Òˆ$v=6ZAE€BjA€GÐ…/€gȃ€€€€~€€}€€,#7€€-N€€#€€€Lw8€€շt€€nb€€€=€Y)1€8€€€3N€€€€~€\b€ͺ€ ?€~24/3€€€€€€0€,€R€1OH€€:R€i€€=€€P€€€€D<D€€€V€€A]€L€€T€m?<z€h]€P0:J#Ò±*€a€€JKw€€€€W€+-g˔€€€㖆_u€€€€UpY€€/U-€€߼n€˿e\j €B€€X€€€B€€€P€)€sު€€:€€€€f
+€ԥ3€#€R€€V
+€J€D€€cHw€€€9K^€€k€*€€#€€ȳ.E€€Xf€ڑ€€€€BӴ€Yå´®i€DÏ…&€7l€€€݆X€mu€€48fD$€€€g-8phV€I€€G- P_ERL€f^{€€`#։€>€€ €Hh€€Ô€˥€J>#9Y€6€'S€b€Tß°€€€€€|F€€GM€]€އ€€]€Dl?W€€€;G€€€_€ϒ€q€€€z€/€.€€T€€€G€€N"€€~€f€Ly €>Ö¨-$I=$€R€€€~.o U&€5€ /*V€n€€€_,,€€€GR€P€€€n€=r€€D1€€€€-€yuv€€?\}zÛ˜b€€€Ð€A8 €|€շ€€?€ë Cw!€Ka€:€€8€$%€€€€ʖ=tÈDc€€€1 <€#€€sm€c€€fo€&3€c(I€€€c;ÞœQ€€γ€€€4{€f"€€ϣs€€€€,j:€€€€hc€ -ȋ€€-€㈋€W€/D€€€ €€€€€€€9 €€€rÉ€X€€€ݹk€€€"€€€O€€€A€)J€q€€H €u€J$Y*€€€eשԓެ -Ò¹0 €-€€'€n€B€%€€2€€)?܌€Pؒ€F7€[€€€uIsd-€?U€ϓ€jla€˻€€\.€€R€q9i€.€r€€€€€€L€€@€%//ؙ€+(€Uk€2€wS€€s/€€€LeQM€r€€€€+KSɃ€€k€f*€€€&€U4w€€_5I€€4 ÉŒ;W€€ܰյ€Ϭ€r€U€v€c)J€[7€€€€€4݆€ F€p'2€E)9€€€€€€E€€€b€€€P€€ €€@€ €€6€€€€ވ€R*€€€€€uQuu€€o€,<€€€€€€ v€x$€1€€r€€WÍ’q4g€€$x3€ €€v€j€,€1€€ z
+~R`8€€p4u€€`€€+u5Sn€!°€€€a€bY€y/T€€ €€€ݒ€-By=.€€€€€€b€€ €€Һ€o?€€3€ɛ€€ѬLZx€€_€_€€/€€€€€€(€~-[ v€€/fg€€p€€€)€,€€€€€€€€€€€€)&€}€,€€v€€€€>€€€%€-AwC|€€W€=€r( €€'€F€:K3€€3€o€A€K€)€R8E/€4€€A€S€€ѵL€€€€€ַ€Hp€›jsFl€€€€€'H€<|Q€€€b€€€€9K€7S€ €If€€v€|€Lg€t€E7n€=€€4€8€\+{€€€n €€ w€€€€y€cr€€95€€i€€€j€|€)€€q€€b€€€€€"bN`€>€€€€,€€=€€У;€€€L?€F€€€€vE€€mܫ€€€sÜ›Rb€€€оY€^€€[uJ€€Q€:€€]=€VI€A€€ޕC€m€?<€`€]*€€€D€€€€ €)€€€9€€€€#€€ =)€€%V€€i^a:€€'€a€€}m€€O Y]n€D€€CV€`€€e€€pd€€:€€&€€€€€Ä€€€€Q€'-€s€0€€ local.guideles€,€=
+,_€TEXTMPS €CC€€CC€lU`"€Q€€€ €€!€€^3€ zA€x!€€}(Ý€Y21€CQ€0€\z€€~€Y7€€H€€€€€a€fÍš5€ €<D€€݈D€d€~ makel.guidelesa<E?,_TEXTMPS €CC€€I€q€€€<€€)U€vbU€€vL€€0 bq€[FY€r;€€€(€x€ąЫdlHGy€(-€g€b€€`€€5K€€€€֭_u€S€€hl€€j:€U.w€€€R9€€^€€€€€;7€NÛ©€€~K€€ݷ€u؉]€!€q€€D€J€€€zd€€Ì€Ý·0€w€€GUnYr8t€ؒm Gp'€l*€*€€€€ʙAs9€€%T€€9#)B €m;%5K€T€€Nq€]R€€€€I€b€)T@z€€€€k€ؖN€2€zWck€€{}€€ €€hÜ€B €€ 9b€€f€€S€€€€€Q>A؇AΡ€O€€{}(9€€A X€€ €€Vy€3€V€€c€v€€€1€€€€€€$€€€]:[k€€€€C€|p€<5€:€€€€€,Ι€€€l€I€u€7rg€€€€€€€€€€r?€g€€€€ unix*€=
+@€,_?€4@€G(€€9~Iރ makele.c.origs"?@e?TEXTMPS €CC€€CC€~iR€KAQ€j*€€!€'€y€0€6p|€€€€ı):€ҭ$€€€>€wtpuq€€€€€f}€€ €€€ѥ€€€€y|>€efN€€€9€€€€€4€€`t6€$€Y€ׇ@m€p?!! SpiderWEB €ourcG€
+?€?€€€Q€€Qz€€€ !! SpiderWEB €ourcG€
+?,_€€€Q€€Qz€€~€ awk€€,_K €A€€€€€€€j€€Cw€ X€€
+awk.spiderrigsDAEHAETEXTMPS €m5 €m5 €€€€3N €€ €€ǽh€€€#n€€ Ë€€€€€&€N8€€€€P@(€€(€GMB€€€€AgGt€aIؑ€F€N€Ȕ{€€€€6~"€€dр€|€€'xGÈŒp€G2E'xw0Q€€€€€D€#€X)3€€Bm€/p€€B€N€IJ€€€̅€
+ €N€€ę€3€€h&€V€℥?€€巽€€€A€€€€€H€50Ic-€€€ 2€€€€€k€X€d|€€=ņ€€Ġ?€0ÎŒI€t€M@€€0OD9S€€€H€€U1S€€)<2€%€€!Ôq€€€€€P,€€DÓ§C€j€€n€€€€€tl@(#€€€QIDi'Q€€€c€H€/4€€€v€+9Ç¥C€€Mn€Z]€€)R€€$\€€Lxs€€€W#N€€('€€€r€`€%€JCi€P&˙€€Y€#€E@€€,€:€€L€€€sE€€€)€€`€ ӡ€bI€€€b€H€€€€€€D€'€P€€cw€€}€Eî¥7€€€n-€€J€y%€^€€Y€€(€ڂ€;أ€€€I€€€b€€€€€v€€€€ }F€€H€€€€Z€o€P€€€Z€€€r€€=€R€˲€w€0Na€€€?€d'€F€I€ø€€u"i_€€€€.€€Q€€€5€1€€€Q€€ꘑ€M5€€€€3€C€€B€€€€€(]$ 3€~€r€€€,€0_€€ϔ{fQ€Ë:€€€€}€$€€Il€V€€€€€€ݥ€]€€
+^ €ͤ€€€y€9€(€€{€pY/€2ד€s€K€O+l€c€€X€€W€GK_c_€€€o;,€€€.€€V€€Ô€€A_€_ϱeǠ€€1^€€p€€盌€ޭ€€f:€€l€R€€€€€Tm€€€{ Ƽ€€q.€€€nF,€n€K ?€4#€1€x€Iر;$8ÏŸ€€€€է€€l.€€F€ؠb€€€€€RvP︆€ÌC€€€€g[€;xA €g;O€€€K€€X€€f4UtN1€€€€., €€€Q€€€€27 €8€>€€€G€:3€[€2€{€€{֔˯€7W'7ru€wq%€M€€|V€u€€€R>€ €€€Ѣ€€\€€>w|€€S€~->€7€T €JK€a€€€X8€m8"€€€S݆€€Kebg€z€€€€€J€€€J€w€€}€]R]€a]€€ P€€€ &(€#s€;Óº!€€€€)It€€N€t1€a-€€€€ €€€7 €1x€.s$€k €GAË­PA 8€€€€{€€p€\i€€OA€P€r€€6€€€a€W€D€€3>t'ˬP€N€€€4€€€0I€€՞LG€W€S€ .€0€€l€€U쎛T€€ €$M€~€3qD€ €€€j€€6\€,€€n0€K€€p€-€€€avELb 5€€€€Ҝ}€€6€€a€N€^]€v €,YI=6€€€ €6S€€ €K€€€ޛAs€D€€€€€€+@Ñš9€L€€ˇ€0u)݉ʪ€€€€€€\€\€:̹Xr€=K€{€€€€g€+€rO€(€€ €€á˜w
+€€€€/€€@}€€
+€9€€€€€;/€4€€€€€€s€'/u€䥞&€ypë‚›Rf€€S€€€!,H\ Jm*hl€%€|X5€€€4€~€€€€g€Ei€€€ makespiderrigs€5A€I€AETEXTMPS €€8V€€@€€€€€€{o€€€€vb@€9#,"€€€<€€! 9(#P€c€md €€€ZRO€dR€€€€fi€€€R€€€€€€h€€T€€Ħ}€)€€€€!p€€€-€€€€€z€€€} :€ӽs;3I€€3€¡FܸqÉ”T4€A€€€€;#€{!'€@S€€€4€€€R€;€€%3Ѹ#(=?€€b€ڊ€€Z€€€€€!'@€€€/-:€q€€€m€[Q>A؇AΡ€w4f€^J€r|€€€VG€A.€a€€D@€ €€f€€؇€€|€|€€} i€0I€€6F€€€€blFlw(€€bb€S€€cNv€sGr€€4f€€€€€€
+`€Ã€Y>€€€€k€y€p|A€ȳ€€ make.unixrrigs €HJ€AETEXTMPS €m5 €m5 raj{o€Q€tH€€€€<$'€€>€€€K€€€€€€€€€€€al€€€r8€€€€.€6F€€€€bl€€€;€I8€95€:€D&>w€€f€€€€€0€€€€-€!! SpiderWEB €ourcG€
+I€AE€€€Q€€Q+B€€;{ BUGS.unixrrigs€AER€€€€€€TEXTMPS €m5€€C€ € ]€ €p€vb€T€R€€f€V€~€€€M€RH&€€€€€tv€&€€€€ €€€BI=C€@#P€cٰ€>€Y€}€r€€€€>Z5€€?"2€Mⶊ€€,€€>Q)€5€€6€ч€p€€€€€€€+€ۜ€€A.€€€8€DIJD€tH
+€an€€UiB€€c€€€st0Dz%€)€€ €i2X€h€€h€*MF8€\U€d€€€€sFR8llʅ€u&C-€€=€b =€i6€€€sV€€€J€OAgb}€€ ~T€78
+u4p€&€€1S€€ ?€hAhpfn NW€+A0ar€ښ€€Jh€€KB#€'€,%€€€€€;€t€>j€3€~€U]2#4 'N€12€Q€_O`€€՞€€u^;?r€€€€]1€€w€#€r€€~X{€€€€€:M€\Q€&€€e€\\€.C|<zw€€ €Mp€jÊŒ}€){€'€€€R6€€€DZ €€&€&€€ttS[€€€€(0€€€€€|€Æc€p€€Tլ€6q;€€€+€{€>U€F€@Ҝ€RY€imeu€€€€3€:]^€5€€€J€€€€€€UyË£6€}o€Y€{pp€€^6€€€€€€O€ZÊšQ€9$€€q€€€€.€€+€€UE€€He€€€VMXZFQy €€€€€€€€€€€€€€€]€€LÉ·o€€T}5hx€*/{€€€€€€€€ܲ€J€6!z€5Q`y-h2e€|TUD€€€yW€€!€€Mm8?€}€uqr€€€L l ÒŽC€€€H€€€€hQbWP€€X€+K€€0€€We€R€€€WcU€€bYIi.€\€€€€Do€€€)€€€€G{W€i€Q E€ A|1€JW< €)
+€€€€HU7€NL gB )€sL€€€€*7pe€€R€ޅ€B5€€C€os€W{j€€€L€€€5€€€€€€€€€&9O*j"€€€€ €€ €€€yaA€€ ;€€€E>Ì«}8€T€€€}-rTֳ€€€*n€o%F€ ]€€D/€€2€€o€Z€€€tY%€€HO€€g\€€€€€;€€€€i€€€Ko€€€€€€"€P€ €€m€€5€€€=€€€Q" 5€€Ո€쬅..€€€?€€*€€€€€ +iz€€^€€Mc€‘€`P+€€€€€€€Z$V€€€b€€€&€€;.€€€€€E€V€B€€Ga]€€R€€ܹW5€h€€#€ j€€€kE€.€9d€€d€€€<e€9€€&]€€>o€ }^1Un͟€€ p€U€-Z€€€€t1€ZR €€p\n€€€.€€€€€€€ܟ€G€U΀€"€€Tn€€€€Lt€€€€FN€€G€€€€€&€€t^/W€.€՜€€5€€€QRU€5€6€Cu8m€€€zr€€€Թ€€€߃€€{ewQÙ€€NkL€€€€€€5D€j€Z!V€€$€€I€°$€€{p€9€€€{€€]€MÊŒI'€ev8€€R€e€E€€ €K€€€€'€
+€c€>€g€J!5q€€€ €Y€€€€C€€€€ƣ€€€€rElQ€䓀€€€ €€€ €€d~€o€v€€€B
+ €€€<€(€#€€7Ӏ€H€€€:€€smԩ€€Ғ€_BilY`Bl€€BX€€€P3|u€Y€€É€€€5Z€€€€€€€C€€€6€€€€w.8€€€€8€X€€€l€€€€€€€;€N€`€€€h€α€2€€qh€€g$€KR€0F`8€f€O€ߟ€€"MZS6`€€p€€€€e€LÖ¥g€Q)ezـB€€€w€€%€u€€€x€e€€>€H€€€"G€w€4€/WL€€€€砲€f€}€€€€[€€Я= Û€€β €€,€€>^Nm€€€€ŎǢ€T&€€;€M€A€€x€j€€€xP*R€€y;pV? q€s'J€€€2€yſ€€€R€€€;͗€€€€€V€€Iz,_€€€D€€lc€€€DA(S€€
+€€"€F€^€L€>d€€'€ Fá—Ž€HkI$€=:€|€€€€€€D€;ϳO€M€€r*Æ´ss€4€,ç r€€€t€€k€€€1€€€h€€H€€€€Y\€€€€ c++.unixdYK cQ€SW€€€€€€p€€p2Q€€€
+c++.spiderrigs€R€bR€TEXTMPS €m5€m51€A€{I N9€€'€`?€€€6€#€=€/ €}€€<¢dK6€x~€€3€€%€€o€€€€€ €€
+€5€Ø•o€€> '€€€€O~€1#€*€w~€€`]€W€Q€€€€€€€;€€€H|€€A€€g€@€іx€i<€gR€(€€€€€*N€BjЋ€€$€DvDW€"€q€|€EI*v€€{€€€€€D€۲S€€~€€ʞ€€Gq€€€€€€[€€€€9€€D[€R[i€€?,€€€R €€#€|€@€R$xQ€€lKh)E7I€€€€€ߞ=z€pxQ€€F€€
+€Ir*i€€ʨ*LO~]€LC€€€ €€€€2€^€j0 ޶€A€€€͛k{Bf€ɣ4€dtd7*€By€€€€ v€€ €€€I€€€Pf"€@ € v€€€€N€€€€€A{€Cg<f€x€A4€JM€€gɇZ€u€€ €'B€€`_ €\€€€k{A#(€o؂$K€€AA €€€oT€€L€€$SC m€€^?€€Gq|€c0t7+€€*,h€€€€E€U€^.€€[€n€_€Q€€Oe€€€\€
+€H* €€ZK€X€al€€7Ó6€ €€G~€W€}F€€'€r€€€"&{5>€€](€;Q€U)5!-€[ €€Vz€T€*ÝrGu€Նd€€'€j€€4€€ €HO€QѪ€t€ܬPq€€aa€€€}qNv€P€€J2r€z€i;€OXÊ“%€€€€'\[€j€€hN€€w€€€€€ܢnO€~€o78€€€€€€^2€€{€€€€j€~€€€€纲€@€€]eg€€€€ko€€`ŵ€€€t€u€€€€€K€/€€€€j![4[r9€€%ÙƒK€€€€֜€M0€€\i|€€€R€C€;€}|€€€€€>€w€€xӣ€>5(€w€o€€€€€€€z€€€j€<€€jU\*TX({P€€€+{€€€n'€€€p€€€0҅€7s€€€=€€J€ €€|o*f0€€'5p€(€È";€€ € €€€€X€€€0€€e€€T€7k€€a7€€'a€€2ֈ€€€€€]€€ǡpO€€€€€€(S€n ~€€€x9qF€€dU€€€A>=Iz3€€ M€Z€ €E_1Cv€h€s$A mJ€€€€€€P €t€€€kpYÑŒ@€€A_F€€b>42s> €€€KÕ¨4 €/€2n€€€%E€o€ b|€O€B€`h€€€€>€€u€kUr€s€s€€€kp€Vd€,€€€€ɚW`€\b€\h€€€€€F€25\e€XQ€Ē€€T€€€3€~€j€Y€Y\€Fmv>€-€zK€€€-€u€Vc€b€h€DuS€V€€։€€<€€€€€€쎟€E€5€€/$€€炀€@€€€]@᥌t.[!€€e€j9€s€c+V€€€s€€j€€\€€ilX€$^€sk€}€€ˢ€€|J€€W€b€€€3S%o€rJ€€€€HM€0€*{Txڲպ€ha€u€€ÊŒRƥ€}/€ €€€€$/€خ€*Y€€d`j€€08$C€€T€T€%1€D€R
+€€€€€€q€€€€€€€€€€€€€H€€M€€€F€€bNPq€€€€€3>q€.8@€€vww€€€FsQ€€€€Iϧ€4€Y€€€€€€p€€
+€€|g€6N10^=€mh€d€\n €€€W0H€€(A€6l%€€h€+ D-`}€€€A€pÍ™E€\A€%Ô¤+€T€€B€€€6C€€€ l€T€5=€J 9i€Xy€ca€€8€q QĶP€9€;ʸ;#!€€[P+:€€€;[G€€G€€CA€€^0€€€€€€`€€'€\€€/€€€ѧbt€€€€€€€:€ G€Й€€€€s#e:€€f*o€z€i`€ho#€(€[€A}€€€€€1Y€e*€6V€€+PƇ€) €€€€€f€Ԯ$€€€Clp€7€€€bB8€2m€€€waP/x€€€_2Ux€s€P€€€C7€
+€2E1/€h€l€€Nd€€€5€v €h€}T€€sj€`/€€X€€€€(€€€€H€Qjd€t€B€*6€R€T€@€€J\€A€€€wA€S€ϘR€&€€€il€7f€€€g€€€yÆœUÚ¹M€€€€Od€€€€€;€€G-% ~€€p€O€"€€€Qv€0€€
+ip€€€€EU?i\S`€€h€q€t€m>)4€6€€T€]h€ʌ€€R€?€€-ݢ€zF€€€F€D@€4€€€€€€€€t€€l1€;€€€H€\ǬU€€€h€€€ܘMsLNel€b_€@ȆgqNg€m€`€€S#€€_€D€O€€€€_T&l|€€€v.€€€€€€o3€€]€d€€~€€s€ €€€OX€€€Г€rG)€kU€@a€ €€Z€mQ€+9'€(€€vQ€€ €\'€€€Ř<=€€`€ €H€[dm€€€€yj]€j*_€€€€1€€ €€EM€€{XN€€gDvk€j€V€€€€€€*2#€€€z€~ݱl€f€€=1€F€ €€€_€€€;€2T€LS€€Z €̓€€#>€Z€`€€T֪€€€€€E€€€€Q"€€ҙ€(­€€A€€€(6lu€€€€€€€#€€€E€L€硾@Ä¥€5y8€`€€€€€*€€€€Ŏ€ o€!€€gw€V€R€d€BWT€€€HÅ©<€€ӊ䥗;{H#B֠€u€€€pAi€+€€€rÜ‹R€i(€S€7€€g€€€€I*u-€€u€ఽ7a€b G€(€€€Y€̆€€e€vм€,ψ€jD€b#€€Qi€€€€b€€m€MO3]s?j*"€wG€=€ Ó®Z€€€€€€€ߵ€47O€U€€€v€p€Uݹ€€€t~۲€架€<€6€D3֓€€3€[€€€€€€In(€€€R Q€€g€€\€Ө/€€€€O€P€̦€]}vw€p€?Xv€.€r€Yf&€ۼ€XxCX€ €€3$€€!€€€ɹ€€!)€19€€q€€6jk€€€€€€€€€€€€s€€€€{e€Da֑€,€j€€8€Ü®€&W€€€o€zβ€L€Ç{€€\€€€€d:€[€'6S;u€J€CÌ›n€€€h€d€€٦€€€Der€€€W€€_3 ֞€€"€€_.ÑŽ4Qz€€q€7€€I$6€€€€'€€€=€€€#€'€€€€›ڙ€€€€u€€€ xM3(€[€h"ÍŒm€G+€€€€€€?€ €€ €n€€Ñ']W0Ý–@€)€€€€1q€€%]€€xM€€K€€€€€;~+€€B€T€-(i€E€€€0G[6€€_€€cG€5€>e€2€€Y€b€€€OV€€€€Jn€4w3B@€€HG€tAs€€ €W€€€}€v€€H€€€ g€€€[€€{L}13€€€€€n€€€_€z€€>€G€e€€€€€€,€€#€ZNQ€€I€"t€€5颉€!€€€Z2Iw€€€€V|v;€3€H5M/€€€€;€€n€€a€€€€6€,(€€-; €€W€€€€€|J€ʜ`l€Å€€Y€%*€5QL‰w€]*E[€p€+\>h,€|€€Ք€lM0%€È¡,0dfs\4t€€3Þ¶h€€€X€KA€U€IÑ™2€€€€€i6ӵ€€€€?€€Ol€€€€T€e2€€€€€Q€€€€€k{€(€€€^gA€j+>;,€Z€€1€€r€I€7€€€H€€€i€€]€UT3€€€€€w:#€w#€ƚ&wV€€ uY€€t|t€€€3€*€\€€g؟€\€#€€#€z€=8f€€€€€3€€€;(€€€R€€0€t>TB€* €€€Y€S(€€€€}€€€v€€€P€€€c€€€S€€0€€€dxK<€€$€ €€€€k€<€€ €€٘~€€€Ɩ€fN€€€s€aYҡ€€€€€€hF€S;€T€Z:]V€€o€T€€[)€€{€€€n6Q€N8€
+A#€^Q€5€€€€€Xw€Z€{€2€€€€Y€€T€&€h€€€9]€P3€r€€ z€€€€kWXs€€€?€? makespiderrigs€5SWb€R€TEXTMPS €m5€m5€ig0€€Q€j*€€!€'€y€0€6p|€€€€ı):€ҭ$€€€>€wtpuq€€€€€f}€€ €€€ѥ€€€€y€€€€P&€`€Ԩ€€€€€Hs€ F'€ì€€C€€T€!! SpiderWEB €ourcG€
+bR€€€€Q€€Qk€€€€ c.unixY€R€s`€c€€€€€€€m€€€€/f€ € c.spidererrigs3€cQq6cQ€€€€TEXTMPS €m5 €m5 ,€ €,ͧ N9€O€€<~€ڥExd€€[€€€€€'€MK€%€0<?J€€€€OW€0€€€k€€€k€5i€O €O8€Gn€ '€€ €€M €3/€€x€F€<€J€€€€|*€€€ʇQ&^F€B€w€€€€€€x) €€@|V*N€R€€x€ġU!€€€r€[€Q€€T! €€t €€€\€$€0*€€€BJ€KR)<€€€€>z€(R€€\f€€&€€K€€€4€€U€€€ߖ2+ @€A€E€€€€ V€!€€>Tt6€lo€ €u€€}gc?€€Ui)€<ʊ€g :€€€d€(€3 Ju$3€t!%€%21f€€ D€ Gs2Í•U€Æ€(.x€q€d€Y€€Fc€i6€}C>*d€U€&€D€€{€€0€e}K€€n€€I€0€(€%€€%€€€€€€L€€I€F€€€}]€b€}C€0r*K%:€(€e{. 6?€€€€J€€Q€€€€S€;€F€/€€J€xPJ€€€;'€€O€%Ϟ€€€TQ€€#€€WFy€€gS€€€h€$€€€^€h€=€€?f€Y€& _=€A4€͟L€€p€€^€€€€€€€€€K€€€€€€€o*YÒ°}€b€h€wsE€€P€(€T7€€ɾ€xX€€€#€€€C:ږ€U#iǹ€Qq€8c`€/Ⱦ€$€€€O6€IF€€wz€c€Ê“%-NÇ•7\;€j€€hA€€€Ü€̓€A€m€€ʷ€9€€u/^8a€y08€z€€q€€[€€€.wD€€€ɚk€€€€€k€€€€5€͛+€/€v€t€€€5W!b钫€ퟒ=€"€tN]sf€`Ź*t\B€€€€€IHQ€qrwr€€€€€€<€Y€€5€€C€x€Q*€Nn€v€€€€€z€€s€€Us€=€C€
+Keak€~xc€€€<€€Nx€cq€jqaT€N_3€€#{€€*TÈ€€€L€p€€€k€€Q€!€€€^8€N c€'€0€ €€e€ʴ€Ö€€^bO<a€€0ֈ€€€€€}€(&€8€{€ɺ2ic€€€$€vK!€€€.7€€$+Ю€Ӄ€€€€*€€hf B€h,€€%€€€@&=Æ¡pZ€`$€€€`€€€€R-€h€Ɨy/€€A€€€`€g€€€H€Y €€ꩂ€€€€ €€€B€€x€CQr€xÒƒ r€E€~€)V€²€€€l ׳2nkp€!
+€K€dy€€uPcay€€€€Ƣ€€€]€€€*€c:â€lօG€€q€€l€€€€€\€€€\€D€€€b5TkxY€ўM€@€Zkֻ€€€n€€%€L€&€Ŧ€€€€€€€4€/>€7{€ €€€€€Vܕ€
+mo?#S]€G€m€€€€3W€€>$C€6E1U&I€€(€€€€j€$€€€€€€€€€vo€€ں'€ $€H€€[€*€yA€Q€n€€/€ €.€8€: {{{€N€k!€y€€.k€:€€€€,€/€/`T€E€G#t1€b€c E7W#€m ?€h(€€€)jI€€c€c€€ A€&€ğ€?€€
+€īG€€0)€ €€€€oU -lrJw€€€€j{€H€€€L€€€€€'f€€}D€€rVP€€-y€€1%Ê€€U€€UUR J[S€€€€€u€~N €€(€P€!Z\yL]i€%€9€€€:jT€?€g€yh€€€1C€J۳€€€€B4~C€q{|€€9 €€9@€€Na#€K~-jw€B€€€0€sj€€€0 L€F€€€,N€€€€@€€€€€€-€€֌M€€ɋ ZT.€n~€€.9€€ϔ€€zP€€W€€€€<cG€H7{€€9€€{€V€€1€€#€€`€€€€€QK €
+€n2€€€€€€(€U€€€
+ip€€k€r€€€Ojb8€€\€€[8@2, ^|€€ӫ€^X€J€_€ĵ€€€j€€4€H2€q€q>€,€€+€w;€xl€€€€li€€€]QR€€€€€T €a.€9€€€€~€;,E*ł€€€]$€€€4€4G€"n€t€pH8€p€€m€€€€€=€YER€QNi'0H)€€Q€€] €;k€ €yg\€€€Z~Ջ€|q€€€€€€€rG`~€€#€€i€€aI€p7L€€€€€U?DA€0€€€g €^€T€€b[€>€m€€3€I"ұ€naa€tE[mCg/Yl\n€€€€€&€€€€€}:€€€z€€:€€€€€_€€d€ p=7€€(€€宠€€€(֘€Lx€€8€(€*uDk€T€€€€!!a€€l€€€€u€3€€ш€€if]ʂ€e€€
+x"3E9€iZ€Jn€T
+€€}€$~€€€€&f€€g€ €€€€€4$-€€€€,9p7T%i €€€P€BRL€:€€:€j€MN€€€€€€€€Z€3€#€€C€K˺€В€€€€$h€€}M!u€1M€V€€CM€€<€z|5%s€€€€€/zW€€oĵ€O€€wov€€€gE2€B€€$K^€€_€%€lX€*€€3D€€€€Zcg€€€c€€ 8€€€NWu]€€ €>I€)€.€€€€€€€€ wZ€#€F€€G€ €8L€€€€€€€ܣ€€3~€€€€€f(F€̀€€8€m€h€€GQ€€€€.
+4&€:(€€]€€Ŧ€€€9fi€
+ɛ€>W€€V€o"*€uH7U€i€)7€$[W€€€€€€AÚ¸Lf€gP €fllݭ€ qX;€€€€s€ €c€َn€~Ì¿X€€€€3€€€€€ /€A€iÑŸN€€€=€D€€>€€€_t 2uÕ»h€€€€Z€H€€H€€L€€€˾€UQ€G€B/#€€U&p€o@€ڗ]€r€\€l€#x€€R€€\`P5A€_X\€#Ä€G9€€€ä`Z€\€C5T c{iPtA€GZ+€€€€€€4€s€ 0€€]f€€Yjָ€€€€9[S,€€^+€m Θt€ŗ€2€€]€€€€€€€€B 2梅€€€€խ-€€2€€€ €€
+Q8€€€x€€€;,B_€PB€߆(€€Y)€€`T€€€€B- _€P€€€€€›€D`gLs€#€€۪3€€.h€zsEp€€%€k€€w€Ȳ€AΟ€€]€o€€€€€l€%+€`€€€Ե€€€#°€€€T€,€€€q΀T.€# €E膣€s€2€€ AM<|m2€b€€ۯ€|Æz3€48€U˙€€€;€€7€0€€€ܺX€Þ¯e€€.€€bv€€€€€€€z9€ĸ€.nL€ΚO€j€bU€€)t€€O€€^Ew€Ԝ€€ ^MXJ€€
+€CY€ɴsl4€€ f€i€€Û&hx€"@Ñ–aRt]JWkz?"fs]€€€€~€€|€€GÅ€j€€€€?€€l€€€€€롫€n€€t8+€kW€€w€Y€€.bc>?/€']6ЕGs€Çy€€q€7O5€€€3€€pg32x€€€ir€€€P/j€€€€7€€J1W€od0S€ €"€€€€7€Ӈ€܅)€€€7+€ €c€€̂€C€€/€€!€€p€€[4€IoJ€€€€€€€€o€€N€F€€€€€€L-9 €Q2€X€€€ӹ€€RA€€$BGx€E5€€€€€€P€"€€€€€ߢZ= c>Et€φ<€€€€|!_€€€€4D€€+€\€€͋€€?€€€€€€$€€'€B€
+N€€€€€€€€|€€€€ makeidererrigs€Cc€r€cQ€€€€TEXTMPS €€8V€€8d€€€€€k€€€€vb@€9#,"€€€<€€! 9(#P€c€md €€€ZRO€dR€m€€Y€g€€€԰€C€rZ€v€j<€ش€;€€!3€Լ€€C€€€Y€€€€/A€y€wng&€€€sFR8€€€7€ €€€€=h?€3ug$€b/€€h
+Ѓ€f€8Û±={G€;€€€S€-Ư€€H(p€€P}yl€€ €LÑ—€€тP€€€Q>A؇AΡ€O€€{}(9€€A X€€ €€Vy€3€V€€c€v€€€1€€€€€€$€€€]:[k€€€€C€|€€€uIr€sGr€€3f€€€̓€+n€€€A>4_]€€€€ €~ €^[!! SpiderWEB €ourcG€
+q6cQ€€€Q€€Q€e€- clean.makeoutsBcQt-€TEXTMPS €€Ce€€Chx]€_i€Qi> €€TaD€€!€€€;€{€€&y€€€€e€€A@€€€€€€ɢk€6x€>w€€ €€B_€+€€€>€€lp€`€€w,€€A@€€H€ COPYRIGHTeouts€s`v€€€€€€TEXTMPS €m5€m5€9€XN€Q.€€0G€€€!€x€€€€er €_(€€€ €€€ €€w€+D>€?€€?€€~ʉƾ€Ï< `9€°/ `(€-\€€C€E0€Q€O((€|€€/€€€`0€€cV€€€€|€€c€€€r\€€€€ܞ0h€ €€;(tp€€#€€€€€!.Fh€C€;(i€~€F€€€I}€/R€€€mi€T€€€$~~€€ €€c€!/€€x €€€€ !€€)€ca€fY€7u€€€.€€rGTH5#€0 !€€€[rfH€( l€€€y€Ĝ€=€€iS€€i€€€ǔ€€€;€€€€{€€€È€€Y€€€€{ܹvQF€n€€3@6€@€"€dnG€FmiB€€€€ 3€E€?M€܉€TFd?€€€€ €€€]Ê­W;€ݚlM€€HW~€€€€€nL(rS€€$€
+€€dzT€€€K€~@€€€€€€h€&t€
+€7€Æ´D€€`€€€,#€€v€€$DY€p€€¾la€€ǺΊY0€%€€A€€€ y|€$" €€€€€:€€€P€€l€(hKrn6HQ7l€@€$n€€€€4T€€€
+€€€+€|X B€%'€>/'€ cp/€t-€G€wF€€€€€CC€€€C€?€Ш cp.spiderFiles€€v€€ v€TEXTMPS €CC€€€5€€;%€i€7}j[€vb€€€€€€#€€€€€€€?€€€LoJԗ€€€€8N-€g€b€{€€{_€֯4€€i}z€€۠€€€€€O€€€€€܎6€t€€€P€€އ€€€€w€A€d:'FH:Ou€YP€€€€€h€€€€"€€2€X€I€€3€€'df€€€43€<€<€€a€rB,€a€€3x€€€€€0)€€2%}€SЙX€€jH€€O:
+Õ—Ç®&€€1S€€€€O5ZÚŽ9€ N9€€'€`?€€o€€€€€€%a€O€D¢dK6a+? €X_B€€€€vLN75NÐV€€IG€4€€€€p¯#€#€#€€€'€€M U€€€Z€€5€˓n€€€x€ €€€€g€a€€roU|€€€€ J-€€€€€V€$.€€€€v€Id[tT.ZW€€€€€€ݸ-I€Ǝ€€€.€b}7Ñ­u€.€€y€W€€eW\€€€€€€€€€€w€€€9€€DS€R[i€€?(€€€R €€{€y€€ʥH2€€€"Q٪€R€N€Jq€€~x€€€m€EÑ“b€2+D;€e€P€^€€Y€€€€€€€€€€4$€€ €€€€N€€x3€Z€€'ަ€B€€µk [Bfm€€€4€d€e'.€By€€€€ 6V€F€ˤ€bjGf"iC € v€€€€N€€€€€€~€€!€3€@€€€€a€€€e€Z€m€X€~RM€€~ɾ€h€2€?_ØŠ"A€}€$Y€p]€ Z`€€&5€+3€7€L ,t€)t€:€€€€`€€€€*,h#€R€Ӣ€€€K|€-p3€ge€€€€S€)€<W€p€&€€B€€€€qK€a€€€ÃNf€hl€€ü€b€€F€x€O€€O1!/€ޫ€)€€T€€Z€g€Ԅ€l€M€^€€]€R-€T€€€€€€ €d€O€Q€€[;€ѽ)€GzÚ¥@€Òs9€Z)€€€=€죙C€€}py€۟`a-€€€€€€'€`J K€s\€ՔM€1€j€q€€€€€€-€F€ €€|c€€€€ܹ€€!6}€€x€€€€ϸ€€s]ڜ€ኧƲ1€zoε5€€;€ڜq}4€€|y€€€€€€\€s€!^L€€|`[3€€€d€€9_€€€:€€V€€'€€T€ۤq0n€J€€5€
+€€
+€H€€7€o8€€#€€C€S€yÔƒ€€€€իUq]€\€€€€€<€€Z \w€Q(€[€€€€€€€n€qi€€€+q€X^_=€€kv€€€h'(=€€€€€€?€€C€€€€7R€L €h€b €€€€7€4cy€€I€€/+ƆL€|€€€€$€€ Vz,c€€(o€€ݲ€€€€,€€騬€€€€l€ €2€_.€Ëst/€€e 6€Cx€€;€--€€NÕŽ€€€=Fȶb s€$€€€€€`a,Z€1F&€10€\VLFpj€+[̇bg€#u€€&* €€€€lM€€€€&E€7€3€€E/€Su€€€€ $€q €€€z,€€€˟€€€u_€€X€K€+€€h€ p€€0Aα€€4€Ph3€€2\e€€S€Ē€<W€€€3€~€*€Y€Y5€l€};€€C€€UXؖ€:K€€(Cs€€'€:€€€+@€mm€2O€4=€€*€€Gk€t €€€€;€SA@€!QitϠ€RF:€ HD€<Fg<_N€D€؊€x€n€€€'O€€€€rU€€€€€`€€€€#€k,€€€\€]€#r€€<€#€€Om€j;€#r€֧.k€€€€`€€€€]€€€€€dÊŒ"ȹ€g€€.€lvO€€@+<G+J8€€€D%s]€=G€€G€€d€€q€€€*€€€€D€R
+j€€€-€r€€;€€€`yi€€w€AH{(€€a€Sf-N_0€ty]|€W€€€€^€€€€€€€€0`€.€
+€$€€4€,€€€=€€€x0€M€u>€€E€ €€<€€2~"ׅ€€€€ €+€R4*€€€f4Í¡b€p€€ r €D€€a€€€#y"€ щ*€Y.€€B€€X7C€€€ l€T€€9nM€i €€Yy€€€8=y€[y<@€€€Î€]È­ Q,^€Z€€€€^€€VL€+€`<"€€v€{q€uI€_€€?€և\€€/€}€€Gbt€x€€€p€uB!€l€=j€€V€.€€Ù€2S€€€€€€€6F€€€Jԣ€1€€€€€-M€LE€€
+Q€€€€€fu>Q€D?€€Y6€/ f(€K€3€yò€ G\€€€P€b€ €1€€€K€
+€€]bn
+€;t€€€*S€
+€€€1m€€€?€€Z6_€Q8s€€€N€€€€[€GF€q€#€€€€2€Gۧh€z€€W€€€€>€€€I€J˶K€F€I€€€€~Ų€6€€k€€€p€D€ €€?€c€€j€€$€ǃ€€€G€€€Gl>c€*mߠ€€y쩎'2€€€_9€€G%%"~\€€a€€K€Ԋ€+€€=VH€c<p€Q€P€€'€€l€9p€H
+€€€€:€
+€ €*€4€Iiy€€€g€YaLL:€ €A€€€€€G€€h€€ €€f,€€U€=€ ]€t21€YD|€€€0€$€€€€b€€g€€€€€€ &€€bÏ€€€5$m€€&`€rxRb1q)€€i dɳ€€1€%€4€H*&€*€s€€€Ȋ)€M€€€€OB23€_@%€€F€q€€€AI€m'€€+€UW߬-€€ǔ€d j€À6€€€M cAe€J/€Y(.€ZB€€ݒ€t€€M€\€€Oye€I+d€€€6€€B€C€€€
+€€+€€ @Pm;j€W/T€€NA]€Y€dhf\a€€Ԙ€kf"3q€€O€€€A€€€€"€€C€깎j€€4<€€€€€H€(_P€€€35€k€€€4s€€€€€€€€€€€€€^Q*€<€€ht^L€{€€€€€zʶ €€z€O€€ €€8 €€u€T€U€D€CYAOp€€6€U€EZ€T51€€€zd[€€q€€€siprov8€(€€€C€K€uQ<€€+€8$<A}€€Z3Uj€€€P€K€u$€€R9€##€ؓfA€VLw€F€€A3kS'€€ €€g€%€€Αi(€S€;€€UC€{€$€€]€€€€l%€E€€wÄ™;€€€ՠ € n€€$m€€xÖ­€€$ņ=€#h€€€€€v<€€€q€
+€pU€y€-€€€;¯ѓ8€ڹi€€€ > {€€`s €€Fm c€[€S]€€€:|€€s€€€Hۘ€eW€€H€؂
+€\rA€<F€H5€-€€qو8o€E3€{b€€7€.€M?޽€€€L€€y€*€
+€€e€Yf&Õ·q€1€€0€ €€ 7:€"€€€ə€!)€r9V€i€€&€
+€L €Ş=€€€€€M€u€€FD€€€ €YG&€€#€€;€r-̿2>3"vݑ€€€€,€€€~€€~Y€€|€€L€€U{€u€€€8€€€€F€€{€E€Y€
+€De⎽€s|€O^0 €€€€€€"PY€€5€=~€€5u€€€€&€€€t7€€€y€%3€I€€€€€m€€€I€€)€€€碌Ls€>€€x€\€€€̭€1€;€p€iq€ !€€€"9€€€€€€€b:€€€€€gT€€y6€Z€€€€€rh€X@€K€€€€€@€€€€v€€aH€€€w'.&P€€€%€d€8€.€Ag3€>€€͡F€ͣj€€M%€&4<+€€>Ê‘ͬ€€o{€€6€8€€d€€€€H€Õi€ĕrWB€€€€j€r€€-€4€€V€52E€€x|€€(€'€€x€= €<€"n€€€`€€P€K€@€U€€WY€€:€:̼€G p1€tL V€A€€G
+€,€€€€*€€ 3!|3+€€€€€U€Uaf€ €€ݜ<€€ €#€€_€U€€r€x ~T`_€9€€€€^v€€€_€€€€€€€€n€{S€Y€€H4€ܵP€€€€€ЉlÇ”M€V€9€€€€€K€T€€€€Â>€€ƙL>:,€&3€.€K€€€|€a€€€r€€g€`€N€3€€1€A€3k>€xn€/'€€€€ì€) :ȥ€€€m€€€€9€€WF€E€€€C€ €Ʊ5€€€A€CYd€€€€hXgi€€w€ۋ€€€€zY€Wd€=€B€€€€H€4)3€o€€€?€€€YO€f2€€€€ë"€€V€^&€졭€n€{6€)€€€€€€€€اj€€;€<€€-€W€€t`€€q€FO€€€зC€ь,ޭ€X€€NÊ€€€!€€€€x€*WT€€-€€4^€KBHf€€ɺ€Ʈ7S€€-?3zb€u€€€€€€€*=€€W€€ݶF€3.€€ÎB
+UU€̵€}|€.€€€)€u€€€g%€€€€€dp]€=€{€€X€e€A€€€C€'€€Do€€O€ah€€m€€y€€ €av€€€€7€o€5N€yP€@ơ€€q€p^€i€€J€€€€€<€teȈ€€€€€ |E€7y€z*t€u/]TwϘ€u€€€Q€7€T1€D€€/€€€~€n€T€€€h€€€€i€€€€9€€?€€? makepiderFiles€€wF€v€TEXTMPS €CC€€N€€€€€€Fdau€€vbU€€vL€€0 bq€[FY€r;€€€(€x€ąЫdlHGy€(-€g€bG2:l>I€€€z€k€€U€€€€>[€€€€s€Ë|2€TΧ€W€€€€9f€Î€€v€€€€R9g€€€FvbWu€v\€s>Ѳ€nsv€€7€€€F€-€€ݲC€Q€[€€ €d€܉=€ʣ€€|"€rfA€\€€l €~€H
+€PBr€NI€R(€€€€Sj€€#)€{€€XFz€€€€K>€ '€lfo훟b€o]t9-6o€Q€€€s5!'@€€€Ԭ<~€т€ã±Q>A؇AΡ€f€^J€r|€€€VG€A.€a€€D@€ €€f€€؇€€|€|€€} i€0I€€6F€€€€bl€a€;€€'g€S€€#€€€ܑ€A€a6€$€€€€€€€|D€€€€€$€€€r?€g€Ʊ€ unix*€€ €€v€€€€N€ħ€9€€I€€ makele.c.bakesa€€g€TEXTMPS €CC€€CC€€ig06;Q€j*€€!€'€y€0€6p|€€€€ı):€ҭ$€€€>€wtpuq€€€€€f}€€ €€€ѥ€€€€y€€€€P&€`€Ԩ€€€€€Hs€ F'€ì€€C€€T€!! SpiderWEB €ourcG€
+€€€€€€Q€€Q€€€,€!! SpiderWEB €ourcG€
+€v€€€€Q€€Q€€€€
+ dijkstra.unixޫv€€$€€€€€€€€€q€€q6€mk
+binary.webnixsb€€G€€€GTEXTMPS €m5€m5!€ Y/€o Ny€ N6€€€Y€€€}dF€6€G€€€€d{d€#€)a{€€(€€€€€€ €:€2€€€€@W€u}×¹=€€€&€€€>€€B€€M€€€€€€€[dZT€€€EmV€€€€€O€€.€€/€*s];ctQy€€€Vwq€]€€€V€€j;€€€€^͋€TZ€€€€€F€ɳ€É^€,/€€h[€zit€€€€p*€r€b€€t€]€€j€€q€m€ s€€ G€€z€€Y€€€\€€€^4€/€€)u€€ g€b€€€€c€yã´½|if€€k,€_,*€€+€€y€€Ko€l€€€X€Y€€^APlRW€k€€¸€€6€kk€Z€v€€]€ €€^€€[€5€,€€€8€€k€€€€]€€ε3€€y<=€W€€W€v€S€ˬZ4€g€|€€l€UV€€qr€}ihGsS`€j&c€€y€€€€Y€€€€l€9Y€Փb€ۺ€k€S`€A€z€m=€?€€€€€`Xf €€€€€G€€€€r€€€€€7+€€*GG€(€€€v8€€)€€€n€m€€€€x;.[=€€mÙŽ~€€w€Q€ O\|€ڷv€€€€uC?€CM€}<=€i€Nyߪ€€>(dO€1€4+€€.K{€|€€€€7€€YfW3Vfui€_km׌€€€€€\m<€sj;€€z%) €€ZMM€€:€3H€€€€€€.r€3€#
+,€€놉K€*ˬ€€€€#€€€z2€€€v/;€N&€I€€Ӯc€€OZ€€1΀€MT_€zs4ɇ2€€€€€1€i€€€€3/c€€€r€€€/€s€=k€€SLFg|S
+k€€€V€K€A€,€ v€9€€ƨLW€:n€Ի^X€-)D€€€=€€p廉vxÅŸsd%D€ڛ€€L€€€d€€€z€9€y6€K€!€a€€צ€€b€YTB€|€l€n€€*+€€mKf€€6%4ʙ€k€k€‚r€7€mg€€€>€€P€D€X_g€_€€€€K€€h€n$€f̈€/~€€€€Dgwx€€€€€€ӽ€k}€-€€g€՛€ 2€€_€€o5€€]€Үq€X€_..z|€#`N€€€ӧ€ €`/€#€IR€)€€€"!€ 0€€€] #€y€€b€€b€€€c"€€9R€{€w€b€€€€у €€"Z`€HB€N!€€8€.3,R0€kT€€n€€RÜŽnF€€h€€-€5€€€€J€€D€€f€l€€0€€vF€ €39{m€€€GÔ‹N€H€€€ Hz€€€r:€
+€Y]g€€€c€€€€€9C€r:€€€{€€BV!€qD4€€^Zx€Yh€€€€€€ugϚ2s€ԢF€€ɩA€Q€€€ !€N€g€Z"@€o€F.Sڟk€€S:$€€7€A4€€W€€€i€F€€€`K€%€€ Ew h
+}@€€_D€{PN `Ffk€€€QX8€#„}€€m€€z€€ €~]€€€€€H€€€+€€(€_€€k€]€€€€ ^0€Fb€€m#Y€€0ß©€€€p€c€ġ€@€;€=€b F|%RVTﺔ_€€€€€l€€1€€nD€€€€^€4m€` €€€€€€€€"€4€€€4€b€`€€|w€€€€"€7€s8 €;$T䔔€D€€lt^. €€€YpK€€€€*%€€O €k!2€K€€__€€ \dZ #V&A€`€a€@9Æ·(€€€ €€€€@€x€€,z€€Z€"€€€€" €_o€&Ev Q-`€€l€€,R€=€€€dG1lY R€%iecn€€€€€cx€€€€€4X€p[€*€Y€)QD€J€\€>6
+5gV€€€ÌE€€NѸ-b ER€€+E0€FaGf=€E€@u"2h_$€zVf*ʸ€T€z!=(€€€€€TC~ӆ؄w4')€j€D€€€I!}ia\€y€@€€{€Ħ
+F€|€€€D€€Cu€+€€l€€€s렞€€a€O€€@a?€€€)0€€M"€€߱zBl @2€N€T{X€€7P,€€€| 8€€€H€yf€S.€€€ 6衟€€ԓ?€€€€q"€C€€y€l€€"€D?€€I`2/g€€€k€€kb€4'€€€(Q€€€V]}k€€X€~Ww(€ n€z\€€€K€@C7€€ Th€B€€M€€€€vW$€Ë€w9€€w€€€€a;€X€€€€Ƥ€€璫€ €€n€€€$€׶€C€(€€ €zХ€Yt€*€M €€€>Į€8€€_+€€2&€€€€€z€VKQ"€
+A€}€€€-7€S 3€Wś€T€6€€€9߭€€;E€8C +7Ʈ€€7€@6!€`€€€b€C€)YK߈€ koO' €€R€€€€€b€€+€€Լ€€€€Cl€€7€R-€€ᨀ(8c€3wق€E!€€BX€c€€€ߦ€M€ e%M|€lKi€>9A€€€j€€€將€€#z€€P8€€=€D€€€€Mg€€iv€K€€pP1v€€R€aX-€€€0€€H€&€a€ْbp3U€€B€Ԅ5 ;€x€€P)€€W€b€€€5€+€€@€€€F*\S€€€@y€f€Dz€GS[F€€€€€€Ô€€O€€€O€Q€8#€€R g8€€€C{!TN€R€e<L€*€0€ €€>€9€'
+0€€€€:,B!€E<€€ Ky[€+€€€u€9Ù«T€i/]€H!€€SOπO€€|€€€€€SO€€€p€>B€€vttÞ€V€€€€r;€€o€,ӟ€€^€€€€€€gT€,€V}€qÑ€OO€
+%4€ €€ɔ5R,€c€€0€€c*v€€F
+*È£ €€_€"Ï€sO€€€€€/QB€€€u€€€%_€€€€€€€€-€>€AS€€S{€:€€O€M€€€Ad%a€~€g%€ux€V€^1%l)MfQɺx€€€€€€F€€€"€€B€ô ==€€O€€8yYT €€꠿€o'€€€€€€iHÈ·x€€.€€AN€€$lH! L€€€€€@O€x€€#w€€,€€p€€Ev€;€P€-Y;1L€?Ô«A€€J'BR€4_J€€W€€€j€€ €€€#v|EvÛ¸z€€M#€Hʚ€Mi1€
+€€€Z€_€qY1A€€€ǃ€€4€€7€N€ݿǫ€€€0€€€€H!_€F€;€€b}_€€€ZW€€K€€€€€I€o*j€€3Zr€s€磇€bw€€N€3x€€€€ܬ-€xD>€ €€€€]0IB€(€€€/€€E€€€!K,n€€€r}ҷ€I9€)1€ӕCd€€€U֬€€8€€G€€€D³€€l+€P€!€?€€z€€€g€d}€Nz€€s€f-€9 e€~*H€€13€€}€"d2€€€€x€€4€€{€€€€€08j€€€{€-$€€F€€P `H€€€€€C0
+)?0@€r€q€A€€€gϫ€€0
+€ d.spiderebnixsvT€€€€€GTEXTMPS €m5€m5€€n€€€ €O€@OF€€€T~€€W€>?€€Β%€"€K€axF(XO`|€)@^ €:z€dM€~€7hB€€@N€€}€F8€p€€€[€A€€t€€d€€G€€LF3€R€€
+r@ €€*€i€@@U€)y€€3€€:€€$# €€€€RU@€\€R€&R€r€P€H€ €$4cR€ @bÆ _€€€€€€?€F=ɦ@R€@d$b
+ƙT€€S1€€€S€€€€ €j6€€ €$1€L€@o€€9 ""€€3AALs€ ͭ}€€Lb*@k2€8€L€ ,B+,f€€c€€}€Y€K€€€ €Q€08€á+€V€€ΰNg! €€TC€C €\دw€ €Q€€0€€ʆ€€€€Կ€\€͈ €zi€V€]I€wkYo-€e€€€۵l€€-{€€€;€E€v€v€u€€0Kg€€@q!€€€'c8oQI;=€€€€€-€€€€J%S^€€Z€€R€9€€€€]€€€;€€qy/€o€€p€€€):. .V€E€j€€a9€^€€XM€€Ɵo€E€€U€€A X€Cx€"€hB:[=€€€€€€€c'€€€7ؾ€»+쯷! .€€€€€€€\€€€€€M€{€€€l€Ͱ€c5€€[€€€X€€Ndw<€fj€\€€r€€)=B€€€ދ€6€€€M€€'€x€€C€U€€* €€~€€€€€€€€€€%€€€€I€7€€€\€;€D€=€€TIK€a€€Zթ€۫€hz€€€kh8Oi8Qx€€€DŽ9Ż€b0€€€€€O€€$€
+w€"y€€v/A€W€€€<Ü—bb€9lgN€9:%€8[€q€{€ €€€€H€k€)€Ǡ€1|6M€€w€€bQ(€K€€UrȰ€a€€€€€€€€€s'€#Yh€€€<dq€w>€PC€Ô‚a€<pQk?€X+€7
+€S€^€rv€<f€V€V€ 0OB€€ NLjx€€€€yx€€€€'€Jͳ€͙€z€€€€€€.€]€b€€€€€*=ԑ€cj€€0€9€2-€6;€m"€q€€t€JG#I€X€3Sg€sm€ڵ|€2€hc€€Y€€T€€t €n*Åh€€€W€K_€€ €4€€Ue€rÆÚ­'€€&p:€q2 I€€}€lH5€R€€X€€X/6€€U€RCvo€`€€D@€€p€̚€€€uC€K@7ݲdg€%€€€ Gjl8€O€=€ٗ4€€€·{8€€€H€€€€'€sh€€€8€€€€€̶ǣ€€e€€€|€|x€A€€-€€€€€€€€€€V€5P€W€W0+v€€€{€U€:€€€€€€€[a€ ~\>Ka€€5€l€{{hOtCd€k€€€h€W€y€q€;€€m€? makeiderebnixs@€€€€€GTEXTMPS €m5€m5m]€€€1Q€tH€€€€<$'€€>€€€K€€€€€€€€€€€al€€€r8€€€݅€€€€€€Z[€ͼ€€$L€uI`€sG| €a6€ͼ€a€€€!P[*€ READMEerebnixse_€€€€€GTEXTMPS €m5€m5€€#€€5Q.€¬€€C €€€ €€€€'€€]/ €€P&€€€€€!€€€€€€€!oۇz €;€F|(dB€M€€€€€/€@3n €€€€€`€+€€cAÔ€Kӛ€Dc€|a_€€€€B"€€n"և€€p€€¾0€4€€L_8€A€€€€%€ß}€d€~ sp.weberebnixs€€€€€€GTEXTMPS €m5€m5€€"~ 4Q-€€@#w€03a_Ö€d€==€€\8€ 0€Q7y€€`€€@€`&D~€d8€<€<€B.€^€0€€€/€€,€€P€€€!aKNزi€€€€n\€€€€ €€€€€ €]d@€€€@€€€€€€[6z€Ezm3€€D؉Ԅ€€€€0€y€N€;€€€'€ €€€0)€ع€€m€€g2€€€K9€€[b(€F~wkI/X€1€19€-Bj€_€€€o€€€€;€€€ €@€Hm€€/q€ €€W€
+€
+}€ €€€ €€k€rJ/ɛ$€lj€{€r€4 D|€€€€EO€
+€V-€€/€€! €€€A_N€Bc6€ɪ€€d€€P2 >~€v€€M€€wl€€䒰€€0€[€<€͵ AÇ©^&S9ϟ€)€|€€ €c€€<€ €W(l)5€€€~€B!€€€%!! SpiderWEB €ourcG€
+€€€G€€€Q€€QĜ€€€ doc€C €G€€€€€€€€€€€q€€{'z#€€€ abstracts.texs€€€$€€€$€€€€TEXTMPS €m5€m5€€€€Q€=€€€€?€€€€€>:€}€^€€€u*€d€C€;|€ؠ€
+F€€ €f| €€€L€€€€ç¾€€€€€c :[ €€0€e€ €€;€€ €€Lt€29w€/Yh€€€ {€?€€€€€!€€`€rY b? € €€€€u€€{€€2€>€}R€je€A_8W="€!€ €€^€sÖ©VVZ€€4a€X€€@€€.€€E],€€€€c€&F€s€€4€€€"3€€&€z€€€€€€€p€ϒ€|€€€€€rųq€€N€€€4€
+€P€€r€|8€ €€€)€/F€t€TZa€g; €€O€€€€€€_€€€€f€€Bw€ Ú…8Ì€O€€€~€`Y€,H*I€r€e€b€6$-€'€€€€€H€€g€%w€€€{H€€€4€,hB73€ܯ[€3€€㈹P\€€€8€|€€€wu€€€ YN€€€][€`€r€&€A€€€€€€<9_3€Tf€€8€€n-€€%HF(€#€€€€y0€2€€ cacm.auxs.texs.€€€€€€$€€€€TEXTMPS €m5€m5€}s€€-QÝ‘/€€€€=~€€~€€Ya_€€€€€€€€€2- €H€€€€€€W€È}€€o@f €=€€}€C€€€€?€€f€€€€€€o1#€€€}h)€B€~f"_N€€€€€€€;€ €€8toi€ABd€qÌ€J€€€€€A€€€ €€}€€P€C€O€"€€€€€+€€€€AoNs€p€€ €€€€€[ € €@€€€ܙ>€YB€\_Vf/€€e€€Ⱦl€€€€ev€€A0€">&€ldcY#rgfOl€"€/"€€v€E>€€Y"€€~Oz€t€p€l@>6;h@€€€€€w-€=
+q€€€)vc€€E0€|€9kx€€€€7€€g€€€r€Am/A€hí±O€`×–`€~9;s"7лK€v$€ B€5h@G€J€€€€€€€ cacm.texs.texs€b€€€€€$€€€€TEXTMPS €m5€m5_€#€oT€€€O€€€maw}N-?€€'崫€<€€€Rr|e€€KO9€€€€€u€|€€€@€€}€s€~€Y€€d!€€€B& €€l2€da€)€€€駽€0L€€€€€€€€€x1 €"€€€€€Q€€O€QÜ€S?€€€€88 €€I?€€#)€i€(€o2€€ 9˧€Q€gaYo€ €€€€a€€€4€€,€€Qâ°Â€ß€€ €€>€€€€€C?€€G€€0NG<€€?¬á±j€€ҤȂ^€'€a€zw}{}€€€€n6€€€€{€€l€€€€b€f€/€l$€W€0'€Σ€[€^€€€Gc,€€€0é…ΗY€€€4€€N€€a€G€(€YƜ€`€e€'€€q€|€{€€gvl€€w€^5€/€s€3€ '€€€€€€€€€€<€Or€€ʀ€€€€€E€€<€€€€€t€€€€€€,Lf€N/€/€^?<€€€_€~7}€€€ߘv^€€Ŵ3€€q€€o/å·³0K€€7ny>€€g€€:€€€lf_€t<€€€E€߬>€€€ӻ€€#€€e€0€€p?€y%€€Ar €r€9I€"I€€Չ
+€7€qr~N€€€e€r€€C`6J€Q€€€€o &€€ ̸0_€C€݇$;€ €€€€€ 6€4pT€€[€ii€€€€Ǥ_€G,€€€ W€€G47€€€|65P|€€~€€€€V:14D€€V:€€€e€N7€€V€`€08 E€x€a"J€$€c€€E€€€=€€€ p-€€;%T(€ Gq€ €"͂€€€€Q€€"M€€?I3€ke X8:€€€~?€FYz€€€/:=L€€€p€€WI€i€€€€€€€€€e€€€lS€€€:€€ €t€€€/€afA€f €|€€9M€€C€v€/Q€€qn€YLF8M €€€€qo€€€€{€2?€˸D<€cf€€€yT €M€€€)~
+Ty€€€>w€2,€{€€w€F€€€'€M€H€kZ€€r'€€€x€€64Wi
+nZ€H€o€€€€€€ †܇\@=)€€€€€€€A€€(€Ga/:€pX^d€^1€p2 *€€€€€€€€$€xv€€[1V^l€ €b/xDqÐq€€€€€8h€€€M€€€UÛœd€€€{€3€€G€€v €€€€$€€€S€€€€€^€ €€3€GQ€2J€'€€ vMUnA/J. ؀€;€€€€a€(€n!€vx>€€
+€m€€€y€€A€w€8 € 6€€}€S'f€ی€W#0€Hn€6€~€{F4€€@€7LI€€0l€€€€@€€€[ބ€€XR€[€@6€€y€€€€3€ci€€(@}€Ņ9€!€#q€€d3\?€€O€€€€€€G€ÂA^€€€d{€I€€ €R €€€€G€@€sr€^Þ°8€ €.€€€ɉs€€%€€€ €@€€€€C4*€}€€A/€€€€A} 2€Q
+€p€€ €€$€ X€€€€pOd€ї€€€€2€€ w€€U'A^-€l€€€=$y€€€€€€€€yhV&€€€](€€p€i€€€€ǵ€h€11€@A€€€€€€VO)n€€*€|-(€7`q |€vm€ܘ€H€O€O€g€€(€€D€.€s €€€d€ €ao€€?>€€F€€€€mA€pHT8ҌJ€€B€3 €€Y4€€€€U€U€€€:
+€€A$€€c€€q€€O€€B€€GK€S`€@|€€}P€$€)w€zZx€€€€JO€ 7] _€€€{V"€⯕,€\Y+ € !5€D€€>e8€€G7o8€b€,j€0
+2`€h€o'€€b€=T€ €€y€€γ€€€h€J>€*r0€@€9€"€ €€#€~€€h€4:€Ƽ€€t2%€<&$va€QFe€€€f€€€€ €+€=!€€€MU€v€€€@€G`€<
+€ϛ€rq^0€ €€€€€X`d)7€€ `€€Um€%€N]€€H€7d€€a6€€f8I 2€€€-[€€€€€p2!<€sNNpsz€€€闊9€€€!1
+€@€€q€<on€y€<€!€€€iz€€6€n€J€+€"€ f€€{뀀€€Fss} ~v€u€Ǯn€7€€€5z€g!l)LX_€6~1€€5€€€€€e€"€&€ag€€2€.€]_€€)€€€€+€ٿ€0€€€e€[  €%€VÛ€€€€֖{€€€€*7€€€€n€€€Í»o€(€W1€C6€€[|~€]€€PB€ö€€t€ed€€€e€€€}_€€}a€#€€€€€€€€N€€€€€€€跗8#
+€LgC;€&€,€(Y% nÇ…Z~€€€;€€]K€€C8€u €F~€\]a€€x\€ N€€{€×€uT€€€€W€€$Vr[AC€€C€<€D8€N€€gNYWb€V€€€€!€€TQ7v5+€€4€€€€E۵€€{P"9_&\Ty€Q3_'€€G߃€€€€€:€ף€€rrҫ€D1Wj€6€0':€z€€€€Y€z&€5€€?€N€€€€€n€6?p €ĭQ€M{€€_Uz€€ €R\€€~€O€W€€€€€&X€ €€€€V€:€€€-!€€€€€€€ql€OZ"1&€€^€€L€lÖº}[€€T6tp€fe0,€€€s€€€!€hU€€$s\€^Ѕ€€€€€Ї€€yFE`er€€€G<]€w€?€N€X€€.€€€p€€_€n€€€06%€€€$f€€€+<€€€€€r€€ç2P€`E^€p€ €KS€€3€€€I€€?/'^€5€:€€€€ €R€€€€€G€#'€€ €€€€€#€4€JH€'€€€€n:.€€€€€€€€€€€a€8MND(€Dk<€8 1IZd€_€Ñ‘\€€:N8€1vpb%!€*DÆ£Q€€€ \>€{C€€r€€Xt<)€7€g€-€€€€a€Њ=tr{s}€BG[€€?ڿ€;€8€)A€C~€€€€4€~€k€€€nX€3€€€€€€€+€€A€€€㵤€}A?+ÉŠ€FÙ!€Z`e€€€€m€€€€s€€*O€|€€,2€E€€€6`€€[kb
+mmU&Y{€€H€N€UD?YX€€9Bc€yiN€€l€o€€€NcELPE€€€€€€€€צ€r€€€M€€ €PC€ꊅP€]S€€€s€/€€cr9€6€h€€€€0€u:F €f€|€€€€€j€€€Ԡ[€D€[?w(€€€ €v*qD€€24€71sç©$€'!̹{Z.?€€€4€€]_€€€€€€P€v8m?"€ €€€€)€€€€b€€€€€€; €lT€€5€€€€/W€€€€€'e:€
+€r€€€f€€€nn€€+€€u€€€-€€͵)€€Ö•^oG€€\b€w_€A€€?€n<SB6€€€.€€€}€€€€€(x€?-#N€֛X€€Xи€€~€€€€€€€€€€]€€€r€8€?€€2-€_Ia€g[€€¦€?€€€€q€?€€€€v^€o€€€€1tUEe€K3q!€@€g€ߥ€gb€€~€9€&R€E€€~€a7<€CJ€N€!d<+€.Ư 35€M€1€L.€€q
+€b€€"€ €o€ €)€(€R8€€#€ x€€\€€€n€€€ f}1€€€ꘅ€ ƚ€€Ö€DL.€e8€{€y€ 9}7 jB€ CA38(€̇AA€M €2€€€€€€X€D {; *€AY€€W€€]€€€X€€x€€ִ^1^€€€€€€w€€€D~ji€€€8€ /5€l€€F>€€€€€€€€€€€€€€2€V€eÈ°Ä€€:€A€€€h€v5
+fr€Óq€r|\€€€<<`Qd€ \€€€€€€sC"H|€€'€€E€€?:8<€€I€€Ү€Ԙ!9Ag€€€€|€€€€Κ€€€E€PVDž€,i€OHjG€€=€S€€a€×z€€s€m€P`d€€Nb€€rG8€
+€#`€€€@€€ .€!c!€}€ţǟ~€€Q€OO=€€™^€V:€€€.€€V€HR€€!€€€p€-€ E€€€€CM€ %€7No<Z̀€A€€€;€€€€€a€€€€D€€Ίt€b'c@€c8€>€€ €€€"U€~_%M€p€G€XR€0a2h€€l€GB€€yIө€€€9#z€€$€5L€[€z€€€€€%h€€€€l{?4|R€€€R€€€€€€
+€€€$€€!€ao€€€€ €€0€€2€oV€€u€€nlm€€;w€\1N€j/€€€€€-€U€€€r€j苽€€€€€€€€€€€;z€jS\€€(T€€0€Q€&f( €Д7€€€_€x€€5€€€€C€€€€€:€€€'€€.[I€i€,€x(€€b€_k*ؖ€€Ćuޕ€-3€Km€€į4€€€:€€)H
+€Z€pu€€€€4€€€i€m€€>€ f€P€ {"€€€€€q(€J€€|€f€€Y€P€€r`€€Pvn€€€,OE0\RX ch@€€€€3U€€€uf9€€Q0c€D€€W€€IvT€€&€#n1}€ Ô›0€€€y€JtD€€I€€€€€€X€€ul€) AK€#|€ €€ P2€ql€_-€€U]O€Y€€€G8€6€XS U€#€€bL€€€€€4 ت€1€€M€H€( "€€€€ €˵€R€u€€c€€}hW€€A?#€"J€8|%€S€€$€H€€B€€?D€€("bO€€N^€.6G€€€j1ۇ€o€€€[€n=€€€+i"3Y|€J€6!€€F€€€E€*€€€€<€€€€wxwdiî“»H€€A€S€€€vQ€€"%€€ €)€€€€€v€€a€€€U€€
+€€€€€€a!€€€4€€R€\y€L€€€€dr€)~1€€P€€r€€€$H€[€[€€
+u€€€X€P"UÛ…X 'A(h€k CJåšštW€Çn€S€x€€/, €-€C€€€€€O#L%€S€€€(29M€€€ €€ €€€€]€$T€F<A€€O!Op€49€-€€€€zʈD€y]€&€d1€#Ԏ€€€<D € y\'€h
+:aN€€Ñ€€cc%=€ J€C€Sz€1€N€€€Z€€2u!€™qx€Qf€€ A€Utr€€TE/€€j€W€J€€ €€€}€€ U€"Z€?c€# €i€€€;Q€€lW€€R€€p(/A€LhN€€ᭆ€€օ6@€Yy€,(€€€€\€p%%€€€ʫh€2k€r€€€>€ €+,^€€˾€€€]€€€€€T€€*3€5D%` /=€€Q€€Jk€Ҹ€B€C€X€€+€Ĝ>K€€D€€hY€X€€FGdn{€€Ð…€€Cpۀ2!3\,x €d€€€_)YAe€>`€€€€€Z€`M€€€D€G€Q€€€:E€€€V€T€€€€€-=€€[€€Ï4+n€€€]€€€€`€€€X€*s.€R€€+€€€€/жt€{8€a€€YsOy~玴€€€€=S€ €v€€€o€j€€€€Ƽ€)€€ €€€_€€I€Z€€€cV€#H€€€€s€o€Z€€€yoo€3O€€ €u€6€€*€o€€s)€€An€€3€|F€€€ɷ€2€b€ €‰:$€vO€:G€€ a€€€€P€€0€3€)$b€€€€qkC€€€t>€֘€DR€€€ħW.€€€€€(#€€_€€€;=|€€€€H€€€>|€€9€<€0€(~k€€G|€#JV^€S€H2_4€€bO€V+9Z+m€2€€€€v€ €€€ܶ3€€€€ ] €€€R€€~€€ €€*€€.€€€€€I€U€F€€€€€GXJ€€(=T€€n€€F)-A$€Htj*€€
+€€€?X\o€€2(ەTZ>@o€€s€€€€'N€h€bْ€l€€€f巌 %ކ€}\€€€€4{i{€\D€€€9Āto€€€€€L€~€ޞ€/€ N€+€€Ԩ€y€€€B€Q€€$€€€ .€ €€€M€€o€€kY€P€v€c:€V3:€
+€R.€.(v€€edj€€\€g€€€j€€€€€€D€€ €€€€€ €zKoi€€€hl#Y€H€€€€€€€€€N€€€€<€€,MX€u[€T€€h9I;Û›$€€€e{€€€8"€0Dæ”–Z€3.D€€€h€€D€€ż€$vl€z]€u\€€€*]€€€€€€€)R€`(1I%€Ҍ€N€€#P€€€L€€€b€#v8€Hs€4=X6€€€X|×…a€€A.€/€Ԩ€€Zqf€X=kKQ€€€myoV7rFM)q€J| ʅ€nHU€€&€aP€_ €J€€V!9€bcKT€€€€38I
+€€€bxƄ_€€5m€€E&`V 7€p
+€€"-€Ë} €XnuAR"!.€fj€€+f€€F1€€a€€€ğ€c€€95€SN6€T€€x$Tr€d9€€€€€€0Ȓ€€€€€91€r€)Yx€€`€@€€iQ!€€Y|€B€ +€€}/€€€D Zՙ€h€]€d€b€€C c€3 J$€%U(]€?c€Z€4€ ={€Ya€90€f €€€e€€€U/8€X\*=d0€i€€€<G~Y€€€i€"€fOe/€2'€/€€W€Y€r€vĀT;€€€v€-€9>F">€€€€;€ €€€€€ ٷZ€^!€€€U€€"€`€€€0€€W€€€r€€€3€€€€€€€}X€€€€€T€b,€^€€aU€€T€€-}|€€!l€€f€5€€€€֚M€€€€^€=(€€€€KN€"€€€€€€58€€0€€€€R(€zH€[€19 T€0€C\€€ކ€~=@€ҵ€€5€}.€(€€K>SS€€A*K €€€@€€0€€€€"P€€€t€H€E€€~/€8.G:€ރU1T€ߚ€€€€€€€X
+€€Y€K|€€€€ly€€€€(T:E€€€€#W6tY%€€W?€€a€€€€€€€t)R€€€>€t,€e",w/€€nkNM€T$€t€6(€€kO{!€€€€€€c€
+€ao@€`+€€!h€€t.€€€€€l(b€I4y€€€s€<N€€ (€u€€€;€=€€€€€U€€W#+€d?€€€"=DʔM€€;€%ϩo€϶F€}*€€4€[€]€-+:€€€*€E; €M€N€,€€LtAz
+,€h/€€ʅ€+d!/Z€'74f€€€ W€€G€€/ջ€Ⱦ€€3€T€K9J€€€€^€€k€[€o€€€€.2€€R%ӌ€I€€€e6%€$€F€€n€€€€€€K pM€€S€€6 +€Q1
+X02€€4€€-€€€,I€Q€€€€F€g~[8äš…U€€€4€€u €€e€€€4q{€€€€Æ€6€9D!h€€k|€B€S€=€k1€€€€€€€m€€v€€€̤€€€x €{€55€€€15€h⢺ Q€€5<IR€€€€,€€.Ì‹!É„Aj&€€€K V€€K€]€€€(T€€,€7€€€€?P€€€C9€€c€€q&€jHD€€2€€€€I€€e€G€cK츨€Df€Fr€x€O€P€€_5€€I€€_ݨ€᠅G€N€Ҕ€€͉)|3~߂€€€P=€6€€?€H€ii€ly€j€€€PeÕ¬*U€ռ€€€€€€Yx€h->M z€€ 2€P€€€€&€nx€€X€€yl€€^xn!=€0€€O 0ql€<€€€+ӊ€€ €€ .€C€€€€€€€<k€€lo€€€s€+€€\€r€€~ €t€€j€€€€€Z€€3€q€aQq€)j€€Q.€g] €€€&€€€€p€€6€€V€(wxu€€€€€€@€(È¢֪€ €]11"€a$€ྨprb€€€Ój:D29€€€€€€ PQ€€%_€€€€€€ti8دR€€€€€`E€J€@\~€8Ö_Io€€u1€€€'€€€€ϰ€€€€͜n€€€€3€#€+€[€€€x€€-€\€€~c\€€€€t$T€<92e.*€€€€€[bV]k\€€zV€^B€€>€€f€߲R€€3€[d€€Ge€€;t€Ҧ€€ Ro€€Cï–L>H€€€J€,€&?€N €€R€€V€G[}€L€.H€\<#€€ʽ/€€q€€€€€q€€Z$€rN€€€XbC€^€a€
+~m€3€€ €€W€=`{€€d€€Ж|€€(€€€-€U€€€€€€€€/qc€€: €€€€! €€꫰€ײ€L€\_N€ު€€&t8€€€[€۶7€€V€zuN€€j€€k€€%€A€€€.€€zn€;€€ €€€€í·¾Â€Â€€ӣ7€~&€{€c,I€€€€ܧ€L€a2€ÍaV;€€€VV€€7u⦂{ €X€€€'€`€€bI8b Kq€€€€€€Oaծ€€q!€u€.b€€y€w€m€€N€€d€[(=€€t€T€€ €GM€€%x€6C€1Í–)S€€€€E€€ "€#€f€€€€xg €€(€€LB€€|€L3€€€€ly€7€I€/L6€d€jW4€&€z -?€l Q€€€l>q1€o€lq€€5FC€€-€)E€[€€ €MBHI7€
+)€.&Mj€Ch€€€€€j€€Kp,€E0€€|€%>€
+€b(€€8€d[w`S?VxknB€€ €h€€Z€€nJ€e€&€l€€T€€;>v€€€؅K €k€K)'d1€€8€€5€€€l€ €
+D€Ϳv€€€I €P€€€€€{Q€g,u€م€#€€@€€€n€€€€€U€€€€!q€€ÐU€P€Gx€€6€)v>€(€; €v€9,-€€}€M,USb€5
+! €€7G €€€€ ey€€J€0€€€EfMZY"€9E€€2^€€5 €€€€€€?€Y$€})€€€€€F€€€€T܎€5ֆ€cX};.€€h€€Zw@€€9Op€€€5€6€€P€€
+6€€€€i`€o9B€€€€€€€8€f€$€€€€€S|€€<Q€€
+€€€W_€P#w8€/ϯͱ}€€o?Y€€l+€]HY€+€;\€€€bж2w€€y5€€#€€€€€ €€F<€vٰ€€€€.?€€|€€€€z-€€M*€€€y€
+€qJ€K6€Q€2€€€€_€€€@x€)t€€€€€€nKsg€€(€€6€.ZC€€h:tZ€+~€€€€€€W$€1(€)€€€S€€€y`€€q€ŤMl€€_€€€K€€€j€yی€€!€€€€p€"K$krf>€€U€P2'€d€€€T€€€€€€l€@V€oЂ€€€€8€€€ k€€€€€:€u€€N€g€€€€€€€q[€4 $Ù°`!€!l€€jR€1P-€€TlcR€G€€€Y€=€€C€eノ€T>€#€{8€&mjU ]€5^-€~€*F€p€˞Uܠ€WDÌŒ€€€e€\€grq€€}:€p€&€€€€€€€€S€€€f€g€€I€7€€€€€/y€b€€€€€€€eˇ€f€?€|€wO€€€€[HuL€€]€H|€€€l6€n€€p€€Æ€€na€l€k7Q€~=€^zÀ€3€€k€€Y€€€3€€€€T<€K$€€%€)€€׻}€€€€9˽€ |€€€€M€€€f€ݮ€Az€ع€€€€€€9€x€;€#j-~€>Y€€}€4!eD4€k|€€O€€(9€€n[€€€€€€4€v -€€Y€c€€€:€L€€€s€€€€/€€€s$x€€M€)
+€€)tXy}€€mno)€ €[€€]€€€€€€!€R}€€6€_G€@+€~€€€O$€€B€€€€€x€J€|'Ч€ €€€B€]#€€@}AX€ €?JO€s&Gu€€€#€€m6Öˆ{€€?€€€€ |{/€w€4E€€`€€ >~€€€€€€!?3€€€€€€€€€€b€@€y€€€fs€€€€1€€€1€€^€€ѳ€Ð€䯷€M[€%€€€€S€€ DESCRIPTIONexso€€€`€$€€€€TEXTMPS €m5€m5M-H€€X N)y€ r€<€€ѓw€l2€d€€M€[€€€c€€€(€G6y€z€€ğ€:€€€-A?Z€€€+N€<r€€€ddm€^€€€Ϯ€€6€€n€€€`u€ݤ^€I€~€l€€&€€€~€€h€€Z€€€D€€€%O€€c>\&€€;o:€Ƥ€~€q€€ou
+€€C€9€€-ߨ€Ў€€y€ҳ€€m€j€€=€T€€€fp€€€€tp€Þ™6i€Z€€€J€-F1€€€{€€€3~?€€€€€€€I€8M)€€€€€€€€€3€H€€re€€€'݄€€f?R€€€H(>Q€vt]€$7€]€zÝšk}{€€_€P€/.€€J€֦€>€toi€A€€€p/ë£Â€z]€€€q€€vV€€ԇ1€]€€i:'d€€ €€€k€€€€'Gů$€€€$€U€~€L/O€€AR€€Æ€€€€€€€7€€o€z0€€ €qG$j€€g€€x꫋€^X€8€€€(€G4€€€€€€ €Q5ap6]^€€_,.!€€€y€€5j㺣 €€'€€-6€&€€€8I%4€€€&€€€UK_€;J€€kFZ€€€a€€€€q€(€€€ھ?€1eØ¢;€€X€n€0fgM# <€€€ _qH€€n€}?X$€Å•Qi-€€ >h2*g褿b%€U€O€€€€ J€€;€€x€€€€€€€>€€€€ €€€Q€g?v€Q€€u€z€€A€€D€€0€€S€^€€Uu€T
+€.>KZ€€׾€Ɩ1€€U€€5€9€j €€ M>h€C)g<€O€€€€f€€&€4€C€Je€€%&h€sH}@€/€$€€TU:€< €€dd€€Ww€€E€€€€€€€V€€€O€€-€€f€€V€€M€<€J€A7 €)€)€"€€€|€n€€F]€V€€`t€X|€€€€€€€€۟Pa(€B€̊h%\€?€€b%YW€€ROl|€6€€AD)€€;€8 €V!do֛€€]€tJ€€C@€Nh/€€0Y€€xf€€€€€€Gn€5€€X€€€k€v€€V" €D€pn;M€€]€5 V"p€P.~€u€L€yn€€[€€t Û‰x€|%€7cr€€m€€€P€ȄE: €~€€€€€
+M€i€8€Pk€㻠€:€m€'Nޤ<€PX€Y]€Z5€)€;'g!B€€€z€_€€裉€扦€€€€€€€
+€'/€`P€Z€€!X€x€€€Wf€R€€€€Е3>€€D€€DY€€€Eqo&€€€€€€€€"h€7€X€zs@h[|€€€y!(€#j€ e%#€#€6U€€ҽ{€€€rY€4K€:€q€€%€Qß‹Õµb€ë€__1~b"8&€i€€g€€(~€€ˮ€7€€(DN€€€€€€F€4k€€€tb€€€%U€€JB€€€€€N€€€6€KÕ²RR<€̯y€Ӄ^w€€€t€€!€€€€;€€€€&€€€Np€,O€D€r€€€A€xFlRl€€ @i^P0€€€€d€?€€y즥€€޼€o€€ݼu€€;€€€€€€€r€a<O€_€T€€€€€ͶE€@€€€€Mn€€€| €Kǰ€X"€)€GA€K€€ 
+Õ€€ H€i€€€g€ADhǽ€v€IH€€@€€€€l€50€ B€€Kp€€o€òJ€€€€%€nR×€KI€W€€*Y€€€€€ϫeW€€T€xfE €€9€,`€€
+,M€€€€€€€€€'€€~N€€t€€,=€sԞ€€€€R€D€€u€i8€Ӆ€qۚ€€%€€€€€€€=-€c€€€€r.J€Up€€ Q€ €€[TÎœ)€€€€€€€€€€el XZ€€€SX)ƪ€3€€#>N€xq€E{tE€€€€€€€€€€$€Ou€t€€€€9€€€€s€8€Ù€€sT€<€€VN€ €€€€€€€€Ǥ<-€2q1€€€€€̥si€b€€€€l;^3Ydu€.|1€€/€€9€€
+t€€€€L€€T€ €€€€ sZˀ€-€22€€d€€€€€€€€J=€*e\€€ԙ€sI€€€"€X€€€€€€^€Sq fe€€P€b€A€qȨ€ €S€C8€€€?€€€! €€€€€€[x€€€€TY€@€p€~s€€_6e(€€€€H €€€ , €v€Q_€_€€€€/€€D€€ve€€j:€€IΓ€€€€b€€€q€€Y€€€€.€d€€€2€Ixb€€ €2y+€`;€€€b€€=€€J€€?>WN~€x{€-J€N€€MakefileIONexs
+€€€€€€$€€€€TEXTMPS €m5€m5P€€€clean: -rm -f *.dvi *.log *~ overview.auxxs]€€`€\€$€€€€TEXTMPS €m5€m5€€۞€DQÝ‘/€€€€=~€€~€€ €€/[de€HT€0kВ€€€mÐ}È}r€L€€€€€2€R_$[€€€€I€+QDh€?€€€gЀ€a€€€ĕ€!_€0€€€€€€€€€€€!€€€€]+€€€8€€1€|a3@€€€P6H€€ǀ€€V€ P€€iz €€€€€€€€€€€€€d%î’™M€ʽ}€€€€A€ €€€€€@€h €{€{܎€€€7€€gk|l!€€€T>€€Ý¡€€€€Z€€;€<A.Ln|€€ overview.texxs€3€€€€€$€€€€TEXTMPS €m5€m5€
+€€n€S €€ €€&€€€€z*;;€LV€€€h€. €€"€F€€€€0€o€€€€d€€€@]€u]€b[€€€h€€A€€;0€o€€֭3€E€€€€c9m€3€JU€€€€ȟ€€€€B{€\€€c€mfT€^|#_Z9ղ€:€3€€€€Ô€€€^Úªhq€{|\Z€€€p€T€€j €€rf
+-'?=€€€€€?€€€2,€€€€U€€q: ÖµB\€6kJ|€C[€_G€:€Y+LVè¸&z=€€ Z€€m€T€€+iʺ€t€5K;€€€€€G68€€€€n}€€€€ߞ€f€€€O€€€J€€€:d€€€vk€€€)s]€€f€€o€zn€ug>(Õ¥f€€j€XM}p*€€g P€€Î*KS€€ByD+€f€€€€€
+€€)2€ _€€-˦2€€€€€€€€€€€"€€€G ݞ€ [€N
+k€͞}&€€N€€€.(€S€€?}€)b&`€)€-€ r€€fM€€
+V€2€€€|2>€t€=€€€ѹ^€€€€L^ bhϟ€>|€b3€€€A*€V9€€€€3u€ou€€BU€F€!€€€€€€v€€€€a€€€€]€€€FŜ€J€h/€&€€€M€€€€€€€-$€€Ue€€%m€€9€ v6xN€8W9€€€l€€D0€€D€Gcn€X€€€€RS€k€-J€€T| 3{€lcG€BI€€J€€€j€€/P €€B€€€€€€i€€€q#€J€€€€€;€€€Rr€€€]]€€d H€B[_€ԿlȾ€Ð€€€T€t€w%€€?€€€F€[NMá©ž(vQåžÂ€Â€Â€Â€Â€\+€€9€LV€%1Qu€€~"N€€€Vi€o€VS€AF\€ݭ€€€€а€P€LTVz; +€ €k€€\w-b€€€ €€$}j€€€
+,s8€€€X+€€€€€€#€€X€€€€€@€€Q0N€%€
+€€€€Ʀ€Py€€€1;E€.5€his33H#€€€€€\P€ӥ]€€D€€€
+G€]€'€€€€\€/4{5*R€€9€€€q€€_€ O>€.€€mD, €€r€€€€#xySʼnSP€€€€€L€m€2 €9€h .$;u€Vvr€+ʃ€aE€W>&€€W%'W€*€€€r>€€€€€€t€N€w€vFW€€E€*€}`"€€€"U€€€€€€_€E^"4r\€m1, €€€-K|€€c€y€€u€5€€ɕ€j|P=€€€C€€Y'd€€ޢ€€8€5€=~ €tOQ€(Y€2€€2O€€€D;9€8(@M€[€$€€€€€MBE€G€K€-€K4€€s€€€w
+u€€9[ʲ)€!€€€xy€€E€€(€€DHcjQ€2!€€r€߫%u€x€€qDY€€€b€l€r€G€D€x€€€€€h€€G €$,€ƽ€t€b€€>M€ܟ€€€€ €€€T>€=€o>E€)U€SD€"€€ReΒ{€€w€€J€9€€€y€qh€"&€€ޤ€ €=€qaP€€€€v€€w€€:€€€€€€D8€+%_=;€%.-€€€€1Q#$€*
+q€ €€r:y€€
+€O€t€h€-€RU`Z€Q€€뽡!€I€]€zư€€€€€€%Ji>€o.€Q€€q€€€FoBtkv2€€f€€€€€€€4€€ €<$€€€€€€&€2€.€",#€€€yJ€E€ 7D€q €€€€P€€€€€€€€\€LFXcpa€XI€€€(0€€€V€ܹ€5 €€c€€€€a-€€€€€u^€ :hʃ,PKkhJa€€D >
+€€€€€€=1&~€€h€A€€€€I$€€€u€T€€P€€v€€- k€€*s€"Xq€€Po€RH€Ff€.Æ€O€€€€ €€ I €€ufJ€€P€€€7€€€w[.H€/B€y€M€€]g€€€€€€px€uu)K@€y€7T€B€֦€R€kC+ 寅 €5€€€€5€G.€kH€h€€€g€€€N?€€€€€0€€€€0H+€254*sb]€Y€m€€=€w€q€€:€€-€x€>_€0€t€€€!I.€Q€€p€TA€QÚ“
+€C€€€€<pb€€è­œza€d<€fG€€€%€€ €"€d&0B[;@7€€K€wn€`J=€€hx 馾 €˫€€F€~B€€8€l'€€€€€€ޡә€AKpYGߒ€\€L€i€€€(€€~W(6O€;BOԷ€€€€{?€€€€T€€vƒ+3DnS€€1€€e€€)€€GK€€€€]`€€bD€K€€W€€DO€E€€B€€瘺€c€{ì°ˆhJ€€€€-` €&oS€€jxo€€<41€€€€8#€F€€€€TAQL};Xe€€Q€O3⻄€€1j#€xg€€S€€BS€€€€€B€1€€€-€€fAD€:;€"€8lwi&.€:€<€yQ)€€€€\€R€€€v€v€"f e€€€ykbiT€f€€€€,€ l€€Q€@€u€€€€UͿ€€€vP€Ь<€€€€ €i€€€€x€€ €o€E K}G€€€j#V)€€. <€@*€-$€Q€€6€€8€€Ü€€€ӻ
+€€€^<@€€)€€PUD€,€byx€€tt֡c€]€€€Hoa8A€Ή€1 J€(€1€b€€Z€L €]€€€€€7:€4€L\€€@€€€€گ4€E€R€BM €€_ |N€k€_€€NW€C€€kk҉€bU@€€€€€ €)€/m€€l€b0$€^€€€Ϫ€z€^^€=dD€S~}€]€€{O€O€€=€>€€~{€€€c+DA޺€n€€}}€€(Lg€€€ɽ€€€T€€.€>0€€€€€€€€€n€€G€€ȓ€€ݕ€€€pxpt€€€??€::x€€'"€[€G{€€
+€€?€€€€€€ €€€€€ Š€€€d€€€€G€€€€p8€v€€{ut€f€€A€€]€€m€€$Ѵ€Ƨ>€0Oe €S€€€€V€€€€Qt€€€€€€Dt€&€g`b€p K[€€'{2€;€K€€€€Ci€Q&C€€€+#
+€C€N9Õ®;5€€߇{€€€€}l)€}€}_€ spiderman.auxsQ€€\€z€$€€€€TEXTMPS €m5€m5€A€€€e €€d€€4€€€w€ sÒ€p€p€€ՓǓ€€€/B€b€€x€'€G,P€€8€€€€€E€€!'CN耓cyk€€;€ d€€€#-€€N€ €€€>6eok€€@+€€€€y€L€ *€N€€xB€ţ€€=MH€€ ɓ€€É€d€4€€€M€€€2€€ d€€€P€ €€x€M€€g€r€u€€€€€NÂœb€€€;r€€T⾩ז(ZaS€ʋ€T ]€€-~b'b€T€0€€`€ǃFH€€~}€€€€3<€D€€€€:€|v€MU,5€€€<€UF€o€€m€€€/=$D}X 8€€€€€€€U€€V€€d€/Û½[€€€o€€%D€€€
+€c€_+€€h€sf?€€€@€€)€{6€€y[ #Ö±`€€€)€€5€/G€9i€nWP€>€€€N(€€€ҟ€`€€ӈ€B€€׎F$€2Q€€^€€€€`p,€GÂ€È S€i€b|€wO€€QU€€]€nG€€€ <€!3jJ€s€y€)sKP3r9€)V9#Z€
+€u€>Q€"1€€Jo €€€€XL:6^€W%€€€€P}€€€€T€&̻€3€V€€s€,€=[Ís€€€)€€€€€oH€€I6€5-<n"€€1@-€€€€f\€€j €€€r€€€}€€q€€€FnU€a%€€L€€€€€n{ €€}a+|€
+€J€0€€€Ϫ;€XK p€€€€€%€"€t€€ €El€iTfY_€€6€€0€€fdV€~F€o€€Y)3€E€€€^H>€€lA€€‚€fP€C€€z}€3b€€€€€呶r€€M€€€NE}€€€6(€€€<€€€p€Xp€<€ €€ԡ[€€€ €O+€€€ `A€J€y€€€€€q€ћ€4€€€O€€"€=€ ط€?€-€C€m-€qce6 ٯ€€?€5?Aa€t€~(€€ ckZ€€XC€2K€€€D€4.}€€7rF€o€]]|<€v€€€€€N€€(p€>N€~€ʖ€(CD\€]€X€€c€?€~}:L€€€s€€€YmW€t€N€€ت€WXP€]΄v€
+€p€€€@#5Ÿ T€€€€€.H:€t€v€#ld€C%€€€E$€o €€€€E€:€Z€]€ͯo€€}0{W€€b€b\5€z[<€ €€€€€N€4€€€<€€€€€€€€€€ spiderman.texsw€€8€$€€€€TEXTMPS €m5€m5€Q)€€ [N)y<A€BO€z€€c€€€8€n€ݦ€€r€O€Zۅ/ O7=|€>€€€4€P€€O €€
+€u]_€€G+r€#€€,G n2\€€t€_ 2V€u€Es€€€Ygo֥€€e€[qr€€€]€€€€j€M¢€€€€}€]v \€€€H€dC2€€%Tu€€€€€€8Q€A&Z€k€€3:€€8€€€ ?€€€€8€o€T€I0€i€€g2u€-:R€€슞NDR€€'€Ne*t€Q€€x€€)T€:€~€t€*R)EO€Rl}€€€€ Þ€€€€€(]€€ €€€A€Xu%€g-€W€b€€€€c€€B€€Z€3€€]€4r€€€!Z€f€P€o€€€t€'€
+BY8^*€@€Q&€I*€(ve€ €€S€ݓ€@€€€€K€Q€_€[€o€€W€€€Q?€ހ€€JC€€€€^¯^,n€€Ot7dZ€€/^lL€€B€q€]€€€€Ԫ€€n€€€F2€,F^0€€€€€ѵs€€D€.€€O€=€f€€€ØC€€r€)&mÞœc€.€I=€9>€€I€ t2€€€[޶€€€€€u'b7α'€v€dH€;Bw2Ó‘x€K€€*€€M\€G€€€€oI7€€€€n€M1€xY&€€1€€.€*€€k€z€€€€€€1€€€€^€€€㱳€#?€€o#€mܕ€2€1€E€6N€i&€4:€*%(m€€€?€€€Z€€€€€€~€
+€€€€€€€&{€€&€p€€:n:f€c€€€gB€€€€C€€.€a€€€€;<€€XP<€€€E*€€€€f0€]€€/€R€€Ǝq€ͩ€€qWUz€3€ܧ{€=€G€)\€€1:€ί9{€Y€€€0e€h€€€8€€XI€*.€o6€[€oË¡MWî·¯fg€€u€b)|€€G€€€€€&€&€€2€hU€€€€۰€"S€€Ď€ْ€€€€}i€€5r€c€֪€€3€€€€l€
+€€€q=€€€i€€^6€€M€8€8D-€m€€€€Nv1€@N€€€€z€K€€U€V€€€_€€€€D€ڞ€$,€ n€ƪ3€9€€_.€n€€€€€€Y€A€W€€€€€€gEq>€{
+€€)€W€€€@€%5€€€0u€€€ Aws€€C?€ˬ:f€j€€X€#€w€€u€€€ ]€€p€B@f€€* €€€\€€€)€€€€€€€ow€€>9€~€NĦL€D€<:€€r^€€€Nu€€O€8€ܰɼej-€€€pFe[k€ygV=€9[€4Ml€€€p€€€€€|+€€/€Ë«X& €6€€l€€]1€OGT&€€o€}€€€^€€€#Gb€IOqf?$t€€€€€€L€€! €€€=€f€l€€c€€p€akN€N€€@+€€€>c ;j€-€d€€[€[€#€ΨBa€N€€€ €€€€`}€b€€|€€€€ڲ€€€€}?€€€Q€€€06q€i€鯊€sT€€G€e\€€i9v€Y€€7€m€€z€v€y€p='؃€€€Ql€O€v€€€C#€€€€€.6€[€€€u€€Pݘ6 €yH€r€<@€€L€R[qp€€<€€E€€s€vxZ€€€€€€`ZbE€6ʆ€€uŪ:`€€€a€u@€€€€€€A€)€€=€€€€<O€€€. €€yp€€€|€€€|€€R€P€€€|€€R€€l€ F€9€5€;€:l€€0€G€®€ma€€€€€U€€N:^€€€€r€F€€€`€€€d€€€€ɔ€:2€rt? puG€€€e{€x[€€>€€vW€N€ʨ€+8(DU(€€€€.<d€€€€'ķ€yV=v€i€V€€€y`€€€#Y€\D€8€€S€€€@!€€ d€bI5@ €€!€€"€€6€€€€}€/€€n€€lx€(.€a€€€y€Z(`€€€KQ€*€€!]#€5€v€€€)€€€€C€€]@€h€€€8vþ b sƪn]€cqQ€}dc€Ap€€€€€€€nc€)`t
+@3q\r]€€€€3€J€€€€€€t €€f^€YA€c€g€N}€S€€€/6€W€Y€€€<%<9€ΰ_l€€€gE€€W€€€m€€€.J€€€Xo€K4€t€€Fy€€€+€€;5G€b€l,€ €_p(€€n]€€€blu€O€QXXÈ«7€€ lC€#1"€iX€€AB€€€Ųng3Q€€€:€e€€€Lwp,G€€8€€€ڵ€€€€u€€5€€€€€€€€€€_(L'€.€8SC€€€|nJ€Ů€€€z}€\ €L€€€€€}0€1€€v€€& Q€€€€NGRp{€F€=4y×°hk€€€€€ t}wè’‡q€€L€€o€C€€ €r€/d€r€$€ N€P€)€N!v€Se€Wv#J€€W€{l €٨€eP'€?ro€㼀/9^O€ €ؚ<2€z€€
+b €4H€€h݉€€:IȀ"<€€
+$€)-€7€;€`8€€<€:$X]€€#€€€_€€?€€€€r€w€€€€x<€8n\€€%߀€€€~~!hY €€ €/€€~€€€1!€€5€'K/€5ř€Ϸ€€T€]€€hmr€€€€%€3Ù¼-Ë›/€e[€€€€€€y6€€~@O€lp#8€L€€8y€
+€€€€€}€'€€nyXP €€ €€$`o €€€͌$?€9€€€ € X[€€"€€€€€1€+~8€(g€4€v€0€@`€€€€>€L€FUޗ€€€Ë¡3?*7"€€€#€82€€X€€?€€`Xp k€'€€W€€eJpO€(^l€€€l€€xp€€€(­€`€N€y}€€Õ€€€f€|€€Ve^€56€€ɽ:P€$I€$`€v€€€€€€؂=0€€€€Pp€#>€€€€€€ټ€€6R€jD€
+$5€!n€V|€8j€<\MpHb€€[!€€€+€€€€q!v:(€r€bU€lԭ騎€€JÒ­F߸€W€P€e€€/€€Z€€€€V€ €XM€.€PIJ€€6€Ţ\€ € ws€'2€#€€€a;d€.€e€"€€€E€€€€€::€Ԙ1-€€€€€ܟ€€->~Ø‹@,€l8€€|€s"€hf^7_$€8€€]€€>?€r_š€€6€A]
+`€>HM€€€`€€ 5Q€€€€€€-!6€a M€%G€€Æ$/ͦ€W€g€J#p€€ts€S€k€ǡ+(D€ 4j$uH€l€€ʓ€€€Yoq€6p2G€€€€€5€€€€֧ƮT€€UTFV€€€q€:€€Qٜ€€€eg+:€u€€1a€˺Ó€e€€+€8€I€€0€€?b~€€F€€€€C€€6€€g7€PS€V€7R€€€€€y€€"`D€,@MX+€Û‚+€€€%€€mT]ST €€€P€S €v€€`€ €['i7€u€€€€€8€€!q €€€^M!€€|F€ .€€ ?%€€€"€€[Sa[]G€€€&l€€1€#h.€€k€&€6'^€A€€It€€a€€€€€€A€€j€€㩸€D€€€€x`€M(e_€€%€€|Q€ǃ:{ €€€0x€ԢT€€€ËR
+€1€*K€€€€`Ó~T#€K€€I€H€€(€S€t€€<€.o€€ЇK€€€s€€€$*€€€€t/€€\F$D`€Zi€€€€`€€n€q9€€€6,€€€€€€֠€€!€€€€€€q?y€8€€?€LhV€€€F,s&€€J€€XeK€^\0& '€€€,€€M€C€€ק Du.W€€1€zB(€6DmrS€€€€J€@㨷[€€€€€€ĮNx€’€€+€€J€€ڭ€€6Ph€€{€{€€RÜ €9€€€M € €<bQ6€€€(iÜ‚€g0€o€€€hx€
+<€dÉ”=@€€K€€€€€[€€Y€€€€€@f€€h[€8€€zoT€€le €n€ O;€S€:€#€€q9K!2€4€n€€P €$,€ bB #€jr€N€€€€5g_€K@€H€€€^E,€M€c€€€N€€*2[€€ڻ€€L€€hv?€O€€€€€oO€M€N@I€€€ۢ煲€*t^U'€-€L€€ny|€#€qh€ýŲ€€?€c^€€€€€€?b€D€€w€ޘ€Ö€K€€€]€€€xW€€€T€e€€€
+{€_€€Ҵ€€€€Z€€:€€€€€Z€€R€€]×€€€€$€]€U€Ԩu<€u0€€ʇ €€o€€€^€p€€€ۯj€€q€€l€€׺€P€€_€€€€€ֈ€€€OY\€€Z€u0<Å‹€ €€u€X €€€€€6,€€€€[€€€'1$Т:€&€?y€€€€9€ 晼05€€U4_€$|1€)@U€€€J€lE/w €5hf0€€o€€€€?€p( |€>1Nu2b€^H€دaBFhC€o€€€$€€(p€8€"€€€|€F€0€u0/m€€J€)GrƉ€Yla€XZN€)€`€€€€€€€] €l€€Qh+%[€g€€$n€€w%NÅžJ€€ܰ8 €3sq€€€Hp€€€€g€8G!€u€ez€b€:€XÊ‘{Ф€;€ŋ€€o€€€T鉓€&€€€€€€€€€€€€€#€€
+1
+u€€V€"BOe€€7WC€€eL€€€€€uG€€5€N€€n€t€€9€q&€€€€@-€€"€€€€@€cjZ;T€S€b€:€R~@€$€ c!X€+€wÛ%€ €]€€9€€U€t €$€=8n<€;yp€I€Jm€Š€|€ Q€€€€€l€\€\€€€FE€|U9€€b€B€uW€yj€`€€)-/f€iNF€-€€€gu€€t€€{€0y€ipTb€€闳r7€€n 4€Z}€€Ihn€4<R€€M€#E€)9Ùƒ/€€qQ€€}€/3H€pT€€€9h€7€cHS1`1@€€d€&€d€!€I€ٟ 1€€R8H€3€€€ǵ€€学gϼ€€I€€iTkBv€yC€€€-.@€] 2€`C€€>'€F$€€ZBJ.€QǪ€€6o€€^€€€€^€ȋ€€Z€) €€;e:€ €r€€€€E€€u€€€€€€€{?h€€s€q@X€€A€SÙŸTe!h€€€~}6€€€€€€#€N€€€'C€€€Iv[€q€€ €y?}€m€€€Ś€€€€€€€€W€)IP€€ƿ€E(€€€^€߹€€r€€€j,,€Pn€€€R€l9ߟ8˺€€€.€€^€dÈ€2雺€rc€E€€€€K€€l€L]€€€€+€€f€x€€V€€€€€g€`€€*u€qͷ€X@€ €€<€€W€€€€P
+ {P€€€IT4€f€C o€Y;.€-Ê‹e€€E}€j€€ל€q€€{€€€€€ۢ€ €t؟€x€ǫ€ @Ri\/@€d€˼€8€SJ@€€ {€[!€]€ *€€€E€dX K; €%€€O€€€€3€€ €€6€€AmX€m€t€ b€6€,$€p€тã€Han2€Qj€zÀK€€€€€€
+€€€֘6€€\€Yu€3€€n7{ € .*H€€€[M!€M€ˢ€€€€L€€:€ €€ €€€C1€€€YU€K€€ i89€€-€€€€€X7€€€€o)€E€72€€ݹ1#I€t€ˈ€€€€D€+€(: €Cw€Y8%
+€Q€7$€€€YW€ €U€€€€€K2r€€Up€r!j €€`b€[!(€b€ˀ"UG€"'€\€}€z €Q0#€T€'~NR€€,d€€(!€j€ €4€do|€Ԫ€€L€€€€a€2k<€m€€Ţ^€€€hæ eCw!€€Y€z€€U€|€$ V€ly€€,w€\H€€_H€€q€p8Q3€€€mЪ€{€\ €B8 װU€=€€€݆€S€\R€M>X€S€€
+€u€5€€x€j7B/€€€!€€嵶€€p̱€O €€ʄ€ٸ€@C3€€€*H€€€€€4€€€ €€廻€€Y<€_Lg€ft€Vj€€€€€(€€&M€€€€k€€u(ɾﯭ€%€€)€€P€€€x€€€6(kN€6€p-€J€€|}7 6€€€$€€q€€{€€-t€€€€迡;€€€O€ȻD€€€J€o€^gA,€l€€€€@`2€ю€€€S€€5€€-n€€2€U €fh€€e€U\ l€W \€€Xv€€€Q€€"€uI@%€ p€€-{€Ne?CV€6€€F€ €Q: €ɪ7$,€€ح€@iuM€€€1€€€€€U€€ΒX€€€€P€€oDI€/Z€(Xk€c€ €Z€€e,z €%€€€Kq€ p,TT5€y]I€]<€z03`9€bZ€€€m€€€€I€/G€+hx0@H€€€€L€€€&€W€v€€8€[gv€@:Qç„Š_€e`€€m€€֯U[€8€:€k-€€H:€€;€|€8€K€V€d€r€!
+€€€€AҌQ€€}LJW+€+€Z€h2+€€€%⟷€€^€€€/b€_€€ކ€"& €a?]€€S€Z€iT€€@€€x€'|€g€hۭ€€ €€ €
+ #<s€€b€€b€s螜b€*€€]€€€8€.x2€5€€&y€€€€Toa€€€€N~€€€G65€=i€€€v€n€-$E€€€€€E#`*€\Y€^r€~€€€_Z€4€€€ €[gpS€d€ܢڎ€€€€€Մ€€€€%€xYr€€€€~LO€"1=5€;€€
+€2ؕ€iA )€m*€€€:K,}1<_F9€-€(€€€€2€€€€€€qD€0€Y֚€A€€[{>€€€€8€€i;€3€€b€E€€ '3€€@( €€€€€€€€6n€#€b€D€€€d€v€BS™€€€€€]€€€€&$X>€€w€€:€i€ €"€ €؅ €€€AR€(1دS|'0€€B€€50j6€€#€W1w̹V€^€k€€0s,€St`€<H푾)€_€`€€_(€€€옥€+€#€{sko€P€@€€€sO€€u`v"€6=:€€€}€pW€€q5€€€€8€€}€€€SyF€€ €;€€y9€l€|€€u€!yY€g€
++€€€9€€€c€`\€€+%w€€€€€€€{ €Y_€€
+€€€€€€_€r€ B€€3€€€€€€6€€€€6q€و€€kOc€z€€€€€€€€€N€l€€U€^€m€|5€w€€€۪€€€€€%€€€%€€€€€Q€€€)€€€*%€€€.$€€€€€€€€K€€€*'b€-€Ã€€2€€v;€_Y!y€€€-€33,€€|€<Mje€€€u3€€te€?€K€B$ES!*!€!Q€€ €€€2€<€€€a€€0€5€8t€@p€ҹϕ€€€-€`€V€€ǯV^VT%%€€€e€€M€pN=€€6€R€0€?€B&$g;eK€€€€F€€5€€4€€€8-€uO€\€<€€ۑ€FaZ€8€P€€€€€€EL€€€€€G=€0iz€€€u€$/€f€y€€f€A€PX€c€€z€<€€Zk€z€f.!€-VB&€'€[€€w€€a€QtUo-€€r€€Ⱥ€Shh€€XHR€€€V€€O%€€$€hi3€$K4€€4€€€\€Y€€sM€G€;@i'g€€ €€€Q€€B€W( €€B€€€Õ€8E&|€€€€K€€C€€€€S€x€€€[€€€€3lJ+;Úœ{€d@€{€6€$€€€€C€u€Cy0i€€€€€cш€ߨ€R€h€€ q€€€*€€H|€€€W€?€€U€€€a€‹+8
+!t€@zʬ€€@l€R3€€"=Åœ€LוC€J€WO#P€€€y€€€€W€€€€:q€€€€€J€eN€ʼԡ€+Cǎ€€A€€w!€€€+€€U€<81€€F"€€E€€6€刴€€€݅N€w y€€Z€g€€€V€3g€€€sQ€-Õ€ Nkŷ€%€%OX€€Tr€= yB€8€€€Fe8W€$€E€Q€€€X€ŎO€€€0T€€u/T묱&q'+€€€€o€€0GKT€!(r€I+€a€€;@€€l€€>:€f€;<€€€h€€I€€€€AZ€߅€€~€R€€
+0€€s3€@€€€n€€,€€€o€€€8€€€wj€QF€€/€€MȲ€c>ۈ4[€Fk^€؃€d*s€€€€€w€t€€€€~€w€€€€=€\Äp€Qpi€3?€€^€€iMpЀ€€=€D€€Ѱ*€A€/€Jch€o€€€E€€€€€€€B'€\Z€€€€€€€€Qb4€€K M€€o€€s€€€]€€2 €€€€€€€€ugItB€€€I+€3€bdGc%^€_jwG 3.+€溌€€€€;=€ €€4€&€€€€ã %€l?~7€E€€€€€x€Úˆ Ëͧ ?€€€€€€i€€€€5€€€€€?€~€o€ĩ€€U€`€F€5€Ô¥T-€ĩ€€€€o€€€鮞ً€,$D€g,Ö <m<6€g€Q c4€€€€2!u€M€lS3t€€€€€€G€€ TGc ήP€€;;3_€6?€a€B4dfR€€G€+€€Iyn€3€€:v€€€€€?3€0€€F€^€^6Э€€€/€n€€€È7€€>€€p€ӎ€€€€€]€€rs€t€€#v€€ )9g€UKK_€X€|€Dt7s€,a€/ €X€JJ€J€6€€(€€GJ€€€;7€\@^€€€€8€€€€iQ€€€y,€4Q€IA€€
+€~,€€€k|3€ Y€:€€€%€€€s 8€€€€€=NO€€€T€€€€F€€€ i*€i,€.gq€€€خ€€€Y€q€€ € W€b€N€ €6S€€€€rXk€€€
+,€G€C€€wM€8€P€#€€ɚ€I€€€K€;v€€-€€(=BH`M0€at€€W€ €€*T:€€€G m-5€€d2€-: By€f€yTu€(€uf€(L€h€Åb м8 ÛµL€0S€€€L€-v]C€€€5{€€p€€€€j€€€€€V€,Tӂ€?€C€€x€€€ €€€€2€wn€N€\€€€<€€%|€l6€€2€€€€78.€€€€~!r9€€1Ç®;zġ€T€F€€C€E€I€n0€<€€
+oGss@,€€€€pƑ€€]/{€,€€€'(€€€*€pD€p1€G€€+m€WM€€€M€‹j€€€&#€€3€€SwT€$€€9W€J€Kް(l€*€€€W€€vy€€Myb€€€€D€€'M€z€€1€€€€€EZl€cx€%6€&f€8€€< €€€€€€€- €€€!5)Rq€|€W€€"t€€IN€€€€€€4€HJq€€€;€€a{H€€m €€Q€.P;€€€€W€FB0€7€€Ym€ o€€€S.w?€€€€€€a€"€5y€XH>sg€€€)€€@{J€€€W€€2KD€€K:WOڗ€ e4€q0€L€Ќ€€ €€€q€tR€€€€`w(€Uo€
+€B€€€€€€]€€€<€€:E ;Z_€d€€2€€h€€R€RÉ®W€€nsL€€6-R€f€€€€3€€€tm"€€޸@ØžTk€€€X€A€ €€€pH€€/€Μ8€O€zN€€8+#€€€€€€€l€Cv(€w~€O€€CmÙ‘€€€BN€QmÚ€€ҵGSI=€My<€ €{<€љ^v9€€€€`€€€€€€€Ap5€€P€=€€€<€gP€O/1€[€h€€€~€O€=€*€c€€€€€cm!€׬€€€A€€€€€€€€€€:̠€€_€€€bQZ€€€€€ZF€€nF8€€0A€e[guf€€~<i€5€€€€t€+€fO
+€€~€€W€P€€Xq€€€€7u€€+\o2€€€*€@%€€€€g€eY€€€?€y#€x€ €Q€€= ;€Ъ€€[€€@€yT"g'戜€€79LB€C8€€
+€r>€€€€€$h€C€f€U€nOS壣T€Ncm€€Y€z̰€€6+€X€€b€€B€€Bѥ€8€q€0ml€B€€>&%3r€€D€€€€€y€€]+9€€€€p€€P€y€€j€ €W€€g€Z€€€€e܀8~€ln!g\€€yrN€€€ € ;뜃)X€?€€
+ɧ€€'€€װ/€€€#o€n!"€€€€m [€€€k€€BÖ€n€y€Z€'€€€u4€?€€€€-K€DjY~7€€€€_ €€E4€Xx"€€{O_€€€q]
+>H€€ €€€;€€€€PKN€'€€#5€[[;€&€€鬨€€ €/2€€€€WzG€˨€qr€€€€€€`€€SYB€rN€€4T
+53 €ywr€€€ €€3/€A€2B8[)€€%?Ke€€€c{€hL€€<EO€p€.€1€€%€6€€h€uz€Q€u€Hs4W€XdUC8 (€€XD€€€€{€€[€€+w€:€BD€ c\€{€€€€€€€uu€F9`€CK€€Hgx€€gLh€[€€%€W€€y
+-€J€F€<€/€I€rxSJ€€x €€;;€€f€?€€€€€4€e€€€€fP€Ex€)€€ g€€~€€€2`€i€!€
+€-€€I€€€€U€€2€F{7€€%|l< €€Yj€^€€!"€y€€€€€*€D€]€€wW. €€€R€€y4+
+€€6€)€GpF€€€,_€€veA7€5€€ݫ€,I€€Ϯ€€);€€€€pI5D@ÜŽ.€€)€€N,€CM€T€Z€€€€€€€z€vg€)CM€u€€{ׄe€€kW!6€€€L€€C€€€$€YD€€/qpL&€M€pQ€g€€Da-€$€€v€o€@8=€€€ €€€ڒx€€D€€€֭€€3d&€%€cR€6&€(>Ú¨J"€3€!Y€€€'€€€Í€cSH€€+m€€€€€€€֥€€cÜ¿0@/Y€€N4€Cã°†!€€_€pg'c{|;€&€Ke€.€€€€,U€€I€€€tS€€€[€#I€"€€Yw€T€?€€€^€€€=€:€€-⼤XU€ €o,ʆ'€s€"°B€ە1€€€€)M€f€4€€€€)jE.p€€q]€€R€Ȏ€R€Ec(€F !€€Y€V€€r€.€€$2(€€€C2S%Rm%k€j€€m€€€€f[ZBUp€€ ,Fva€nf€zQ€Η1€{€€€T0 €€S€€€4s+c-€#.€g%€€€€€lU)+rΡr€3€E€€.€€€€€€€Z€!€/€9€2?€/€€€{
+€V€€b9€€1€78v€a €€€€€o€€€t€€i€€B€C€8€€1€€76L\€O`q~€€^E€€X€€J€
+y €+€hC€?%€€ €€€€€€E^BM€k€€0w€ €€K€"|f&H|?€/Ɖ _€€€q€€€€€€€а€€vݯ.€D€OOz=t€>€g€H€=€€€€^€€€y€#€€€l€€€y66È€€I5€Y€€€ϜJR€l€p&€€€J€ؤ€w€€€€€=M€t€ۭhV%r€j€ 1€jo€€"€€'€!€:€€€€Ȱ€€&€€B W8w€/€C€€2€^€:נ€€//Ч€€€6€€€x€1€aG@-€¿€pU€ €€€€€€€€€dpDV€€€€€€€W€[1VzÄ€0j€n}€\_€~€€€b=€v€3S€붸€€<€!ī€€P €€€*Cdo €€€"€€€f€€'U€@€U€€.€$|€%º@)#€H€f" €@HNY€p€
+wD€u€Ƙ€"n€€g€QSraڑޫ€€RڔEL€Z€€€€b€€ƾ?ݿ€!€)N€€p€€€€€€'€€€€€€0€
+B<€W€h9&€u€€/W6Z€€€€€$€€]€Lڸes€€€€€€3€€€0€/€!€€,€€ZH€€€뜽k€€z?]€€b€ €r€€k€€Ͷy€(€#€€€[F €€€㸭€€€€xun€€€€€€8€,@€€y€|€4€€€€0V| €V€(€B€/€v€€dء€ҩ€€B€RR€s`m€7kH€€€€€S aY\`1€$€€€€
+)€"€VO€€€€Ҽb€€\€c€!€€.€ TF€
+7u€g 0€€\€€0€€F€€Ǝ€A€€m€€€€€€€€ˎ€€€€€€jsB€€€€€c8`@<mC€€€€€*€€€€U€€i€$8/€r_€}€€€€€€;€'€(€3€€€€5\Ø &€€€Ί€v€c€€;S€€jp€C>)u€€IÔ¹W)휧=€€€su€O€€_€g€~E0€ 1@€G^€€oRO€€€€z33Ë€€€G€k€€y N€:€;€€IfY€v€€Ԁ€',m=€€1€7j€€€E€€&2r.€)g€F&9_€€
+€ IK#ŷ˛^€€€€E)N7€Z!k€f€€€€€S€.EK€XA€H)€€€΅€}€g€€DWk€€2€€2€€-B€x€€R
+€€C@€€€€xo€xk€€"KvS€€G€g€€€€€rI€ €y. €_€d€b€.K€€€
+5z €€\€-9€j7€=Ɖ^€€€€OE*Q0Wt€Y€i)Ü­ €€€L7€€€€€UՒ€/J€<€i"€d0€€,€aޭ€J€JKOI€€€€€9€o\)2;€€ıפ€€ 7€t€€6€€€ɣ8MKܶ€WD€L€Y€<€€z7 x4O €€€€€,€€€]€n
+%€m?Am€€7€~€듥p€X8€4€N€€1'+€€€-,LV€€B€Q€€€€€€.€d~D€ 8mJ€€7B€XK;€iWY%€€(€€#€€€€-€|K€€x€l€€€f€€,iKF%AÆ™)€€€€€T€}0€€€G"€y€3%<€(hgd€€€€€P€W€q2€€€€hX€"€€N€€=€n€€L€_x €€k*u€€€3€€€עYk€€i0dd&€€;€dAG€€3€b€€z€R€€k€>€b€€€€Ȫ€^€€y€Y€r9\€)'€€€dg€^€c>VB€Xk€€lW€€;€k b€C€
+&€€€̙љ€ €€€€€qv€€€€ydm-k€€€̪€€€e> -€FI€€€Jқ€{€€`;€€]€€€€V€€€.e€€R€€€€€€e~€qm€€€ȀF€)W€€w €€€ €.A€>€a€€€€€ee€€y€€€Xi€€
+@€~ÂŒu€€€€c€h=]€\€/x€€€]€€€€N!€ 4Uu@!€€€€$bÆZ 4€ً€€M€8q€9WA?$€M€€t€€Ja€€€€€€^€€€6y€€AN€$a€€€€€€€<€€2€ͅS€8eh€€€{€A€ €o^,)€OD€6€+€€€U€/€€RiG€VX€"Q€v€€€Izh€PhÞ›n MQ€€b€€€0f-€R9€E€,^€;€؋C€bn€€€n€b€€ e@ّ€c€vtA€€O€FbX€€pA€Oi€€€{ €Y€€L€X€€0€X*0€B@€€€:€Y€R€ €%zUҸ€i€T€Z9 *€€4V€€€€€( A€€€€€ €€€fE€m€B€>€€€€€€€d€~€€F\~€b€€€€wY€ܪ€Ƅ€H€€€ɭ€€€€€M€:€€€E€܂.€.i6WÈœi^€# eg€€€oY r€€bjA€KdE3\€K€bir€€€+'€€J*Jf€€.€W€€€€€€€6€̱P€€W€h€X<3Z€€*€€hiCÍ”A.€€€ L(€)€€`€]5€€E€HS€€<@9YrK&P9A2V€€6Ï•+€€€€'€4€€/it`~€€€€€"¾€H€€]€€€X€€:?€€€€€€€pqG!€<€”€€ €`€€€€\€i=€€€€€4€€V€,€€|h€€€€€[€B€A€€.j7! (€€€|€A-J€o€€]€€€϶€)-€_€€k€€b€€€<€€€€/-€€$€€€€€€$€<"€u€€€€€F€€€€€€_#TG€a€€R€€€€f:'!|€"€€;€€€V€DS€€€C€@y€€€gs€€€€i€€V'€H€€€€€€€€€ 7€4s€€Nc€8€€!€K€€ [€,€€€€ €€€€){3€€€Vfƅ€/€€ €M€€€^xΎ€^øPB€|€€#W€Lj€€€6€X,CO€-n€€ɡI |€QD€€n|
+I[€€qh€b€Z€€€€oy€€A€€$€€€€"€D€!Ag€
+f0€QR"yZ€€[€€€er8€€Bv€€~i€C-}Rw,8€l €P€u€€w€€€Z6€.€?mKp€€,o€F€F0€NH€V€-€€€Ë€47>q€1€€€ݾIEq€b€€€a€€'C€€|ޗ€€€L€99€6^7€€€Kv€€€7X€eÒ•~€q€P€€€€ €%€€€€€yh€u€S€۰L!c7 LV€y€Z€NÆŸaGɊ€p+€ؚ>?€€€w!€€€€|€~€€€€lw€V€ M€`J€W€€`-Zs]€u€G€€€nL€€m€€GJ€€e€MC8€k-€e€ru€€€ث9€6€l€#{€%€€€€€z€€A!O:€€€€€4_€wV€€€€€€EÙv€(€Y€T€€w€m=€w(+?b€޻-*f€€x€-€\€€€^€€€€Q€€M€-€fEæ«„€€w!|~€€€€€NP€H]€F%€€€€;d€nDV*€%€P@€L9€N[€€y€H€€A €ٜ€sO€LCsjH /3€eF€€€G I€fx5€ d1€|€[€&€€_r€%r€Ư€ۑl€€y\€€€Õ’€p~է€ ,€€€€€€/ÜŒ"A€€€€€s€€€€,€€q€&Ù²ui€,7€$€웘aP'o6€€i€ |€;€€€w€€€€u€€8
+€€"€=€ €€€€€n€B0€T€͕ €Ko€z€€€G€€V€€dJ]ä¹C€{
+€Қ,€€H]BQ€|K]€C€z€9€׭݉d4€€€€ͤ€%O€-ti€Σ}X€€€ҋ€D€ԩ€€€3s' q$€€#€€€ €€gpGVZ , €€€NE€76*e€€ Å¡%€ !€3€€€Y€€€€1€# ؜€€ €o.€ >€wt<€€L€D.€€€€}>€€ €€[<€#]€5+€o€€P€*€€"€€€7k€"€6Ey€€€n:9BDmSZD€€ZA)€g-A€ €€,€€€iF€Kv€$€oItH€€*€€98€7€`€€€M€%€bJ€€I€€€e͎€€€k€€В醀€'T€붴€€dg€r€€€€€€8€nk€€=V'B€ €€€ v€€€o€€€€Q€€<6€€%p€€N€€T€€!es€3i)X€3€€€t€€/€B9€€€€ֻixf.€?€A€T'€€F^i€€`ʈ#o €dm€€%C€€€Ȁ€%nM€}€h€€\|€$€€2$€€We,á©£d €Ym#€-:-€€s€s€Nн(€€€SzC€€ {€N5S€€D€€-B€€€o€~€yJ1E€6€&€€€b€<G€€3€$€€€:€rE€€zīę€lR€€!1€5€€Z€€ r3€€€C€B_lr€€Kn)€%:€H?J€2~€o€I€>`€!€€ɜ2"€g€€€€€cy€€/€€{IS@cQ€3€h€eO€k<O€O€€qo€€%€€€€€NR€Q€ÄBת€E€€€ŵ€!S(€u€4€X3€€u€€*€€{€€€A&€€€=€€2f€g=€s€€€€€€|)`€€1-)€€7u€*€€Ï“+'bݺÔ³X~€€n€€€€€s€€dZXI€F€Z€rf€€€H€7I+€€wH€€€yW€@€D€€ €<r f€m€F€€€€€^mO€ !s€zq@€€€€€€/€€€(2€G€]HN0€€h€€̤2Kh]€I€XV€A!}s<€€C€€€€@CD€€lp€€ļ€V€A€€€€Cl8€-ՠ€€€€A-€
+€€I€<€hF€ €5€]€€€U€€€|€,€X€o€€€?X€€€ШӲ{€€+€€€# h H€€€b)Hs€€4*<F€€€€€€S€#€#€€€€,€̚€€v€d€]<€€Y2,=^ymqi€€€€o~k!&€€€#€€/Aa€#€y€g€€Y
+€K€, mrV|>v€€€^€c€0€r/EOUI€o;€XR€Nv€/€Wr€*.€€ 6+€€/€a€€€€H^g€€€€oU€#€-€)8f€€€€X{€€_€€^€€€€P€2€]€€f€N€€,€q€€€€€€€€܄€€€@il€ €h€€€9,€:PIwã®Nl<€
+€kF€6€* 9€ T}H?€€] 1€妇n€€€Z,€€€h€€€€Y€I€€4E€€WH€iZ€€€?€L€nX!!
+€€q `Ô†'€a$€X€泈€V€()€€+_m€<€€€p€×€j{€€€€€!/Y€€ €H€XÔ³j€6P€Q€!7aq€y{€€Q€3€j€€j€8v€ј€€€ €^ؤ{€"Ï“€к|0€6€€!`uB€€p€€€]t€}€€v€€;€B€€€sfEۢ€z€@3€5€€%€€€ €<€|€€)€€€€(Es€O;€a€€LfF0#€€€Zh€€nz[$\€€~€€€l €:|m€€€5*€jC€€€;€Ƿ€€f€€)€€ €oVwc V€A]q€€ݕſ€l€~aÌ”2€€€"w€ɉ6}NbJ|+m€€r€€
+€€Bs€€€q€6$mG$Uw€6€!€€€ €€,p€.€€a€€㙪€;6|€Qj8q€€€"{X€^€€€€€?$Jl€@€Z€w€y€EkM€€ODk}€€E€7nN€€€€€€:€€€€x5€a#,€€€&!d7€€€€€(;€aM€€K€m€€€€Gv€€B(€€/$
+€€\|x€^€l€{ÞŽH€€=€:€B€€€"€€EP1q€€ €@r€€€o%€jx€€<€~u€€V=€€g/€€€€Vw€€#r€C€,;€f4ORG4€€{€€€€€e€€€ښ? €G€€€€€(€H€€1Pe
+o€\)€€ʀ€€€€]?a€€€3
+€€BÉ®l€U€€]€€€Z*€€€€V€tÝ"=€€€€€€b<{xj €]A1€bU€€&€€#dA€€:€A€€Ai€€Ztd9㤌9€€€ⓩ-E^n[m}hr€€J€€€€m€Z€=€o€€€€Q€#7C€5.€K€'>€€,D€€€0€ȞQ€+€ €E€€€NH€€8€N}€€9q€€€€k5BiZ€€€€€€C€\€D5 €€Y5€̒r€#]€pvS-€L€y-€€L€}J€#€€ݦsq€€€3w€[
+=€X€H€gpgt€€|€€ћ&€z€€#€%€egT€t€s!€€=€€€€€.€€֩k€(€zr€€,1€€D€€€K2€P€€xT+,b< E€nÈ^ß%€V[3€€)[€€sԃ€Uc€r€m+€€]€`€&€€ G€*€a J€€€€ €r€rÝœM€€€,€€€$pytOr€€oh€€€/€€€€€.€€&X~€€Ye€5€ݣ€€U€€€Ê€(€€€€=I€̨ €D€e€€€€G€xpJ @]€€€9€'€ZF'€,V€€€8€€V€€Q€㞲6€€€€E€Ť< €>€€€γ€€€˘Vm€WdW w[Æ„L€€€€5€€€€€€LwIhwN-Nqgf2€z€XH!zE`€nt{€€€€€lp€€€€€p]€€€Z Cg3€€€"E€c€J€0€B€% Oq5€?ÕºTR€2c7(`l€-l€€]€€€,€€€
+C> p0€€Sw€3pXp€€,>9KF€<€)€ź€S€4s€€)€€€ԌTt€€€O-€;€#€p€ᑾ;€€€HZZ€€€* rb€€€_€€€€
+l]€)€L€K.€Bbx€€€5€k€€Q€€€yE€€*-€#€€€€€€^€P)M€€€$€€6€€€€€\€V€؇€€€€€€€VAŸ&¥€€wG€8€€;@:€RE€_€Tr€o€譴€so̴€1€€%%l€€€€€€8,€€€€G€€€$€mgC€X ,€ʥ€-_)€}>€€€€€02IK~€$m€€Þ *€€G€€#€iw€€€d€en8U€
+€.d€D
+€7`€u9dE€*f€€€,I€,#sJ€S€]bLm@q€€k€S(hf€N/€QO5€z`€€€s€i€|P€#€f€€^€k€€€8
+€NȲԘe€R€ϯ1€b€€9€E€€€ż2€%Ӥ€t€軋U€€;€ €B€5€$€€€&#€Ɏp]>V€€€€<0} 5€€€€€N€€YN€Ery€€€€€€}€E€V€€€€j€U€w,€0€€4€€a€Xr€€€€y=@€€€€6€<€>`!€€€€H€d€€Q~x€c[€? xO>B €(€€D€\űe€O€VS0v7KxX€oyg€€D+€€%#D;l €sR€M€wFY3€€€\ƈI€ėq€€€T€ /€€€Q
+Y€€r€)F<C€€=n€,€€ȣ=€r€€}€tB€]l€€€€€€3€O€B€,€e€€8€/€_€>€€€,K€+€y€€G{€;ǷuS€Kl€`€ʽ €€!€\€€€€|€x€Jv€̚€b€ re€l~€€#›4€€sb€€c?8<€€:€aD€B9€€A)€S€V€€{€€€9€€FE€g焮1-€€€bJ€ )y€€N䑅€€*g €L.
+B#7/€€Î€
+p<M€S€€h€€t€€€€׿€€€3&C€€€ͭ€€€€€B€\w€€5€€€2€I€+€€nK€€[€oƕ€€€Ҡ*€€`€,ZL€r€z€€€€€€€€Ð€n€€€€~€E€f€*€N"€G€*€@%€>X€€D€3€R€a€€€ €c€›W€€L€%€_€,€€{ >€~^€€ß8v€B<€€€ €Щ€€€|#€[%€r€f+N€€Ñm€֦€€€~€V€@€€€ץ€€:€€,€Jw]R€€q44nJ
+*ᦌ*€€)Xa €€&€MVRb€€D€( €€€€'€€N €^)€€]$€<€/€-€Mo€€€ €€z{€€€P€q€€w€ 
+€>Ip!€CS€€t -h€,€dx€"€€€B€)J€€€€g€}Ҥo}€€€€I9s€€€€€€€€€€'€€(YZXXXb,K€€s€oG@€€€lE€
+ €؋/€€U(€€9€| |v€/€€€€k €€€l€€l€qo€{€€€?€€€mo€€€;o€€
+€/€€€€€€C€€€w'€€F€n€€{€€OvU€7ա€6"€i_€נ€€€F€€€€€Z€I`€€€.L €Lߩ<:z€Zv€€Ϧ=€7€€-€^€W€€€€(zN€€€€€€€e€M€€€8€ E€€)"5€€==Ԅ€q€C€€€€€€€\T€ɱA.7U€€€ BC€€€€`*€D€€€€€03ӗ19€€
+F>}fjs€\€€Y
+€
+€€€Чy€€Z€x€薣 .€j€€9,€1€€€0€G€€&w€€oc_€X€N€VO€€^€0T/by/€-[€M€€vn[€€w€€d€{ %€€ 6M€&€€!p€I€€a,€߅€qGX]^€3f€<>Q€€€ Q€;fLCs€l€)€
+€q€֠€€(€i, \€€s€€€C€8F€€dq€o€A€a€€€@MhF€€€cl€j€€€€€€€€f€€)€€0€
+€WP€L€€v€JA*€€7€{T3€YO€.€€€€) €€<€*€&× Òµcw€€h€e€  €to€,€€€.~€€€€€€€€€oh4€€'f&kT€€>|€=eMÛ‚7f€r(O€ކ€€Yb€V{eV€*€€!n€€E€-€€&gÆ i€€€Z>€'€€*€+Se€€N+€€€€€8€€€€yO€€ Y€Y €€€€ԣ?6hD€y€€€€l€v€~b€Vpt€J€q€€$f€€RL€hd€€€€€0>ec j€€€~Ha€€€Ʉ€*€g€€€€i €€€€H€4q€€H€т€ €€6€'€€wv;.€8€bi€€€x€2€C€€€€ze€€€KA€€€2€D€Ú½)€€€€Ջګ€€js€€€€€€€M€~€€€€/q€€€€7€€€€W€€L_€€€~^€€C€79€€€?€€€.r€7€o€ €.A€Q}E€€e_/T;ܥ€€e€€€@€€€€d€€€€EM€(€€€MK€€(r€€€€mUZ€݄/.€€€€w€>€€Y€€€€s€ӽ€N€w€€€z€ €€-€-€€€z€]\Д€€ѧ^€],€€€c€'€Íg€0€€+€€
+uV€l€€€€IO€N€mWU€€€Ӣ€€و€€(,€y€H€ȚZq €Bc€ €€~€?€€
+^€€w€o€G€€K€€b€ €€€€€€€Sx€l€€US€e€€ĘXg€@-5€€€m€5€%€€€€€*€2€m€€€€€Ô€;€NÚ -€€€€ h€W€€€€d)Ô€!€€i€-LnB €€€€,€€^€UXn€€ bq€€€S€h€€€"€€ɸ€=€€€F(€~H{b€ €c€p€€€ ҟ€€€/€€€€€€t€€:h€€€€€€k€€ͦe€^;€=€y€€h€J|€-g€|€€^€C€€
+4€€€€N€€€FO€k€€€€\€
+€€€/?KR€€o€(€ f€€€€y\€0]€h^@€JK€]Vt€€€t€% W|€@€K€+[:€€)€Kp€&€€0w€S€%€€€ €€,f{€Y€€Ѷ$€a€€€=dg€€€$€G€J€€M€€"s€f`€v6€€)[€€^R€${€€€b€wj€€€€€€€€€5^€ €A~€c€-€€€fÍ°}'€+€H€:Í‚W€€o2F€dV€;
+I€€L€d€J€€N€€€€€€€R€߉€R€€)€x€€HƎ€€6€€€€€k€p}€€€€zh%€€0€€€€z€€€p€€
+O€`€€€n€€€_g€€€€ ;,€€€>€€€€(lس€go€€€€,€c€ €€€x}ZiZVt€€€v$€€ p,€w€P€P €€€`7€€Y€b€€€3€M€~€Vl€J.€€ X€€€€€U€€€DXPP€En3?`€€€€3€,€r€€€3€5B1I€`€€€g€€](€€&sV€?{€Í¢8€bV€]€€€€䋥€€uxqs€€€€€e]€€,€{€ {R€€ €o€ܚ€/Q€4€€Qd€}€€€yޱ€߭B€€9€€€z€€€>D\]€€€8€*~€€€€€Kw€_z€€{€€€y€I1x€}€u€€€ €0€=x€€A%u€€€€~U€G€㶧IKH€€'€€€*€djQ%s'D+€-v`Ԛ€k>€{R€€€x€€€,z?€€E€ǥ€€€€㨜€!~€€5[€€€e€}(€€-€€˲€€€m€€/LY€€O?z€€€G€€€€€O€€€k(€€ecǰ€* €€QJI€g€€€<€€3$L€€€@r€€€Hә€€&€€€€€€}F€V€>Ä°{8€€€€!€€M€X€€€m€T€-€S€€€€;`€V€€€€€€€€€€]€a€€>€ €
+€GÏ­.€€ѧ€€€€€l~€€€V€ϧ€€€qE€€1^ €€j€€#€>f€€€2€€€€€€Ii(5l€'€€ |€€[* €€€€€Øu€m€I€€€*?€\€€_sY€€€€€€_€^~€€€€€}€€€m5€J€€€T€€€€)/€w€€€#9€€K€%€€€<v9€q€4€E$€€j€€ €€q€I€oQ€€?€J€€̜0f€]€W€€€€€€€oGΔ€ja[€€€y:€ZI3ÈŸK
+Ѳ€g'€'€H~€€€€€€€€€S€€€t;€€€w€€€T€€€'`a€€€,I€^6h€20@€{$€€€€[QpK€n_€€€⛟€€€&{€€At€W€€€a€€€€€>€€€yc€€€eC~€R€€x€͈€€€r€€e€€€^€€€"-€€3e*€{Tav€€Ķ ޶€â¦EǪ€€€!€€€€€€€xG€?€"€€b믊€*€z €2€€<s0F €€€€Y€€{€m€€€€€€ש€6 a€€€€#€€k_€N:€€U€€F€€7€€€6€-€
+G€€̒t€€€€r€€i€€€0€l€€€€1€€€/_h€'€€€€]€؇€ €€€%Ö€€K€}]€ €
+W4€ɱ€Vb€€W-€€r€9€krO€ɇ&k(€€h-'€€€€€€\€cn%f€.
+€ަ€€€€€€]d€]€C` €€€H€€ 9€€^€hr€€u€€€€€€}€Jf€€ã¦Â€ a€8*)€€2€mak€€~€4€ހ€€€€€€€Zu€€$ZRQ€|€)ԙ€0€€l€
+€€M€€8$€t€b€G€€}€}#€€Mؽm€€€€€J€p$€u€€€c€I9€€€+€}€€€€€〼[.n€$yB8€€€€<噵€€€€/€ €'€?€€u[€€[Ωm€L\€7"€€ €|W^€ €€W^ڛ*€TZ€S
+nF€€ڈX€€*6mF€€1€€5€€€€7€€€€~f€€S€€€€07l€€€€h@q€€€Ņ€iXl€€€€€<€€9€73€€€s€€X€M8€€€k맓€?€Ic€€€1N€€ц€€7媨ִ€ND8€Dp€€€€נT@€€^D4J€”€/t€€!d€€8l€€€ spiderwebman.tex€.€z€p€$€€€€TEXTMPS €m5€m5€'€€m Z€N€x€ €-€<9=o€vy€€€€€€~]€€€€~€€fx€€KO7€m€€€€d€h€껮€€€.ã‹‘}€eBP€€'€(X 2€}€;€>€[€g€o€ȮQ.:€€€€€€c€€sK-Ԏ€€&'€G+Р€€€€{+n€€xd€,€x€A2€€XGU€Ѫ:€€w€{5 €€€€€zw€€€€€D€€q€€m€€€]€€m'pl€?T€ €€€:€€€€€€9*
+€€€€|€'€<€€€8€€&€;€€>€€|G€€€c€€7€T€€€Kw䨃€€€€€€€]|?€€€ھ3 €€€€~€€w€a€€i€€w€€g€V€oO€UϷ€9€ݞ€€~€c€ €?€€@€€:c€;lh€ €€€&€Mß‹&€5r€9#C€y€€×KË™D€sf€€};p,,㌩n-Ρ?€€-€X€7Ö¥;€/O€€€Y€€€u-€€cG€G €y€Ӻ€€xnģǢ€€€s€N€|/€Z€€€=€;€Q€粡€€<wd€RV&€;€^€€€€€€8€)€€mOg+€€€4 »€c€€€€ 3€€€W€Or€:€f\€SL|€€€ )€w€x€€€€C€w//€€€^Mp€€€€w€9€/€€K€€€€7:€€€€i€€€(P€4€€~V€M=€€€€€€D€ת€{7€€€€j&y€€68l`€€€Vv݉€€k€€€€€€ €a€€Ç‹o€$XX€~-~€€87€€=€hӀ`€_;€So€€J>€w€€€€;€{q€€€C€/€€€P{€€€0€€€€€€_k€ܸ€L€€6€w2€Y€HYPqK€€ӗ €€=€€€[€r€€0€_#€€€€€€€P_€$€',€~€€#€G[€€€>€ͬ€€>€€€€€€€;9€€€|€ V$€€"€-€€€{€m| €€K€7€'€€?€9€€€]ƨ€€€aq2Z`O} €€€€EXc€€€€x€€€6&€(€˕ €;€e€€€~€q'€€b€/L€€×q€€€€€k8pÑ3€€€Y79€€=pp;69€€€vß™x€aL€€M€$€€€?€€€€€_€€l€|€€u€9i6گ€€P€€Uc€N;€€zY?:€€€Aиn€€@€v@€€eAl[ €€S€R€t
+r7I(€€€sK€€ €€€1€{€5€€uo€€j€€€€.~€a€€€p2u€*€>Õ? €€€:__Q5€€€€w߾€|k€€€€VP€R€€€€€€^hxl,6C€8€€€€b9€0oY€€c€€q€€jLJ5<€1Ϙ|€lo€€m€q€D€1€€ᡋ€€k€€do€€H€ €};€€~€8€w€>€t7F€€€^€€*U,€:€€€qÆž8€€€€_x7€€|€€€€€|€y€@}€d€€€hDa €€Ȫ&
+€€€C(X€€p€W{€€€€€0€€€€G€6j
+€Υ€s€X€B€c€€?€€Fɥ€€Kkk€K/9w€€€OƘ€€€v& x€€€1€<`]€€D€p €€€€#€€-R€€€€\€u€{€S-€;€&q€€8€€C,€9ÂLp*€€:y€€€>6<€€€vGBÈ ]€mj#€€t€=€nx€:€ٵ€€€c58€€€0>€_€€€zǙ€j€3€€KÙ¼q:€€€ȋzE9€€€€€€€S{€€Y€V6€€€G€@€€/€€ose€€€€;€€g€ƜC6€ a€€崭€€Q<€€€€€q€€
+-€$€.R? €€/P€€h€
+]€€€€dU 2€J€€€F€І€`ׅ€J(z€C>X@€€€€tM€€?TӃ€{QO€0> €€~€€€€€€€€ €v:€. Ê’€'€€€€€h€€@$hV#€#€€~€€€€€ï°‘@€z{C=€ €"€_€G€ €q€M€x€€}€€€o0€€|€€€€7q€T€€€Zx8€€€€w€@€€;?€€:€=€€D€W€€€h€€€€`tWU€sÞ¢UBÊ\€€€<€(€X_€€\€€MÑ„R#€€€]c€k€€€€€€n}Õ ps]€€€`€`€o€€ś€?€;=Æ!€€€€€€2€€ovS€€€€a€€:J€€€{^8€€€€<€€€=€€€N€q€€y=A€€€€u€ĩC€]0€x~€€€%M [ €€I€.€ALÕŽZp€ce0€^D倀€€€€b€€€8€€{€€€-9/s€b€€
+€g0€€€dP.W€4 f€O€€pJ€€R€€|€_8AX€€€;# €€>€w€€€€|Ό€p€€ȹ€€F€ €O€€AH€挳ٛ€{N€ʺup€mp1\€€€€`€€€€€€(€€޹€€F€€V/€ I€4€€€V€€€€" eSs€€€€€€€L0€ €इ€€{€U$€€d€'X€€Ap€<€;€:5€€)1€€1€/€ ݱo]*€€€€€{€(€p€5Gc€RH€€€[€€$1&p€€; €@€=B€€#€&€$€E€"hc€p€|€ €€}€€<€Q
+dN€`€ 5'€ €€€ €ИT%Qz7€A€N€!€#€'€{€ܚ€eR€€?€€$€A҃€€€UM" €E€ޭ€€€<€€x€[€€]%u€tx€€€€€€Y€2<€€W€;€€m|b€€a€€b€€B€ш8€d€/€
+€€ڋ€€u€g€€>€€|f€€\S €0€€ }€TI€!^€>€"€€€;mp€a€p€X€€]€5€f€€€€%€€;dUDN €I28€€k€€€W€*€'v'€,€L€€ݼVZ€~>ć$R€€F€€K€€GAz€€€I<}€€ *_Ü®€j€€€€€€€€€L€€k€RԢ€€€4A=€€€W€€>nn€€€€€€O Hm{€€€€€a(v€2o€Lr€Z€B>™a)W€€K€€\€TÙ‘3€7€€€€`.€G.o€€€€N €Ó‡Zw8€t€`€qq (ζ8uݽا€ €€€5€€€€€,€€l€BI€vQ=€dW€F€€€€"a|€€€€€+€ €€€8€€€c€€€€€^S)t€K€€€K€:%X€:<U[€€7€Z€€f€€_ǯ<z€vI2@b€#€&€€ €^}n)€€F€€x9$€>;Ι€€.t€€ €6 M"'!€'€~€]`P0
+€€Xw f€H€€g€#€€€€€€€€5A€€J€€u€6b?€€X€€€€5J€М€E€w"H*€r€€€€€5€€S/€i€€€€€€€€1D€€=€S"€€€E€€2R*b€€|€cX€€€€t€n X?€€ €[6€ ly€6w€/€€€€ €€o€PÕ¢Bu0€ᠣؤ€€€C€€€€€€€€ip€€M€€><
+€€€0€€€€$€B%€*.\^(€€h"€ €@€€Q€]€€€>€€9@€€X€$n€€€€(C€€ÎŽ €€M(€b0€€/.9-@dB€€!N€2€€WN3€€5€€€׈€€;[€^€ch0€€R€o@€€€€€:x€z*€€€N€€00 €€€9F€N€€€i€t€r€€€€€€€tÇ€€Ìa€€€Z€o@D€O€g€xx€€€K€͋"bh8€€€M.;€aN.€€[€€€?€= g%€€N€€€€3€M€€a€{€@t8J€Ġ'€€s€?m5Nl€€€€€x€€€€
+€#(z€€€€jU€€'€>€€€€€€2np€€€€€r€€u{={Q%€€€-€W'€€€€`€y€;€3QQ€€€p€€€€€€€€1Ò§B€+=€A€€>F*€Fa€e€€n€€€;€€€њ$i]&€€4w"1€€€€޴€€~Ú‘ €e€ €R €l€€€€>€p[hqi€€ €€v€I€€<C+&Ý¢&€Q€€z€Vrے€'M€€4€z€X6€z€[€/€*€€€€K.€€%€/2G4b$2€€€X€€€"€€U€+€€€€c€‰€€€€vhD €)Ô¸~P€€P€֠€m€RiCK€€^€€Y€L=€xɸ3-V€o€x:€H€B€€'@€%€)e€m€"€O€€€€€€1p€Y€F€€€!+Ō€C@€Fߎ1€\e€x'€k€Lzp€€C€€€€%€qkS€-j€&@€€f€€€a lM€€€€S€QSI €ϡ+€€€€8€€N€9€A'q#r€€€€`J€ƀs€€ʴ€l€.€([Xie€K€K>€s€D"€K%W€BL€€Zq€o7)x€€[€^€?Ǿn€S3€ €€€ПR€€€4PH€*=ܘ€hR€€€ؚ%€$€U?h]€€€€€,€`€€@€€A€6€ŗ€€;/ò€€_€U€€€€2€3€1€c€@w€Ո€€€ €2P8€€&€UÓ @ß©4€€8[p€€Z:€€€€€€>p€€€€€.€M.€€2ґ€€s€h€€M}";€}?9yJ€€Tۂ€>}l€€€€ €€S€:€N€U€€R€-€AHP=€ ­}€98i0#€J€"^€ &€Z€€€b€€€ €€€}€l1€€€€€€`€@€€€€ € €#
+€€€€ۑ"€Z\8€€€€€€€AtäQN N€@€%c€4€€€W€€w€€*e€€JF€A%Þ¯;Δ €€€@€€€0€D€€x€€C€d€]K€8p]€€€r€1€€€€€Z*A€>кDX)D0yR}`€!o€€0€›€L
+o €.@€€uѧ€
+€€€€€Ŕ€€A €9obQ~€€€€€€:€jL€ €(€<€%1€€kp€€€;V€€ €X€€8046€€€N$€D€€€d<€F=€
+€ť€e€€u€zQ'\@€€>L€ €D€€@Z€-@|[)€€GPM€€.€V
+/€€€x€h؀#[€|w_ّ€A€€ €€s€<fQQ€2n逊€ j€p€ €"€OadL€ ]3€€€_u€$€€V%~ #F€Âxͱ_€€€ `€€€€/€.D€€H 0<Ë…b€€>u€€€/ )bCi€€€V€'[r!0€}`€€ W V1.Vv€U€N€€>€jM€"€M€€;€€€€€R€€!€]€€€r€€s€uQ€€€€I€€A€€ €<€ |G€ Ñ„u@&€p€Db€d€Kc€€`1_€c€€"€ݟ€€€#€€4€Î€€V€€%€y€5ZP€€łr]=˿€€€6€g€F€#€=d€ȣohH-€̜€&s€€i€U€݀€€z;<€€€k=€T€€€|€€.MSϿ€#y€+€€€€€/eߋ€po€P€M €€$"L^€€Nx5 €8€€j€ƥ€€€ €ֻ€€
+€€€€kzI*€€€€€€Q€)€[€€!€9"m#zZB€!€n€s_€€€ €€€%€€€€\\<€F€MwMÕ Â€Â€Â€Â€Â€€€€G?t€€5€ @€€DXD€€b€€[€€
+*4€€€€].€€€4oM 7€e€bU#€C€~€X€5$O>€€€€3€€€€s€C€Yq€€€€€Z€A~€ PQ€fxRXH€ )7;1x€€dgÛ´O€Q€€tvL€€ *€€.€.€€€&€-TiA€!€€*ͫ€€€€€>€€€€€€€€HF€9€€BMI€€€k\€€(€€A€€P]€'q€€€v"€€ W€€n€i€r€€€P€€€€aoV€€€€€`€*€€€€HkÌ©bU€H€€<€e€€€€€€-Å€€€€M] €Q"Ø‚V€H€-€€€n-€q蛔€@!€!€€1€€€⛳€H€€€€!Z€]Q€3€dw€P€׳€Ý €€€kcF0@€€€€ޟ€ 3Q€L€|FD€'d!€o€x€€€€i€€€0€@€JBu€€€|0TS9CU€€9>€'|€J€}€jb€]€€€ݳG€€€zj|\€€1[€€Z@FP4€€€ €X“G'v€5€€€€ys)Ù‚*[x€Q€€G@P€-€€.8€76€€€€€_Xd+{€+Q4€€€8€7p€P€€߷!€€€R\%€€]D€.P€DW€~R7 z€€G,€€+ǕŔ€#€€Ϋ €ނU€€o€m{!Ll̓€€B€#R€€€€.€(€€€˹p@€€w€D€€%a(€€w€€f,)€g€Rq€`Õ²(€t-€}€€̼€f€€€y€€wH{S€U€€€T:€I€€-€€€C€€Ù€j€€€€X EdQ€€esU5€qO0K€E€=l@€€o€ €1€{€€J|€G€€hgMO€€€-€€€ €€€€?E€M"€€4=A€€€€€€v[|€m€€€.`€€]€Ö¶ca€j H,€å¡"`€'A€3€€ƭV_w;€€€" 9€ƃ€€€€€€rZ€€€€€€շ€€J^||€€€€€d€NP€;€؆€f=z{ €€ G€$͗€€€džp€`€W€lI€€!%€€€€ *€€ܕ€€€z_€[€#€€€uY€䅅q€L/ȕ€€€€* Q`DP<
+J~C€x€€z"@€X<€tBѵ g€'€W€}W%€€€€€€€ €€€0€€Э€€z€€€€0€€gi€0w€ [€€)€
+å¡d€€],x€ٚ0S(€€+V€€€#[€€€€ €k€€5€EfϞ€/€:€€€€3€€€dEPN€€€A€-a€I€M€€"€"Kp:€{€€€€€X[€€€)€K€€ 7$€a€€ X€€¹1Щ*T0y€GR= n07€(€0H;i€€€€€C€€K€€0n€g€Q€€€9!€€€€PgZ€€n€€€€!€€€€€A€€I€m€€H8€%#BÆ™)a€€%E,9ÔŽ€€/€>€€€€€{€€€Aj€€e~pN€€
+n€€€€€€x€€jL€€€-€_€€(
+€€€Z€ ]ٵ€€€€€€€&f€<€€|&€\"% t€p€N€1€˨€€€€€9XL+fg€i/m€v€O€€qr
+%€Ď€^p€€\€#€|€KP€€
+€5€€€€%€R€P€€€€q1€€[w€2€ €uzXN€w€ €lx/1X€€x€€)V€Yׂ€€P€Z€l€€€)€€iw€€€€€\€f8`€ €4€€€€ €y€;QQ!+€€3!€x|"׃€S€ H€€4€€€$(€€ %\€€€b€N€€6xq€€w/xC€€€€€"]€x€b0€€R€z€;R}€€ ~€e*Q€?Ë–h€€@€€k€Hd€€DE€€€V6€€B%€)P€€€€@€~!€k€€Y€Z€€P€5€€'€t€€rv€€;€€€b€€É¢ € €W*m€€F€6€€€€r€€KT€€&€€xe€€€€€€€€-€€a€€^€z€€€€€b€l€€Φ€g€j€€€€€€€€€T%D^D€}€ܘR€$€3€€l€€NS8€li€€s4€€€{~€€6€€,€ €€€€€V€€€dH €nL€2t€-€6l€G€€€€/!€€€€€ꀯg€m€
+€%)€€`€€UD€;€B€q€R:vfX€€¤€WE
+$녑€s(ËF9?€&€€o&€€€€ #0€,&€€J€$6€€_€ /O€€pÓƒ;€Vo"€€U€L€€€9€QF€]€€€€2g€eJ€r€€ma%n"€K€-€ˈ€€€€€o6 €€€O$€€KxHLE€%5oh€
+€€6)CO"C-'€€(€{M\%.1€€E6€€€N€/€e:y=Tj€ܦ€€$ub€I€€€ *W[8€W€€b0s€€€\*€$8tG€K€€€€€h€€fD€O>B€€. €€q€€€€€€€€aB€€€&€VX€€€h0€€Bk0€иgÏ  €e€€ A1€¸O€€٠€%€€*S&m=€3€€/B€ ߀€€lF€ 4@t€p€€Y€P€(1bS€S€(vKQf@>s€4€eqb2€E€)€p€€:j€€NϲCj €-€1f€€€€€(A0€w`€€€hŸb€L€*I€=D€€€D€€G€€v€€Լ€ €k<€€tTR€€€2€€^p€€€€€ €ɳᦎ€€w€yi:C€€4€c€&€€& €t 7€[€}€1YH€€€8S€€€5i€€€z€€~M€€€
+€€_b€€€€U€€+
+€€€€€?€ג0€\€Hc)€€Y€€€Wl3€[WQf€€€0€€€€|D€€€€€*€V€€ €€X€€p€€Q€d€€(€[€€€€%*_*€€]€1@d€TE€€€'€€€€€€€qI€€€€1€€l"€€€€ € h€€bvX€n€cs€€}Dk€Éyʦh€c1€Y€€U€€€a€€€€t2[)è” €€,€€€€€€€]%Â€Â€í»‡Â€Â€/ZE €€w€Ƌך`"€€y|€I€€€JW€\h€€yZ<0d/€^LS€N€€d20€€ €)€€ɠ€€€"€€€€€€0g!:Ö©l/ x€€7;a€€" ,0Aá»Â€Â€"Jlt€"€f4€F€€€ ؂€€€!M€€]p@€€ €€.PNdw€#€€%€t€€€€`€e€€€W€V€€ €€ӆĊtӴ€Ö (Ò„a€$€€€@?܇€Ѵu€ €€€€0€t>^D€€€€€Q€N1€€€€1%.€{€@ €*€qH!-XZ|~q€l€lz€)Y€{€7ih€€!€€€Yi{€€lKD@H€ €€€€Y€M€v€€€€p€€€t"€3€€):7<€€€6€€$€,€€€€i€€" €€€€€€5€M#€ €`l€€€€€€€1€€:83€€€|€€€€B€Ρ)€?-€€9J€€4€i€pQÙ”pV€2vPF€€€u4a€X€M:EPLDA€=)€`"#€oVj€^€€­a~€h%X€ah€+€\E€cM€F€€€rƲ€€L€%€F€6€3L €€€€€À €€€q€€€€mω@€
+€wj€€€€€`€€€€€r€!Q!€€€€!Rc:/€l€€TA@F€€[€€>u
+ v€p=Z€€re€D€€dU€Ü€M'H€#sNw€#H€f€€€̙€p€€\ms€
+€ }à€'€R'(€x>€€/{€i€€€ׇ€3i€?€€PԀ
+r(€a€n€kY€€V{*c'€€€k€€ש€€
+€@A€€]€f€€' €€7€)€€€€77€Eoh€t€€Z4I€€bf€€Z€(S€€P€€€€€€)€I€sꢠs@€€p胢֟Pj
+€?> a<€&€€A€ €€1€cx: !h €€t€Q€€€€€5€€€)€ଞ㈄€D€=€€(d€S@€G#€€€ci€€TU€€n€3€M€_€+(&€괼*€G€€p€€;W
+S€€m€€€B€th€I€t€R€€I€€(2€€uŲN€$€$εLa€U€Fs€€€)fRX€€+€(€€=€€€y€€€€I€€€3B€€ăN€
+k€€=€R€€܎|Nt€o€€59€<u+|€€Hx€€<]B€€L€€€5lÃǦ€N/€C€€W€€<1*|UJ€€bGI̔€€€g%€!^RbƱ€€m€€€I€€H€€+€€€^=€€!€€€€€Ṁ€€€]6€€€€5€-€€€^€€=€d€€@;`sHy€€5ZM€.B€E€_€ r€$€\1€€€߆2$€%€€؅€%€€ €€@€€€Zh€€€`€c€UZ€V€€€jq€!€ Tb6J€:€1€€E€J€€n$`€ ;€€^€#p€€€@n€€Lu€R€rM€_€@Wa€€q€€€€:€ +3€1€€€<]€iy€€€€Hoz6€ €BLurF€€Y€€ݔ}€0e Î¥€{ i€€€€<3€h)P€r€€t €'G1€p €+.A €€D€H€€€€€is€€€€J€€€€€:l€_i€€€j€x€€€7€€?€€{€ڻ: [€C€p2€€€€€8c€€€€X€D"Æ¡X-n/= ?€A€1€€€tT€€€€+€€IkX€ƶx€++R€'€0AdP€€€]HÙ€€\€€€!€/H€f€€H(|VKŀ€rN\€pZFi€RYJ€€C#ɢ€€c€r€~€€^3Qt€k€€o€ €€€€€€DҖ€8%€Q€€9€ €&€0€€Ç¢l€€͔,:€ `€€€CL€RsH€
+€W€ €€{€k@€-€€3A€€BYa€€€%€"I3|€
+6€7H€j€_8a2€(u€~w€€k€AT€B€€2€€€€(€c€T€n€€)€€(0€€€C€€€€$€€€t€€0€€€€s€€€Æ»xpt:€{€ e>€H€"€Z€)€\l€€€V@€€fns€,€€€€ho€€€/#€€#&p€9€€€€I€€y€ ]€:€3€d€€€€€€€*J€€€/€€_€€,€€=€€€S€€$i_€F€€€€x€-€€€(~6€W€3€€€€€;b€
+€DLR€€€€R[€\€€虺˥€K€Ʒ(€r*€e€)€"i€͖Q€t€€€€€ €N€ €Ò€€€€Qg€€c€€q€€z$€푌€1vN€€Z€jU=€Ĕ€F€€c€€€€€W€nW€€^€€€0€€€2u3€€ €#€€<3€€[€€f€z' €€5€0O-:€t€':!>-€q€B3€€2'€glZ€z€€€€`€0€€C€kH€€€€w€bb€€[Ô¶}[ €j`€y*.€j€€€SV€€
+%J 2zN€€€€`Z€€€6_. Il€og]€ZH9)(€€€€D€P€€€€u€€Mш€€€€ڧ€{€€!€L€C€€`€Ɉ€>3€ñ.xsbE€Pp€€?€p€Y€٥9f€;7€$q€€€V€1(€G€HG€$Ì€€€€€%€o
+€m€u€TU7€-€€A€o€f€€€€U€E^,€€0N€Rt €€C,W€€F€L€€€€€ZA€€€€B€€se*€€€€€€€€€^€€N€HZ€m€YO8€/ 
+€A/{€€J€v<€€€ˌ),\ €€€\€€^€€€€վ€€/€€f€H€€Oz€€S€€>€B€c€€sV (1)e43,€̟n,
+Í>€>^€+H€€€2dJ,>€€;;X€€gu€{E€€€5€€€/E€\€€€|€€'€&n`€€)I»€€€+€€€g€€€€V€ €€9ֱ€͗€'86j€r€O€€%:Þ½>߼€€€X€€€€b€€€€€€€_€€>€$€€v€€€€1€+W6€oC€€Ch€€€-€€F€jL€€q2T€rQhÌŽR€"7€bi€K€s€€€@€€€€]€€€€n€(?€€Fb€€€€h€hU<*€€D€€€€€€9€€H€€.5€€€1c€€v€H€€f€)€€€Adj$€u€€y"€Id€€
+€€B€Fy€T NN€7€€€~/agP.€[$":z€Yb€€€€€"vQV"D'€+b€aIdq€€€i€€€€€€YZ!€.I<t<€€`€€?€€€[€D€.€€{W€K€€?€K€O€€
+p€RÖv€?ub€€€0+€€L}€A€`W:€C€€q€€LEՙ€€pyj-QN€mi€€€€ €,8€+H€€€>2€€<€g@€€€€€€€?€€€€€S€ €€€?€0h€€€€O bV$€t}€RP €lu$€€Y€€SY€€w0€€f~€€d€Li€€@Ps€1'€€€€q€X&€€€€€€€[€€0€€f€€€\6€T€€]L€AH€€€€(&€@€t€O%€€V€€b#ۆBjQ€%Z€€€€€!~€€=n3€,^€€>U€I)€"u€e€DvB:€€e€€=0€€XJ"€&c€1€3`€€is€``'€2 €€q€"wX€€€h€€"€€€€J0€€€€Cy€€-L€S;€3€/€>зi€€€gM€€€€€€€€€Aɴ€€€€€,@€7$€€B€TxBʊ€U€E€f6 €€€€.€y€€e€aÙ¶[r€€€€€€€i €&H€'H@g3J€=€'€s€C€M¹€+€fR€s1Ù¯Ö“€ _€I4ñʼ1€г€'€~€€f€x€€€€€̒w€xs€€ܲ€€'€"€e€€€€M=€{z€€€€€ޒ€#€oPak€\4<€€T€r+iU€€>YÒŒF€€ €€p€?€t€#€HF<UKm+€f€ui+€€2ßœS:BKGh9u€x€+>€€9€0€€V€€€JYR\Ï€€€I€ٻLÞŒ[\€1bL€~p%J/x€3h€.9<€€€6€U€m€ZP€7€7€MÛŽ8€€€€€€>€€+€nVnf€#Y€_€€€€sO€€€y_<€€y€€4C€€W€lF€€u€1€€v€€̌YY€Y7€€€T€J€JVIt舊}€€€€€S k€€Zk€€;€€f€҆€:€€€֯O'qc5CYkʽ҇€i€€€€K+€€€b€u€€€€ {€€(̸Ei€€e€€(€ SW6V€|#€€€a€,ju€€Z2'[€€€$<^€€€b6(€*€€€€p€"€€|€€€~€€E€b €a_€|€x€€6A~€5€78%€L ?€"€.€tǽ5€)Oon`€1S€3X€vr趦€€€€r€€€€€[zÍ€UǬ*€^rAed(€€p€€€€€€nX€€€绋€gq€t€잭€€€€€r€j]€€€€g€€ E€((€€f%€"€ZB*u<€hUJN€vy€Ƃ€. /€ukd€€]€1h€€€s €€GÆ q€B0€€1€€€喑Ki€€€BBwG€€=8Bhy^€4€Œ€€€ ٘€٘€€€€€j€=o€€€'€I(b.N€€€sAф€X֚ݫ_y€€NYXN€€€€€€`€`#f€P€i€€R€J€€€€€8€€=€€U)€DAL€
+€p'€3€A€E&€)€€€€ij€0€1€H€€!H€€€€b€€0€(€€!0vÙ•Ý!0l€˪€€€€F|€€&€€.€€€?€€€ €"=€€I€€S!N5€$€a€€€D€,o€{Z€ۈ€€s€€€㲻Zf€€€i3ش€€$€\zÈ•U€[€|€€h€R€€#P€ޢ€€t€€€€€Q€vi€ €^€€ޥ€€€€€NMH?€€:>€
+3t€Lz€"f
+€€T€€d€-€sҶ€D!5€ €Xe`s€€€Ⱦ€€}t€€IO€9(€ €€€€€>C>€€€€J-:K€g€€€`VT`kZ6€BD€Q*€詫€€€z€v€€]Օ€€I뤂€=d.ß F€€€/€r€`bC/ €€$€€€€€€H^G€a€€€B€d€€€Ú« Å«`]€€r+€€7€€|?€€€]€€l[€>z<€€€€€b€€K€ȶ€€_€ >€€^k€€J€s8€N$€€€€y€€'€y€€稔€€€/€€€X€඲5€€€C€€i€€€[€,H€€wL€€€€€€:F(€€u€~%5€{ZD€V€2]e(Y܈€€rQ€A€6f€"6`/M#€m€€W€ NO%Ê€€€AK)RQc€ V€V€€€m2€€ €~€V?€L€€kƪ€€w(U€€2€€7€€q€€€d€€+H(€v €€€f@\€j€€€€WqT€+€8€€|€€€€-€€be%€~Z€h€€xC€€€€€€€€€$L€€€:€€ €€€€&`€€€ߑ"U*€ui€;J€€B €Eا|€€%€뙀eWRN€€1L€K€JŊ€9€€X€€Ȍ04#€r-€c€|-+€^w€` ~T€Tm€od€פ€TET€€€€ڼ€g€€ eO€5ʑ€QߟR€€€P0€TEu€€€€!V€€€.€€Qt;Ñ™M€๚€h€€€o€Rb8'u€€€€€€I€,Õ¾l€€΃.€`K€2€€€€€.٢€gb@€Qh€d€€Ԭp|€P7€€€€a€=€€€ =€ 5,%€<Y€€P,€€26skaӃ€Y€a€€֭€€=)n€ے/€€<Z`€€€€QxL€"qznx€wN[,€l€ۙY€€J€€€‡€€{€€ž€'):€€€t޾€€€E )€€h€N(€5͜€€€€€€N€€€€F€€€)j 7˽׺€-€#?€€€I]€€€€B@€B€FFm€ߙ€€ޔ€€€l&?€>€0mO€ZQ€€€Ĕ€.€€7G€M€€€ܤ€€Vq€Q€ΡÉs[:€€€€x€R€€}€€€ E)c€p€.€Y€€ €%v€€ÚO€F€8€€`]q€€"€€€€NQC€tp€€€,y€|€€È€€Q/€Ib ?€€€€€+r€4Û­QX€o€?€€;m€Qf#C.€U€q€€{€-€@€2€[€Bx0ʜ€€,€€€€€€€€€€'3€8g€g$€:?h€@xUЈ€ €€K8€\€O<Ö’-€pr€€€9€€€{e€v€UÕ­€€€s€8€€\€€WO €€n€€€p2pb€b€n]' €€€€& €v,!o۾€o€8€m€ €1€€€?I€€e&< Ù†_ €j€™€ [€\N€€€€€€-€€C€€€€€Z€?€€g h€0Çš"€€€;|€{!€€€(€€€€€€€€€-3Ïxjf5Y€Z€€€€h€x3€L€e €5€€€€%J€€csrr€€€D9Û<€H€€:€€€*€{&f€aF?Æ´€x€€)ww€Uw#8€%9<Uy6€€{€€€€€ ͈7€i%€€€€€€-E&€€E€Ru+€H€TM€€€P\€€
+XY€€€€aMڦ€Ҿ*€€€€€€€K¤#€PKP=€€€M5@wBh€€`C€€1b€";€Ɯ€<1€Rw@I€€€J=`Z€€Di€€J€_€€€€嬩€€ €(€mÒ„?€€€€€€DgC €€€€€€+€€*] €j€ €€€€.€€v0€Ux€K€€35€€€3 € €€[€€V€€€€{[€€@v€€€€€"€€E€4|N€K€€€€€O€w€€€W7€'+€€€{.€€t
+€}€€€[0€$€s€€€€€€€6߃w8€,W€€($€TM€%€W€€Tc€-€ €€€€€9€€쬈\60HC€€N"`€x€I€:€€€Q €€Pt€€j€€€a€€A€€L€€€€c€_€9Y€€Ϯ€€€.Þ®\€€@€€A€h€gʊ€€R€צ+€+€^€€€€€€€€8"+€*€€T€pQW€U€5€€}€2€€ €€€€€nr€€CÒŠP1€€a€€€€7€€€|w:€€€€Z9€€%€b€€€C889€7€€H8€,€€~€€H>8:9€>m€.€€€€€$i€€\€{jX€;u €$€€5€T€p\)ÄD5G)€€€€€€wճ€3€8K€2l(€€€r€lÆA F€#€m€€€€"ÃŒGÛª€€?\G=$9H3€€€€€€9-€€J€€$rt€€€€€€€€f€€€€G2M€€=P€€G }€€M€€€L)g}€8€€€M€\ €i`ǪdlE€€€hq€€2€B€€<€€€[€9N€F€€B€€5 €€bn€iAs€€€€€ €H€€€(%:€X-]/€ݒ€K€€Ö€€€€€E€€y5€4€€€ o€R€R€9€I€h€€qv€<3€
+Spyw€€"45€€VبX%Ü€€=€/€€=_€m€€€€(€€ €z€+M€€E݂€€(q+€€E€O €€€€j3YK€C€ܨ€€€ ؼ€r€€)ma*G€'h€tp€€€ŷ(€€€€r€2€b/b€3K€€€€€ռ€#ԟ€€D€€€h*h€€)H€€8€€|!c€3€€€i-€€€Uo€€€kkÛ©_€€,I;Óž(4€€*€€€I-€€€u€c7r€Q€v€Zd€4€€cP€W€€!5~€€€€€€
+€0I€y€x"€X€€V€€jQLBhc€y€€[€D€€+€mK€ˆY€€ad€€€ֿ€|?€€1€C-j2=€C€)J€C€€€s€M$€€!€=Mu€+€€I8€O€€€Tl€€RV€€€io€
+€5€€\Jr€€€€V€5W€\€€Huņ€!€+€€€#S€i;ʼ€.g0€z€6€€6"€ۈQ)€€€€c€&
+€€€€y€v€it€€rSt€<aE8B€ug€90€&€5€€€=€8€€€wߕ€!€€}€€M€1€€HQX€€?Y%t€u€ɑ€€L€€i-c€T€€€€€Ӧ1FÝ–€Ue€7vU€4ě€S⓷€&1K€€UH€4啴€9€#€!Q(J[u€@€€€½€Ѯ€s€l€€3€g]n×€€€R€L€€͔€ €=?€$€j€|V€2€€+w€€€m€€x?€€V&ј€€C€€€€B€€;€/ €8€€,LY,€?a€q€C€Ͳ€a€*€6€€%!.€€z:€?'€ &€O8e€!€€€€- €n€[v*ՠ€€aI(€€€ħ;€*€€u€€€i€€xG€%L[-_y€Z€€€€x€€€0}h€*€€€€-€V€u€(€€!4M߼€€€€D€!€€C€r€b€€È2ԗ€(l€€€€q€*&€N€€€]dU€"€R^€a€€€%%J%d@€€€:R€#€€€,V€&€`fv:€€N€€€n€€€€R€XK>€:(# ܵQ€€€/€)X€|Tn€4P€Zra€\j€(€€Z€מd€€€€d€€.€cvs.:€€K€€?€2€eh
+s€:2Y€€€x€*€#€€€3€ë°o+€€€€.€Q €€G 7€€€F€ €€n€€€€ 퉑Uo€€Ѧ€
+€€€€€g€€&€a€€3 ƔӜ5€:€*0Ii8dfyܕ€O ::SN4Qͨ€F€ڶ7A€5€€9€"`€€lRG€?~€?€€€:€l'€t|€v€€a=€[€w€€€€@m7^€L€ug€€€O€€g€€€€s€>HGtY € BB€€€K€€€z€ѣ€€s€!Ԕ€€€D€€:€€i€,"€Y€㊿€€s6=€4B€x€€€€D€€w€€F0k€€€€J€€SS"€€€5€€€€iX€S€€a€מo
+€g8€Y€r#€€€€ug€Þ™c€€ߨ7€€͗€€€€€f€€€€€€n€9€6€€T€@€}tYUTJ&€€KUQ€€B€€mc3[€M 똶/€€€t€2axE€€€_@€R€€*lj€@d=€,b\€€€€€J U"H€€€K€ €p€E]/R€&€@€€`€[j€s€€€_.Qe€€N€€€€€;€i€1f€€h €8r€€€V€Í$€ 0€2€€€€€yR€A€LcVr€lvA#6Ѐ<G€€€€[Zf0G€€l€V2€€€
+€]€€t€
+J!€Gq€€ÄHO€€*€€}€€€/€€WMm€€~€~€oF€ PQ€M€€D€€?Ŏ€€€ €€}Qz,€€€W7€€€€zL€€€Ay€\€€ʖ€}YGG€4€Z€€G€n€€€̅€_€,€€5€€€€|€€€€O€€x€€5*ϡ€/*gpuwy&€€{ €€g€!€€€€^€€X:+€€ €ݭ€€XZ€f\QXf€ʥn=PK€€N€ €S€Y_w€€">g!NHz€€€€€€€[€z7€i:€`€D€€0€d€€€€fܣ€O€A€\€€€9ܦ€]Q€V€€€€€€€
+V€ئ€4zz€€€e€ׯU€ٖBE€vV€G:|kd€€€|€z€€€I€p€n€訕"cg€€€{[€€€]Cj€ €€v€I€€ €€G`Zz€+€+€D€€€;€oP€Rw€iTl€j€€€€€€Tu=ڊ€€€6€.€_€wi€€€€4>€€€€$(p€1€9W€€)€P€$$€€<9€*€€€€7€€€€H€€
+q €€
+'%€€[€j€5Yd€€2€
+0 ;€€ܕk€€ouݞ€לD€*€€€€G€h€€€D€€€€f}x%B€:#Qm€!N\W€JT*€€€YQ]€]€î‚+€F€€€R2€Æ€€5€ÌӀ+€€KDU€0E€€€€e€R€:€ÄSiÒ¡€gW€K€€€m4GÚ€Kk€€€ nv/€€€Sl€3~ €O€-ǹ€€€€€O€p€€>).GU€€€!€€€m;J€€€€€uC-€è‘_€I€"€<:v€€go6<€gi€&VÂ€í«¹k€€€&e}€u€€€€€€€$R€€0€ ] Q|€?9€Y^+€)^€€a€]eԀ€;€!׫€e
+€ M€€€€oC€€<€€€€€€L€€€P=w`5,€Ya€H€€N€R`€€€re€€)Š€=€€x€€"A€+/':.lh€Y€+€€ʎ€:€'_€c€€€€€#s )*€€€6g€v€o¾€iŃ,€€€€€€l€€*4mX€2€s^€ݷ`€.)€k€$a€s\A€€€€€€WvZ&€€Ew€€€€^f.€€€€p.€€€€€b€y€+€€€€€€Dm€€€€†€Js€4€u€€€7|€m€͙€€{€=€€€G_€€€;€?€c$K€€C^×€€€p€€Feu€€€€륭rE7€}€€€€;€€€€{€€€ଞ€T€}W€€€%a8€€€€€"/.€€Da€v<;<€€€/Z €r€€*t€€€€€€t€9I€O€uk€o€€n€'p€F4`M\€€6ʸ€-bSU€L€J v€R€€€€I€€t€€pa€€€ v{€췕€€r€r€€€€€€PV;€€jÛ^€€\]€€n€€€^=€€€˴yb€2€€'c€ -€€:˺€€€Ap-€€f/€€.€€€€g D€€€€8€€D€€€€€3€€(t%ͻ€€boV&€) W€€]2`O€€ X cL@L €(@L8€€€P€€pUc€€€^-€€hL€\€€`€pVZÛ¨~jgf€|€€€fdo>]&%/€€€9€€€€€€€Km€€ €€€€yq€5€€€1Q!€€€€j€€s€f€€€bÂΕ4€*€E.€p?€8€€W62-)€€€uG€€€LÌ„-$€€K€c+Ap€€ fvB€€€€€b€y€Q:g€€/€€Y€€ €€1J€s5,€€ZK@€€€€!-a,€€Q€€€b€n€N€E_€€€?-€€€)€ €o€€2U>€Z€€€d€cӖ€€€EEU€€L€*€@€€ €€|€5ܷ€A€,{€VȽ€€€€fh€€€€. jm€€€w€I€Ê‹]€€€€n5 €B€]€] /€€7€TÅ¿;0€t€€€~€EC€X€.@€hZd€*(€(€k€⚻L'w/e€>eH€㰒L€U€M( €\€€\Y€€qTz^€jV€l~€€ €€€€€U€€R€y€ϒ€€€€€€€€]o€€€qV/t€K€€€€_€€)€€{W(€!h€€?€€`b €d€Fm€'ru€€€p
+€€( €~8€€€€<0€€B€RÖ¨€€€z_WKd€€€€€€€€€vY€€=€A€N€€eg€guӭǸF€€U€€=Xu€]:AT€€ €cr€€0€f€1 € €Y€X*
+шo€T€€Y€€Y€o@€€€|€€€&€2E€[ €€€€€ͯ€€€ €€L€€€€€€€€€€b Â€Â€Ç 7~fp(P€H€w€€( €[U`€€€jz'€lgl€>€€-zh|X€O>€€€ €€F€6€0l€>€€€"€QF€}€€€ZÅ€"€€€a€€1€Q€€떰s€:t €€€€V€M€)€3 €^€O?}9€B€&5€€ك€.€€x€€€€o€4€q€a€!QIG€€€ڛ€+X€n)j€(€€\UW€ST€<€€(€u€€N€s&€€€쨀€7€€€€ƃ €€€€€€€€A€€& €fU€`æ3€&¢[s€'R0€€€€€€;k€€d)€`€€j€
+)€€€€€x€U€g$|xq>Lnq€j€€]T_€`Mَ€ϼ€XQ&€€€R€U€EE€\€jR€€ﻪY€€€i0€8€€€r$-€€€€)ow8€6EJ8@€Z€mU€€€€E€€RG€#;$€nN€€€ @€f'mUV€V€X€Ή€0Sl€Ƞ.酔€€€Ⱥ€P )Ҭ€f€vπ€€
+€۫€€u;€€€f_€€p€€€9W?€€€€Az€[O3€ÈŸgL€ezϧ+€€€€*€€€x€H:+€Pj€VZ€#-€€/€€6-+}rD-O*€€€€€U[€x€z.5€€Q€Pİ€p€EÍšM€ €€;€-€*v`bf€€€;€ړ€€H€/€€€P€{Õ—)€€|C€h~€ҵ€E€€8€Z˒€Jgt€x€ F€ʴ€mqq€=€q€ €9ľ€€€€*<€€€*€€IÛŸYt€a€.€€€f"w€QԲ€z€#ڸ€a€_$0I7€€€n ߸r€€R~K€z€€€Y€Y8sh€l€€a#€^2 €€\€E€€€{
+_€€€€-*€€€a€Z€€ŗ@€x€€l€€Վ;`€6{€€€€€n]€Q'+€€€€;€€A€€€ €€€L€€p€€I*€s3€€Sw43€r Ze€Y€€€{€€nS€.EG€€K€€€q€f€;€[ €€€,T€C86Xr=6€€E€]+^^2€€韱€€€€€€€t8R€R9O(€€€€PY€ yw+€€j€€+€ H€€^€Í$Ńu€€€€f
+€€€/€^€ѓjyڳ€€v€4€(€€€KÌ€€\
+8€'€€€  \f€ L€€€€€€}€ \(€€Y€€E€€€H€>€€}€̙j"BW]€€€_€o€€4€€€^!ObKw€€€€€j€~€*F€7ll€?€ €€€X€4€D€l/ʧ€€€S77~b€€€{i€[€€€€€N€z€€t€€b€Y€€m€)J>€Bֽ€€€N€€€€8€lӒ€N=€€]€€|=€€o€€'€]3Gw€€€€€€t d"€€. €€͌2€P€Z€1t€€IJ%€q€€U€AÉ q ]U€€ €$€aG€€E€€€s€€d€Y€yÅ€?€€ €jL€€€€,€€€կm0€€9"€UTb1€€/€_.€€€h,€€3€G?hqqso€€€€N€€v^€€0€€€2rr €r'j€=€€QKHy_€a(u€*+€€€€€€€€€€€F}€€€[€c€€F€€"€VC&f€€€€€€€€|€€`€Ș€€n€€J€δߢ;F€€€ƕ=v€€*3Y7€4€,€\v€€"€€€€erDÔ€€ €^€$I"€QlaW{=€W €€€€Оl€?€UQ€€O€T€€h)€€€BiHF€ j€€>N7€€€Zy8€€I€nx[€B;€€€Gs€€^€Zd€;€ē€€€€€€ 1€€Ύ€€\€p€€€€€l5ZbO€o€Ghc€€$JK€€ €-P€€Q j€€|€z€R"€€#€2€&€€€F4€ €€I€O€¥X€GB2,€€ €ugT€&^€€!d O€3c€|€d{€€€P5€€€€T€€7(Z׶$ .€x€8€g€ӧ€G€€A€G€€€€€€€a€€a€€OX K) €€L€&€xa€>€€€€€€€€€m€ܗ €€€H€WV̕€€€€€€€U~s€6€€ۂ€#|€€z?€€€9€%€z€*1Un€€%€.€F€J€€_€€!€€s€@x€€€i€L€€€Ԥ€'€Kq€€t€€/€€€r-€€̀€ F̟€|R=€€€|K⡻€€€*€8€~-€<€€)N€€T€€M€A€~IÓ.€N€Dbç¡‘ €€€B€€€̒€;€^W9;€€€€€€€€€w€ €WY€h€xÞ€€1€(;S€|_€€€€i€€0Ç€Nز^o€€\€€:&€€€/€€u€o`Pmad€z€e€eg-Nt€ػf?€Hz€€y€€€sk€a€€€S€€€€€€€€@€<0€f€+1 €#Ü„ÎC€a.o€€t8fG)€"€€€€H\.€Q`R4e€<€€3€f=1Ê´GN€h€€€X€=€€€
+€Y€€€E€qU€.€%Qv€IP€€€nND€€Q€q€4€Kb€€Po€w€€€iʵ€ѵi€ €]€CuW5Br€Z€€o€€9€ y3€@€€v€@M€€H€l!€€tu€J€Pȗ€€€€"*€€ uo+€|€/;€€rN€
+€€ݛ\€/SE€K]r€ €€
+€€ q€€€$€€iD€޽€€€Na€€€€€€€.d\S€€&ݽH(8€€F€€€e€4xw€-€€€9€ǭ€€P€€€€€8€.€€€€€€U탌x€"€€D{:€OɈ€ĥ€H€X€O€B€€"€€=€xhtq€-ay7|€€€~e€€€€€Í€Q\'t:Zx€d€s€€i€B€€]€€€d€€7€€y€€m€€€€€.A€€€r€€€&T"3wp€hK0€€€~€€ljJGu/€€h€€€€SA7
+€€!Z-€
+€€ޤ€ €€€G:5€os@ &€€€€C€q€EK,q€_€q€€Y€:€€€€8€.€€L+€z€€€V:€€€€€1*€€€€€€€gZÏ"\€U€€€€€`?RZUE€€€ʉ€€€€€?`]x€R*'€€S7€€x€A' €€€€ꄣ€€I€€iˋ€Y,R\€3€m5ј€€€2€€y€ ^-€€^v~g)€€€iZ*#€J€€€€€Y€€9€FE€1%€N€"€t€ €€dH€€:6rMJ [E
+€€ €U€€€q€'€€,€€0Ӭ€€€€0€F-;€0€9*; €€>hhT€v€-全cnj€€€P€8\RÆ«j k€T€€z8€€U=€€R€%}4€€<€k€€b€€€lu€€€f€N~JL€9€;6ZM3y€i€€H€bV€€]YB€€€€€€Lf€€€€?C€€|.S€€aY€€€€€€)c*8O€€"oJs€u€`€>€|z€€֗€c)߫€E€€€#P2@.c€:]€ %RBc€޹€€Z€€i€€;€€€€ €-`€€=}€€€€R€€4€B€&€€
+€_€€1€€€€P€€JoM€€€€T€ev]{€€€;€+€€lDRv€^B@€€L ܸѭ}€C€€€ٕVbX[Yo௣€x¾€^G€1€ €ܲ€€Z€€€€€b€O€€f_€+€*e1€€DZ€=€]m?d€€V€€€[e19€€X€Z"U.\գ€€|rr%L€<o€խϚ€€€€4€€€ep0>IS€€T#€€€€#€z> &€F€h_€€€d€€€;N6€€Q€CC€€w€8#NTI€F€€€˚€2€L€€3€gnP€u€ǭjL-E€€P€€8€€€o€U€€€€P€i€€€€u€€€€€€€[+H€}Ó»G€€L€€W€€€̺n€€&j€€€8€a€C€ƥ€9€G}O€+€qh€[€j0$€O3wm€b.d€wb€€€e@ q€€€:€Y€€€Gw⧞€z€€€7€€€€*€r€g€!>f16K€€ €%s€€jHP@v€$€€€g4$€*€[€€#W-9€J€,N€Û€`€͙€g|€_€G€€-XJ€++€L€€€8€€7€h€F#0€y}€G€€€=€€q€€€5^€9;€w ܳ€€€P€€U€€€i"a€=€A€€uD3,€€`€€f7Q€€€€€v€tt€€Oc€€€z€aIYZ€>3€@€P:s€L/€+PP€€€€!€jƠ€.€€€I€€€fÙ¥/€€z€.hd€R€E€zl€:€€€H€b€€땩Ì6€b€0}/-€%€€€$€€Q)€€€€€€V3؃H€[€.U€_Mo€€€€X(€€€€€€€€
+€€3€€c"€_€€y€€€€"€€Bo€֫[€€€V 4€đHV|#=St€ €€]€D6€HgR€w€R€VU,€'\n€b€)%€€€b€\€€€€o€€€C€€}V€(€K€A€€/€€2€5€€€6T€:€av[Ø€<€€3€€󀀀v€€"€€ m€€1=C>^Ĩ€\b€€€€€€]U"€€>€€A#€{€€€
+€€S€€!M€&€\x€€€€€ȕ\€0k€€K'€v€R€$;I€€€€€I Q
+€F€€D^€€QfI€€€Ƅ€€€m€j€dR9€€D€h€s €€€]ݨ€€=rh€€iI€€€<€€G€€€€V€€q€€€6 €K'€y€€a4€€€<€k€€€=€|€XS€E€g€€€€d €,@€8€'z€€}p+€b€*€€€€€€€#€V€=€R ވ€jKL]€€€€x€€t€€"%€€$€€+€ԕ€ X€It€]€€O|T*dL€+!€€€€dm3M€€€€%G€*€G€a€€e€D
+@j
+€0;€:€€S€€€2S}€#€S'w€I*=€
+d€6j€€€k€€L{¬€€€€€A€Q€€յ8 P€4_€V€€A€€€9zA)Y€€&08k€€€/€€€€€€€€€L€9€€€€€1]?€I€€€€€€]€€(9E€€g O'7>0€€\€'p€TSk€€d€ݫ€q€5;€€J!n€€+€sF€€g€x€€€€€€eޓ€€Ǽ€!W`€z€5L?j€€oc€€sR€€€€߽HV ª3€€€t€t_€j7Ey€€€€9€5f4€6€€D€P€€7€€€H€eɔv6€€P€€T€H|€U€€€€V€€;€ҫ>[€8Y€qj€€_€|6€ تFOٽ€8€4B€ €D€€ۅ€`€€Tԇb,€r€€W€€H/€"(€ ʹFz€O
+P €Te
+€€\3€€"5ܣ€€€g€3€€h q€€r޾€녅 €1€€kɪ€€mH$.€Gs{€`['J€DN€€€€+yu€€€€€e€€€,€h€p€€G€€>€€€3€€€€9Y€€ {€€€€;€x€€J€pq€€`=€€€f:/)nѧ€€€€€5€\€P0€€€€A€€€ €€hh€Io€.$€;c€O€ €€A€€Qf€€€€;€€z€$€-€b€Mf_0H€€c€€W€€9]€u€€a0}E€'€L@€ Ù• €0إ€€b€€O+55€dg€!€€€Ü€€€€€€€#€€€vF€€^€€ʻ€Q€€€€2€[€€0€P€/€1€€īoX)€€Œ€€)€+Ԉ€€X€€€,e€€€[+%€€)€€~€€€€@€€€€`€€h8€X€z€€C€€m#9€€pl€+,€XT€€=€;b€.€€W]€€cÉ‚3€€6€(ٶ€€l€mn€=€€€€3€€€€€nj€u€76S€5€s0P€- A9€€€€ RTk€€Ù€€€Ȭ^;€?
+€€?€<ԓ0$€%T€(€€€€€€€€o€:€R€_^€':€€€ €96€€NY˯€€€€€€)€€i€€€_€€€€€XW€p€V€9€€~EלxR €Ϳ/€€€b,Pp"€?t€D€!J€YE€€"€€q€1€ 
+=€€z9€D1€(€b€€ €€d€€€€`d€d€R€h€€€€@jÛ¾'y€q:€}€€€€4&€€€€€ €B€qC€€€uRvf€̔€€C€an}O€€Ɯ3€TÚ½>N€ 07€GZ3 €UÈ(s€€~€%Mz96C€Δ€ə€€iZ€€v€€]"€€p€/P€u€?€€€{€D€€y €ͩ€^Ŧi0P€I=Vg€€€O€€€€€€€€€€G/€€:€€U\€€€cS€€lQ€r€UÙ§I€€u€̥€ne€T€€€Q€€,€Je€€€]*€n€w
+€8nz €€؉€€T€€€\€-&+€€?€€ry€€€U€€JV€\0w€6vw€€€f€€€;€]€j.€€L€[€;酼€U€€l%€;€j€,€n€€€€z€€4€€&€Wv€€€oO€€K,€€ĒߨT€e€€€]_€c€Q€€€€V€€€€?р€€€Fi{qg€U~X웸€˻€€€$,€€€€€€iÆžH)€€
+2€€Jn€fw€€!€€{€ÒaY@€:€d€€€"€u€/V€€ GC€€`€
+€p!€€€k0H2dd€KIl€JNS€€€'€€@€MN€€:€-YÉ´W€'OW€€1€€€upI€€2>dY€$@€ I€€)5€(=€€€/€_f€p€€d€€€ €?l€uL€uv€€[f€v€la€€lj€N€ €%if€€7€€5€€€~xD"€S€€€t€X€^@ 2€€J€X€€ *€€€,F+€€€ދD€€.?€€€€€K€€w€€H)€{[or[€ш=3C€€ =€ J€v^MzZXT€€€ky€`€€T;€€€€q€€€€$&€€\€5 Z€u€€€€_€€€€b€#€€;€€Dl
+N€€€€/€€€€nyc€,€K €€\,m€ll€ €[€€€€WȽ\€€€^@€€S:€€[€€€=O€€c€€j€€€U(€€ʖ^`K€l 4€€€€€€=[z€€W€€/J€y€Ç3€€ €€F€€€)€€(€]€,€€ɪ`w€€:6)€T€)M€ؙ€€7€D€€€#€€€d€€€€>@€L€x(€V€b€€!€
+€€€€€? €€€|ʇ€ €€€?@[€€€gf€e€€€3€€€+oxu€€Dn:4Є€=€€€aM€€€€!€€ €€€€€i€€€*€C€€€f[€€€€€€€w€€€€€4€€A€E+€q€jn€u€€€€€"€€5€€ۇHM€€€€€€€;Ŭ€_|j€aY€ƶ€€3 €€
+€€€€€ €>8C*€€ٙ€€^€€?=n€€€€d€€&zK3€6€€€=€€T€€€ Z€᷇€㴒Q€€-€͆€€D €€%8€<g€.;i€v€\€tf€€€N€€V€€n€€€С€ €զ€G€v'€[€@r]€€ €rI€€€€€ €Y€w€)€€€€4€€nVU#€€€Çz€€@€€€B€€\€'2€-ƵE€€u€€€€T5MC€)€€z€€%ZI:€€7€€ C€€Z*Û¥[x(h€€€E7€€x€0n=€;€€€y€€€s8€_€)Ǒ€PIW€ 
+&RkK~€€€€d€0V€`ק€=€€€€p€€;€€(€€€€/€%€C€€€<€€€!€€€€€€{€€؜€N€€€€d€p@€€U€€€s€//€%€[ÔZ€DM€€ΑO:-€BU€€€]€€2 ;b€K5€s€€4[€A&]zRLl€}€€€p2@yC[€€bF8Qz(€€XV€€>€€€~€(€€`€€€€y€€€S€€٦€€€€A€*€RJ€€€˧€€€€D€€1Ĭ€&F€Y€ĺ€€W€€$,,€7€€€`€ €@€ €@€€€_€€€O€)€€y€\€€˿'€€€PR€€€G€€€€€€F€€0€€€€MaN€:€€€DP€&€5~€€€€€€J€€[€ؘ€€€€0%€€<lb €€€j€M€€M"€€€€€+€)€ˇb€€€+Ê€=€€€>0~€€Py2€qF€€€€_u8€ €€A€F€€€4Lz^€€€€s|L!YHHaTL€€\€€€rR€4€PL€€h?2e€€€€UYf€€€€>€׵<J€€̂€€"^€_€z݀€-€€H€Þ€€@€(IudF5-€>M€k6€jsMCF|€d
+j/|€€€* W@p€J€€€€€€.€€N0€W€€Ù¦yc8€€€€€€N€7€€Q@€€C€€_€€€€€€€€€#€d€<€[€nr&€A€r"€€€€€€€Ì‹f€€?€x€Z€€`€p€€€€z€Z€)E€€€€h>€h€_"€€|W€a|?€€€k€€€€)€€€t?B€€€Wv €a€€+d€^1€;€D€VU'I€€V€€wHCNagu4e]Sl@€9€€ V€€,k€ॳ€€f€m€I€ǵ€c7&€€8lW€!Â€í³™uÔ€͙s€€s€€"~€€a€€€€€o'Yk€€A€ZÙ¼O1€i€E€MKf€UXÄŒ"VHG€_nr€6l}€O€€(€€€1€€pc€€€€€4٭€€€€€u7€AƼ"€€+€i€IwE*E€€:€N'€€(b€€ €o€px€]?€€€€€€€€€€I€_€€o€€z(sC€JÈ·8H€€>X€ة$€9€w€iʔ€€€Î ņ€€]AN!T0 P€߲\€~€J€€U€€}8€L9€€€L=€€€r"€V €Q}€€€c€€fE d€X€€€€€ݾ€€€]€€{€€€€€'€[:C€€@Q|€€€€€g1€€€€€€€€€€€+i€c€*o{mY e€€€€N2Ö–u€[€€€€X€1/ €€uf€€R+€6€V'cU€€€ǽ €€€v€`€ܲ€€€€+€€€€€jg€€€U꒼ϴ€aR.€€€B€D€锴jJ€€€ 2€a€̛xZ~€~€Q€€'€.€VY_\|X€€€x€€€€€€€Y~TF30€?€€€€r€€'€n}'€€€€€t€xw€tr?ʉ€€nĽ€o€€ €PM€G,€€€€€Š€*]€€€€€|w€€€€N€€Yd€€f€€€€/€€Wx€€€€DeX€€€€¹r€)܉€€Q€€8€k>yC€@€(€8€€€€y€N€€€w€ }€^N€-@€@É€yP€'€C€g4c+8 €€€?€€€Z€f
+€BSH:€€€k€xӷOݿъ€q€nŨ€Ǫ€€s_?>€€Rs}>€€Ȫe€G€€?€!€€€€a€€€€€€E€€A>€€p€€€L € €€€€|€an€€€€€Ω€€A€(€VTq€
+€€€€€J€€€A€€Z€K€8€€<<€€|@€؃J€€}Q)V€W€€)}S€€€€N€€X€€€€'Ab*€޿c!€h€€€l€€G€€€€€Tr=&zO€^€€ω€qkR€u€[_-1€€€g€€€€Yl€€€€B€E=Q€€€€€€`X€€€>[€€_€€o€c&|| €P€€€€o€€€I€€ €Z€J?€Íb<€€YD€ǥ
+a€€€€,€€.€pJ Qu€\€€'f€€ €\€e3€r€€ A€!F4€`€€s €€€€>**o
+ej4€€ε€Ðd€-€€€+€b€$v€l€e€}Kl!N€€n€<€[€TZs€€€ €N€H€
+M -1€€€3€6<€ZuB€9€-€€n,;€;t;€€€rU€.€4"€о€VF€Lvbv€Ɠi€\€U€€€Z€^€B€fO€€€R€€€ n€€€b€6€€ك€f}c€07€€€€€€€€g€-€է€€g€€Km€X€к€[€€€€€€€€^€€€h€-€€ݽ€€€Nw€S€€€€_w€€^+€€€€€/€s€€€€€i €_€○w€w€€m€J€€€€€S€ v}N€€]€€€€8€€€€€€€€€L€€€€€€€€€J_/€y€€€€O€€N€|x|€,€z€€u|€€#<€€\€€€€€€ æž¾:~€:ͳn€q€€€b8cD€\€€N€€€5€€€q€.€€%€€€n€€€y€€6€-N€O€€ €€q€kX.nc€€
+€€€€€€_\.`€x€€€7€€€]€€€€ }€€€€€€€€Ƴ€€ J€€€f€{€~Mc!€S€ŋ€a€€€uK€ €t€€€€)€€€~^€€€€W€!~€€]€ְX€€68€€eqs0<€€€€€€€€€.
+€€€||€<z€€qV€=€€:\€U€€\€D€$m€RQ6z€^€۟€&€€€€€€€€%€€q€€Ú€oN€>€€€f€1€€€€€Y€y€€i€€:L€€€-s=Ge€€{€G€€"€€8=Y€V€gϻƀ€P`€€$K€€€€€;€€€71€ I€€€ €€?€€ì§S€€€€ A€ 1€]€A0p€€€€5€o€/€€k€-€f€€€ϙ€€€W2€€#€€€€€7€€€€€€%k
+€€€}\€s€#E€'€Z|€u€O€€€€샧€€c€ʧ€€€€€€j€l€€p}€€z€_€d€€€€]€r€ €€(e€Y€€QŬj€€}€^qK7f€5€8Q\€€t) €€5Tٱ€%|€€€<€X€€€€~€w€1€,€€3€€ €ù€$€€s€ B
+€'€€€³€€€Z
+*~€W2€€€€€F€4yTCA7€Y{-Xk~\€€'€C|€€€€€€€ €xG€€g€n€u€€€€)€€€€/€~€:,h€€€6€(€FH~eY DģY€w€N€€€€k€€Dz€€9.€€€€€€€€%€€€"€"€€€o€€€€€€v€Q€u€@€€€G8쀡b€W &T8€ u"|}}E€€]€Z€€cݮպ€€Е€bL€D€A€r€&بYb!'@€`'V€€€;~Br">|€3€^ €€Y€AM[6€Î€ €€€€;h€7z(€€b5€€€JI€~Dۀ€ř
+wb€€r׫€HV€R€€n€€Ă/!€€€L€€l€ €H€€€€€x€Q€€}€aBM€€€€|€޽€€€K€€€J€€ҡ€D€D€8€0€ݼ€&€€€>]€€€(4€yAڲ€€6€[€4€€/€€€€W€€€€0€€(u€[€€€߸€O€1€€€9€c€€8€€€-€9€€€,€Ks€€*P€€€Λl€Ȭ=J€%€€[f!rg€€8 X€^€p€<€~€€v|B}!€,€@€€a€€#JЊ€`€%[p€ǵ€€€€G06€€Z€€?€€€ݠ€€€€€hC€6€Ï¿A'%D9€vYt€€Q| €X0€V€&Q€€€ q€€€Ǹ€1Jaj€$€_€C€gظ€€T7{€m€€}€3€t€"€€!@K]M€€€l€€b€R€L€ €]T€€€V€€i:€€3#€€}A7€€T5;/€ €€€q€Ԝ€€€:€]r€€€Q€p€kZ`€€K€€}€€€€€€€s_€Y€€6€€€T€€g^€Y€_€€Rr֋€€֬R=€€9€;o%€̫€€w€8€€ﴂD/€€fu[C€:b€€€q€êœd€ړ'~_€N9E)€€€€Wj€b€xwج€v€€€يF€8Ϥ€€€5€€]Ԅ€qW€€C€kg?€fdYG€ €€€S€€7}€€ vD@€[€€m€T w €€i€X€€€€~€w€
+€€0€3€E€€€[€ €&k1€€€€€{=&S€fT€€€P€€€€$Q€]€€,gMs€#<€JE6sz€€€|€G€€€€€7€€€͕€€€҇€x€€'€€>€5b5€€^-€€~€€2€g€O€D-M€€€t€d€€€'o€,€€k!€O.Ä­?€€€€V€o€€€€€€€€?B€€g€g€[!€€kJ€o7€Ȧ/€€€€N\€€è€€€€z€x€€€O€ӟ€€€:€D€e€Tz9€€:4€€{€€$€W€€;€j€€{w&€w€c€€€,€$€€€+SD€3€(€\€€,€€ O€0^€€%€k€d€€€:
+€V̂€€€\ €€:€€€€͉k€€Q€h€€€wsre€ȯ€6€y€{/€€{€(_[q%*€2€€G€te€)€"@h,S(/^b€€€€j€7gÏ^LON€€1€€€
+€ €CgZ€ AƦ€Vs€6ʉ<€€€€{€€€€T€1~€€€€xȗJ€ €Džm0€ΦN€€C+ €€€'€L€ €匩€2€€r€m€"'€€€€€ї€€
+€I€;€~€€€€Y-y€€
+6ğ€$€€€R.€€€5€a[€€€€€€€€€w€€u;T Fw$€?€€?€,=;m€€€€€|Ĩ€€€ds€€€%" v€Ͷ€VS€€1Ó»os€€C€€€g€ ҂€€_€€€€c
+€
+€€t€P}q€'€€%€€f€&€xR€(€ €€
+Þ‘.€0lz€ZÛ¬,o€€.Ȳ\€€€ Yeˉ.€#€€p€€€€€<~/€g€!ç“€ޯY€€€QB€r€X4€}X$J04a€€ €hL]€€CF€C€€€Dt+R€y,u#€€€€€€X€€o€€nO€€€f€€@]€o€,(
+€€€€w€|€!€€3F€€g[T҈€€h€t€?€€€€€^€€€€€9a%€€ €%/#h€€€ß €sp€€@€Kԟϋ€€€€€€ €E€_€€b@€6.*€€eP€€€€I€ ODeZ€ї€€ß“ €€€6~€€q€€€ €€~€M€ {€€6€€€u€"€€€€Z€U€ €€h
+€Ȱ€€$'7€€€€€,€€ €€M€€SG€€€2€€V€€€€9Br €€€€w=~k€€€X€€€nQf€ ,€€ €€€€C€€€(€€€PB€€€€'€{€"€€i€A€€€P€t€kFe€~€G€>۠Д`€€€€\€2€€€P,€5€ €€{#@+if€€€M€9 €€€ǟ?€{€€
+o%[ф€*€€|€€D€€€/W€€ €€_̰€!€|€|€€y柀€ J€€k~|€.PdV€
+cv€䎦€*€h€d€€2 €5€€€䚿€)o4v€! 8€诪€U€!€€e€6€€€"€QÖŸ~N>/I+€€€z€€3fu€h€€€o€€祿Y€€€€V€€1€ €€7€5€€ςՖV€y€ €€€-€€N€P€€€€€€€€o€q€'€ʛ€€€s*BqT€CV€€:€L"€€€W/€€€€C)€€€€€si_`x~€€ \yzS€€/€^€6€ M€€q€€+>€€€k?€×€X€l€$V6L 3€€~V€ri\ €bᇤ€  Y€€€96IgB#€€C€7€u€Ϫ€€ €1€€€€€€Ôˆ`A€€€b€€I€€I€€]€Q|̫€€7%€€€Mc€27€€€€\€€5h6€€€9€€€€ޅ€€€€€*gkh}€€=€G€ٽ€"€
+€9€Ȧ4€!"€ É¡<€./€k߀'C€€8H€€S€l€ €Ð€€
+Zm€IT €>€s€Xo8(€~܄€Vʨ€€€V€Q€>!€€քj%z€Rkn€ €%€T€*P€€€€€i€SY€!€g€€qD&<}€€€€%€Tu€Ǥ€I5u€€I€M€L]€y\XTbn€€€€彩nj!€€€€x€F5€€Ρl€Tʉa€€Y€{€25€qh€b€€€€Hə€<P~€[€€€€D€€];€€킳i€#€€o€€1€@€O7*€2d;v€c<€€€€€€}Ö€o7v€€€€€# €A€€€Ʈ €€€ n€)a';€z%€€FA€€g€€€€(( /%€>a+€€5€w€H∟@ €#!€€z€€€@f€€€O€€j€€€€y?uF(€€€'€€3€€i€j €€€€S3€€Xw€В;€€.€N092€€`O€€€€€6€€"€€0€a€!€€€!€€0f€{^€\(€ €€€€€}€XX€K€ €€€c€x€_O4r€€€i€d€I!3€H€ş€€€€C]I€K€,Y€€J€0k`T!u€?€€€€A€L€€z€ɨ^BÈ–0€€€ʂ€5€r€N€€€€>f€D€암€€ܶ~€@€€€Ӭ€€€5€zA€& €!=b+€€~jV€€€}€€ €2/€€€}€T׋€8iÞŽ$Y€.€-€:€€€€€U€€€€€€d>O€€€€€€€€  P€m€G€€€Z S~Y€S€€PX€q€€€€€€$€/w€H€ݲ€€
+€€€€€t8€€€Xz€Y€€r*3€€e:€U^T€€€€€€Ps€BbH€gv€h1€€Å|€€€€(€V€P-€€€"/T€ci<w€€B;€€Z€O€;€Y€€#bA€€€€€C€€Ց.€EĈ€€€€€€Z)MF_€€".P!\YÔ€€'€€ _i€€€€@€€Y"€YS0&€€&€€€-zsM2€€19sØH€`€€€€€f€€,€€€'€@€s€yB>€€&€€€|€€€€€-€VVL€)!e\mi@€€Dڄ€3}€€%€4`€c|€W€€e€ua*=€€€€€Id€€€€€€$(N€€&YI€z€C!S€€€€€Pr0R€€4V€€(€€€€U€€ €9RT€€€€€€€t€X€€H91€ظ€*'0>s€€@€€K€€k€€€€€n€1r€ r€€>3€4$3E4€€€€€^€€€͹ €€€)€I€rJ€€€+^<6€k€€!ZÄ“M€4Be€€uJҵ€€€mÔˆ €}D€1 0mG?KA x"€`g€G€\"€€€€ €€eNo€€R€€€N
+€W€6\O €sű€_dÒœJ€€ܩ€#;€€iC T€|.€€€c€€#€o€]€€Kp€€FN€7"y€€€/Z€P€€€€팙€*T€€ML€€@0Ò’ {€a€€3€s€€€€6A€" €€€D€€€€€€€M€€h€€Ǧ,Y€€€€€€€€€y_€~>>f€€€€€€€€€€
+€c€=[€€€q€H€V€}F€7ՃS€€,€€€V€g€*€€@4~Tm%=
+€lE'€€?5€>z+f€€€0€€€o6*€€€w€ t€:@4€€€A€€̆€€€L€M9Ew€H?7F€;€€€€ŖJ€€Q€€% €3~È€ή"€€€€5%€€€T€€€€C2W€˃€€ €M€B€D€€꘭€€e€€€€ri€r €€߿"€€€€:€€€€€€€hi>€€?c6€-€D€€€€€
+€Δy€€W€€€[^jU€ǭ̧€€€=€€1€€@d€+€€€FPd&€D €%c€€€^ yL€€P€|Â€í ™xH#€€€yJG,€€€U€€€€w!(€€ €p€2€T99H?f€y :€q}€ϲݲ€BW€€N€_€€KØÑ ^€i€€€€(X*€€€€I€€Q€1q#*Kl€*~€Ͷ€Y€2>[á³¼€€G/c €€s€€€<+|€€€ €C-1€€€%€€€€€Üp41€€Œ
+€€€€€€M€J€fK&€€€€@u€P€Z€€Qqb€€€€܉€k\խ"€8!€€€€Xs€HW€p€ €€€B4:€B€o€B€€€€€€X@€b€€z€ €€I€c€g€€%€€€€AXB€>€MJSJjҥ€€€;-҄€|\S€€€t-€T$ AN€€;ߌ=€e!A€ cš€€(€&n[€€F€l^€<,€€€€c€f€i€/€€n€8€uʽ,l€Wߵ€3Aq€€QYF€€̩|7p#€ֽ€€€€€E€\Z €€@€€€€€2€€€@e0Pp€Uӟ(,I€3ԩI €€؅Iy€€=€€/-$5d€(€ ?€X€`€€€3€{G€€p€j€D€g<€-€€$€€€€€[(1s€€€€(bM€P€ ,]&8/€+:lr€U,€FL€#€€#H> €€=€r€€-^l€€€a€r{€€
+r€Xo€M€€t€.p€ €Ø€A€€r1€Ƶ€- €ng€>0u€1€€k{/€I€€_€apz€[€u OR€c€€
+?O€€ji€`K€Y€u€€€:€€f€j€`€{€Qֵ€e€Q xm8繱€eG€jw€ys€8Ա€뺾€@W €+Ú!€€@€€=ע€€B23e:€ut€8 fѺ;-5ᡆ€f€€€Dbf^Li0€}€ s€€L€€€€ҢCx€€€€€€€H€P€€€€ €<€€€2J8Xԃ€€€€(€G3@€'€€€Wd€8FIm€€,€d€€2%€0€*€€€€Z€{€`Л€€T€€3€R€€€€€rJ5m€D€E€&]KJ€€€€ /€€]9€€€€(f€Cfd€}€€€D>€t €€€q€€€r%)I€dMÒ F€€€:(€€€€€€€S€U€€€€€5<5Y€€€_{€W€b€€€^>€D€€€(€€B6h€C€€~€{€m€-€Z€\&€D.€z€€€ m€€=€b€}€€9A3€Ó¦ €*€€€€6€e6€€^M€|€(€€€€EH'€€€€l)€p2€€€-€€€€n€7:Օ€€€2E€€g€€€€€Mxc€€tUP%€ S|€€uN€4I=M€3€TF€!3&€€€€LF[€*\€€B€?P.€j!~l€€€5€U€€Ć U€€€,dz€NP€k€€E€,€h€89€€V€€€L€L€=e€€€Q*3@€€T!€Y€H€e)€}€€€/€€€€€€€[3S€€€€€hgW€b€€_€€8{ת€q)"€€€€&€Z€€€A05T€C€€€€&€€A€€x€bDn€€~€€€€€€€€€xLYh€€c^wIx€o€o€e5]€/€€K$ U€€€-€€€€Q€_C€= (€b€FIL€1€€€€€D€w€g€j€€dÞ™c€€d€b€Ƙ€|#€€~€An 7€wހ؅€€2€€Y€€c€b#2JnǺ€€€€€€€c7€gqh.=j3€
+€y€!€^h€€€€ €T€€€۶B€ €S€€
+€,2€g€€j;r€€z€[*€€€2€€€€Yl€€€€J0nTt€€[€-O€€€e€€C;€idм€?€€€ZWh€€_€ٰ"€g€€ʔ€€€D€3€€!Lc€€€€AS€M€e؈€€€€4€Zl€N€ €€αO€S?{€€"€€€€Y€"€hX€=€€G7Oړ€x1€€€d€R€€Q€Nw€ (#E€€Dl€m€Y€€S0Uv€g€g-€l€€GH€=D^€€E€€,P_€W€€\€w€.1A--iw€5(h€b€KS€€€ÙJ€V€€Wb€€€€€n€aj O€€€€VЀ€€€E€€L€)1€€T\Z€€V€A€€€sq€€€€v.€€P€€h€b€8bg€€`€k€H€{o >€q€PꯈX€Fi`€€A;€€{×€ €b€ €€ѱo€€€€V€€€@9€׊€€Z€ 3ܞ€.€€€€d€%€€VCL €F2<:€B€€€u&AfB A1€"€€9€€€%6€€+ €€€€(h€ M€bGpZ€uAr€_€{€Q€t|€:€€€ԕى€)wJz€€€€€€H-€&€€^I€€_0Ù‰€"ǯ€€Pc€ƈ €€`€~€€=€B€+€€]/€€€ €€V€€€€WT € €€g4€€€€Y€€ʠ€€*€€€€NK€r€iئ<€3€€Y)€]W`€(€D
+€%€"€€p€€€€+*ʌ€i€8€0@€LN€o{ €€R€€€€€B €€€_€€d€€R€€€€J€€$Δ%Т€€Y€&q€€|A8€m€€€€G€€€€"€+߂€P{€€G€€@2€=€x€|€€o€#€t€<€€€/€€RGRd€ $€J<}9€
+€€5̀‡b̫R€€€€.q €€€#^€#2j*€W€€€w€t€|€€(€€€€€€f€€€€€€€€9€gR(#]€T€ )_€/*€8K݅}]E€€€cB-€Z€€€9€€€U€}€(€˹€M>1€€L̀€€;A€@%€2\P
+B€€€ F^€yoh€Y€K*!€€I€Uk€€q_€ˑ V"w€2€K€€Ý”qw€€$vX€1J€€€G€€;fU€€€ZIBA'T€€0yY€€€F€€w€i€r€#ØŽM€F`€€€€€€€€w:h€€€€*€%1€€€€M@$€€€€€݋kPH€€.-8€p€ €,RR€€€€C€JX€€H/:€€€€6€€a€KrA€3€O7
+ €>€;"€ €€€ R€€S€€Qܼ€8Dn#|Dv€€Bb€$€€3€€*€€̤€€€€€€3Ȥ€€2€€V€€U€€J€€o€€~-Q€7$^`,€O€=€€PȯQ,˽€ө€€s€i€=t€€€
+€>€k€;€€€\€
+€€€{€€Ut€ +€U€C€7ᅷ€€
+e€{€2€€€Nr€€9 €J€v€–€€tݒ€y/€€€|€€€€1]_1tz&R#€3€9€€OŽ2€L€8€€}RT€€R/T4Y€Z€dکJ€€V €e€Z׭€7+€€€€€T€S\€2 DNv€M€€I€k.€€AI€€€2€x1€ZҎ€€€€€€€€U€K€W\€Ad€
+ €€D€€gTL€))F)€€wuHoxÓ½"€r€y^€€€€€mH€€€b€D€Z€@€b€€x)€€€l€€r€€€cC€€€:Óc€€€€b€€^-B€H:€EAܹ 4€!B1o€UW€2€€€32€@]6MFw€€€€l€Ҫ€=€€€€B€€€>;{QU5^€€€€€€-€€TPfr€(€jg€€&€€ €@`Þ¼bX€l€€E€ €€€U€€r€F€_€€€8c€9€€€€€€oW€^!€€xv]lJ€F€€*€€9€P€r€
+í#/€€€m€€ ;€-€€m€.€€O€q€€&€$€Y%€€ t€€€E%€P€€€4:W€€4€ Rgxl&r€€6€€€€€€|3€DD€€}=€׳
+9L€F€\€€r€€€€€:\€
+€€€€<€EV`€€Uݸ-€€
+G€v$I6y€I€w€;O€€€€rFrhÔžÚ‚^€!AL€€He;€€€ޑ€€!€(€h€€U€m>€€>?€V$€€׶8€ €€P!N€UU"€€€<€€€0€ԧ€€€€€8a€ZL€€€'d Ï°U€bp<€z€o€€`€ؒ_€€¾w屄>€L.e€€.B€j€8eR€€z€'s€€€€q]€Мw*ɵ€!x{Wof€€k€C€€A€€j€€€€€r€€Ђ€h€€€=m€€€Z.€€€'€#ʌɖd€^;H€ F€6€€€]€€€Cm€2€€H€€0&€€€€Lʗ€€`&€C&€^=€€-€k=[€€€€€€k€€6h€l€€€€€€wbkd€€€€J€€Ե€€U€€€€€An€€€$€€€=€-p€€€Y\JtH €>R!€€U€€+-€uE€€pV€€€€Pk€€€€H" B€L49€€L€XE€€O€€€€T€€7€Lj€K€€U€€DRÞªT€6yÀ€€nw؋€=€NԻ€K€.b'C€×!€€€€*^|€!a€I€PN+y)€/E€€/€!€F?€. €G€€€$€2€*€ €€€€mÛ€€€€€€€€'coC€F51€L€bM|€̙V)x%a~ Ղդ߄ €8€#€€&H€Eh€€vw€<€€€3€€€€€ Cwv >;€€"h/$€C!€qt$€?€Ҍ5€€€€ €q€€€K\PQ Q€€?̶€€-€V€=+!җ€€h€€€€(€€€2+eV€4z€U€€€€j€€€\(5€€€€:€d€€€€4€CF€Ub€€€€€€€€€€8€€€€TD?[€€€€R3€€~€€*-<€\Kkl€Ǵ
+€.€€xiM€Ǵ€M
+6Wp€€€€€€fǧb€Iv€€'Ç­OhIO€€€Mб€€€€€€bkyuuk€n€C€BE€€€Чâ¾fQ[€}:O€€0U€H`L6a€€"c€5P€ZLC€€O(€€€€€€{€M€l€€ô€`JT€€€ПL^€lJH@€€€€€€S֓€€€4€)7€C€l€%€€bK €€Z@3€H€€5€€b(€wQN€ €C€€€€€DE€€^€€9Ph€2GA€OT€€
+*H€u۠LK€€€3€€€xV9t⯪u€u€V€<€Nhp^€P3?L*a, €h€x?€kO€R; d€€€€B€*€.b+€€€€€€M6,J€€€b8€€-€" €f€:€€€ua€T€S€4c€€€(ء€ >€C
+€€€.n€€)€€R=`R€5HA_€€Ѡ䈒0€4C€[ €€ 69T~*€=M€€hU/퀀a€h$K€b<€€€€L€S|gC€ݢnP-€€€j€€%€N^€€h*€€€€€€'Ó˜ *̎€ a&€C€{"]€€€^Q€r€E€,€|€€€4u€d€€5a€€€q€|6€€€9J€3D.€€€€€€J €€c+{)Na€€U6LU€Ghi€€A€O€0€T€ij€€€&€P€€€€€I€€€ €0x€€€€G€$M׮€€€É€Œ€€€€3B'€}€O€|€2{Ù…B€€>\Õ³jA€9€>€€X8\<€c€Ш€s€€yx€€-E€€ €€?spiderwebman.toc€B8€€€$€€€€TEXTMPS €m5€m5€w€%\catcode`\@=11 !! SpiderWEB €ourcG€
+€p€$€€€Q€€Q€3QlI FixupMPWSymbolsc€€€€€€€€€TEXTMPS €€€€€]T€O€-€€:€_€€vb@€*q€2€€ND€€K€€Ǧ%€ €A€€@€È€€?€#84€O€ͤ€€~€€€€bE;;€€€q :k@€عI€*€ZeE€€€S€€€€€Z€€€€€!€,€€€€T€~€H
+€(€qq€€€r€€ ]€v€͚€€U€€N$€€AO€Y€€€nt€€€ѹ€€#(=?€€€€€V6*w€юB€屫 9b€€f€€S€€gnn N€€W€ `€€29€€6b^€€€i€€€€€ZyjE€€€€9€S€€€€€ir€~NP
+€}ߤ€G?€?€Ɉ€p2€+€x€f€=PO€޻€€um•€€€€€HE€€ו€ ?€T5€$n€€€c?l€€€R€€^z€€"€.X€h;
+€€-€€K?NR~€€뮫[€€€€€€x€€€ÔB7€d€S€€€Y €€>€€i| {€€X€€ė€€%%9`_ E,BoLq>€R1€)€€€€€€9W/€bO@/uS1€J€/ĉ€€
+€J€€€&欠hS
+$J€1€R€^m€€€€€€f€€ˑ0+€Z€R]€е€a€%€€€€o€w€€€6€C€€ €n€m$3*N€^€ €€ É©?La€Hl€€€U=v€ߩ€ €Q€a€)֊€7h€€5€߰߯€CTm€6€=?€€`€t€ji#7N3I€€€*€€€€|cc€€w€€€€€^y"I€€r€1€7J@a €XOh€|6| €€€€m"y'€€Z"D€€a€€€"·0AF4€€€€޻€€€€€. ފ€`~€€€c€€ €(€X€€€a€€Co€€m€@i38€€K€€]$€€#€تZ0M'€€%Q€,€ €DH€8短,€€€€á±Â€Â€Â€$€:€Q€€4M€ũ€€€€€€€€2€€Ԭ€€f7%R%@€€€€/.1€€s€€D€3€|€€€+€d€V€7N€€Y€€*€€p€rQ7€€Լ€€€€ €w€/€€("y€5LU€yL€&€'€€€9€€€eRj€€P
+y€€Er€€E#Ғ€€9€)qb?€€&€€z€€,<€€:n# S?KDC€ €€2iPM€dp) 8-€€€€€ұ€+c€€J€€BiSrL6€r&€€€d€4f훹1 €l€€€€€t€s€€ -w`€I€€€€€€e€6,€€€l€:€€'€ €€€€€€€Zl€m]€‘€€Yf€T€I€Ò€€€€Fu€. (X€€š€2€Ec€€A€€wWZd€€U€€€€€i€€Tw ٔ€y€€€€*&D€*F@€€€X^؋€€€€€)€€€€Ȧ-€€€gr€€lam€€L€€TM€€?€€€€}4W€>€FNzyN€9€z€€tKsJ*€€€9U4€'€€€€*\-€€€€€ €€mu€€€a€€€K€€$€€€pHҎ€€€€€=X€Ä^j€j€€J€<=|쇶€X€€€€?^??€€vUU.€z€P=wS€€!X€€
+U€€€€屠€€֋€€y)€€€€^d2€n<v€€S0€l€s:d€KZ0x#a€U€;€0€^€€RfS€-€€vp€€€<€€\F€ € J€€€qaU€u€P7C€Ps€ȷ\€^€Fj€kv€€€Lu€€?4S€€/€€"€€G€~€€&:6(u€au€€ ^€ AC€€€gѬr%€tp:€ã‰Â€Ç­Â€Â€U€€[}€€€vt<€4€܃€€;€ٺ€€{€€]€€f€€_/€€%dÓ  €€{€€13 €<jZ€€C
+yQJO}€ը€€3O€s€€0€aNv€€€€ԕ€€€h€€€"€€Kv:E€€€€"K €€F€€€€S €€O €€€€_=€€h$€€2,e€GR€€I€€€€2€€€!-Üm€€]€€€C€€€{€|UfUy€[Kw€U €€S €€8Ϊ€€€€y<€€{€€€€€6€>€N\€
+€5€€€€I€€€۔J€€€I€€€€a^E[Λ,dg€6>€€€€|װ€€€j€ Ŷ€€€F€#€€ot€€]t€€€€€€1nd€vy€Sw4%€?€z€€^€€lS5f€€9€€€€]€So€MyF{€i% €€€€sv€€kNu€€€:u€€8€€-C=€€€€_-&€E€€€€€€!\€€€€€€|€g>}ɘ2V/€€€€€€€p€0<€€€ϥ€<€E€t€n€+Ïr7€ݵ€€d€W€E*(*/?F€€z€G€€|€€;€€€6€U€€
+larch.unix€7€$€x€€=€€€€€€{€€{! ;z l.spiderixmbolscK€€€€€€TEXTMPS €m5€m5€a€€€€ €O€@=€%49€€0€ '€me€€e>96€€€~€€qJ€y€€€Aou€d€8A?Z€ €̮ €€F€N8s€N8%T€Y€€x€Oç…š€€€W_~%Fs€*/€0€0€r€+^€s €/€ €€H<€:€TXJtÅ›\€€€i€q^€’Lg€4€R€<K€€€€Ӽ€Be€€€€ʳ]€€c€H€€€€?€€?}€€€<€b2+E€
+€y1€0€€‰/H€|[€L€€€{Dy€"€HN@B€€Ig_€,€<MT&€€€€€€€€<€j€€o€ €€p€€€9ʤ€b*9a€&€X€L€€€ €h€€愋€L€E€2€€{€€9€EٲL€$€HE€NZ€*˧€€t€€-0/9€Y€Uf€T€P€€N%€C`]€
+€€€€€,€€€[€|€€A1CVy€G€€֊X tD€$B +[0b}€ʣ!A€€U€@€a€€€ֳz€€€3@€€[€€C!' €€{H9€m€=R&J€v€¾€€€€€€€w€€rY€€1I€-€€v€Ɖ_(€€E€,€#€xY€€€€€€€l€&€J€€€μB€7€:€o€QXÖ¯P€€€€=sP€g€e€6€€ Ne<€AÑŒ€n€k€yŞ€m€€.€39iÙ«€b€Xw€c€€)6€J(3€Z€€€€  €U€-EK€L€€€€}Q€ €€x(z€€D€€G€€/€z€ €QRÃ3$Z%ꀀ€€€ƴ€.€h€qA)=€Sl€€g€:€€€€(€SA9€€!l\€ Ã’€T€8=%JC €€€$€OU6z*ah'€€€ OT€(p€*a{€€mt€€€%€€€74μ.€iv€€€€k$€_F€ {€€€`€€tl€€Ӏ€p€€x;#CB€€€€˧€€€€C€€p €C€\H€€@€7€€Y€tѶYVg\[Mbm€€A€Ƶ€7d€W€€>!€Wm€5€€€d€€€€€€€€k€€€H€߱&2€#€€€Mjl€€JJ€ €€€€*€,€€~€€U:Z2;€€ay€8€€€€€€ ~A€s>[-S€>|€€Z€e€i€€v€UV-pf€€€'Ã¥.Tt€"€€€€uM€m€W€Ò¹ €€€t€€€MS.€€en~€€ʒ€f]€€€@€Zy7q€€€2€€€€s€€€É€€2€ G€u Û°^€€€€€Ԃ@€€€€@€!€6€!P€Y€+€€€€€ €€€‡€a€L€€_€€-€€€̩€€€C@g€R9€v€h€i€?l€€€x€p€€€€€ɣ€ €O€€€€€ssY€€€d€jlƹ€6^€8€pp€€€€€€GjH€€-Aclj€L€€ݚ€-X€Lp€€€m€*€ €d;€€€SX€j€$lv{=€2\€€+€€€€€rr€€W{OGz€z€PGEX K€9|}€€R€S-gq~Hs€_W€4$;€ҥ8€€€`€€Np€€
+/€€Š:€9€€€v€R€'€,a'€€2\€€€€Y€€u€€|G€€O€€€w ۹€ݽak€€wBt€€€€9€ €€V€€€€€€j€€>€S €/€€։€g€9€ XjЃK€փ€€€€€azqʹ€azz€€:d€€€O{€€R€[3a€€m€€y€(Xʗ€l-2€pF6d€dQE€€€MX€€+€€€mOE[€€€~|kq€N€€€[€€>€€6ݯrz€€G€a;DE€€€€` €€€T€€€€€€3€€€€`€upn€€€p€5€€Q€,*xD€€€€
+€b€.€€€O8€߯€€€`€€€€€€ €pu€€€€v€j6€€rY€T€9x€t@߾-€d_€€v€3€[€€~€;€€€€€X€€N€€€€$r€*€€v€H€€€€€Zڵ€8/€€€€€4€ك€€ €€l€€€€y€€€z€2q€€ЅΞ€€pϠ €ҷ€€€€ň€€€€€€fu€€@€€€€o.€€ €€p€€ _d€€€8€€€}€ ~€RI€€w€€`|€™M y€€W€-{7€€ab€v€€€ lists.webxmbolsc€€=€K€€TEXTMPS €m5€m5&€€€€€
+N)y<A09J(€€
+€V€V2\ɱ#€€€€€€#€€€ % €€€€€€€€€€€€€€€€_€ ÂŽ##F€€1€€'€;0€€€€+t~ n ?o€j €€D€€`\mL€Y€=€€€ab-€"€€1€€] €€€€^€$€€v€t^€€€mT~[€€€€€€q{b€€€ €㮆€
+U€€€2=€W€#u€€€€€Tb€€W&€€€€P€€:€€T€"€T€€€6€€€0€6K€€€N;KG€"€T€*g)a€€€€| €€1€€ܚ€€€5€T-]
+'uurB€€€€MXհ4€P$€P€€|€Ц€6z€mI9€GԠ€AS€€€;h€€ €kꓢ€c€5€޶W!V €€€€€€€€€!€NM€-tDk$x€€€€€i;kjh€€$R€5€€;€
+䩅€€Ϙt€€!€€7y€€€€€J€&€€Y4-€(nx€>!aM€\m =€€€€€€€€€y€NeZ€€€€€€a€€€K€€€€C€€€€€v 8€€l€€€W€€1€€€€]€i€€!€u€€€€€As€€E€;}чx€€s€cv€€€ྀ€s€€€€|€€'€€€€e5€€$€€€73€€€€z€€€C€cb€€W"f€IK€'\u€€€\€€B€H€I?KKi€€M€€k€€Lz€€f€P€€€!'€€d€_€€Zv*€€Ö;€d€z€R^€eȞ€€|€€€0€€€7%ij€€RD>&6€MP€€€o€€€€5€ћ1€€€€=€Z&€ makes.webxmbolsc!€€€€TEXTMPS €m5€m5[MY€€lQ€tH€€€€<$'€€>€€€K€€€€€@w!p€1€t€€c€ v€2I€F]G€€€Hs€ Fg€`r€€{}Ô–
+€!! SpiderWEB €ourcG€
+€K€€€€€Q€€Q#,G€o€ Makefilebxmbolsc€Z€€€€€€€€€TEXTMPS €m5 €€B€k€€aAp€€€vbUѣ€9€vG2€4€>K€€€€€€€$€€€8f-€g€b€y2€€€€2€yr t
+€c€=0€€€ €€€g€€z€€l-€€
+€€b€ڡ€n€€s8€€€€D€€€€پ€€€Ы€0t€bhbg€N€€€S€€€€vt€7gk,[€€3€€-rV>€€€OzF9€€a€€B€€€€,€€€€€€€x€2k(=?€^ߺ6€€;€€B €€ 9bÌ”9w€O5Z€€€
+NW€€€€€€ʎ€€€lBL€[€€]v+€€€w€€Ȁ€€R=/`u €V€2€VFP€€ €€>€#€€9v€t1<y=/|€m€8}€{€€€h€^[WJY6}€€€€ €t*€!€UZz$Ñ…# )BM€€€:pg!U€*KH`M€p€€€!h€9€€ښ>"Lu€€€€n€€€€€€€€€th<dڡ€€5€;€€€t€€0€€€Z€FtR€€€€€'€TkJ€€€€?€€v0€x(€x€r€U€€r€€j€{€€€&€€€€€€€pK.f i€€.(€€€€€3€NB€"E€€€€
+Ȭ€R€€€€K;g€€Q!€€fSg€€ra]€€€m€A3U€dz€m €€lY2T€€2€h€€€ݶd0-€2€P€E€v\€5€\)€€U€€om€.€€uo€|€!€€€D€믢l€€€€wV€€9W€z|€ €€ֵ€€E€`€€h2€ɰ@€p€€o€€D€n €€8€ €€€ð€^€€.€€€b@Q9d€€6€5yyf€€€€g=€€1€
+€€€lv€&€€%€€<€€_;€=€]€;cN€€ €K€L€5€5€€D€/€>É€r[Yk€€D€Ut;7o€€€€€€m€ -€<€U:C€€4 '€€€€x€},€€_€€€6%?€?€1#€+{€:3>€€\S€U;+ /N €€€€ٓ€E5€L~€j€€€€€€€lv€l€.€k"v:\Y#€0€€€€p€W€?I€€!te|03va€.€ €IQ€€€$€3~€&€Y?€q3€€€s-€€€€ ^Ä€ Makefile.unixlscM€€x€€€€€€€TEXTMPS €m5 €€€€€€T€]€;€€x€€€u€€€€x[F-€'€€€€B€€`€LTb€u€D€€ €€#€ԗ€"C<N€€€3€€€
+€n€€e€€€€€i€€c$j€€6€l€€~# UJ€€.y
+€=€€rM;Ǝ€mG5H€€#c
+V€1€F€€,€U€u€u€€i €€DO5€€€hJ€'€*€M€c y€u€€€€€W=€N}7@€€~r€€ P€{7€U€€u5Z€€€€€0SÓ€€€€3Q(€€
+NW€€€€€€.exF9F€€€€c+€쒰s@€u€9F€€€kx€€€€`€€d€€€
+Ü•4€3€ȳ#€ €d0J€€€ € €ԴFÝ”^€€ޅ€€s2€Ô€€b;€€€€€)Z€&/ab-€J:€b€2o€€90€€ƛ€,Z ]€|€€€5€€N-€"=€sU!^\~LOO€]q\€€H€€A€ €€L+B€RY€ €€s€€€+8€ €€€€}€Oi€>€+€€˖€€Vd€u€€n€€€e€$€€D€€€€€A€o0€:;€09€m€€€tzxu€€Ng€€ W €!€€aL€ 댄€€€+j€€€€ji€€0Ś€€€r€n€^€€P€3€€€l€@1~B€G€€€€|>€€& €€2Ө€€€'/€ך€<€€€€%o€.€F\)€d€
+€s€€€€%?Z"€
+€€€%"€€€€M€Z€€[l€s€$€€€€P€€7€K
+唾 €€b€$]€Ub€€€Ż __Ǚ €€€€€€}€€€€Ƥ
+iL6€7 g_y~"€ZiU€€g85y>€€€Q€i€€P€€€€€1^€€3€M€€@€€A€€É¥w€K4€+v€€D9i€€a€€uk€€'€ucޞ€_€€€x€€'6€€€€€€2_€s€€€1[a€€H:€€MV€€€€ 8€@€Ӕ8€c€€€_?€O€€€a€lfc€t€€€€԰*€E D€u€€€€ѧ€€€€€€ €*€€6€ѯ€#€€M$€€€ßµa€€€~32€€|€€€€00 XhZ€`€eJ€€€€€#€>X€7€m__€K€ٶ_€6€ master€€€€€G€€\€€€€€€|€€&O;€ € common.chutixlsc|C€€€€€TEXTMPS €€z€€Z€€€m€€z€;€€vb@€#€fF#a*|d€€€=€IK€€€€I€՛€328€€€y€3€€B€o€c€€€Tr@€Û€Ggy€€82€€€mN €5z€5€€ʲ€€y_€€€€k7€€€€€€E€€€€sFR8€m€€DÊ´€€ɔ
+€€Fn€(€€h i€€6€€€€,€€Y€v€€€€F€€€€€€D€€k€!€ €v€/€]M€ c€(5+€€j€ €3€ N9y<A0€€€W;€€€€Û€€€€€(?€Évٻ€V@€€€€€€5€€€h€€€€2€ '€€s '€Ɉ€g€9q2[ €€€@oi€v€€€€
+26€€,S€J€3 [y€r€g€€V€€kx €jm"€€€5€€aC€'€€
+an€€ J6€€€?€s€s€O8€€€€Q€€A* B€)€€€€^]€€€€€€G^? €K€JÒ«s9€×L€€Y*u!€€p€€.€QzÛ¦A€€€€Y€ˡ€€K L.€r€€€€D€U^h€N€q+"€.€q€ €@€+m€€hfΑ€ +N8dEj€efDֈ€€J€€€S€€
+%M€€€+€€ )€€€^x€2€'€)!S€?€€z€€€€€5€V€€€J€€v€€€€€€'€€€yëp€n€€uo€€€€€>€€€˽€€€€_}}€€€7O€€€€€€޳€€€q€€ €€(ͤ€€€'€€€ً€€€€€€`.Ý€€€<[€y"€r€€C€0l€€`€€n€r€€€k €€€9q2€€U€€€\BX€Rq€!W6צ|€6,€€/€€fe>€jbzXd€€`O €€€
+€#€€H€€€k€€€cAwdj€€€€€€=€€k€€€
+€D€~*€8o€j€38K€e}cn€€Es€Pi€€ZX€€€€€€€€q€!€q€€(j€€b€2€!€5
+€G€#€€)€€zF€€D€K€€€€€]h€:P䚖̩€T* ˩€€€€€€lU9€k€J€C€p$€»€€*c--a€wT€€€A€/€D€?|€昼€€ŸkL*€€€U€{S€Jg €€k€€€s€€#€}3€€M€]€€p€€€€€t€ €ư€sO€B€t5S€۩#fZ€€€t€;€€_€Ɇ€-€& €€Kk€w€v€z€vii€€`f€€[€/€€€NUE8P5N€qB€€d7[€€L"X€€誙€jD\O GgP€€€*€€̠A€€Z €.€[6€€€€€0€o€€!€ӣ€€Pm€€աazr€~uX€€_€€€[ =JA€CÌ­5#)? €€€n`€€ȅ€"€€}(€€K€\Tǘ>nT€€!b€€€J€€Sm(€€€€€€€VA€\K€_€i_€€€€!j€h3LE&€]\O€s€€€ǔN€YfNl#JȆ?
+€'m`Ɍn€h€Ӳ ڣ0l€lC,,€߄€Kl€Y€€€€€€€8-€€a€[.€m5€\X3O=Y€z€ǵ{rhrq*€ҭ1€€ׅW€ € G€+o¢c€€wM€L0€€a€\€a€€€
+€€9€€F€€"€{`) \h€€,€€€€€€€ G€€€VE€€ €€j\€N€€h€
+3r€€€}€€€€€w€F;\Ιr;,H€€€ €€€% ;4€ €€€%€3€N~.€€€:€€€€€€f€€1?~il€d€€_a]€€٢€€€€ €€€ѭ}€&€X€€'€ꀟ€€"M€ge€€!€E€€<q€€}€:o€&€€€:*€€K€€€€r€5=˿s>€ֿ€u€€€€l€€€€ common.hhutixlsc€A€\€€€€€€€€TEXTMPS €CD€J€€€€€€€€ L€€vb€€€>w
+€€€̗GՒz€€€ P€3&<€€€։€J€€€>€]€€$<€~€H
+€q?€#,%=+L΀9€€$,5rB,€=€f€€u8€Zg€€l4€J€O€ˎ_[€€€T_€€€ €L€s7€T€€€€€, €`%€€F€z€v€(o@€€mv€€€€-€€€G€€gO€`€,€S€ym€€zq€€ €u €€yՙ'l€€o2€ {%€
+€ €€€€€j€ €€<€5€€€yY)€€KM]}€R€€ €€€t€€P€€i€f*ǀf€K€€TD€:€J€€xq8€|€€€€
+DO&€20ʼn€€€2>€€€)€ɠ€€€€€ۿ€x€€€€ _€}€篾~q€€€€€_4*S€p€€^,€€€€€€YZH+Z€ʥ€X€\>Y€€O€€+€;D€X€€€>€€€|€H€wb€€€€^4€€b€UQ€E€.€UP 7y&€=y€¾r$€/€}€€€€OǓ€€:cO}Eg€?%XUI€>r(€*S(!€€€€€I-€€€€Dy€€€˗€D€4yW.€YÙ2€€J€€\€€@€€€€5+-€J^x_€z&g€k€€€?p€q€€pSim€ωU€€€€7?€w€€€€€€p€u€€€€3€€€€`JW€€€€€Dh€mZ€$€€# €0€€€[€€z€€€Qi€€€A*}€€€M€€€o9 €b€€g"@{€$€P€,€ €€2z€€O€€գ€€€€!€K€δD€€{€O€{'=€G[.L$zs€!lFe€€€u>€#jFȭ€Z€脇€'Q-€X–€,€p€#R€€i|€:/dN€€€€€€€€ €€p2€=€€€€*\n€€€{€9€€JfD'€€€€€G€.€€ޠ€€€b}, }€€€€€€X8c€]€u€h  €32€€€Be#M€€€€S€e0€€J€{€m€%€)Ѣ€q€8o,
+€`€Z€€ŅWn3 €>r€D€*€7€€€€Y€€m€2%€€HT€€€€€3$€t€>:€<%B€€€€n€€8€IV€%€ɠLh(€€€I€>l€deK€@mGdy€l6€€ ao€G€n€€€ a@]€€€R€a€E€€€@€€€€€
+5xd€€6€€ں€8€K€€R€€€€ȼ€7P€pH €€Qe€€50€€x$Yi€Q€€€€⸸€€€€_5€yÛ¦>€-un€[€€€€w&gw M€EØ€s€@€€9R€;NB}v€€VS€"€w(€8€€_€1Ñ«- ۄ€€€€€z€€9€€€)€#€€€€€j€Z€1€6€Y0€ep=)€€€ޖ牱€ڪ€€`€S€€€€3€b€7€€` €C[€2T;Z
+€'#€€R€€€€€>:€?q'Q€€€o€€€.+5€r t€€\(:2€€-C€o€€Xܕ€€€€€mS&b€v€€€€€ Ý€€-€€€€€€€€F€ґr€5€q%€€#€€€}€€€€p€3@€91€_€€€€€Iê„€ֲ€€€€t€€y€-€€uH €> €1;€€€€€€€t€ €€m€€€6€€(T€1ϰ€!€€X€c€Cw€w€ r€\_€€
+€€€€€€[€=€€,y?D€{€€€€8b€)`@c/6€\Vm€/€€€ߙE€€€€5€€€€€‡€+€4€€)[€6t€€$€u€>,€H€7€dP!€€DB€€B.€€F
+€€€V€€€pÛc€€-l€i*€€&€Ġ€€€€4299€3€É€/{A€€j'4€€-€-M{S: *N?{€!€&6S€G€{€(€X|6w€^€€;€€/ €Z*€)€ $€>€=U€€€€#€bee€p€LX1€€1€€*HA€F9€A€€C€F€€€j€bVYP€€€€j€€€ €€Ɖ¬Ă\H*€€€€€S€€%€€g€5€€€,€wz€€.€€€€9€W€d{?€€JV€ץ$n?'€€€s"€€€€U€€€L5€x€]0€€u€€("€€O€€€7€`€%€€Z€Ɨ#6€g€€t€Z€€€:6f€ȟ€hҹ€€€as€+ãŽ:Wwcl€ԇ€€€€€_€€l€€d{€€1€€5€df€€y4€-€Þ€X€€€€€4€€€€€2"€€`vǷ€#â«» yC€O€o€<€€€€€^w€z€€€TJY d€€€"k€€€Žݣ^€Ñ€q€8:€c€F€k€nJ€€=>€Ch€€€
+€€XoF€€3€׃€€€€€€A€Ù+€€€W/€€G€\€€V€iq+Վ€G€U€€n€€€;Bl€ /€h€€w€€€*7Nx€=c€€$Hv €€€€€.€ €v€Ö€€2€€' €€€i€€&€ ^€€ݔ€€ 0ޗ€6;€€}~ }€ Z€a{€Oۊ€~€€3(€€M€{k5€€€H€€€ɠ?^€€€lEM+€ZWL€ 0€&@€ *-€€€ Ƨ€€ժ€]€%€€{€€€L€x€€€[Bܾ!€€W€€9Z8€€€^€€w3€$×™D€€r€€.€T€€€€LC€€€qy€洣1V€€0€€t.Y€€9И€U€€€€n€2€D€ d€sb|€#€ €€€̮€}D€AЀ
+common.webtixlsc€C€4€€TEXTMPS €m5 €m5 €€€<ղ/€€%t€vbU€Y€F€€€€€p&#,€6€€浑L€'€gdp€L€€€€€€€! €€l€€€{_F=€€€ €€G€DE€€€€€€€€)€Kd€_:ř4EF8Ìd€€rU€`Ae€`8€[€NM€Z€€€nn€€€a€f€€˔$=€€aZy€€)€VO€1€Z|€*M€AT€€9#)€€€€ €у€f€€€€€€8€@ã€A€€)€L€€ H€€O:
+u4p€&€€1S€€€€O5Z€€3€Ny<A€€€L€^€€€€€€€z€€[]€€€€>ϳ€4€€z€7€З€€€€€€€€M€d!€,\€€[€€B J€€€J€€€€g€€€+€lzY€Ƕ€Qr€/Y€r€/€8€ѽ2ϫ€ӷ€€.€ne€€€€oP߬€€⥷€I€#€M& €€89J€€€IO€K€N€p€€՗_€€D€€,vq€ƹ€€Ä?€€€{(s€f^ €y€€€-dn=€J €(s鋡€DV9.€T€2*€&€€>€L€0A€C€U€€€bFR€<€€€€€7€€€€[R€n&€B€a&€Be€z€€€~€€€PCq€€€€&€€€u€€L€27€4Lֽ€Ҭ€€€€D€€E€€kyA€€'€€€-v€€ۤ,€€€y߽€T!1€ €€A€(_€Qw€€€vü€€AY€Ç€€_|,€€o€€€€€€€ۖ€W)€{q"€8€B€S€€I€€€m€/$€€D€e€€n€V€€€"Ç‚LdF€€€x€u€$- q)€€Y€€€€HN€E€c€> €€29€€€€&€ܞ[€Ϩ€+€N€&€)€%>€€-€?~€
+G €w€€€€Qz€€f&2€m/ξ€€HN€€€Q€€€€€€€€4€€€H9}€€€v<€>v€3'€U€€€€€xW 2€Ó”{3€h€€€L/p€F€€gT€€?€€€Y€€€Q*/€€€€cI͞€€t€€@€€ؓâ›Â€n4€(€_€€5V€羽€€€€.:4@€g€€€€€S]€M€€U€PdE€€Ӱ€€€B€€o€€€y€`0X#€ϞL€x €i€f9 T€€€G€o€8Jհ€€€€€Q€\€,!t€C7€%€€/*})€€֎€f€d€€{€€€€€€€€€€€^€0>€€€€/€!8€€€]€€+€€€€Ûƒl.€-€ꭊ€€Ȕ_z€€€€ לG€%€€6€)€€€@8€€q€€׻s€^|€h€€€€yKcÞ‰*GA4€vd€8à¡Š"u D€ű€€€€€€{gIHcT€€:€€S€yHĺ€@f€:€€IL€€€€€€€GX€€€O€-€!`€@e#*>€€DD>€  _€€`s'€€'J€€€€€a€?€€e€;#€hٲ€€֞€+€€=€€λ€€Y€"€€b€n€tN€€0i|€€}R€€€K€a€€€€!€€5€€€7,sl'@y €€€.€€o€€€€€€€)x\€€R€€€W€€g€€€€B€€yᇪ€€€(€}s€€€€€€€G€€€N€Y€€€!:€€{€5€`}€路€{€€?€€€€g?€nF+€@€Q€?€@ ϱ/Q€;€5/€€b}€€€˄€
+€€0@X(C€Š€€€€+F€€€> >€(€€€d€€€T€€8€€€€€@€€€9֘€a€€€€€€ €]B€E€€!S€S€m"€=Y\JT€M€=€.€·€n}:3Sl€ €h€.:€€\€€€.€€€!€€€€q€€ d€m€' €€Kw€€€^€€E€€€)€X€€€€ײנn;€<€gsU€€€€€€€$r€€€=€"Lw€~€F€€p< €€=€€9€E€€ӯ€€€׫
+€€k€€X}J€€€€€€1@r€A:!€8€€_æ€Â€Â€A€FDNT€y€bbCH€@€@€€L€€:ò8€€[€ €€냪€GDH#"€€>Xb €K€€€€€€E€€l€€€ Å‚p[€d€€€€.[G n€€pÊ_€€€6€e€€q€€?€€€D€€ B€t€€€€ z €€€€€ɩ€€€€j€ €€€|€€€3a€Ȣm5;€€€S`€!€J€€ƀ€C€€}t€€;€€d€
+c €€€$Y9€A11Lk3€€€x+€€+ *€
+€#+q€€;,d_}€A=€€#€(f2€€P4€€€€"Q€MΣV€€€`X m€€€€€I€+€
+4€ €€Qk€€, 3 €]€leÇ‚8h:€€º.F€€€€3€€d€t€€€€`€T[>€u€;n€m"/d€€5€€d€ €It€05€؅l€€€€€c,ìœÂ€cHR€€VÏ¥4P<€\H€€€F€&€€l7$&HF€0€_;$€q]F1€LXJ€{NX€€€€B€€
+}€<J-Z€kKpJc€%€€€\E€€I€un€€$ x€€ €S€€{€E€€=€~ €€€€G€7€€€€€€€ €a€€q€€€u0phV&'€v(€€;€7 €€f!€$€€,€3€€€€Ze€kXBQ~P€ €X&€€x€€{( n4€€f€.€€€>p€hO€1€mٔ€€P€€€ €X,lE€€€6T€€€€?,€k F9o€q€€ m€QÆ°y€€i€E€i€*€+}€€€G.$€?`€€j€€M€q€€f€Zr€]?€KL( #€€2]€ܯ€
+€ΘX€€;€;€M€€N€€€€Y€2}€vR' T€yH€rU€€€_€k@€€€€€€MƂu۹-€€c€W€€
+U€,)667€€€\€€4€€€€€3€€7€u,€b€€€€€O€"T€€I [%/t€€€€€'€€e€€€%n~.q€s€7?€€€€o}.€v]+€ €€x€B€€€€c€x€€:€€€y.n€7S€)4€7€J€w#€ݼZj€>€€€€€€€€:s€êœw€qj€€€s€€|€Z€€Ɩ€Y€g€€€€€€z+#€€p€€€€€}€€€€V:€€V€€ݼ€v€€€€€€€€€€€€€€€R$Ad€€€/€€?€,€€`I€[uy€> €܅€6€€H€"B€€w€€€B€€€€€%MH€9WY€€€€€€9( €h€
+€7*Y>€J€3€Y€.x$U"€€Ig€€€6€€ۺ€0€€€Gk€Mp€jQ€€€pK€6€;€7€ރ€€Y€\b€€ւqR^q€€3€m€€AE€;F€€€RK€F€A€€++m#€€€Se35H/€€€€2NYVX€€w€A€rPq;Q€G€€2(€`€€c(€.€€^€Hf€€€Q€€L€V€€€€€m2€nZc€€€€Y'4€€b€1€?w€x Z€Y]i€%`€Y€€€€€m
+€ յ€m€€€€€€€€€€hj2/E8hvT€€P=" €€€JiŪF €€€-QÓŸ^AH€5€€mA!>€€€€H€€€;€€M€X€;€Òƒ/€ˆ€.?€[€OxI&€€€!`€€{€bU€~uiT€€Οm€€€€€€{5€PZMÊ”c€€3I€€@G€ € $D)Tt€ M€iU
+L€€€.Ԫ'Z€€€€€F€€€€€€€€€5€h ;U,€G€€€€]f€€€&€€€€a$I€/€4*s€01ڗ€ €Ór8 €€l€Ȍ€€€€€i€&€€Rt?1€i'I€ ѯ36€L̔€€D €€ r1€€€€|Y€|€)€HB€€€`€y€€ĵ€€€P€Q@€€HC€MN€€fr-€€'€7+€3€`#€\€]€r$aQ€€€€!€E€D€m€&€€I€h€€€€€[€jR€(€€kb€JXC€X
+€€p€>€€L€€"S€€*€€=€€M€€kZSX€h€:€€PW€K€€€€9K€?Yn€4W€Z€í§Â€Â€ßžm€€_~€X[Ϸ€€€€€/^~€€€o^€€۷€€€|€€€G€€€€€€€€O€9ywz€<p€€ <Gq€€€`rg€W€€€€€€€€s€ec€€€t€€~0€€€+ €Y€V,€€€€[€€€H.€=€N!ÇœÈ|ZX€̈€€i€€]Ó¼9€€J€w€`€€€€€€€d]€ JL€€6<I€2t€€s€D€€h€€v
+<€€€€€€Ί€€&e+3€€=€N;€ȭ€"GZn
+{€2r€pOBË€Y€€D81€(Ou€€€z€ܧC€Wg€Y*g€€H€€L€{€€€€€€pÛ¾ctx€€€€f{€(ov€€€TÙ€躹jG|Þ›P by€€;4€€!€€€ €€&€€€"*€€€+€R€(€h--#
+Qs€€€ͻ€"€€€€€z\€€O6Iw€`€€ڙ€b€`$€=^€€a€0ÇŠ! €Õ€-€€€€L1k€>€€bV€]€€>€€€€}€Y€"€+€€f}*€€s€€€ wB¾€€€€Bao€ e€€U€€zÚ‰€~€F(h€<€,€€€kL í¿‘Â€,€€€€€€€>€6€uKF€&€€€€€˕4€€]ɹ6€-€€€€:i€D€€83€€€8€X<€s€€€€;€€p€J€€x€>€{N€€€F€€€&:A€€M€€bk€€€€y€S€€€€€€\b€€€€€@€€€€€oE€I€€oU€懪€!R€€€€€cP%€€܆R_€€€:€€ €€U€€y€3€3U€€€/}€€€€€€d€€pgg€x€AoWI€€ʱFX#Z€€OO#SY€f€€€€]€€€6€€aݪ€/€€€3q€ €€e€€€|o€0LЇ~Y#€€€€€}€b€:€=€€€{€€%€€€~€€ B€€ €<€€€€slY<€jj€€€€€€€[€€€€€€€,@ϥ€
+€€€€€ʀ~G€ש L€€ €€@€€f$Tn€ܼuڻ€€€€p€`!€9m 4\€t€€€€€h€€ێ€Y€r e€T€퉌€!€€€f€VG€$€^€nV€€LJ6€ Kxßy7€€C€€€€Y€)€€I€be€M1J€&Y€€€mH"e€€€d€€€€-€vMq€ph€€C€€e€€ €~€€€5
+€i€3€€)€@&6Ö € Hw€€€€€ €€€§€€}^€l€g€€€€€
+€€€:q[@/:}e&€Y4€܀€p€Z€,€Ã{DfH€€S€%€3€€€€€€€z€€=€€€€rЩ€'2/€€t|í€pGG1€€€€ݶϷ€t9P&€€€h1/€I?€€D€€€m€
+Zˇ̧€@€QÂ€Ä (€By€
+x(J'€F €KR€F`€€/€€'€€€E@tf€+<ͅ€€€ 2:P€€€85€2€€gDj€€€`€1 €€€z€€KC€€€j€€€€€*€p\€€E€;15N^€€€€€F€€ٕ50€;€€€O 5j€€F€€&4̥€0€!eQ€€ܫT`Zk€€€*€€Z\€€€GJ€€€€€&€€,!
+8AM€W]€FX 6€`€€€i€b&ܵp€!€€€€€8€€€€'K1€>€€€/nٗ€€Ѿ€W€A€zôI€ BêvVT$-€€€€P+ €€€׻bu€€u€€/h€P€<€#€€S!€€€€€JJML€|M€€€€€€X1t(Vh€8€93€^€ij{€}€/€cI €yT€,€Q€€Q[€{ۯ%?€O^€.QVÂ€î· `€€€€bųicm€l€{€wz€€€n8I€€€6€€€ʘԼu-€€€p€€3€h.€A€€€€wM€J€€€€J€€!H€k€€€~€ l€tL€€-9€CC€€€€J1/€!`€€€C€JWPn€€cW€kp€€€€€3€9€P |€9%€v€G€€X€€€
+€ €b€€=€€€ Ó\€ϕAƲu(!}z€€€,€€€€G!d€€€-€٠€\Y€€€€€HC\€6€€€ €€.€€m€Y€€€€€€2€€€€€Y/€5€€€m€֦€K€l x€6B€€3€̱€€€€€€€J€`c€€rQ€XN€€C€ z#;\€€6€޺ o€i€X€€€+a€€€$€€€€J€ €YD~€€€€Gl0€%Bs€Zxv41€j€R$8€€-Ù€€€YF€€E€Ę€Ø• Ó•€h€ €€=H@C@€€t€€€€.€>$€€€R€9€€ €€€€'€ €W€€h€€€€€;"Ί€BZZ€€€€€€qr€€€€X€€<€€l€€€€€/€€€€m;€Ɉ€~€3€€€z€€€€€l>aRg@PuEÕ‘WÖ·?€W€܃vg€W€€r^€€€iå“‘€€op €€)k€€€€€€1€€Z€€4€€DP€€B€$€sI3€€€.€€݌BVV=JÖ¯WZ|€€ij€€ŗ )€€O=€€€'€€€€€=€+3€m^€€m€
+€€\€€ˣ€€€@€€0Hk€€€€€€€W-€€b€€]€f
+€h€€b €@€€Y€ߖ€€]JŶg'€5]q)€#€&€€€Iĵ €€E7b/`v€€ՖEf49€€Ҏ€X€xl€€h€A€€]Ε€€€€€€^€€H€J+€7 €U€€€€HB€€€ ËŒIkÈ€€ܗC€ztPLƀ€ €,4€€6€C€f€€€€H4Y=i€4€€€€S€s€)€€w3"G6u{€ߧ3€€{q€€€,V€€€€s€€X€€€J&Y€:€}ɳ€XM€€€e €7€F€K€V€C€6€€€WU€Ré€>€>€€É‚G€ €fR€5€H€-€€|€€€€@0€€"€€F'€ߦ€€€nwH9€V&€o .I€<€€E
+€fs*X€€>R€Q0,€Ô$U€<€€€0I
+<e5c€)h@"€€€_€€€€€€€€&ÝŽJ;Et€€€.€€k€p€€cF€_€€A>€€ݚ€€{r€€€€V*m|0o€€€€)'€"1€€€f€Ai €6{€D€€Ƅ-J€p]€€BZ+€R 7zW€^5€€€E€u€€€:€ڥ4€€`]€T€߲€€?€€€ 1€j€7€R7z?€Ŋ€€€+€€€5dG€€L*/€€€€€€€€€¥6€X€€€€€"12€D€€{€*€Z€€V€4u€m7€,€€6€€;u€q€о€ql€ll€€€€€€€€-/ €N€€€@BS€M
+€€€€m€+'€€;€€}Z_ҳ€×`h€!€'€€€uÖ«6€z€F€€Fd;G€&€€xGKח€€q€€H€€؊w{€€€€€4#K€€€€ |€€€y€€u€} €€€€€€o€Xy€€/ߤ€ €KTH€sX€€<k€€€i€6€€€€€
+€€xN€€nn€"€-€€7€W€:€qD"C#€€&^€iWQ9iJ€€4€€€€w€!€Aۗ€Ʒ€€€€j㯇}€€€€€n€€€|Q f^6€y€}€1LhÙ¿€m€€BD몮s,€SND€€(€*€€g%€,€V€&€&€€€m€Nqñ€€`€2[dk€€Pk€€v €€1€Px €l(€ m €€€or<`€€€€€Վ€€€€]y€B€*€r€vp€€И€< [ac€€€T€5€ €€'€r}€y€€€U€ R€€4%'€8€€€€€€*u€€€@Õ¢cT €€<iZ€`صC€€€€€|ӱ€sz€)D Ta€m€d€€Rޜ€ X€€€Q@zl€€U€Be€r€˦m€€€D<w€Q€€BI€€ȳ€M€€6€€&XQaW€ӎ€c€€Ë·Y€€€ F€ '€€x€(6€kZp)e€x6-/€m€€€€'€н€€7@€*€€]<€€€€F€To€€t€g€€ѼU€D€€€!$=qq €m€€€^Q€)x€W€€|'€€€€eq]€֚€
+€^r€{€€
+Õ¾€y€g€€{/n€€*€€€€€C]€Zxb^€L€<€€€€f€2€€€€€€€€>€ug€߭x€5€€€M-€<ׅ€U~€C€y€€€c2€€ €t€h€O€;€€€€€€€€8F€`}f€1€€p0y]€€ݾ€9€ԗu€€€BPp`+€}8n(€€ €€kK@:€€b€€€uL€\€,€€€€ki€J€Q€€€H €L\7r€ӲN€€€!t€€€€k€Ul€€K2€€€ t#€€€=€€ €J€€€.€<¨€€"€1׈^N€}€€€€m1€(>w€€€€,€Źq€€€@SW[d8ޫ€s€CH€,€€€R€€l€€€€€_7€C€€0€€'€€€€4z€.€@Jy€€Z,€ٻ€€̾i€€€€€€S̄€@:€A€€€€€€5€€Y€€€€€_€€€€&G€b8€JD€;Kq€€F €€\€€چ€Q€9€€€ €#|H€jgi€ӂ€UBժ€,a€€V€ € Nf€J € A€р\nFHH€QK)€C€€€€+€܋PSSü`bh€YP€€[ =€€€€Z€2=]CN/,€€8€V_€€AhELJFx€€ €.€]€@€S0bD€€#€€A€€v1"q2€fqɒ€4€ܱ€€h€I€'9€c€€€€€€€.€6}4ݵ`€/LBD€ s€B€ջ€f€oNCp>€€€€܉€LW€K€Yт€Z}€€{ €q YDp€M€'+)X€€W7T€w&€€€€5€€ÈÅ”!€a€€€€€T€j|€€/€€€€€€€_€B<€€€€Ȋqr€F€€f*€r€ϰR€sC€ҵ€?f€€€Q"€B\€€e€€€,€$qb6€1)€֢̉y€d@€7€u€€&&€mlW"€€t0<[€€€€S€BPK€#€€\€€€'€b€€:l€€ L€r!*29
+€€<€€̎€€ ңD<€€)?€€S
+0W €€€€€q€o-€o [€(€€€€×a€€ϫÌ¡'Rm€ܱ€6)€%ڡʩ€Wc=€ޤ€€h€I€€€:k€€_$€€€\€€{€I€€)€Io1€€ǯ€`€BH€€€€€€>,€Wo€\€€p/ɚ€€€€k€€€€€9Y€€V€€s€€V€€* €c€&mgګ€X€€€€>€)€€ܵ!W€€,€€€h26€ק0P€~€!€€€V?"€€€€€€k€€$€€€(qʺŎ€ €€y€€€€YÉ¡<€?r€y€€€€FZpp€€;€ȟY€9€€ۜ€6
+LB€€€pb3o
+€€€v€mE:΢X=gÙª*€ft€!€S€2€ ,#f1€U߀€?^W`/€$€€wtsw€€€5@€rP€!€€€€€$o€€e€ua€Vʻ€)O €€}€6€bM€€S€€>z€€€€G€€7€:Ĭ€@ k6€j€€€€'€o~€4€L€r€€7€^aNzq)kWK;€L€f4p- Ø€€€€€^€U€€<[€€\%€6€€c€€~€€Z=€AF€mf€7=€€€€€€ Gv€€€_€€1C€Cȕ€€€C€€€a^€j}€^+WA+X€€Q€KP€H€WV€€€€w€€5€€qQÅ«Q‹€%€€;€s[€"M€€z€€€c€€€€/€€ö€€€*O€:^€O€;€€_4€O€€€€€2Ҥ€6€€!€mj_d€,2€e}c€€.€€h>€€ Mv€A€j€x€€˜w€hRs€€€€€p€€ €€:P"ê¸Â€Ð§@3#€€€H€€PF€\€€€.€w€GW€z€€D]€€5€€־$#l€n€mÜ·_ ;M€€€€€€€X€€Ch€€^€€8€c€"€€€K€u/€€<€Ä€€b€€nZk€ݗ€暬g€€€#k€€€€e€ȗᲾ€€qGz€ vL€€EQ€-"€€€€€€€€€€up€€€€€崞€Ù€€mH€€€€€x€€"€x€ f[`f€€€€jnA€*€U€€d>B€ȗ*d€b€7€€€w}€@€€gbD€€1€{c€€€€€€€io€€B Ô2U€e€
+bK9€q€dc€€€€€D;#vI€a€oel€€
+€€€"€x€€€€tvpp€€o€€ 8€€=€&Vh O1€€"€l€”@5€€€[Z€€€ ry€€€:*€€€ T€€€ä‹ʴ€€(€*€m{€€€€] "Þ¥.p€۹/€VÓg€€P€€kAɤ€CuDG€€<r\€)G€1€€xJ.l€V&-€Y\€€€€€€꠪"9€€€€&€@€€L€j€€€€Լz€€/€" €v€€c€€€*€cHp[€ €€ʸ€€⊑ ÖµDsX€€€€€€0€9€€€AS€|€€ [€Y€€€L€R€€€/p€d5€pk€ €€€€€€€N€a€@G€€€w%€€c@€:n
+€L/e€€<J@€y€]»€{ €€[PJa º
+l€€k€>M€x&3 ስ€€ja€€,mcc}Z€€=/2€l€€€qQ€€m;€y€:€€E€ z€€t€€€%͊z€8€€€€-;x€€W€Y€̚})€E€€€ ,€,€ d€€4€€(€€K|CU€€W€€€€b€_€4€k|€€&€t%€(€txS€I:€€z~9KnTM(m؜v
+€!1Qۈ€R€rѻ€€+UH€r€€00$€82€€€€#
+€€€
+€n€€J€€€0 x€€€o€sBIlY'L€€t8IC&֌€€88€$j€€€€x€€Az€E€.Z_zPݱG7B€t
+:€€)l€V2€€€€c€|€€g€€€€7€+7F€€o€€€€€8€€tv⤭>€hwW€(Ӭ€€*0€€yaF€)m€Յ€€c€€!€K€c€€€€.€U€€€€€€,€Y€€€€dEq뤴`€]F0€8€€€€,€BN€€M&&J€€ .Z:€'€-€€€€5€ui€@€nm€}€€1Iµ4€
+"5€€€^€€€€0€^€€€*F€€€€€€€V]€x€€€€B€B€€€N€€€€€€⒆€€KԷ €cW€€qLb€€H€€X€.\/€€
+o€€
+N€€p'€€HW€y€€€€g€€C€€€z€:5€€€}-R€€"€]€€€€ Ъ€€!€€’ ^3€S€€€€J]ң.r56€bm€e€€1€&€|`wa€€€€6~€0 co€ c€€€Y€B€1€), C€€ €Pd€€5V€Czx€ǘt €f€V€Ư€€ݶ€bߓ€.€€K€v%le =€ j€€€€€
+€€2€€€ǜ€€€JN€€I€€€^€I€W€€€R@L6€€€-e€€€€Y4H€€€€€^€€€\€€h9jÚ½Ô‡€#€€€ ̆բ €#JV }€4€€#€€€w€€N7€€€]€4yL€€€l6S€r€€€€ƻi€Þ€€€€O7€€€/€€€€r€€€Z€Tr€€€€€!€€€€*n€qG€€i)€D`€€€,€€M€€z€€%m€ .`€8€VdJ5€€7IHp?€q€R€TVgg€kc€-&€Ş€4€€€@X€€€XyE€>€K[€V€S̉Ԇ€h€"€#€€.".€oP彤)8€€֨j€€€N€€ €<€06€2ZjA7N€5€€€VD€€€u€/€#U€€€<€o37€A€^89€0Z2{62*NoD€€ @g€€.x-DZ€r€nn€e€NïšÂ€Â€:€€Y€غ;€€`U€€€^2*y€€€z @Kx€T€[€#nZ€2€€F]€€€€бj€€€E€K:u vYR€a€€€L€r€€-€‰Q€€Z€Ju3auK>kGA9€€ѿ€-c€€€1€"
+b€\W€€|L
+€€{€€€CpIB€€€E
+€oiʚ€€€`,€Wb€˾Qpy€+€!€€€2€€€5?€€L€w€€€€€Yu€@€€wuB€€€€[VX€A\€€J€?ؙ€4€g+U€)0̒€E€€€=€f€€€I€BW*€*€€€€€@€€n€T38€ €€€Z;P`_€€!€€€߄€֑€Z€Y€n3д€€nǓ€aÕe€€€._€€€€Ê« €€€'€€i€€€S-€€å€€y
+€€:P€S€€f€f3€€IJW{\€"!I€-€€€e€€ ˜€€L<€€v€eds€UsuGPw€€&Ù¶Bv€€t EX€7€€€Z‹l€4€Pɼ€P€A3€;€r9;V€€€I[{€€€`2])€€€€T€ Ƴ3€€H€€€€€ٙGq?8€€\ €€y€€€€€€Ģ€}€_5€8PBRm €J€虞€€R€€8€,A€\Ù¬X€€X9€l@€€€¹>€`TÏ®{Ò¹j€€€€:9€`o€#€€M;€€€N€abv€€п%€f+€€B€L€€€n*\j€€€t?€E€€IRߎ!J>€€o D€g€€rgFy5M€ȥS
+€_€€€\뢓€ÖZ€€]€€v)€€Bs+$gtè¡€L0m]T€€€g"q[Dž€ }8ʈ€(`k€€eK
+€€]€)!€€€€€d€€€wޔ€2.€€x€€p6Zn€€€e€€`\X㡴€€.€p€J€€€m€€€?Y€€€€;€\€`y€4€€€)5F€[5€€q€*€=€€€€J€€€+ W€D(o€K6€>(€€€<€€)g€d€€€{€€€€9ˆy^€€€€€€(p€€€€€€,€€&9€€T!(Úǜؖ€$€tf&.€€=€€$€j F)€€D;Ғ€+:9€€.€맭€.z€€Q85
+€€U€c"y€€>€€€kHx€€€€ÖR€€5€€}9€_4€€XS€êŒÂ€n€€€€€O€€€€€€m€€€€9€€|€€€oÛ´€€
+€⓯€€3€ς€€t€€€F€€€€Խ ڥ€€&€@€€€{€Ӆ€n€X3€z=;€ɮۘ€g%y€e03Q,K€3€FJ€EO€€VYu€€€0€m€[€€€€3Ҧ€2€A€f€€0=3U€lG€€?mU€x4€€T€soQЫ€€€ €€€€€€€€N€"ZAh€€€€€sM}A.5€PE€ɡ쪑w€j==U€Qq"€€€€S+€G€€P€€_€{€€€2":€~€€q:€N3A €2
+€€!€€€Q€d7{aU€€€€€e€€g6€€€q
+€̤€€ˑ€€ €D€64_yX€€O€{€ָf) AL€€€€€9^~€k€€:€z€'€a€`€€€€ F€&Ħ€^A€@H$r€€k€€\€ZR€€€$€€zê©®)€Y"XR€& €€€€M;:€ݩ€€|€F€`&€8€-€€@€$€€€€P€€€^€/€€€€€J€Qt€€H€€45€O€€€t€€€€p€€€A€€€pI€€€Ȓ€€b€2*€€€}QzLx€€Q€#€/}'+€€>€€)€e€htBn-€'jZ€^i€ʹ€}c€;€€S€€pUr€€SF[s€Q+ @%€€€€T€€€€u+€ƃpT€€#Z€€앚p.€/€€€€€€T€z>€+€Êèe\€?€v!€dM}/€€€€3€€k]€O€€bDK€€€€H.+Pg\€€€€€D €G&€€M-€€F€€PK€6€€tкk-v€He€E2€€€€t,€€Ҡ€€€we€€€D€€e>)
+?Ke€€<6€€€ul€&^€W€Gj€€€€q*^>€€€€€bW€(;\Mʲ€Y€€€uf€€€ q[O€8kYYNo€€,'buG)€€€€€b5€€€€]€x€ӅH]75€Q0€ki€1{dT€P€€€@i€€΋€:&+€€J€ €€€€d €€€*€€ {€€8€€€"BG>€€ċ}€8€€; €€T€€
+€€u€J<€n7€#ƑD€!H€N$$€] zDH€€g€ɽ€n€€I€€€]]̩€L€€€€€€Ψd€u
+5€=.7<$€bv€aZ€Dm€€x€€=€€€€o€€€€€#w$€&€m€€+€€|F€€Ņ€@AC.€€e€€'€8€=yV6>€jcíž«A四€p€yf€%€€€€XR!Z€€€O€€€€y€ €BZUlRj€^€0€<mAG0€u, €C€B@€2 €B€N€H€€€€ω~z'€v€1€€€€€60€ػ€Y!€€KÕƒ.€d€€€(}F€€€€a€€€h|:`€ €€"do€€5€€€j€€Þ€zs€и7€;@צ2xG
+=€€€€€€€J€€8 €#€€€p Q€!p1I€A€€€€€€e€€aaj€€>6> €€F€€€€=€ɶ€<x€€j€Hxy)€€€€мbT-€$N]€€€€_V=€€<r€€࿲V€€€hp,U€€Eu€k{€{€&$€t€€_3€3/HO"€€9NЛ €€€܀€€TB €€Pv€€4€r~[€ €[s€B€€v€€€9€M€
+€@g€)ûJ€v}1NnOY€0€9€ _Ï—Z+€mS€'z€€p€€Xz€€€€€€€€€wm(_La*€c€'€%€Ԧ€€€fꀀ"H€€€€€€9€{€€€8€€€€@€B€€f€G;Z€€kAƀ{€`€>€?P€U€i€.€/€€I€-€Gh*3*R€€[>€\*€.Na€E€m€$€ *€+S~€€7!%€Å/€X1}€~€[͘€€€7€€€-€Q€€p!€Y€€4€n(L€€5€€N€€€(€€.€€€€€€nN€€5€€v€G>R!€i€1€€ +%%w€Iwvp<€€伺L€€u€€€_€€€€:€€€€€€}€€8@N`N€G€߮€€€€€_xL59€r€€k€€Axpe€편€S$c]€€n€,.€xf€€€'Z€€C5€0€}XK€_3€€[,€ԋy4€€€t
+€€€ꂊ€:%j€€€.€€€x1,€+€€€1&€€€o€€nV+€€€!€€€€€€NA€eqF€€€ c€% -€:€IS€n>k€lH€S19h €€€zA}€Iq€€€€"€M0€ wT€€€C€€5T€€€€€€€V€!)€jl €N12m€4€€Lò€U&€V€{€,€€€n€€€€€{€@(,€d€l €5€€€>jzӥ€€€€€€:2€€"€s]t€)€€؉€€€€€N:V€€ €B€€€
+€€'a€€#\pVI€€|/€€.€zd<i€0€!€[€M€€€€ €N€j€pÖ£VL7€jqAMam€Oa€€€€€p€€
+€€Ub€@:€A€€€8€€:€V€0€DXނ€ €o€<€U€€e$B"G€nc€€€€€€€d€€:o€M €$̪ؔ€€€€쌌€€[#ʮ€L€€€jDES€;€L€t€x:€X€L>f€h€P€€c€d€€x€€€€pf80o€.Q€ ( €M3€5€€€1Dz€€|€%Q€9~€€ €€N€췧€&€4ØQ€ Êœ€€€;9€€_tw>€ʰ€<ĩ€€.>€€€e5€x€*e€J€q>€G€€
+€€€€b€€ B. €€€)€€͇€€&~€€uݙ€€y€€€II)€€€€€€U- €-}€ Ë€€|j€>~€BJff+€€R`﷙€€€\€Pm€€6€k€€€R €H€t6€€€n 2€€.Ä•Iu6€7d5€(€€€쮾€€)€€Êcn€,€€€~€/u€€r
+)€4Q`€.€€€€€€h€4m€7€€Q€K€L<€`W;€<$E.€yb€Ŧ&[€L(€K#€fpH#€€\r€D,€"€=Em€€€€]€€Q €9Q€€€6€z€s}€€Ź€€€)€c€€Ir€€k€ €E€$_€€€€€w €€/€€€tq€€€€u€€€€€€v o€€€€}€€n€€i€€V?G€€<布€€€€
+€€€3€Ք(€d€u€J[€/k޽?€t€€€€€b€€@T €離€^€3L92€€€€€€~€ €€€t"M€€€€€€:F;€€€t€€€€#€]㴇€€€€€b4€z+H€€7€d€€€€€€€€€€d€€€€€#€€(€Km€b€€,€&€€
+?€€€"€'€v€`܌€€€4+€€g1t€u#:X€ €T€€Hp€€wpH€€€€€'€€.€€S€€
+JR€€€̘2$€6€<_€€ _€ 5-€B&-`€`€€K€€#€€€€v€a=\€€r€€N-€b€€:€€€Ժ€Lnӥ€€€xJ1,€W'K€€0h0€0˷€(%L€€KZ1€€€dq€'€f|€€€€€|<W€J€%€€€n€w€€€I€€€€€€4ë–€f€€k€L€€4€€6€€nj€€a>€1c€€^€€€{€€t€€4€y$+€€€ h0€€€€€k€0€€€K8Y;€€6Ìš€FM'Ü«Q
+T \€P€€)€€h€€€B€ݘ€b€€€tÒ“))g,U€/Ws€€r|€€€+€€R€€€f€€€€€m€€l?€€)€€€W>mT€€€gb€€€€.Ù®Y€€ ]€€€€€€VP€€W€€€ n€I€~€€€K1J€Y€P€€€€€€€€L€d€€!€vVAa€w€Ì€€ޙ€X€ߔw€€€R€`€v €p€ q]Ú¬€b€Q??"€€€€m€€^ט€€€T€€4€31T{€€€9€آ€I€€ C_֬€qT€€8€€€€(Òd€€€ w`€x€`€ <€€[w€f€"€€€€€-€R€€fI€Yf€
+€€L€€€G€€v€`08€€€€1€€I€2ÎmS€€€€€€€€€en5.q€A€W€3€n€€€9€€^
+€€€u+<€/€U€j€7€€[€.€{R€€/€€>8€C €Y€€;L€€€h€€d€Z0n €6/€7€ȕ䒗¶j9€K&€ȴ€€€€KpV@Ö»2Æ¥X?p4€#€s€€,€4€Ï€P€€€=€%€€€€KW€ǜ€ɳ̲d€f;,s€€m:€€㼳€€€€Z}€V~€õ€€€€/Kfq€{}ք€€€€€€€<=€€w€€€€€r€W€-a=xP{€€k€^€6€€;€€€s€€€.Zl;KÆ €0€i€m€n9 €€€Q+€€Th€6€€y€S€€€Z€€w€€€€1€O€?5€؋€€/€€€}€b€>!+€€&+€€€€\€€€€€t€yp€€€€G€€€€hI€_'q€€€g€
+€€€€]K9€€{€€€ €]:€7^€ozjblX€€€J3€€€€€Ϸ%%s€?€J€€cÄ Â€Â€4o€>€=€o5€€€€€€E€€Д€€_59€lV4:D€€€€5€€€J€N€€JÅš'€_€Hz€€F€J7€€€2ILP€€,€mK€€_€u uN€€€€]€€€€e€~.J€€€ÇžP €€2W€€€€€€€#€;:€hH€K€g
+(h€ €)S€€€,€€r€]€€€€
+€€€€4Qzko€€<€€€O€€€€€1€;xZ€C€(€"€&€v€iک€v3^€m€v€B\€`=€€€,`€L€€€=ќ€~"1E€ñ€j#€€€€€k€[o€n`€dzˊ€u4€t€€€ѣ€+-~NL€€tbfx€}o,€€3€€t€€}",€€€Թ^κ€{€f€€]m€€(€€€xj €€}€=US€v€€+Y€€|€T€4€€€ cycle.awkbtixlsc€€€6€€€TEXT€€&K€€&LX€€a
+€€ €€rz€€ԉ=€€`G€#3J€€Q€+ó#€ x=]߀{€€#+Y € €€€G€'€n%FP€r€@€ҋ€Z€  ieB (K€€ €€€€5€€>u€€€€€€7€€u€€ٖ€€\€€€E>€€l€D€a€oW0€#;€€€V€v€€7€€€hV
+o~€€
+€3€"^€}€€Hx2€€€€}€]mIQ
+i€}€ M€,€&€€x=O€€>€xw€%Öq€@099L€€€*€R-€
+€O€€"~o㈾€€€*f€X€€q€€€;l€
+€x€pxhH$:€IEmycoc jÒ€€N€€€>e€€€€1€1€o€€"€s]d´텎€€M€zx€p€y€z}€€€€€#€€X}i€€^oZu€s€€Qg_€€€XG€e€€€G€jx€€Z}€€>€€I€€€~l€~+ZÕ¢|I€€Ƹ)€P€qF€€€Z€€q?€.MRHpy€&J\(F€Bv}\€%€O€€q€*#€o0@(9€€€€€T€c€€s!P€€<€cm€ € T€€>€F€€€Y€€€Mbya€€b€=€9 €
+0zfY€ʸH€A€a[€€€€ڀ€ cycle.webbtixlscb4;L€€TEXTMPS €m5!€m5!€Q4€.~ NW€x€ `€~€€z€<~€<€[€€P¼:J€ €€pJ8€'?€€€Sz€€"€€59€€ €€€€9€y~€89N朠f€€ ,€Em9wz€€€€€€€Ժ"1t€^Í»t6€{<Ѕ€*qiF€€€T'A€h€.- M€€€:r+€r€J€€'k€9|>A\X€H€I€€t€+Ec€+€xv€€€€?^BO!ST&N€@#€T€€GQ€ݑ
+x€fB€<͑ ^Im€€€€€1€Ύ€0€€€€€€€€€€€€€%͜Fm0͵be€€€|.€t€d€€€r€€=€e€€€€qi z€'€€%€OF€€yJ€(r€€.H€Y€Ы€rAA
+€€MR€€J€{€ɸv€€G€€%€Ps€€`€€i€€Rnm€1nzWLJ?/{Ñ™Q€3;€G€€PjMP€(€̞€€ €€€€@!K€R€€€SN€'b€hR€Dž1€Q€}€ í½°`€]€q0v€hg€€d[€u€nGW€F€€€1€P€€€"3<f:€yS€€yngL€€3€K €€€€€€€€'€€€€€$cE€m€€P€€L€T3€A€d€€X€YmR[pN €_€S€€W`,`€€€€€:€€€V€€#€*€€/€x 8€̺;€€[OEa€'€B€€]€€B€-€€€Nh o€€€ݦ4€ I€<d€|€H€{RL€f{zQk{€`€€8:€€€€€5€€€€&n€C€X€€n€:€c€ވ€€€€€€€€څ`56݈€€gj€€Þv&ο (€€EB€]jÞ˜f€0€€€Z€€€€һ€€€P:€ˡy€a{€€.€€€مs€€€€€a€€€#€k€€A,€€K-o€€^€€€€k€€]€R?&C}Ê°s€€Z€€g_5ۦϲ
+€V€o Y€̀€€Tk€UX€Q€*€y,(€PY€€€+g9~€t:s|€m€ء€U€€'x€b€*ޭ€€€€$M7€ G€*€B€€=€Y2€?€€€€ 5€€€€S€M€Z_=€yI*€€s€t€Z-Q9€&Q€€qQ€€€nu€T ,€n€€€^€€;€_€X7+€1Ó€ f€s € €uX^ €€kأ€€€iW€€€€|€€€€]€f€g#€€*€6€€€n€q€€NG€Y€[€]€G{€n€€t€€u€€?€€€@€%€€€+€€€O€$€'@€€Jc€7€B€8€€€€/€€€€€€€€€€€€€ junk.listbtixlsc€q6€<9€€TEXTMPS €m5(€m5(€}€>€€Q€j€6Ri€€ZA€€ 6€0€€€PrÔ—.Z€Z<€€ 0r€€A7€€PX€€|€@€0€€€€€€€?€W€%b€0€€ plN€v€<€€0€ꇼ€B€€ܘ€€HNz€P€!b€€€ËY€ZZR € Make.prettyixlsc0€;L=€€€TEXTMPS €m5$€m5$€}\=sQ€€€€ȟ€`€€Qk@z6€A€€€;+€˖€7;L€€€}n€a€.€€€€€Z€A€pa€d@P2€ þ0€€`6€€€"€€g€€~€€€€2€A€€]€€€m\$€€Ö|! €~€€`€€€€N€V€€€€ #E(€€rԗ€#€"€€>$&€u0€Ì€iZ€€€€Ar0€ €E>€€€€€€0€€Ơ€8W€Ȼ€}n/€-€A_€?€€Q<€$w€€€€șN€€<c M€€|€ €€€€€€D'€€€€{€€a Makefilettyixlsc€s<9?€€TEXTMPS €m5'€m5'€€€€Z€Q€€€€ȟ€`€€Qk@z6€A€€€;+€˖€7;L€€€}n€a€.€€€€€Z€A€pa€d@P2€ þ0€€`6€€€"€€g€€~€€€€2€A€€]€€€m\$€€Ö|! €~€€`€€€B{€€F€€`v€5 s!€€€ €€€€€
+€€( €3€4€€€7'€'o€$o€€€€€FaRK9ߓ€{~I€ة€x!€.LJ€5€Rm€B€ €€€|K#€0̱>€ÂJ!$#Þ‰4€€€€%e€€€ multitang.chxlsc€€=€D€€€TEXTMPS €m5€€EH€
+€€€€ X€u€vb€€€€f€€t€Ǒ€€€! €MC€|Y€2" K€€€€€€gv€aO€€€€€ze€€€4:
+P€ql€</ϒ€€€ €€€€M€8X€€ J€€€€S7€€€S+^€IӺ€€9€€aw€T€€9#)€€(b =€i6€€;€>€>|€S€"€€V6*w€3€€€c€€€1f€R€€€€F B€3&[ NW€€|%€o€€€;€€€€€a€€焓€#O€€`€€`€ӕ€Ϩ€n=€~€€€€€€€rr€€8A#9}€5€€€/€€켲"Z€O=€A€T€)€€DQifx1€Nu,€6yI€€u€€€€?€€€v Ò–:€hQh€€€&€Y€Y=€€:S€3€€S]Ò*€T€€<[^€NI€€
+R€€_€€€€UB€%€€€`-t^Z%2€?€€€Pd %-€ €δ6 €€€€k€€€q€U€eV€-I€Aذ€C€€2€€€€g8r€€\p>[€€q€$S€
+Xo€€€€€€'€€€€> Gٙ€b,©€€€€€€€"€€̸€€E€P€€hn<€€€ڊ€€€R€€U€.€€Qy2ګ€E<€€€€c€€}:€8€,€Z€֊L€€€#/€€0b€W€€'€€€€€€o€€€Y€€ED€d&o€€X€ €>€ g€€&O€6t`C<Ҷڤ€b [:€ X€€u€a5€€R€6W €w€HT\€€€Ý€€5€H_€€s€^€€€€€€Âf€b€<€"€€€€€€$€~=k+.I€؋zJ€rq€A€I€8T €
+cf€g€B 6A €€€$€€Cܺ€ €€€Po€E€€43€€€€^6€}€€a€€€v€€ m€i€!€€€€€€€T€y€Ӡy€A:€<€ €T€i€€4ӹ€€€y€€€€X€€€7€€€€:€W_l€€€qĵ€h€FQ €€]a€jv€€€7 €€€ €€€.JlE€€0€d€€dgL€Ʊo€€€T\4€€€€8€\€€€€€< €€i€3/L€p€ €€#v€BlÅ¥3€a9Uc€)€€c€@€m6Ԏ€€甌€€€K€B€€€€€sOc€€~:8hs˔€€€€2x\ Ý€7 ?€€€%€uޥ€€e€癡€€€>€߄€€€€€83€
+|5€€ S€9€€€)np€z!€€.€F*€̂€€F€€€Lʎ€€f€€N[4ִ€€Ʀ.|Y=i}m€ƚYA€€€€€€€ €'€ €%€͖߸UB+՟€€€bt_€€€`€\€€€€К[Z}~C€ €€€,€0€€€o€€€Sf%؆EC?X€4Q€.€€#J€€€€€U€€€€ €€€e€€€€€ €€&QW€€Z7€G€GT€?€€^€€G]€Oj7,X?_€€v|~€'E,A€N€S€},s€€€
+€Î€€€s0*€€Ek €€€ٚGu7€€N€€€€€)€€€€c€€€€€0^([y€3€€I€€€ !€+€ €h€I €€oQ|€ newdefs.awkhxlscI€?E€€€4@TEXTMPS €CD €CD €€c€P€Q€j€a€`<0€! `€ ,€H6€w2€a€€€/€€c? €y€€€€>€ x€<€€€[z`€0)" €7Km€Mm&€v€€€€)€ €€o€LT€+80€€€(7€€€€€J@3b€h&"€€€€" €B€~X8H8 €<€
+nodups.awkkhxlscÝD€F€€€TEXT€€&L€€&M€€?€€LQ€j€6€h€€ZA€€ € €€!r€5€"€ d€|!€Mc€^€€K€f€€؇€ᜀ€€€€€S~€?€g€k€4k$€€!€€!,2"€x96€€€€€€Y>€€v€LC€€€"€€)O€E6€€€Ï€€€AB^€^€r€UKK€e€€ obj`€E€G€€€GC€€€€€AFp€c!! SpiderWEB €ourcG€
+F€F€€€€Q€€Q€l€€€ pathopen.choxlscČF€KE€€TEXTMPS €€€€=€€€€%€€€€€€€vbU€D€*I€€6€t€€€€€2€€F:€€€€ƣ€€R€<N€€€3€€#E_€a€€€T€@αN€€DH*€2€€€)€€€ʙiD€0&€€b€€GR€€p€€# €4€€YQ*p+€3€ ,€R&Π,€:€€€"̲2€9€*€€K€€L*Mn€€€vў€L€€€€€I€€I€&€O€L€€L€L€€mN€)€€€9`€g€Y€€'5{€€`6‘€€€€€t&ַ€ € €:
+u4p€&€€1S€€€€O5Zj€~€
+N)y€ `*9z:€€€:2`€)>€€€€c€(9€J€#O€J€€€€€€p€sek€€ € \GOF80Œ0€F@%̣
+€@€BIs€€€B€#€€€m€€ʺ{€€€€€m>€J€^€q€_€€€€€NV
+€€€€Rk€!€ǬR89€€€€€€&€€€kՑ€€3€€t€=€€IB€k€Y€ч€€A€0€+X€)€€ €€KS€f5€${€EK€€N€€Z7x€T€UJ€;€M€j3€€=€€ܽ l€]€€~€\ h€€€fIx*€€€€€€€*렀€h€€%€€€€€z€€O€€€€€€3Fdb^€€]€p€0€€€QPР€#œ€€€w€€€!S€$€€8€€€€€t€z€E.€€\€_r€€C€ľ\€G/€€€€€€^€€€ڭ€€p!€€Fo€,+'€€€€|€€zDE€S8€ѳ€€€€t<€c€.€€€l$€4€Ş€!€€g€€€€,gS7v ~H€oq.€€祗\€€Qr€R€}€qk1€W€€€mQ€€€mD7€9€€竫€€€ۼ€vf€[€ـ€y3€€~€€€€€v!48€€@€Ү€€€? pathopen.webxlsc€+G€V/€€TEXTMPS €m5$€m5$€€€ }€€ks€y€vbUw€€D€p€€)€€€€0_€K€"€ˑ€g€€€ƣ€€€~5=€€PRÏ?€N:{€€~€˨W`€€N€€Y2-_'€IN€)€€€F\'"€j€-Td€F€kÕŠI€€€€É”1$%€€€€€QA33€€jp€h€€x_€Z€€€€€<NT_€€DefqǢ€ۃtMw€c}€fÌ™A"€ *x€€€€€b€ €
+@t€g€Y€€q€€E7p€€€€€€€t&€X€Õ€78
+u4p€&€€1S€€€€O5Zj߳€ NW€€€;u€V€eG€€le€F€t€€lFX€Y€w€€€l€€€s=% €€€^€Z€€6A?Z€€€€€€€€€Fn€M~€€&€M€€'€€€€[}IOl€)€*€t€€_C€zn€u€€€h€€fL€&€€R;€qJ€€€€€€v€Kze€TS€tBK[R€.)€€€N;€y€€€ €m€€€س€€€€€€ִ4€€'߾€€€€o€€€<€TS€:€€€R€ޖ€€^.€€€€81yb€Ea€€€€€|€U€€y€K€T1 €€W€qÐTX€/&€:O€€€€€€bƓ€€F€€€"3€8€x€-t€€>€< ȭ€\€ڹ€4Ù¦u+€ʃ]cuZ€Bg€€<€0^\j€€€͂€€7A€+tl€€&>€(€QBvIÞ¬5€b€GY& €%€€€€7˛€€b€i,u€E1\>7а[ƒ¾A=Q €F€€€€€€€€€L€N€G€(€€€€€€Ƨ€5IO0;€€(€€€€^€€€€,€"T1€€€V€cb€U.Qtt€I€+l€Y€€X€Ľ5€Z€qFz.>:€€ٽ€Y€€#zj€F€YA€€E€€{}€8+9Ω€€2Jt€€_L~€O€&€)fTo€b€€N€Wz}{q€mqt̾69€€€ >€€q€€€ÓŸYÄ¥Zص€€o€|Y€€€%€4VS€5EyB€"_€z{€Y€5€ J€€€.H`A€€/n€y€歒€2Q}P€V€€x€-€AU€€€8€37UxH€ €€€"€m€
+€8Æ….€€€€b>€`KQ€U €€p:É€€c€B=&€d
+6H€F€€8]B%€X€€E€€€(€U€GI‘€38h€V>N€€€D€€;6R€d~€€`€€€.KS:€ƪZ3fab€€€g€j€ € €v€#€`֘€€׼7€awlqp€6€€oW€€ [€€€€i`4€€€̶FH_€€€3hR€€J€E€€€d5 €nZi€€€€€€_=€9=8b€€|@D€秈€̟€€€]u€g؃>E€ţ€0J$6€ܰ€€Æ€%a€X€`€@€)[€€€*$€o&z€%€€€€?<€P€zQ€sꣻG€`€€+€1e€'G€Ch;Ѭ€:€&nlM€€€Uq €1€€`9€€(γ€N€a€zLj€s€€U€vWa€€VZ€€҃€o9€€ɬ€€\N1€€€€̞€q€€€nM€€<€(j€€2)2€m€4(+UNX€%V€+€€_v€n€€wÞ¡`_€€)wztZ€€U€€$€€€2€A_€€i€€€^aO€T€D`L€NvÖœE€
+€3k€ʥ€*€L€Z€=€/€J€€=+q*XG€x€՗€5€j€€€€Xh€ș€ !'&€€€+€€€"€€€1€€€Ky€BSNe€uu€n€€#:€2€€Lo٠€u€X
+€.€|zu€€€€2O€€}€€€'A>€€€Kt€€€€]WOH€=€€V€a€€€ €!nR€€€Vb€R€jS3€€€K[!Y€€E=€6o€"K, €€vlt€_€U86q"}€[K €€%Ҳ€kz€K;QuC€Cg€€€€€R€OQl€€̸€qcd3Z€€€׭€7€u€ €Z€€€q€$€€4
+V€ )=€A6 €€€€€)?Ap€*€€ nk€€ € N.€€ €S€o€KS€Càh€M-€€D€€€g€7€ѯ€€€€0v€€W€€€€yg€€y€€O€
+ €c".%€€ٽi;&€€s€€Aۛڀ>E€+of€€€€€f€€¦€€€€€Y|m€G€B€.€€}€€€4U]€A€RG>€O6€€sÒ©mO=€c€z€5€8U€€~€Y€T€"Y<€qi4}€€lV=€€IP€€(5t4€&I€€€€&€€€€z€y'€P€€€€f€a4bU[€€€€€€ €h€€€ZN.{€J€c €% J nݪ€܄€€€Z?€€€,F€BM1€x€F€l€&€=€L&Çf|<€€€_€5€8u€€T€€O?nݧ۷%4€x€1€zʟ€€€-twx€, €€€y€ €pK €€v€C€O=΅€&€€w€€€€ϾtM€€W€҅€€€€`l€u€ã†:€-CxrÇ€r€€d€€€€AÊ‚{7fG€{G€#Q€* €€?€€€€ ! €€H€Ή&€<N:€a€€%€Þ•e€x H!€€Cg€€ €aBl€@r€>€€K ~†jh€€€€y€ۜ€€€\€€K€T€€^€€{€'P€5€N€€u1€z€. Y€!€€€V€J`c€€?po€'ق€€*3€€4J€PLB(€€Z~Yn€€€€€ۓ€€%€B(9<€ €€Ä€€XȻ€b€€€€(h€ucD€€€ Q€€€€ €€€N€~€l€l€v€K€ €Hv€b€q&€€B€C€o}€€,๴€.€€€bv€b€€€UP`i€}€€K€a 3|€€€€^€€€€A#€€md€è§.K€C8€
+*{=€<€€€ʃ€6€\B €e€gz€|b€$}€€Mv€€`[€I=€ʊA\€€€€z€€€ÐF` €qPÜ£V€€c€?6€Q€€€m€€L€€€˟€€Y€XS€X'€€€€€€ €€€G€2€b€Kx€rfp€e€€€$D€€€wy€€€J€€ >@€EN€€€( _9€O p€c€€€i3€€€€€€€€€€€€
+pretty.awkebxlsc€
+KEV€€€h@TEXTMPS €CD €CD %%€nx€/^\\Y/,/\\par$/ {print; next} {next}
+spider.awkebxlsc€WV/€€€€TEXT€€&€€&Jy€,Q€(€€d€€Z/=€6d€q€-€,B9€€>᳕€
+€<€€€€۲zq€€l€€€f€]^€4€'۫€/€€W[jpG€ €Su€du5{ee€€€€€€R]g€o€€s>w:^€€€€۟€ݶ3€€ٽ€m€€3€€€€€8€€€€w€~€€€g+€€UÕ‡]€€€€ڹ_kw€€=€€€Râ‘€€€€*~€Y3€€r2€_k€f€€4€€€ €€€Ρk€€€A€€€€€,€€֣€f/FU€/€€4€b€€€ϟ€n/Hݹ€ €€Z^۱€€€3hbr€€€€€^ë“>|€€€€o€vT+A€=€€xC€6i€€€€€€gC€%6mI€lIy€%€_k€|€€€K€F€€€€k€€€/€€=?€X1€€kv€t€etdhDyQ€€h~€T€€€€qN€S€€€p€€€€€€€ €€ _O€H*€ E€I€.€Z{€€v€> €q|T?€€~8€€6€Ͷlf[€€mn€€A€€۟@€'€€€ҖiV=€€€€€€'€?€€€€:€€2ou\?3€Ќ4&€€€€€€€S€€€q0€€V€€€€€(€€U/.ק€O€€k;AZj€€€~€m=€€€€€€]€&€€€i€ €€€s௜€€€w€€ĀV-€€
+€5€€:€€€1W€NjI#€j€.T s€`€€?H€]/p€\g€zX3O€̷LF€€I€€W6€A€€ƻ€€Ņ€€#€€€€€4€~€€€€Mz€€€€€v€€€/€j€€Î€Ja €s€€€k €€Ǖ€sGLa\€A€€%€€€€{8O€€€z€€€^€€€€L=x~€€*pU=€€4€}€d€?YU€€€4€€€z€'€€€€€€5€€€€u€€€E€)b!€€€P€€€€9€7€€€€I€S€€z*|€€x>€€:€k€€€o€#€€€€<u€$jٕ€€F€€€€%͙€€<€€V€Y7€n>[ᬉu5€#䕞€4€€]R€a€j^3Y€€6€€€€7 maÊœ€€ `K<€o€$€€3€N€€Ԉ€€€€,€€+FRp€€!3p€€"€$8f €se5>€Qr{€€€~€ <z@Ô‚^€€zE 9€€€s€€j€€€€7Xskf€€€€{€o€?[q€֮€5€ĸS€fcc€W]€€€€€K€€€6€jv€€€\ð€Zֳ€r=Ã’jgQR|s€€U€a€>€€€=€€€'5R€€€A€;x€€ְ7pZ€~€€#hR€q"A8€}6€€U7€€z€f*}€€ €€@/_P€9€Q0
+c`P€€L€v€P€9€€€j€iGd€€€€€n€î½Â€ €€€€€€€€€i€|€Z€€€m€F ؓ€(€€.E"j!WÕˆ&€€V€€€(€.€B)€쭩~€€:€;€€9~€F`5€€€a€€](€<)€€€y€€D€€i-€€€'U{€€×€€|€ܱ€€8€n€€nG€˩€€€€€!6€XD˔€\@€€€t\[6€€N €<€€€€E)F€U;f9€W€S(x€Ը€kÈk0Z\0€# €€ե€€:?ɉ/t],Z€N m€HP€l€€"z€€€<€€€+€€N€Z_Z€HU{q€C€y€€€m€€€8€€۶€€€>X€€€(D€#€v"Y <>€€Cohu€~`í»Ÿ;VS€€ €]Y\n€ު€R6f€V€Z;]X:€"€u€5€sv€€€€€^€8€y€€€€u€€z€€€^€`€€€€€c€>€FT5W€ €Z€€Rä¢j€/€+€6=€P€€€h€m€€€K€}€€k[\8€o\€€€€€ۖ۳hU€O€€€€€€€Q€ €^€€€€€\"€€K4€€sIgt€Ž.Y€N€LW8€€€R€€€€€(€€Z€y€€€€€U€€_€€€€€I|€€€€€F€€€€>?€V€t>€IY€t€€-41€€.€'€q0€€u)€€€.€€€€€ج€€X9Bc€€€;ö€€€€+HNͯ€€֥ȿ:€€€,D€F 9€€d€8LNb€YL:€€ _€€€€x€@lJ|Ox*Ei1Z€€€€€€€€€€/€€f€76q€€€€=€ \€€€€Ȟ€d€hq€ €.€€0V=€Rd€€jG€@hå¹S€€€€€€(5€€i€Y€€€3€€p€zZs{m€隮€N=€€€<€€€W€€cj U€Բ€0€€€€€€.
+€
+€iT€€€a€€EuSV8€Y€a€€€€H€€€R€€GE€>€€ȭ@W0ZZi€I€#F՞€)t€C8_X6€€j€OnܹsC<€8€€€€=€'R€€€#€AVD/€€€u€ €€€W€€Whk}€f€ 4€\€ÈS€Ⱦ€€@T#QR€€j€L €qj€€€1€҈€Ç€€%€鵺€€z€€_O€;^+c€€€€k€,!€€€Cj€€ €€€t€t9AS*>€€€€3€qÍ¿A€Q r6€6?€€€€!€€ۯ€€Rx€=Ûš€'hz€'n €€p€UmLWE€l€€9€€=g
+€^€<€€JRw€€7j€Oe€7€€€€D€€€€€€9€P0€€KЦ€k N€ €%B4?fi$*€€4€€ ~€€%€`-€€D€€T€y€€4€|ÔŽ}€€€€€€€X1R6@€€€B^ o;€€€€€€€J€V€#€e43>5DhׯE€€բ6ת€.`a%r€d€€d€€V€€N€€€<€€p>€ʢ€€€bd€O€Qu€f##<€€e€Q\(!^Y€qÛ®\P€(>€€€€QGq€€€8 €€€B"b€€@e€4€e€G_€iRZ=R€€€ €T{€\ݼ~€j€ʟ65xf€€€R} P€mT€€€€W€߳€hs€[.€€4€j€ €Xr€€€>W€'Z9g`€#€=€2u2O€tz€%€NÏ¿#€%C€(J€U€!R€8€€.€€€a|5O€€|€€€€ѽ€€xE€€-€L€€e&O€€A€-C€80,€€jR€ȓͤw€€€€€)€|T}C€(
+€K€€€€p€€€€€€€1-€€s€€€!T€#FG(d€;Gm€1€€€€SS1wb€9M€9€aπq€/ €€pg&€€€€6Û–:Gt|€f€;DyD€€€H΀1v.€"€€€$€tD|QH€€.6d74€€€€|D€€€€}€ €€F€s€€€€i€€€€€W€€€׵€(jÜŽQ5€9€5€€€U€2"€€Ap€€€r€Xh€p€r€s!€m€€r€e€j;
+€m€€€€8"€€S€€^w{}€€€€3€9€B=QYFV€N€Bt€ * b€€E€H€ ~nG€6€€֮€€€€n€€€צ€€€€x:€€€€€Z€Q€$ 1d€g€J€€€€€€FA€쭵€.$H€b€€€%c_OIh€h€LL€€€;€<^€€v. €€€ p€ €€J=€L+€W<Y€€o€.€€€b=f1€; ws`€€k€:€€dc€€€+"Ï´\€D€7Þ™.€€€€€!5M€N€€W€/j€l€~€€€€€€€8&K€€€€€!€ENBz€!€X€€8€€€#€X€€6€€€€Z€€u€€€€€-€p 3€€€-߀ .y5>^C€ (8€F€€€€€}@€€€f€€Ŧ€€€€€,,€€€ €z€€€€€6€\€€B€€€s€h€€*€€>€€€/€(cC$2d€€nlߺ€€x &€€€€.€€7€€€€Ց
+€€€ڨ€$€€RH€€€)€0€€#:ndi€V€y€€z€€€€^€€0€€t0€€9€€€€€Ò€ aio€€€5V€€ؠK€€8z€x€&€€i#4h€/e€€sY€€ "ؓ€%€€b€c€6 €`T€€€€€2€€P€*€€_€€L€€€@.€€q€€€€€€R€€€€€€€€z€ €|i€€€V€=W€€ €L€€€r€R2A€€€€$€€Y'?̛€S€€\s€TE}€€v€€YR_€€鋦€]€w€€NB€de?€x€C€€€€€V€€G€燥€€Q€€A€€€HW€€+kp?{€d€€€N€€€€€1€€;€€€€Obe€€4€€€AC<€HO&[€5€ױZt€A€€~€€PQ€M €F€€Na€€€Sl€?`€€Y€WJs€ c€y€€€2€€+€I€€}€6Ir€e }_@q€€4€€€€j
+€€f€€€€€€\€€pEA€€€€€€$R€y$颧€€C
+͖€h€K€€M€'€€€€[€€€G€<€€€€+€x"VJ€A€Z€R€€9ë€}€=)h€€€/(€€ qa€.€€-€€k€€:б€€(0€€€3Ç“;€dt€€€€M<€€a€ٵ€€~}+B€>+]€€N€€€€ €-ړ€@€* €€€€ LEXa€Ш€Ύ€€d€€]€€H`M$ u@k€SI€vj€Y7€€$_€&€s€€€€i@jD€€8€€/h€€\ai€€€€U€€ OTP€€~ߤ€o€؞€?h€0€C<:x0€€€z €M⇶€P€h€?K€~ʼnoN
+€B€Π€V€€€€€g€$€b€€€u6q7M€0=*€€Ȅh€€7a€€*€i€XL€*h€-)€mK€€€€60€€€['€ZC€*g€'m뚿€J€ €t1]€"€€X€bz€€€€\Y€CV€€v€pa€€€€!nf2;€€A€Atq€Q|>C`€€€ĭw€€€_d;€€€€&~o€G€€*€€€ €€€€GM8€€€€a€ChQ€TJ€€6€€€
+ 9fU€€ :€€€€Ë€€ €€<€0€
+€€€?m%€}۫€l€..}HQ|€€'€€€t€F
+:Í€3rE€€bI€€j€€€€
+€Y€n<v€q€€€€H€€m€|€+Ù‰€1€+t€@€€D€Q€f[€"u€€€wfpB€nK€$€€€G.€€Ӹ€€€€!€€l4€€ӕ€r€€]P#€€€'JǤ€€€€"€€€a4#€€8Q`p€€l>vX#€Ƞ{^3€€<€4€8€€€:€a€2€€N€€€€8F€€€€€&{€ǪJb€€€€€€€€€>€k€€€€o€€%€HU€€€€X€€€€q=#€*0c€€I€S€L€S€€€€€((J&1€p€€Ð€9€€L^@€€k€€€€*dŽ€€X?€BL€V mu€€[_€€bWdM€€€€€Z?€€_€€€Ĝ€  €bJ€h€€€€Q€€€€yz
+€M€+r'0€w?O*QaN(€)Ժ€€€€N€€E€€|R€̈řW5 ~€€6€4€T€€Ȍ€A1€q /v€€ ;€€,4U€ €€€ό€€ID#Q€Cd€D€Hv€4?ϯWf€€€!o€5H0€K€€.€€G€€€€€€€€€€u€fe€€€WTK€F€€j€y€,€/h
+€b€€nL€€€`M&/j€ wU€€(Ʋ$€€€)]€€R|€€€€/€€1i͆€Djn€€€ € €€?#€sr€k€v€Wh€a€aLQ|>€€€"€*€€€֔€€r€1
+R€J€€K_YKQM€XE€€€H,_€€Ö_€n("€€B€ € z€϶kݭϘ€ €?€€€ €€€€`€9€€f3€HC4€E€€€€J€{V €€:}€N€€€ €"&c€\€8&€€€-€€#,=€?.€G1€Bv€[&Ñ¢n€[€€€€[M €€%f€€€€hIl1€€€€€€eP |€€€€Ï¡K€€€€€€€€n€€€€(€]€€ʒ€€€3x7:€[€\€dg€6{€€[€6€€€€N€€€€€€€€€1R€€€!€€€-U€€€€€€5€€m€D €€A€€€ |€€#zj€ €€€|5€P€T€€SxmdGwq€€€f€K€\€(>€€€.c€€X€€rH€€:€J€€€=X€9€€€
+€€]R€€€€L€w0€€€nq€€(€[)2$€G€D€n €ˆE€K€2I€€€€v€€x t€H€1í¬†6$€V{g$€€xe€wF€[€€€€€€€E€€Ù‹lsdE€€J€1€j9
+€€€/€€€s€}d€w€€e&€€€€ȥ]ׇq€€€mkσB€h€€€€A€J€f.S€Ix€€_d€€€V€€€8€3#€€\€€€€h€e€€Ø€€€€x|€€€€>Rh€HZIQL`€€€€m€€€l€€€X'€[d2€r)€€D€K€h-€U϶}tĿ€Բ€! V€M€€€€{p^Q<8V€vb€]€€€î²µ4€€_8€Qa@€€Y€€,€9"€€€R|{€l€KC€€!€I)€t'c_:€Bz€PI0o2€€€I€ƅ€&7rs€€h€!€u€€bWH!€`d€€kbHd€Q՗€€P€€€e,(W\0€P€€€L€0€]N€V€\ €h€t GS€}d€€|€/€^€ h€t€)`b€€€€w€€€€`]€€`hy€р€/Í»,€€€~;€€€€€€-:,+€€X€2E€B€Og€€/R0NBȲ€€€€€€J?€€L&€nl€€€€i€rw€͘ €O€L+€€ €V€€€쉖j[0€M€İ€Ǿ€ c€ IR€€*g€Q€36b€€|€:k"2Ӛ€€€€€.Kl؆k€€\K%:U<€\€F€[€€+€€,€€€$GbjU[€V61€€bd€€"€uhUk€n€m}eØ™€€€ €\€;€€<f€€ €w€€Þ€€€N€€lą€#€Tl` R,D€€OH€=€€™€g€)@*€&C€€€€€7ж€€B%{yڳ€€€€€$8 Ǿs€N_€^,@€€+hd€€;
+€€€€€K€x%€€M€€S€€€U€ڷ€r€€c
+~2&€o€€€yŇ@/<;€€V€€W€ €€€€€€€c€€q€€€آ8Jr€€%€€€h%€€€9tۧ€Y€c€€֓€€"kVÛ³(€2g€>€k€'a€,€€€€€€,€ZRO€€€b?K€€r€€{€€€UF €€|Y €Dk~k€d_h €h€€U{€*׀€€/€bGPn€€)17€!$"€R€€aw=€€Bt€&€ R;r€€€€w€~€0y€e€€€€ױ( s3€wvj€"&€5וev€J$€"€€I€€|€€€)€-€€Al.€d€€€{€jZ€3€k€€€€3#T€'€€€BY)k€/€€칈+ gQ.€D€L̶€&€€€î€Oz€`€€(QL€3€c€2u€
+X€9€€€ v_54<€€r=€^Y5€`D€d€L€€ =€@ԡ€<{uG€ϰ;FP€0(
+*T€P€}jv€6]€'*qzY;€€€i€€ަ€€€J€€A€€APb€/€+[€oÅBT€G€jpLH€c€`o%A€€€€€0x€չ€€" €o
+€,€ز
+€€ZBW€hvU€7€)€7R€d€h€a€€!€eÜ€€€€Ւ€T€€T€€-.€€`€€H0*Q€€€€YJ€€€€€}>€dP€€€d€€f:€€xا€€H€4޴€=
+ €Yߚ€%€€€ì¸ÇµÂ€Â€b=€€€,€€;€€€€€€€g54€€ऱ=€d€^€€€DN_€€€€n€}€€a€€€€#€@NaJ€€ILd€&O>Fq€€€€Xo€€€€€lzmy€DÈ¢T€€€€€€l€細€w€€oÉ€€€z€€€^9€A€}B€+Ö‡z€€>€€€€
+]cE)!€Ɍn}[€€η3€"€€€*€€(M4u€&€M€5YtMd€€€€€!€€€€%€))qLua€€€€ W@Q{€&B€€€€€?€€€<ze€€q3€5€!€€8€€€€€=J€€T€€€8?€€€€€J8€M€!b,€€KT€€€€I81€8€bi€[€€€Ѷ€€Q] €€`€h€€€€t€n €eÜ™]€ >=+€€€C€)xq€€ o€€79€S€€G€€€€%D€L€/€B(€€/-€€€€d€.€_+€€€QeWU9eV€tU€€€€LRT=OR$"€~€-Q€ (€_ÉŽL€€0€€€€C€€^0€AO€3€€+€ۃ€€$€€€€/!V€€€5N€.€€?IG€'8€нx€5€€€€€€€€'X/€€k€Lo€B€Z2I€€=€€€€€;ö€€€€€€?2厾€€€ @€i€M6€#&D2€?€€€€€<€
+€€€?F€{?€~€ €:€X0€ 1€€€w&€€€€€P€€ً€€€x€'
+:€Ÿ€dp€€o€€ €Ŷ€L€€€€€€€A€rc€'y€32R€€€n€^€o€€€€€ €€€6ב:€€e€€<c(T€€€&€ €+€w<€8/y€͔€Y€|€€€$€d€4%5€ M€>€€x%€€
+x€€€€€€U€#€€€€€€€ €€€j€G€۞H€€1€€€GB€€q€€V€6€€€€C €€?%i€€€6€€€€€2€€l€€Ab6€)p€[€€r€H€€€T€;N€ C|€€Ds +LA€].Y€#,I`2=”€ns̖€1wk € €€€1€€€€w€͉.kK€ک*€€€R€€!X€€H€A€€ € €u€#€gjF€R€€€€€R€2c€i€€o&€€a€Q€€€€€€4Ϣ€Y€€€@I̥€ s€€€9?€€R€T€,!.€bp€€€€€3€)€Ϙ€€/€W€€5€F€nt€€a€/€€D€I#€Jl)'€€€€€d€h|Âœ0€Dw/€v€€€vY€12xw€`@*€‡y€EE€{€€:}€€!t€€€€@Ç¥€€€#L€aF€€h€€Û¼)0DDIZ €€€€€4€(=€.>€€<€€/€€v€€]€€€€@€€€€€€YwB€ €€Ia€D€€€ƀY€€€&Ȩ{y€€f'l€€
+e*€0B~€Q€c€A€€€€7€€Í€σ€€€€6€~€ 1€€0€q€€q€€G[€7€sL=€€Np<`€H
+^€€,e€€€K€@€B)0€z€n€€ €%€€€|€y5€O€dp€0|€i€€€`€€€€#€ґû€-€Vb y€vlb€6€M€vu쳊€X& kۀ€€hL€E4&€X€€€!€€A€(h€€€€€g€m€5
+€€i€c€€/€*~€Y €Ǥ€€d1V€€
+9€YL^€l)N€s€€€m€ O`€U #rz€€k€ 9€€ã”€ހ|2rq€^€p€€€p€I€€IW~c€1€€€h*€hЋ€€€€t€&€^zhp€g€ѦnBr€€€WoئT€€U1€|>6В€€€€€n~€€ €2f
+€0^+€€x€CEC€€&}€€€€]€€€X€€€€€5€€€G€x*€6€€Jy)€€D€FT)€{:w€€zMK€+JJFf€€€€4€€€€u€€€(€CG€€€€
+€€€€R€i€€ݱ4K€€mC€]€€@€€ XV€=€€{w€€€€9€€<B€€€€޻€x€€€ko€€Y€V€€}+b|g} €€qkO[`€€f€€€)€€€{€€֙hC€€€aÖ…€6h€€H1@r€Y0W€G€/€.j}R€€ €€€€%€€€5"€€€€^d€^€St€€q68€€-k;€)€€{€z€€z€€€€1€gg€V€€€gz€€€1G€€€"€"%}€€€NAq0€€€cz}€*&€U\/€X<€s}€€mY€tZN€1€_:€€€\
+€J€€€€Z*=}tZ{€>J€ €*€"€c€€€€Vao€€/€6d€'C€€€2D€€€€L€ €j€s€€gJ€3vL€,9c€€C€<€€\.€€€€\€΋€€y:}2€R.€q
+@S€f€€C€>€€€`6€€€R|,s`€X€of€€=€€pÚ¢€€€ƕ€u:€€~€€€d€€€k=;€<€€:€]€+OÇ°&€€U€ q5 a€€gC€€_€€€€€€€yds#€€e €€1€€€€xR€€€€5€9€s€}R€€€€€€hI^€7€M1€€€€H€€€€hyy|ܱ€_€€`zaÂ€ÈŒí§ˆÂ€Â€uu€€€€D€€n(€€l*È–_ t€€€€€ol€S@€€?*€;b2€€Y€€ÄF€tÅž{V€(€A^€{$D€€€L€€{€€1'€ tj€€€)€2I*€Q€T]|~€€€qm€€€€(`<<€z€€€€V€€G€L€0€€A€2€}€ᔨR€€€(2€`K€€F€€ޘv€̸€€nj€e]€e!€x€1€Q=f9:䀀崴~€傳A V€€€€.€€€x€€zi€g€€€€}"$'€+䟒J{€€*H€L€ 5'€A4€)€€€€Y€k€^.€S€€s€€ß)ʰ€ €2AFD€€€€€N
+T €{{€€€S€€€rS€&V€G=€€'+%€€x€€€!€K €f€€? €€€}€€€€€Њ€€Xi€?Îh#€Ƒ€ˎ€?€x€€ €€€€€E棎Ӏ€4€ €>xX€t%€E€€€€€€€€€$L€€€€q€€yÉ•}€€Y/€€g€ඎ€€€TK€€€R&€€€€5€$€eZ€K€]€n<€€4)€€y€:€€3€]€q>n€d~€€؈mwCL€€^€fN€ezC€P €%€€G~f€Bz€X(€2€,€=P|€̠€SSx€_v€5€€€K;€€€m€€t€v€,€€iÚ‹w€€€E€A€!€€j1€€€~z€€€€O-€€€€|€!M€~|`€€€€€€€ۂ€€€mA€פ€<€€ H€€€€_n€x€€MA߯€|m׌€4CU€€€sQ€<y.s]€€8yC€€$ժ€€Zy€€D€~)€R€@€€{C€€6Q €€€€€€S€€'€j$€€€}€͆€€€€q%B€€vq"€ug€€€(€2€y=~Õ‡€ȒS€€€€€€€€€.J€€CG€€I€P< 0€€€€€"h€8€
+R€€g<J)€B-€Ո€€:B€7Ύ€€ݾ€N€>€Ex€_€€€€€€€€O€€€u€€K€€o=€@&;Da€A€€+€€ku€€€8`€^y€+?€€R€d€€€€`7h€$€֣1˦֠€CM€€€€€d€O€&€T2]€Y'4R9€F€€w$€h€A`€!€X?€B.\€~€Ew€€`Zy€!Vd€€2€XmSКd€€ €€~€€€€€O€€un€€€঄įGhڂ€B€€€€?^€Is€)€€'€€d€€€6€€:€J
+X
+L€]€NW€| nU€€€1ti;€€v$€a€€€€€€€j€€H_U%€~Ua€€>V(J€€€€L€€€€WM^€€€€TQ€€@K?ߩ€:K€'J€€€€ o€z>€!}€k€]}€€a€€.€pd€<uZCr€€€I€|€x€{Į€V€_b€€€€ ?C€€34€€u€f1€€e€a"E€€A€€€€$€€€[KY€€€Y€€€!A€€€€€€€=€u€€€`€€s€\yzphN€0Z€~€€%ކi€ABV€n€$€€&€€€€z€€€۲€i€wl,"€ Y€B~€' €p€'€€€€€q€€حdZ€€€aĎK€€€G€€€€d€'€€€€:Ah€(YY€€€$B€S€Z€
+€€€a,A;e€
+qVRY<€T€me|€€€€€@v[€8€€'€€-€€x€€'€€€€%QF€€€"7€ €€€=€i€€/€€R€€yb€%€€€w€€€3Z4ؖ€ f€db€ €€Y€$r€
+€€€€€€€D€€€ۋ€€€€|€S€>€€€€€€€6! €€€5 €_` €€_€V€€q6€€̒SîŽÂ€K€€€U€/A(>€€€€r€fќ€
+€€€ZeG€€h€€€̰€c8ٴ€€€! €ރ, €R2€€L€€&€3F€q~[]|.€€€k}€€c€vģ€POͨ€€€ €斸€]€WN.2P}€%€g€€#'€€€€€\i€ªمK€€€€€€€€€€FU€€N[{€€ €,T€€€ €€-Y€€€€€f€(€SG_€€!(Q€€€€åŒ}K_€`€€KZ€3?9]E€b€T€,€L[€]€8 €€#€P€€YC2€€€G€Awj€cD€€9€jt€t€s€8€1zh€€˫€€=p€{T-jOG.V€k€€1s<L8h€€€އ^d€€€'€*€ t€€m€Շd€F€€ ”€G4;€
+I2€L €€8"`€"€eA€J˱€QÖžC€q€€mX€(€/€€€Ð€€€u=€60 €€€€€=€eA€€D€€u)P>€€6€,.€/€ €m€€G.€€i€€€̚mÃ’h#€€€.i€?/w€8ބ€Mf€F]Nu€lG€€b€€K€€ϡ€€,-\`%€€c€I€ea€zP€DwlDέ€a;:€;86€=€€O€P€€3€NB€€c€$€D\€$W€Ϸi€€€v€NZ%}V.K€V:€€X€"€^I€ €€€]€^€Q|~€_MX9G€€M€R€#rے(€€€W€€€€€Y€€€€]€€K€€[€wa€€5nrG_€€€O€ ʯ€€ spider.chk.oldsc€LV€€€€€TEXTMPS €€€€E€€€€€€€€€€€€vbU€D€*I€€6€t€€€€€2€€F:€z3€€0€€4x €€3€€€}€€€€2€r€€€>J€€"J€€Nq€W€L#€€1€€,€h4=€Bd€€LaX€QÌŠR€[q€Aa€€2qeY€1eN€`€€€€€PA}]BgRir€€€€€€€ fz%€~€H
+€€M€6€~"eZ€d€d€lsz€M!'€@u€€<[€€€?€€€ΎWg€€ }GPz~
+:€[€€€rJt€h€\M€ c€(5+€€j€ 48c€
+N€€2€ €€€€€€€€€€€€k%a€€g€hQr€€q€€(' `=€€8B€gG>€€€€€€@5€€8A'€€€{€oGF€€€fÅŽ|M€€cr€.€€Cm€€6$ ]4M€t)€€€)1#\€WZ:€€l€B€€€€€?€€Mث€€B€€€€ €?€€€€€I€{a[€$€€€%[6€d€€I€€€€i€"€`€+@€€€\ML€^):€ʲ€€hړ€HY€€wv€€>€OE€CvVw€d+6`€5(€€D€΃
+€€€q2€€~€$T€Ai`€€LK]€€€€€
+€€L&€,I€€g︟̢€D€$C˾€€€€€€€/V€ϼ€,€3=ʦ€€r}C٧€€€]U5€T€ƫ€w€nET€5;€"Z€€€t*€€"8€ €€5{€T€€.€€Ҧ€€€4u€j€€€€€€ €]2 €%G€€0€€€xo€€<€€€€€€"€;€€?D€€)€2""€€Z€€€N)€€€€€€€_€€€.T€'€o€0€€€e€6€֡I€6zӦ€€Wi€€<|[i€€F€€ 2|€€€Rڠ€w€^EM/€W€oN€€ik€€€€€€4€€)€>€€€ӮZ€_U€€€€€9€W€€ €€€˾€€A€€€€!€€}€ M€€Zb@€V€)€€€€v€y€Դ€€€€]€€!}€€4€s€€^ХYz€Rk€D/€€Y€G€N€€e,".€hP€€€:€€€€€€/ٲC=S0€€€ €€€€€€a{j€09L€€>€€ǎ€€€€a07€vR:I€€`€]€€I€
+spider.web.oldsc€2€€€€€€TEXTMPS €m5'€m5(€U€€d€@UT|€€vb€€€€€%€€€€h€€4€€€#U€€h$L€o0€€Ӓz€€€ ֹ€€€€/€^%@€^t:€€€!(€R€2N1€x€/}€:x?h€€\B€€€€`€ €g#@;€€9#)`€r€€€a€9€T€€€
+NC€€Y?|€€=€i6€€€€o€K_@€€f<€€t€€€€€ €B€屫 9b€€73€€€т€voiNy<A€w€~€€€*3M€z€]t€n€€<€0<€€€€€n€O[€€€€A?Z€€€k€̺€]€€,€€€"€€€2X€€€)#€d€€v€€€p€Jrܓ€€€€€€€&€'€€t€+s€ÉN €€€€W€€€€€}€]^€,€€€ʗ,€^€QBU'N€€3€c0LE€€W€Ew,U<rCq€€9€€׽q€€#€H7€€b7I€绩L€5q€DW€,€=€W€€€"Y€D&B€€u€€ǻ*€€Qg€M}€E"€€€€€^€€€€€€7'x€O€RDn,€T€€Xz€€ǖ€€d€€9y€m]€€f€€€$)€^íº©7€€l6€3k€uwd€€:<€A€+€Ù}€R€€d⤩€ ݸ€~€€ €€€€;);Í©€T€€Õ€€€€€€€]€4€)€€LG~€€€€€€€G€€€~€€€”€€d€€Y8€€€€%€.€€€D[Û¡d=)€€€~(€0Z€(€M€+€*€:€*€€€€€€€j€7€€1I€€€€4€ɦ>€~+k€sqM#€€ €a€^€J€ Vfp)/iV€]u€m€q€A`€€&€@€€€3'€gW€€9T€ €t€€lk€3€€€€€Z€€€€€WN€€€€ €€@€M€{=L€3^€e€d€'€p€^€€[*s7vG€'€)Ü¡AO€€d=€#*€W}<€Z€8=€1€ }€€€€O€~€)€_€€ޓ€ {t€p€€€€€g€{M€@€€€€€u€€|€lj€s€€펟€\e'€6€ԅ €€€|ߪ€j €€P\€€P\€€€€D€]€tÍ´vk<Ä€~1€€€X€€8€y<€q€c€€€€€€p€80voi€2€kS€€G>.M€€DÆ•D€€€€€€€€€€{ꊖ€_€&--€€t€*c[€€€ca€d€€rģ€€_y€€€€F€_,Æ€?PY,€€€=€bq€ڮ;&€1€0€€{9€€€€€€€|\€ €€€€€`
+€ [ €p€€׸+Û´hbVR€€U€€€€€€Y€€€€€€€€€€€ P€VS€€룓€€C€€5€€€p6z€N€ €€ ÄŽc€lţ€A€€D€0€€€€#€€€̇;m@€nA€7T€r€}r€3ؤ€n€€€€X€€h€G(|€€€€€€>€€€€€€€[1H€lK\I€€€€€)€€!€€€€ς€€],\€€K6€€€s€€€€€4€€€0€b€؂€€€[}0€Z€€€€V€M7€€z€€€€9B€€€€d€€€€€YӢ€€€|€€d€ ?YR+€€.€e€%€#=€€b;€<€u€q€€€I€€€€€k€€€€€€€~€€€0€€€^í¹‰>g*€Sw€€K€0)€V죢p€F€€K€€€€€€€˃C1€J€€€6€sw€€€€€€€€JËšY€€(€€ € ]W#}€€`wp€€€€€€€€7€€€_€€€€"€€.€€q€
+€X€e€€€€8€t-€€€t€X€€€€€€€€@€€€€€€€6€€€Hߦ2€D,D4€ŎԀ€€ԅ€€MlÖƒt€€€€€€€P`€€M€€€€*;PP€W€焯u€€3€€l€€€l€E5ߵ€ݎh€0€K€€€€€̰€v€€€<€<!€. ω€l€€Ý}tA€€n€€Y€Z€ €1€0€W痭€+/€N·g€D€>€kO^€%Cq€%€€€€€€€€3€€€€€h€ €Acƀη€€€ڂx€€w:z€:1€€€€$€€PC€&€7€€q€ C; `€j€c7€r€@€€ˠ€€;y€€{8S€gTF]xk+€ *UYTWt3Im€€a€€€E8b _€C`€€BK¢€M€€m€6€€% €€3€0Ñ¡m€ ,z€o€€€€4€€€loe€€€'l€€€^€ۈI€o€25€@C€:€VB.€€€j€vÞ‘? € €H€€€07€.€€Z€G€€õ€€9|€뒹€€ј^€€qv€MC€.€~]€7<+€€pN€l€Oq /€€€€€€=Ѓ€&6€K%a€5`€l-€€€}B€€.€€€€3€€U€€€€T€€(€€€K;4Z€5ps=3€+€t€;€)^{€&֤€c3€€€]€€4€)€Aͣ€€jR€€.a.€d€€{€-q`y'+r€6€f€€€v;†_€€€}€€€|€€€ӟuV€k€€m€€€L€€€€ ˲€€€2€€€)#€},€€<€hv€€€€€j>x€w€€9€g€A€KÖ•Õš€€6H-€u<#€€J€x€C}0<€1€َ5€o€€€H €€d9€€€€[€€€€€e€€ܓÄ€hE€€7€t€€€€€€€t€7=€€(u€ /€€Ӗ€{€?€'€r€€a€€€€€:€€v€€z€(G€€€9€€€b€bW€€€€[ &04F€Cw$€ы׮W/€€/|€€9€h€iz€€3€€u€€€€d€PWC€0lf!€]l€U€€sݼ€6€q€€CN€oȂ€€€€)€Op€4Ý« €€€=,€U€€€BG€,=€<€€€;€V€€}€Õ87€y€7>€€?€€s€€€€>€ȹ€€€€ߦ€€9g€€W€=€|€J€t€RO€@€€>€R!€€w€€€}€€R'€bnؘ€€F€€€Hz~€€4€€€I€€2€€€€! €€€€€€€LXw€€\€d€1€n;
+vu€m€€€€ g€€u€€O€f€€€&VoCv€€€˓€€w€€€€€€ € 5€€hy€VÆŽa7€€`Y€€@$2€€E{<€€€C:€i€€V€l=?i€x€€€€m€U€€€;>×­8€.\€V€€€€€€€€€. €€ |€€€;€q€€€€€€€€{ת€€€€ԑ<J€€€€gr€€fs€>jr€€fb-~un€=`€!߃€€€€*v€mj€€€€€Ikf€n€ $€€€xÒ…PG€Sf'€y€€9€j׀vW€k€€1€ €c€"€2€€€)€€,€€€DnG€€h\€€z€v9€ €9€€€Hg€€"lMM€\€=V€€€€€€ €€C €$€€v€€M€I{j€|4€7€Jc€€4Ln€i€F€€ €€€€€€mH€Ӿ€€€dR+Z€€ę€€€~L€€€€€BΡWeLH€€f0q€€*'€€€€€€2aH €€i€€€€€4€€€€u€p,&€ ' €€8J€€€q€:€€€v#€€€;€-P€7q€A€€1٫€€€€LV€y€Q€̃€m&"€Z'm€€%€Q~€ €B€\2€€r5ЈCjÑ‘€€€€€€€f€€€+€Ges€z/Ñ«$DQ€€c€Eh€€€V€€€q€=€€€ŕXe/€€r€€€€€nr€ǂ€s-€0€€€€€)€€€i€Ð4 P:€€€*€€€€€€`0d@p€€QÝ…l€€€€~Ga€8€B"€€}€€€'€t€€€(€:`f€€€€h€6ި€RFz,€Ȁ€€E€'€
+€€€€i€R€%€^W€I€€€j€VKt~9€1€€^€^C~€€w€€€u€Jn€*HK€€&€p€€0€HD€Q€EVJ€€€€@€€R+b(c€J€€KR+i(€mi€[€F€€}Èy€M€€€€c€€~€7€8€r€8dqJ €€€€€I€€€ueܙ€€ 4€D€€t€€:P۱€€€€F€€"-€€€>N1V€€S€'$h€c€q€g €Pa€€\c#€€€k€nW€:;2€9-€€€B Q€€˕€€A€((v€P€€ʊhA€x€€ I>
+€'A]€‰FX€€€.€€€i€2€€€^€€€9-€€€J€¨€O€€h€€FC?Υ5v6%€€€A €6 €€€
+H€jU€ɛ€߷€\d€(=€€€€ €€ݤe€8€€€]€€ף€€T z€€€疸*IhÛ/€l€€E)€r€^€€€€P3€€€ €€€33"€ €
+€=C<€rԧJ€€*€>^€,€€͛N0˦€Ry\€€?8€€r€f€.€f €€€€€€1€OG€Xh€x%€€L€-U€d<€`€6GL€€€4€e€&€0€kk,0xM€Z€€ fT1€€t
+l)ɉ€€€X€QhT€l&€L €€5€:€6@O^i€€€€€€ G€}€ €J؀€€CQ€uL€€€€H€€@D€l=€:€€€€rWL€€}"€ €d "€€€q€€€€LP€\€ku€+€V[I5€€€M€\Q€€qJR:鱜xNÂ€Ê Â€N€€U€€ Hg€6€€€€X€%€ h€wؾ€c€€a4N€€H€JmÕ¡*h`uИ€ =`€€~Ä€€l_b€0€HH€€€€€€$€€€d€0O€_€:V Y€€€Ô
+€€@FB€€€€€€O€
+€€€r€€X€x€~.€ +€€9HB@bZ`7€$€l€€3€€€€€€€"€魙€hT<R €€6€€€C€3 €<€"€€€€€€Y€Z€//€O€€€€€€€€€€3€€C€:€€€u€`€€€&€€]€'@6€ O€€€€-€€€(€VdY|t@€€€s€€
+€l\z€4€€ʇ€zˮ€€€€€k@€€I9€€€J €€F€€*€€?€F9€rm€€€L€€{kǴ€;€;€о€1~{k€€W€N€ucp€€€€Yq,D€€l`€€ "=€€€W€€n€€[[€ԩ€€€Nx=f€€O€€€ٲ€x€j€€€€]€[7=€Y€8€NK€X9Äž€€$ދڤ€?K€+d"€€€€@€e)€€$€%&q€€4€Xg€K;€€;`!IB€€ €Qf7!€g€+€€€ €+t€€€€&€Op€€j€w€U7€ÏžA€€€u(€^}G€X€y€€€€€Ӈd~€€Q€€F*e€€€:€@€%U€|V€Ó€4€€X€€€€_€€€]S€€€€?€Ara€€%€T€€€€€€f€€jQ€€€:*€ۯ€z€G€€€ <€J€€Pr%g#׿K€$€Ay"€€€,€€d€Dv€vߠ€€f*€€,€M€€€€€?€€€k€€h€€€y€Z€€շ€€€€€Ǣ#€€€G€t€q€€:Y€:€€Fm€€S€G€€€€€€€y€€€€&€:鼸€+M€GQ€€(€€€€€";͈)€€€$€z le€f€€;€€(i€bX€€&fk@A€€ZB"€7€€€@€
+˘h€P*@€€i"€2€@€H€€€#€€Z€€€ǡ€c8+LsD€p.B€€€€€@€€€a,D€€>cE6pK€A€v€€€€€€kO@
+€€€€€|9€€$2€a€P€4;{€l€p1€€€€,&l?€€€:€€ǗMPs€#€€]L€€ €€4€€€2~€;€€G€€p€€%€€ZΡ€dH5x€%l€€€€N€€€€€€€^߱€Xpqp'%n?€.&€€Y€€|}t€€Y#€€;€€X€€p€ €€:€€€€€€J-€16i€n€5€€*,€!€€€N€ €€€€€€s €@mR€~$€€€€o€[ϴ€3πǴ@€7Gjn€~€a€_€Ŧ€€€E€€€€ -€P€Dg€
+€€Z€3~€€P€€J€y€€'€6€€ 2€bf€Fxn1€€€€€ €z€h€€€6€ €€ӹ=€T€3€€B€€€€R€q:€:K€0€€lj€h_é–¢^w4€sV €€€Ҫ€€ €€€€LÞ€€€l€€g݇€Ht€1]€€6€l€€€QY/€Yɬ€\8 €}€€C€5[RV€[€0€?€€€Gq€€ƺ̼cx€$€WY$ €€&Q€€€€1KS€€/€ €F€p€€sr€€İ.VÇž€€€-8€p NWUu€O€^€E€((€sL|D.€V€€€â‰3i€€€iÇل€d€#€<8€€€€€€e€"€€€m€8€6€Io€€€€€€€p€m €€/E€>aW0&€L;€€€€\€fKhm€P€€€€€€rf{ €LI€€EP€€€Þ€:g@€;P;nAb'€V €€Q€€€€€4-ÄŸ^2€€)I×°e€€€€€€(€i€í0€i8p({€h€€€F€€q€€€f€e€g€ €€SÜŽR52B€g€€€m=€€|€K€€2€€€€€€€.=;W€s€vݭ€Fړ€€Ȼ€€€y7Oa<€€€[{QR3€€d€€ׄ €K5,ڸ€ϟL€Aw{€2€`€€€€V [€€;€€€€r€%€Ϙ8€€mRB€€€|W. €€=€€€:)€4$(€; €k.I'XC.€8€+€€)€e€€ € ee€€B€Dx€€x€€€M€€€r^^€ €€nZj€ "#ȋ€€
+I€€€f€€L'€€€€!QÜhc€a&ks€€Pjq€B€/&/BM€€H€€€i€40€h5jN€€€VC€€b=Ò’A:Û©!€€€€$\6€€$€}Ҽ€€@€~€&Ƹ€€€l\€€€€ǹ4Z€\-n1ޕ€€€l€€K€€K:€]82Jb€€€V€g€d€漱d€kLz€€13€%€€dґ€F #ej€€€€qA€€e)]*;€€€d€WN€€€€b7€€€OrX)€p€€aCG€€ €Ζ1H€nC €€€:€€+e€€H&€c€€m€€€€€\€€F€.€€€(€y€q0€€b€€-f€€7€>€O{€€€€€l€€͒+€€€3&€€Kkt€.O€4Bq€]€€€€€ €$€€€P €€€0€€€$€€j)€€SOKW€esÓ½@J(€%€€w€'h`€€€ N€K€}€€1p€€€€€€ӎ)wE€>0=€lK€6€€€€€ 6€€}k€€qc €€€A}4€x~1€T`€$€V=€D€€€€H€€D€7€֢֋€(5€ ,€|€/€€€€€€€ &€€€<€s£$9€9€=E€Ŷ€€<ۉ`€€1%€€D€ VK%€'€€=/€€€@€%%€€€€€€€€-€\€€6€€€€N€€€€€ɪ€`j€€+€€̞Ȝ6€€h€€[B€J+E€€ϳM€€€€ v€€€€pcY€€X€D1,€+P€T-{e€€R€6€€L=€|€€€€(€€E€€?D{
+€€€€F&p€€€f€t€€€Kw€€Z€€p€՘€€^>€ç»Â€UNo€ 㱭€P€€I€€Z€tzâ›H€VS=€ʥ€=m€/i%€€Q€b €i€€|$€j€€€'g€"8P)€€*€€€€€L€€€ƌ€€Nx€€i€€€{€€€iÉ€"€Cx€N€G$€[ €€%Ï‘b€J€ؾ€. €€c€€bH&tr&€=€J€kpz€0€€€@ [H€€%Q"€€€;€v€e€€ #€]x€€12(WX5€€8€ W€€#€€€$€eC€€€€€€€€€€€€ €€€J$7ۄ€c€)t5kt€ e2bd€1)€V€0€
+€€.€:̆-M.€€<€€€M€]€€€پr€€€€€€ä‘€€2€€€\€=B€€ˀ€x€€y€8€€€€ €€€€%€ziF€€€y;
+€![€EZ>€€€€8ldO
+=€\€lm€€€P€lp€1K€€>€€E.€€€[€W€€pG€+iC€!€,V€ y€Ӹ€g;€€€ן€€€€fA€€€01Ւ€]€d€€€9>Ñ€€Ø 4s€€€.X€5YU€€€€c4CaV€€€x€€€i€€€N€€<M€UÌ治ɎY`€X€4*€/ty€€p€L€ €8€-BHC€k$Uv€€p€0Q€€€€ЌI€€}d{Q€€€p€€€€€bv3€z€€€O€>n€€€4[€h}€€€€ á¯Â€Â€P€e"&]€€ "g€ "f€\LE€.€h€€M€9€*h€v€4€U€K€€g€7€{5€;O€€€€ԅ€€ᕦ€z€?F€€E€€€€V€€€qi)4 €e€€ €r€"ԛ€~€€G€͵€e€ÂÈ“%€t€€ €2ߦqP€ᨰ€6M€€Eag€{u€:€_yD€€€€€۰€€€ /€€*ì“€€{T!€€’€€€€€Er1€2\R€€SVNT€€)€b€c€€!€€_{ؼb€r҄€€€€€Df=u€ȑ€€h€€€€€€1€€ Z
+€€B€€€€9€€cc€€+€€€5y€€€$4€qHQ ;ط€€€€€€€KQ€J€€ €€`€N€€€€%{U€€€€iq€€€€]€ €AM€k€ze}€]+€€ҩ)€€"€ZӒ€€€NI€€k€A€€v€ €€€c72€€&€ěpάL,QƯ€Ȝ€ti€&?a€HLU€€€€€Tg€€O€עY8€€LrܱQ€a€k|€€GԬ€vÄ£<€~,€€€€€P€ A&€v€3€€;O-€ʓ€)€€6)ETS€P€M[<^ u86]€€)€$€€ €.Ï€€
+€T€|€+h€€€€€€kX€€c\<€ͧY€€€K€€muz€€€€€€O€€€K€€€€€5€/A€€€50€ 9€€MG]z2K€€€7€d;0#€T€€`€€€€€€^#'*€1y€~€€€S€O1€5fE€]€Æń€€k€!@€#€-s%-}€B€€€<€j)€bS%€€€(n€ 2€€€€€5D Գ€€€€€JC€+€€€€€€"€€€€€ϡ€€Ø„+€€1X.€€€€ €a€_PD€€#y*b€€ 4*r€€€€+j @€n€€€#"J€>+BTÚžD€€ѧ€€€€:<dz€'l|(€|€€õk€€€€:€
+G€€€D]€€/€€ € (€€€ €*)€B€̌i€m€Դ$€1€€€ږ€`€<M€#=d€€€y€€€N€€
+€>_A€€€ €€<€€Q€ €€€€P€D,€_@€€€€€€* ZB7R€€€€g€€ӻ>yEKꭧ€€ .€I€Y€<%{a=€5€'yp€€m€Y€€G€€€c€3€€ɸ\= €=€€'O€€UK5D^cv€€B|€He€€H<€&Z€;€z€€€2G€€7€p5€€€ҽG"€D@€ €€€€iDa€D€C^€€€€غ€€A)Sv€u€4%X€€€€€G~€
+ß‚cй"€\P€c€€[€€B=€€B€€€€€€ €€X€'ZB€ €}SM€̀€€€€Y݆€€ܨ*€QG€€€Hw €€b€€_i€€€N€€€,W€€ €B€?€€K=€€;hå›™Ta€_€fs/€Ү€€MP€n€nK€o€€-€€€tT€€v:N€[€E{=€]a€€~€:€Ttu€€P€"J€€€€€J€u€€ކ5a;€€U€€?€;€]€6€V€{€V>€W€€€€J@€€0€;f€]€" /O€€€€€€ \))€~€€Z
+x€€€W€€~€a€€€€€€yҺ€|€ӛBs䵣 ˄k€€eGCLJ€€€€<€z1€~J€€€€€€d]€E€€€X)g€Æ€g€€#€l n$Ev €€€z3€܌€J4€€\€€€€T €€_€E€€€€І€€<u€€z€F€€~EC€]]1€€ €t6[-]€€,€D€cᲄ€€ €Ů;€€Q €€€€пb€€`€`i€€v<€€[ (€€ťݫ€$€€€€S€ f€€[} €%
+@€.€{gF€.6JI€Qw€&€€7€vx€D€=ZY€€€€€!€@€€i€3'€€6€!y ,$P€>_€%€2€€Ǒ€p€€?€€€7€€€"B\q€,€€€€3w€€E ?€€4€>€I(€v€D%€€€€€.€MKʢ€m€х€€B€€C€A€€!€7€SL€9€`€\€(A€*€€€€€ €€N€bY€€ T6€€y8€3€€€* H€€$€€f€€€x1YU?€B€F€_|€;z€a€€|€z m€€=€€€u€Ѵ€,€€€$€€€€€.€€€€ €S€€Ķ€€Jٶ€M.€€FJh€CI€m€€€"€l€W0€G€a|€€Y( J€ВƤ€€€h€2€€`'€€t€z€€€€€C€€€€€,€f€o€F€7€og€b
+tۅ€€€;€*€€d€Fo€€ h€ €s.€3棒ex zb€W€€d€€€<€€€€€€g€nBI#€,S€€€€-T€€€3€€€\;VF
+F€€€M€vK€€ j€€\€)?9Y€x€ֆc23€ݟ9€o(N71€X€€!7€q€€S".€€ؕ€O+ų< 8€€Ja€€€-€SRZӳ€€€3|4€€€9>€€€€ €C€ym€€€€€ф€€Q)U9|€€€€ZRa€€€€€PPż€OB€€c€~UU€€M1€$€€€d€€]8s€€b€f9€€€e]€€˨-I@ €&€€V€€P€I9€€€€€0€€€x€€\D€€W!毉(€€€OP€€€q€€(€j)\`E€€€p<a€@€SGm,w*9€€€R9*<wJ .€€€8€]€€[€€*0€:€€€€G €#€€/a€ܑ€ʮ€€€k€
+€€ €0>€+€€€€€€€[€€€ڇ€€hݹ€€€/€K:€CoC€€@y€v}€W€tZF€€/&€ں€+€€€€[.€€5P€€€DÆ€P€€ € €NiO€gè±a€€T]vJͦ€€€€=€€i€€€V€Ö©@€T.P€t€,r€ָ€€ti€€€€KqQE€€a€€X€€\€€}€€€k€ᶳ€]:€€€€€T€<7hپ€si€
+€€€€td€€gq€€n,/€Ž{K4a€<€€R€€l1C€D€m€Y€€€)€€€€€€H€€^€5€€t€€f€€ɴ€/€€^€d,€€Ҭ€€€€Qx€ͥ€€€0€€ €D€Er€1Hw€€O€€€$€Jg€*e1€€t€D€€[ÂCd!€€&V;€b€V€L&€8l€pRvf€€C€€!€f&Σ€NNb€€€€$'€€€xb8P׬€€€B€5€NGya€€J9€ؿ5R2€#€U€Oɺ€nd%€1{€€a€Μ€8e8€6€]!€€€\€w€E€pʙ€.€€€ÓΪ€€€W€r€€€6iUR€*G5K€€A €€S€KI€€I€€F€€ €D€€X+h€€aXdQ53€5€i€€€€€€0€€€€€GG7 o€€€€€€ €€T6b€€€€€€v€€€⹂ذÖ€ґ€€B€"<H€€}l€Xr€€:7€€€t€€ڎ h€Y€#€t€€[bt€€€q*+€G:_D .€y€€Vd€€€€€€]€€€f€€€€[1Dh*'€€€€%€T€dٺ€€€ € €€€€€a€€€€€F{Rd€ŵ€€€€€T€wn€w*€a€)Fe€7€€€MZ€OW€W€3h €€u€€0@6\j" €€€€€€*l€€€,€M€€"€€€€`vkp€Ć€>rnB Q€[€€ €€€rjQs] _€€܈P€€€lH€€T#%}€€€ €F€€€€uh€€ ;€=€€€ɾ p&€܋@)6&?€€n &T'_Cs4€€/€|{€€€€G€f€$_N€6u_ €Tδ€]€€€*
+€슞 W€€Z€€T€d€N€€r€€ÂL6€€€€IßAy€€€€€/d^€€{Ov&€g€€€€€m€t{€S€xRʦ€€€€€€tE€{QB2€ €€z]g€€€€Si€䠱€T€+S€?€T
+€#4€€€qQ€p€€Zg € ]€€€€"tO'€5M€€€€€€[€?. Y€€€€€E9iNb>€€Sft5€€€i€?= AM4€€€€€x[JC€€g€-€w>o€€€o€€k€ €€€^{€O€€H€€€%z4€€?€€€€€€€P€q€04rsÖˆ۸€?€€€€3 €€-i\€€"€€)ڠ€q€áºD{€€€ej€€€9hjr€€€:€\;kt,€€€€X2€ok֯€€€s€€€€%€̗€,q€ɱaݒ€€€k€{M>€€€w€~€€?€€€n€A{€€€iM€2€J€J'€?€ J-.€€vAS€J.W€€€ڸ€Ś€€€"[€€/€€L€€DN€,.l
+~R€u€€Z]€€rV€€€€€㚦€€€b€[€€S?10€€ξ8€~€€€€€€€O €=€€€4€€€CV€€/€}€◧€T€€€m€h~€T€_€ ӳ€q,&w€€}DA€=L釒Vh€'{:€€JH€L€][3€S€5€€"j2ԕ€€€ ʵ9€Jgx; dDj€YK€:€#Cb€€[Z€€q%€€€€is€€z<€⳻u€€€€€€}|€N€€€€=2×›7p€J€sY€€l€u€fæ‡Â€Ú¬Â€Â€Û†i|q€J?}ܬi€€Ky€€€32æ±M€~}€jO€€€0€€>'"€€€.!€)1€€€.€1H€0>€]g€K€ G,€b€€€j%o€“=€lia€ J]މ€}€€€€€_€€€>Mi;€€€€GN€礻8€€L€€T€€6Z€€€€e€K€r€Y€€€€€€€€#€€j€ÞŽ)d
+~^\f"€*€€`g€€ɟ€\€€€€ €€i<€<€Ye\`€@in€N췕€€p €€mBj€ €€=f€€4,IO€q€s€€I€€€€>€€i€m€-€€€€*€€€€8Õ® €)9€ZP€N€€!Z€yi€€€€h€€b€W€€€=€€f}€:[€S
+3€Ξ€€ <€F€
+€h€b;€€€€dP h€|t€AF€4㲸w€*€W€dG€k €€L€k€€3€€€€b2mv€€l€]€m€€€Ә€Ҿ€€[€0!€€Q€AS€c€€€€I€\€xG€€€€€6€€€€€.uc€€€H€€€}ly€e€€€˞ K€€€€o€€€b€y€€€€€ w€€3l€͕€H€N!€€BV€€€€€5€=z!J€€ޙ€4<€€€La>7€LF€s €d€G€G€V€€€€.€<€{€b€€€a€ €89$W"€€;€ғڬ€p€Ք€€ +t€^E~€'€ €,<ۀ€€5€€a€M€Q€ǹB€€~€€o€1€€\€€7,€€ t€€€€f€)+ <"A€h?K€€
+2Ѻ˅1 €63€€.,Xh €QyjU%r€I€€ €6Gn€€€޽!q¢€}€m€si€>€€FK\%€TN€]€J€>#?€cv€€€€€€C€\P€€zOۗ €€/€*]~€Ԍ€f€}€+€€€Z'€9€€V"/€1€€2€€€>€€€l€Y€€
+€€`Rj98€ MS€€
+€p€€?\€(€~*M6"3T1€r€€6]t]:Ճ€€€u€€5H€o|W€€*9z€R€€y€€€€€€€€9€€
+€€5€€6€Y€€չޔ€€? %€€€€E(€€6Zc€€\2€€€€€€c€€€'8€-€€B€€€yP€€€(€€W:€vz€€H^€/€€€e88!ÔŸ€€,€€€±€€€€€}N<€€j€\e' €€€€w€€1kfZ€€~€fB륛€Y>Uf€€ n#€3#€€€ʤ€h€?x€€€€^v€€S€j:€ Lx €€[€y€€€€€€1€€€bm~€E€d$€
+€€€rJ€ K!€€€€€€(€}60€€:d€€€€€€!ڮ€-€€€€€Y$€An€€n\€€1€€:€Z€[€€€r€G€€€D72*€€€€@+r€€O€r9€C€€€ÒQ^€€YQ€€X€€ƸË\K€€nU€%€€J7€57€d6€€Q€m€4R€€ €€M$EQA€€€[€0€N€€€€€p €Aa€4N€€:+5€Å€€ռ€€ɒ€€€d€€)w'L=€€*u€R3F€€z€O€€€u n7bnp4%€€1rP€4j€€€€l€€n#€€5€€€Ty/,{€\v.€<€€h€€€ Ä¥ €€€M6€€Ȩ€€€֨خK€€€€€€%€1%€ؚ€C€+1-€€WqpQ`€l6€B€YC€€0€|CR€0€3€€t0€9pZ€q€D€Â€€Q€€€€€€\
+J€)€Cy\€€ €|€€€[€~|n€€9€#€€€s€L€€`kS3€L€€€<€€?€Ό€P€€€]n€€(:`€€€€LJ~Qщ€冧{v€*€€+Ö¡€€€€€€€X€5€€€ۥ€y€t€€y€€z*€?€$U€€f*Z:U^i€€\ 7€$Ã’d4€€€€€€Ë€€7€`€€€€€€€€€[6;€q$~€Ί€€€g€€$€€/Հ€Æ“wa€ €aA€P€€^€€ޥO6€w€€€€€.€e€€€€k€H`l€b
+€€"Ra€n€€5€4<€€t M€^3I€€€€0€€HG6o€€€H0Ε5 €lM€n_<gR€(€€€=€€a€JT€€€ 2`€€&m€€4w€€.€>€€[LÔg€€€€pD€ޯ€€J€z€€€€e€p€€<€€gu}€€€1]€€AbSڑ€€ k€€?cvx€€€P€x€€€€%J풛€.[l3[)€€€€K€Cp€Zh€<€€ €O€Sn€%"€y€M€€K€€€c€€c!€€qܒ€ €€€€ƹcK;+>€\€!㡗€y€€Q~d€€Zj€€€€:U&4g€€v:V <bUPg€€Ó€€2o€€n€€}€^€€<S€&€€€€€€€€撄€8€€€€€€€€€€€zp€X€1€re€)gf0€.€r€<€,w€Π{+€€€€6€€UL`yC€eQ>hM€N€€<* €9K€wy;.€5€€ͭ&€?€€€€€€€€)€€a#"€d€€.XEBa€1€,€€€~€€€€€€;c8ÏœO€€:€18€€€i€€€/€€€€UTR€€€Y;€€€¤€€˔€B€€€V€d€€€@€€€€=€S]€€€€d €€€P€€€€€€ȳ4M€Lb€X€p€€€]€€>€:€€dV€€€€€€€€€wҹ€€qԀ€€rЀ€u€€€€u]MY€€€}Ih€T
+(€e€€€ *€€€€=€€S€wr€ĜS €€e€!bb€&€€€=€€€€I€`7!€v€€c€€}€€AE€€̟€E|€€€=€X€+€[g
+€Ϛ€€€€€€€ђ€a~€T%5€8~€t4ż_€a€M€€€€€ߵ€ѹ€€€U€?€/w€€uW~||3 *€>$€€€B€3€€€W€꼣€€K€€o€€M(€€€,V€Ùž[€K€€€€€€'€NaQL€€ d3€€€€(€3bM€€€E€€€€€<€s€€€€6]€B€Ć€€€!ej€€s€€`€€€m7\€€a€€€€dK€g€€€€€€eÙ³
+€€t܀€Ҩs€€€%€ַ€€x€h€€€€€'€€€€~€€€9€€€K€€€3€0V€€€,€€€{€€€Gbt€€€ᤧd€€S€€€aa3€€"eAU€s a€ݥ€xh€ ,D€€Ð€l€€]Iy€€€\j%€€`€€€;Û€€€E(f€Efki€ٯ €€0€q€` I€€€K€+€€€€€Icf €<L€€€A€€€€f+vd3{)%€;€3&€I€P€€€;€3o€€#€3€X\Ñ¢h€Pn8€`€|t€L€€s€5TKit0BKS€€€ܛ€€€€€/€ofj0€€1€€#(€€€qÔ‹4€ȣʠ€P€iW€€€N5€Դ€€YU-€&
+€H€€&$Z€{€€€€€DsJ€€€€€€Jí‚”€€)€XY€€J뚩€€€8€152€PF€z€€€€]V€€€€€L:$;n< €\J€ D€m"€€y€€-x%€€0FAk€€€o€.2€APbs!a€€,€wކ€b9€Z8€w€w€O€wÓ®H€€9b€犑r €3€Q€<€€€€rG€q€€Ç€}€x€X 8u*€]C€€€€UP€>Co€€A€€€8bZ{€`€:€€€D$€VPь€€€%€b€^€!E€5€64nÝ¡`[€€4:€€€€_€Y€€|€€€I)€€L@€€€€€Jr€v€€٦€€€€€z€#bҕ€.€ɔ€ €w€€€I#J€H€€€€€€\€€€€*s€€€€c1€€€€tip€yZ€€ €r€빘,€ϭݿ@ݿ€€€€€€Ø€€B Y€6€}€€~€(€<€G€€~€€€)F€<D)€€€gt[&€VO^€8 €€x6\€T€€€+eg€U€`.€€€oi2<Z0€€Gp€Yu€€€€€€€;€^5/[\€€€€e€€€IA€€Q1-;€ͦ€€!P\c€X€€€€€wY€€K4€€(€gw€€bΛ:<€€€ €j€€€€i,wÓ£rÖ5€€ <Z€€v€€ €€€O€I9ÝŠ_6€€€_€€€€€€4r^€€€Qk €€€€€€]:€) €€\O0?€€F`€€
+ :c€€€i'€}Q€z=€{€€9-€*€.€€MoÞ¬6V€€jb€#€€€€€€x€`Fa€€€€€1€ 919€€o €€€+€TÚ„ä Â€)QWJX€€€€€€f €j€€
+pD|
+,€€€2€<z€€<|g@\€ä§PÚ€[€€'€€)x€€}?€€€J€€€B€€#€|€€€^>€€€€3]L€€Իl€E€€rx€€ c€€y€€n€€u 1 ~€t zˋ€€€,€
+e€€<€_€€€P€€€h€€ef€d>{:{<€#€]Ì©0€€9€€<€]€G€F€€J€%€€Zؒ€0€pD€€!ӷ€€€€€€x€€N€2€ €M€2Y(ϖ€€€ €5€+€$€] €€4F{:€€s2€|{i€hlX#€€Z€%rV€ 5€€€€L €V@€b€10$U€€€€)2Yw@€<€€w€€€€(€S€€€€€$É¥z€€€€\z€€€*€!€$€/€€шG5#_h€€[€€Xup€1KM,€ N2€€3€€ʢ€F€L€H^~&€ €€Q€~€€ەJ銹ٚ€巙W€:€@h€ 4€ٯR€€€JG€€=K€s H€n€€g€€Rr€€: Z!4€vƌ€€€N- €€:g€w€M€i
+;€€€.€2V€&€\Ç“{ lTDj€*€€€#g€€KL€€€€m€r\€€Ѐ8€€W€€€s€€ €€K€t@€b€€G€͟Z€€€€€P8€€f@€ €€C^D€t€€!€€x€€€7(€€`2€€€€€€JOێ€U€€€€:!5€z€€€ɤ€k€€ֳ伯€€€€[€€€K ir€€€A€€K€Ice~€€k€Up€ß奀€€€€I€€€]€C€€€€F5€sV€4€€W
+*:€€G㺶€1*€g>9V€c€€€€€<€exv9€€Q€-\΋€€€oꞵ€€Pv €€ӗ€i>€€J€.q€€|$cA€b€2ѹ,€€&$€Z|€0d€€€f€ €kbI€€€€€€€€€)€8€h €&€)A€W€€€€/7=€€€€€€€ h:€
+Ur€z€€A€p?€5€
+\.Amef8
+ €€6€€€€€€€€€rL€€€€ T€$F€€€€6 &9Zz€€'1€*€€^€€€tXX:€H€`a9€\€€9\€€g€m€{7b0b€S€fp€€jE€[G€€€€`wn€€€€ f€5Ы€-k€CI€€€€€€,€€€USsq€8G€Y€p€!€ #€€€ޤ #,Zm€YXffm9I€&€;€]€€€€v;€*€€Y~€u€*€2'€€E€€€€€.̓PBg€P€€ Í‹q€F€€/€€€€&€@€€€€€€€€ц€€?q€€lJ€€k€<€h%€S+€€ks)Wd€ €€€€€Su€€#>€€D€€H€ €€r€€!<€s€ *ݕ€JA€Jm€€(€Luv€>€_kC€~€-€,4*€€Kb1€E€
+)€h€ǗMr€€€P€=Vv€€ηK:€V>c€€;€€€Ã€m€Aؿ€7€€€|€€€:€€€€9WÍ-€QØ,€€€`I}€€|"ɇ€U€J€ ;-€'€€€\ͬ€€€€ɴӕr€€€€€€€€€M€
+€e€€€l€x€J4€{€ kC€€€€PM€A€€.c€m€€ΈC?oFq nC€}€ڮ€€€?ޑ
+=\€€G€L €%é¢Â€~bR.
+x€)Ф:€€!&5€H€€€e€€0€€X€€C€l€E~VuK€͘>(Z㵳€G€ă>jdM&9
+MWޑï€*€€HQ€+,+ B?€€|€€b!d/ŋ€|$€€€€€€€g:(ju.€(€€`€€€F€k€+|C43,ut€€€I
+€!€€€.€t>b€kÈ€€€}€n€>P}€1€€_€€€€€€@v€€€€X€q€d.€€€c€d€(%efm€w€€{€-:€€€׵€€6€[a€ϻ€N€€W€€y€€€€€€€€U€欕[€€2€€+€g€1€€€m€€j€€€:€€€€€o€ڎo€V€€€J`€i8€z€€R€U2"o€€\Lr<ц€€ €Mh€E€€€'€[€€€\4€€ €ńgt€€€€€€€€€n$
+Pf€€.€€€"€g€€! 6Z.a€ €L<%€li€=B
+€€O€€€ɄY€)€€|€T€€€€7:Ÿ€5}h€€+€$ €B€c€€€c€€€?:€€€GD€mv€€€€7€›€€é€€€€xkf3€g€J_3€€€€€€l€$#€€€MA7€S6€I€9€XØ„uM€u0€€€M€€9魣€W€G|; €€ɕB€%[ =€€,+n€ y91(€ €€€€€€€q€€;, )€U€€QO+€€F€цa{r€€ɛ€"€€€€€€z€1€p€ܾ€€I?U€M€<T€1€€<$€v€€€l€q€€#b€€xhG€B[p€ 9 €€€:€0€€1€7€9.€n€€pj€M€€€#4€€€€"€€`€€r€I€1@€€€"+€ÔŠ _€_:wV€€-'€€d€€O€b€OcE€_)€.B€€Ҡ€(€>€n€€m€€€5vP}€€&> u€€€€6U€}€€€€€S€z€€g€ܓ€€€€O€X€"€h€€€d]€€Vlk;`€€J€€€€€J€€)ڮ€JXں€€€<€V€€€q€€p€q$€€€€}€€€6Ä’.q€@€€ .€F€€O€9*7€$+H€€€N€h€ €y€: 7€€#€€c€;€€€\
+€PjxV€€^€€?€/4€€P€
+f€2€]aØ€]€2€ɂ-iLRj€€€€€€€€€u€€€N€B€€"~€ €gM€€€z€cnZ€|€E/n€۵€&̑€€€C(€€b€TG€R
+€%{JQ4€T€ €€€€€€€ M€
+e€€E€Gm€€f+€€3"Q€ (€paOWY€€Ŷ€Ү€CG€E€%€€€D#€€
+€€€t€CF_#a€€€€€L€€€f€׷k€H€ €2€k*9€t"HH€€t3€ €2€€a€WA€€€ߩ€€;RD€)€7€€€€€A€y€G€g€€ €?€€+AHֽ€€d>€<2^€€€Z6€€B€43€ߵ€€e€d€€€€4€€K,M€X€ń}Q€UDsYO€1T€€€s!Fj*י€€€€1€
+~r€€€+€€€€2Q€@€ޮ€€€"€W€€€€€1€N€D]€€€€€€(@€€€(€€€AD€?€€€€€€€€€€€e€fm€K͛€€vf€€€€Ow€€€€€*€*€€€@€€<iX0&€€mn€.€v€|4n€€}€€€-?]€ €€€ajV€€p€kEÑi€JXd€€€€2 €r5€f€€H€Y3Ó‰p€]oeHStCe@€ℹ€:€yP2=€Ù€N€€€pI$€yWÚ†HÔ˜ €]o€$ €€€h€ @€0 €4x9HgCxc€€€FN€€Vh7€€€€€€ 'ÓŒm€€Cm€ Q€ө€€€€-iN€€€€€O"€k$€)€€€v]'É¾Â€Â€Ú Â€Â€2) €€hz€G€2€GNU €"€€€t<€€ €D€€Q6€€c*n€€q-ä’³cv->€€<Q€Xf€A€J€€€7€k)€L€ORr€€D€&LИ€T^€"€)€8d€€I€hV€0€OÍ™;€ڞ€xY€R}vp€€€7€€VK^€)k €?h€^€8j€:€vT€BVhʤ€€€€O€*€/€€ €q9A€| €€u%€€€€1Ƀ€€!€4;€5€€Q€|,&€€ؽ€6v€€€€€€€€3€€V€w€ ?j€€=~€€€n€€€€ї7€G=€S€€€K€€BG€j0pu€n6€€BgV<q€€jt€€͹&€€;€€€`z€€;'x€€€&u€€€s€€€a€€PN79€g€€€€€3_€u€€€<€>J€R€i€€€€€!€6€€€6Q€€€€@€XF€€,€€€€€H €-%j€€€u€H'€€€.€€€€€€~€z€w€?€"€k,b€€g€€KjT€€€ܥ2€€€€" €B€€€€=€€€€k€ml€€C€/€€€Be€€G"€eJ€5<^€€€\4€€5€€6d^ >@P€%E€G€Nn€€p€^€€€€€e €iL€€@+€#€€€ €€z€€>€@?€€€?:1€€ V€€Q Rvf€ €€ m\€€4%€€ €€b] €€€€€€ !8€ €€€€€€}o€€~&€€€ރ!€zz€€€€n€r€j€Uw%€€€€ܿʔ€5€Ξ€[P€w€;€€-d€€€€bs€€€%€;€4€€€Ýd€€w €2T€€|€€=€€€€K€dKD€!t̊€B€€F€€€€€€V€€pW €€€€€€d@€€b€X€^-€€M€€€€+Ʊ€€€s€€3E€uɛ€€€mK|€€€EF€F€€8€R€€NaN€M€€€"€&WЀw>€dg€€€€<3€U€€'€T€€7€(€g=w€O€€1€`assjL€€€0€h€€_€4b€€€€D7"€d€ €j€E1€€r€€k€€€<€}GgB܀€C€“r€^[€€s€€l4€€€Y€M€;€€H%€€€r€€€*Cv*ś€ €€+/F€€z0猧€€]€€&€?€€€L%s€€v€€%V€€U€K€€2%€€€u^€€€^€arh€€~€>€€!€€€lÔ¶rn$
+€$€M€ژ
+€€+3€%C€87€ve€¡*€€XOS)€_€Ga€I€€€€9€y&€€Q€4m€€€ҳ-gX€B€^.€m5€n,€€€€4€€= €€€ɤXS5Z€€Û¤>€ok"/|€.€€€€€[€€w7€A€$ve<u€L€€€€€,rC€Y€€€Π€€`ÒŸ]N€f#z4*€ө€[N€é˜Om€"€€q€[d€q€mwd€Og€+C _sn9}0tÏ•:@€)€€%K!?€Sh€€+€M€;J.€»o€"€:af€MmHײ €€€€&0€€\%*€€€€€&i€,€€€| €r:vQ€Bb-4к€€€LwrÖ˜W€€€>!€3€€€P€ €€€€€y€€q#€ظ€€L€€)î³²I€€€\€cp€€]i޵˒Ɇ[ € sR}€€€d,h€L1a€€]7€€)€QJ€?€q~3ᜈ#U€)€€D€p€sy€S€€x€€€€,J/€$|€€IG€€x€€€o€/€ϗ€>€%€€tM€€)€€ J€€.dC€s€%€Ш€{€c.vdy€€Ei€€>€y€€€€€=V€€€€€X€€6 ſ€=€}5€l+w!U€"\)-t'@0%€€€€w €€M8rTy€€€h€p€8€(€€nOĪ€ e€32*r€ €€Sm€6]3UQ€€bH,X>€e€€€€J€3€€€Sp€€€€<[€yQ€Me€]X€>ÉŸL€汩<-B€€?€€€N
+7€€CH6€?n|.j€2׉9€ €o0€Px5€k€&!c->{€€€€€i6€€€€8€€€€€!€]€aHn6cÞ­3bZ€€A€ <€z1€ O€h€Q€€€9€€€€€€-L+€€€€€ZΈ€€S€%€*Xv€€€i%/ ~€J€€?[W€{W\€€€€€aa€€]€r€k €€€b%Jm^€ €€€€8€N€€ƭr!€€ί6€€nA€€A€L€u€€ټ€€h€u€+C€ E7Iw€€]€!)ZOC:&I€m.E€U€€€j€€u>W${€X€€eL_€€€€KÙ¬S€Hq€€9€€€€€(€0o€4€B;€ȡ8ߟP€€€^lm@€{€M€€€r€€€€€€€Q€€€@i8€€€€€€€7€Жm€|€Ǜ}€،g €€€eB€€K€;ZED€€rB €€Z€˴€ZUx€€€H€'1€ڪ5}X€ôI€V € €$€؅€€:€€f€€Ù€€aπèi%$-i:€€€€cWZ€C€ڡ€~€&Y{p€2€k€cn€C~€R€K~+€€€€€€€€€"€€?::8<9{€{Rݭ€€€ݾ€€DzUÝ«! %R€}€'€€^M€_G€€ݮB€k€[€JO€€€K'€€€€
+˫X€€"
+*6{wTe€€E>€€€Z€6€€€€€€€€Xm €€2€€r€€€€'k{2€R€€€€€€€€?€+€€€€€€%€€€)€%]€€ 0€€€x€€4€€€€y^u€€€€u€€€.|€mj€JN€€€({f0O%€RC€ȸͅ€€JOY€(Pֳ€€8€Â€W€€€€7€zD>€E€>x€#J:+G€Hi€&€€9€u€ݭ€u€p€€€I؀€€€o€F€X€€€€€R€yQ€
+4€N€D€S€t,UҞ€W€+€<€e€W€€€4€bŽ€s€€G€€{@€€€€€€Rb€_`
+€ €W€€€€\€€*#€€€€K)hZ€€炪%i€Q€€w}HE@€l€KK€^M€J7€`I€€€€ &€|€s€Q!€텱)€c€䞶€0z€€.€1€a€r€€h€€n€1#€cL€€€3€€d€Av_€€T€o9Q€n €€xXE2w€N*€€l€7€€€^\€뮣ӽ€w)€5€€€€1L€%€?€R€€€€l,Ӿ€€n€€€€}
+€€€€€xM€ w€€p^€€€M 2E€€p€sz€tW€€扯'€€+€€ €€-€%€+t€€d€€€€€€€€7d€€€=*f€&V3fcV€€I€';;€€ή€nn€€€s€€€€L€%€çŠÂ€m€€€€]€€€€Bk€\Ó¦YX
+€c)€Ȓs€€^:€€"€P€€`€t€H€€€€€z€€€;D€€;€he{€€€'€l--€֫€€€€€€!@€€€dd€D€Fȓg€;!€/r€I€w
+\T€]€+€€€2€
+€mH€ 8gN;PSH€\€e€€i4€~MCc€€€€~*€(L€€- Y€€R
+€Ü€€K?Q(€P€d€€q€y€€€Eb`€€f<€€€J€€ =€€€€€€€€€Glp?Q€€M€€€€6€-€?€I€í¹¼ €o€€FS€WU€En4n€Rx€€Y7€€&]|€Sn€€ €i€€&\
+7€^€J4€€*€q€piI€€xRc>{€9€€w€3Y€؟4€€€'€0€R€]`C:€u[rij€}~0€y€€€#-l#€€€u€C€4CF8€€-€[.€@F€€~Du€u€€€€€Y€Cn€t€r€cÒ¹€€€€mn€€€€€€$€5€€X7€]أ€(€RC€>r/"€ը\K€{dR€X€€€ˤL€€€€!€gnي€}€0"€€1€€€}$€€€bj€€€€1h$€[€٘€€€€€€(€€h€n€"z.ÈIA3€4€WQ%€4$9C€ʷR€F€€€€€n€€TGU€€U€Yoȶ€€€=x/€
+G#;€!€J-€H€€o€€V.8;K,€HD€€€Uq2j€€T€C€€€€4€€€|€lu€€-€6€w€€K€€0wt}>xȯ&€,@\d€Њ€€\€D€n&€€~)€K€J€€~C€@€OQ€€€\€VË—?€€w+{V€€ΗzǶ{×€€€7€+€du€€^€M€>€€&K:€€ذ€€€qM~Q€6€€,웊o€€t:C€{€*€i€€8mM€€mj€€€€€@M€€€€#€€L€ʠ$8 ϶.$€1 ]€ €#€€€€€}€0€€#K€!EC€A€€€€€E€q€€€€â’5Q€B€ȉ€,€€I€€€€€€ "€€}'€€ن3€3[F€€€€i€LM8j€€€€€Jnx,€fK€g€+8a€€€rC}€o.͈€€
+wa€e^2%
+&€6€€Y€!€€j6r€€€€€W€}€X€€€N€€>Rs€X€€€|€-€/€€€€A€#]€IR,€v€€€gxlÆŒJ€€€:€€`%؆€f6€€H*€€έXD€&€u€€zR€_€*€€$€h€€€ €€M€Y€? €€€€u€ˢU€€€€€€€@uÕ¶€C€W€{€€T€€€'V€€&€€€€τ€K€€€€€E€€ɺ€l-€€*€W€€An€€€×€€€"€€€1€n'7˛€€4€Pi€€[/W3€.€V€€€v€€€€ӎ€7Z€€|€€^4t€€o€€€2€ Q^_-€# Bd€€k€€€€€€€€=P€l€Ë€€€a€$€h¨€5€€T€+€_D€p2€€!€€`€€T€bR€€7n€%[`k)€€€x€€€€eCR€€åªÂ€Â€*€€2€€QIO€l€ǿ˚*€€d
+€d€<7€€€€€<€€'€h€v€{€G€€€P€€|€ûSv€a€€€€+€Tk?'€y^€`[€€G€Ô£> .€,€jA€€{؄€€€€€€c€S€z€€€|h@$€€€€€`€:}i€v€y€$€€€ݲ€€€€+i€(J;€ԩ€€€€€zu€t€~€x€v€ߩy€?€4€€€q€X€&€y€€€€2€€€WmÝ´(%€9€€€{€€f€h€€~)€.€Ws€<€%€؟€€z&x€w€€€4€€S€€€Ҝ]Ly(€c#€C€5<€€c]€_€e m€G€y€*O€€u€€€€€W6kV6€ €K€€€
+l€€€@€֗f€€€€€;o?€€€€sv€;€^€€q€€ߧ€€€y€€0MѱYs€Q €a €€€q€a€Xv€€€€L€đA€€jq€{`€N€W_ €€€€ <€O|€Z€d€A€~p]€€R€"€l€€3€€€€0|Ԁ€~Fb€*
+6€O4€€€,U€€×€€€e€€~[>€€J€€9€}}ae€€]:€Ɠ€e€€d€€€€+€€€m€>6F€€Eȱ@~^€€@(€€€€u€]€ay€€'€€€,O€/€€€€l]€€€'€d4 €€<€9MB€€$€€H€>W€
+O뉘€€€$€€"+^!M€3€7€h€€?|€€l€\!<€P+|€&^€€€C o/n€€S€€€Dj€€€€€2a8oy1?€)€l€d1lN€6€€ € VA€€{!€ €€€€€€"?,€ €€I2€€Md€6€€إ€p€€T€;2+12€{€a€PJ€€= €€€]!ƒ<€]€€,O€€€€NK{€ʡ*€5'€1€^€€1㸬€€€kI€/s€€€tÏ•É«<(}6ÏŠ!ȭ€€wG@-€€€Lb€s€/€@<€€{€@N€€n[€€(€€*aQ€€€6€€€ꔢ€6€€€5€2B€t€8€7.?F€vݤ€€B€€Ç­-Ó¡`€X€€̚K€&€€€:€1C€(f9€€†€3{€ev€a€€zX€kSP€-9€H€€€,€|€€€yD|€%€B\€€F<€s €€3pÌ‹€[€ƿ€ Í£oA€€¨€ }€V€|vj4pdQ€€0I€qWt€U€uéžÂ€Â€Â€3Ο€€Q€€€€€€9h},€Өá¬+j>kfZY€€jN
+€€€@a€€€e€h€g€€`.u€€sP€ާ€€|€b~|&€Wk €_3€dR:€€"€UY €€€€*7€ܒ€€€sx€€nz€p€NoΜ€€t€i€(€€€€€€€€yI€€Ӵ€1€€C€€&yIb[۵€]€€€€€€€€€*Y€mgr-€h$^€€)€,€w€€€=T€€?g-€€#鹒 €€€_{€€0€6Yc6€e€€BY;]>6€q0€€€5€a€€ܞ€2€€,€€)"€€d€€&!€€u-kb€0€N €b€€N0€.€€€€cc€OZ€}x
+€€€('€€€€#€€:{
+5€€QDOi€€€€&F
+€/€€A:€ot€€`1ci€L+c^€€U€€€"l€P€€¢l_c€o€ ˓~\€€y1€€v€.4€€@€~텦€€€U+€_€€4€2+€c€b3€_S€€€€|€L%€o!C@%oO€a€i}p€>€0€W€q€8€€t€ˣ€X.€€€;€€€€s€€€€€,€€€3m€€>=Ҳ€€Ll€S€€€€ά€€€€€lF€"
+€A€GF€H€Q€X€€"€€€$NG;3Y€€€Ĉ€XsO}R€€€€€PM€8€Dc€S€€I€€2€€=:A€€€€€€€€€€€k3$€€€€€b~oGI€Jy€I0i67˛€€€€€M2€7€XCok€R %€<,b€nÇ£" €€f€€€€=k€€€" €€€€€N0€j!ۈi7€$€oæ‚›u€S€}r€€e€€€=9g]G€g€€€€D€€€.Ó¼€€q€!`o€Q€E L(Ö€€€!€A€€€pE+3`€8]8T€€~€\=z€燱€YCe€€؃g€)€€€€Nn7€\€€ί€>#(€a€j€€€TGκu€€ɻ_€€c:€êŒÂ€Â€ €€a€€€L~€€0B3€6h€JMbf€[L€#€c€€' €€v€;U€€€{>€O€€€€)€€}|€€w€€!Ù­fly€@'€tY€ €F€€מ'€G€?€Q€€j€3>È„g€€!€z,f€€`€€€€M€€p3€ʡ:l €"`€l€r€€€k€-(€mk=di€è‚2€€o€K@€€€€€€t€€€8€ޫ€€Z€€N€€v€€
+s€€Č)f?€y€ӷ1€y€€€>€€€€;?Y€;Yub€€ (€€>M€€q€€€ bzp€7€€€o€%:Ñ¢€k€€€C:!^€€U€€€€€€€€[,€R€€:{€v€€}€€€€€€€€W€W€€€€{€ €€€€€€/€€,€€pK€€€€€€x€€~€4€L€
+ſ€M€€€W€€ڎ€VX€€oj€uR€€+ֱ€€p€€q€€€JԞeg€r€T*>€߄/}TEݰ€x(€iu€€x,€€l€e€€b|1qe€Ah €€€8€=F€€€k7&€€hckdFqG׀O€q€€€Ʀ€U:[
+€€ z3Ҝm€#€€qV8€€€€u€€4€j 5€€BC n€€€PΘk4€5€€7€a3€€€€τ}€€€€:€€؊ €€J€ }€€D€€9y긓€€R€€H€€x
+r0€O]^€€}L=9&4uu€]€€K€#€"N/€㇟Õ€€6`/Ǽ!C^€=eN€=€e
+€i]?€€}€€ r[€ *nO€€€|It€J>€€XD^HښYh|ۘ€n€8€€oq
+Z€ € bB€B€€€€T€€€ .0€ €{€€@€€€€ƿ€€€€_€€€€~€€#€k€H€ €€€m€€ €€€e€Q€O€:€x€+€€2uH€!€€UK€w#dH€€4€)W €&&_€G'€€€€€€8x~@r€g€€€#€zD€€_€MCZ4€͹€€"€ʼn€h€ € €€'anNӭ€X€;7$f?€%Y€€€€`€g€y€z€€/€;€\€^€€~n€Jt€\€f€€c€€€fG€ٙ€y%p?€ €€€€2€W€ €F€€€€€K€!~€/€€P]€3€l€€8€~€;€$OQ€€y€J0€z#€€€݀€€€[€€V€؜€€€0€Z€€€;€W€€€€€_€€€€%€€K€€ߑ Ж€€Z€E€€€Ǭ€0p)X€€^FG€DK€y€ €jj€L€E3€y_!6€€€€C€€y[€nZ€€€|/p9€:!€=€€€0v=€<1e€€|€A.€(*€I€T€LOIӽ€Q€€51€m+0Ej€€€€$€ 47€Hs€a€€!%€€:;€}g>€€€ 2€a
+€€€€€es€€€T€€€€N>&E`€€֥€€€€%z€€h€€a€€€)€oL}*m€€€€€€,€€X€€€€€Ϥ€S€Z€K€<€_€€OH€€€€€€0B€€€&€€€€S?گ(`€ €€€€€€SR€€O€$€€=4€€(€T€€fb€3€k€€JNU€P€Y€
+€€`H€€a€D#€I€YK€Nv€,€€€b€:-h€~ €y €r€_€€€U1€!€bnqB€MD;€}g€€€ ǹ €€c€€€p€ 5kI€s €€€€€/€Q€€3€#~€1€K€€€€t€€€€€o€l€AVa€~€>€G€޻ˢk€:Ê¿g€e€[e€€e#^€€ 0q€f€€€€€€k€('D€€€€€5n€€6Enn]€{€€ tangle.chb.oldsc€€€€€{€€TEXTMPS €€€€L€€€€A^€}€€€vbU€D€*I€€6€t€€€€€2€€F:€z%a€€ԗ€€€€z€€€ v€€o€c€€€T€@€3€€G€€TD)#€€)€€€ʙiD€0&€€b€€GR€€p€€# €4€€YQ*p+€3€p€(€€€eUÇ”9]d€YVF?G€B€u q€I€É€z€€.€3€€€T€€9#)€6€€€€€i€€€€S€€€!7€€€!:€€e€I[€ €€€zW€#(=?€^ߺ6€€€€ €B €€ 9b€€f€€S€€gh N)€€ €€€JV€K€v€$ϩ€#+#€€0r€#€€€yN9€s€ճ€€€€$#€G,€u=p€d€'Ç72á„“1#€Ʉ€ €d €€߃€+€\€€€€5€€€s€€ `€(Kx€bQ€W€^€€€Ƭ€€€s€€WpX€€€υ€cnVW€x5€€€K€€€K€€€~€€3€Ƌ3€€€€\€ €€L€i€€€3€€€787€糰c€€€'E*€€ED€€ǩ€J€ʠ͊€Iؼ€€€{OK€€€lR€€€€€4O€€Z€€€€S€a€Y€€€€D a€u€€€I"פ€€€N=€€poN \EZ<€€€€€€€`19€€€E€*€;€U€0e€€x€€€3@ #{€€€€v%€.€€€.€A€2c1€y€Є €2^,€
+€€€€€€€Me€G€[
+pu€a€9m€€e€€o€€'i€€€€€€€ Ö€€CQ€ €4$€€€€€€€€uy x&C€j€%>€2€0},€#\€;€?W€€€&$€W€€€€p^8€€͑9€)2€€nh€n€S€€€€€@€€-@;€ €€9€m"[pܤ€`Q-=-lt€,€€de€€€UqS€BCa€V€9€€€N€Y€|€€€€
+I}H€%€Z€€*NdÇ•R€€€€pZx€€€)€;€ €Ӡ€€€€€hy€ €€€€(€e€€€0€gf`Ï*€€ u€c€€Jbh€,P?€€,€€€2~Ƴ€€€€t]8€R"J€ln€€+€€h€€ ow€ђ€€NZ€P /€€€€€ι1V€Db€€|9€€€ךQgAu€6€€€qk€ €€€€€€€?}ckk€€,bÒ {Rl€ %ShՈ€€€8C€S<€€J€U€H6$?€€€E€{€€o€I9€(3f€3€6X€ 1]€€€ܬ€3€v€8>z€
+€fPVzU€}w1€€€€M€;W€€€€;€€_p€€€€G€€€N€€<€o€5€€r6€`m"n€7€:€€ €€€
+€€€g}|€lݞ€#%€Io:€N€€>rn€%€pA|
+€€€€>lܻ_e€8€'€€)YI#E
+€Rt€%'Ew€€€€<i€€€%hݨd€€:€€;݂?€€€Tb€qT)-€€€\€€km#pf€€ѢJS€\€:W €KT€&m€€€€jA€(L€TG€€O
+€6ٕ=؛L ȀhWc€€þ€€>€€€tG~A€€*€€€_€€`€MP€€K€€v#R€€€€€€=N;>N€€M|9€€ݽ6 €ݹ~€t€€€Q€M€5%jXj€€€mŭjz)mҳW€1€8€Xs,€u€c€
+€€€€8s€H€x€i€[€€€g)\€h€c€vK€C€`gX8€5€€ܤU€+N€€ €€€€R€ڨÜ€@€j€€€€H€pX€€H€€€ €f f8€vG€€€-€/:€A€€ov€€€€d0€€€€€j€<#€€€R6€2€€U€€W€€€~€[€;۴€C€€)k€€gR€€€€r@e+U€.€b)€€€56y>v€€€€€E€€>€€=€mc>d€?"€€֟€؄Ù6€&€Û‘€IY€€€€c€€€€V € €T€€Æ{€€組M€€d
+€€}€€€8\Z€A€€h€€€6€U€u€€€F€+€€€M$€€|€b€€ €€€€€|€T€€€-€€€U€M€U€<€€RÜ´_€,8/€h.€&<E#L€€Ԅ€ €Rp€U€ tangle.rsrcoldscL(€€€4€€€€€€rsrcRSED€N€€€N€€zI€Yf#D"* €€2€Tsi$#ǹ€€€.MK€€€€€E€€€5^€)€I€€tC€9€€}n€€6< \ft€M€€€€FÔ›e3€€€€€€€€€yO€€t€€€€€Y€€%€Y€€p€
+!€€sEˤ€€&€-'jM=€€g4€€€$c€€K€€H€€€4?€€ћ€e€dZ€4L1L€I€€P€€.E€ u€€€€Q€@€G€u€]€+Q€€z7€€QW€~€€{Q€€"N€€lvM+€€€€⦢€€€€€€&7€€€V€€€.€€O€€€€ؿ!࣠hϿ)€c}qϿ)€c€€ €ÛM€7|€€€€€€€€⤞ €€N€€|€9€€€=€€€€€'€M€€o
+€€€Myk'<€o
+€8€o€€-€€€€€€€3€Y;€€q}€€_€€€}|€y€€€€€€€M€|`ͪ€=€ܿ9€c€€c€pOk€€ﳎ€€€€`e(&`€ËŠ+€7€€;Bi€€€€r€=wа€€hÞ¾i€śF€>QG€[X4€€ ; #€€ؓt€€-v€.€€€€m€€c+€€O€,,€€€b [O€X€ €w€Ct€€€:h€€,€€t€€= LGW€w!]iaY€€C€-€>`€€* {€?UAW[€€€w€>ba€€€€€€€G€€{
+tangle.webcoldsc+q€{D^€€TEXTMPS €m5*€€lR€€€J€€€%€ub€vb S€€€-€€ŵl€&€€€|€€͛ŕ€€€€€pIXj:€ €€jx€€€€! €€l€€€{_F€€Om€€>€?€׬€€€€G€)€ J¸€€€j͸€€€c€8€)€€&1N1€€i€€AR€шdicY5€€€€€€€€€€€bF€ȹ€s€€WR€€猤p€€€Gυ€u€A€€€€'€€M€1€€4€€€RzW€fW;€€€€€A€€)€L€o]T?
+t€h€\M€ c€(5+€€j€ Ծ€i Ny<A€k€€€€€€:€tYË“?%€€€€~ €_€4|€€L€ۂ€wS#€G,P€w]N€r __€rd€M~! A€SJ~%€XYp€€€€€€nHh€€€€ؾ€C€€M € €G€R€6€€€lj€€ [A?b€€o€€Mʦ€€€€p€}€€€P€€r)€€'/ÄŽJ&ip6€E€€7_€€D€€4€bq€E€€4€€p€€C€Pf€K€€€€2€^.3€€8Vb E€ɡ€T€€€q€&*€€Pq8A€€€€JĨs€åŠÂ€"€R€€P€€€€~9€€€€c€€€c)/€q.€A*€\€€z}d€~€€€P#q€C€N€€€۲€q€€R/z&€ny4€€€€€ €€€A^РF€P€€D€%€€€|€€€€€T€€s€Ô¶€ê¾™Sw;A€€€€€€€;{€€€;€€€€€ۇ€€€ǿ4€€J€$Ø‹DI€!U€€€i€~@#€'Ik2€€g€E€M/D€€\€€<€eJ€€Fx€€qR€€R"€w€~€€Fg€€€{€zH€€D€€rx€x€?€hbk€€€€€;r€{€€5€Ú€€~€€€€€Fpc}lj€€ €€€€L#×ү€~(€~€€€Q€€€€0("€{I€€ۖ€z€€€xp€€oM€€P€>|€€€A€€€4€€#€4t€€€€€€Kk€€_R€€1€}K1€6€^|€€€4€m€XR€'rt}€r\€=<9€€€ы /€€(€_€5V€€€€Ë€6:€€8JSuyW€€u€€€Ǝ*8EV€z> €P^ۋ€€€€€?€̼€1€€çŒÂ€h €€6€r<VE8€z4€.€5€€€€€" €8{€!t€{^€I߀€J1€€0€€€€€M€€8€$Ue['Tmo€€€3z€€€€€€€€PW˂€€A7ON܀€J€ €€3€€.€€8Oհ€鸯9€ֵ-€€˄'F^€€€[4€€x€€€€"€€€€€%2%h€€€€K%€€;€€?€€€.€`€c€€X)€€€HbtA€€€€€|€€Ķ€€€@9ؤ€€3€€€€J+暎€€h€i<€VG€*b€g€e;€f€€€s€c€€€p€8€€^€€eM1€€€}€픡€€€x€x€€F{9€€%€?B€^€Ĺ€€€Fl€€x€.ET?€[ÞŸW2V€€€`€€€`X&€€€€;s€€=s€€€Vwo€€(€U€6€€€wz€€€€€tr€^€m€R€€P€€€E€\€€ €3~€€€€g€€`€€X€€€€€€€w€€\€8€€3€€€M€€€K€€v s€€ǒ^€€I€€a€€y€ j€/€n€&=4t€€8€^ €€€)֖€€€>€W}€%€€€€€€€€T€Dy€€€co€€X€l֩€B},C\
+€>z:€\€€F2€Λ€Q€f솴7€€ttNyY€€'€€€ Í’S€vO€€€€€D;€$.€€€€h€€9(>.Ù§CSN€€r€v€D6q€€€l€^€€Q蹭€€€58&o€€D€|x&€4€€N€d€1}<ʀSB€€€€€,€€€rIo€€€n€cv~€€€€€k€€/M€v€€z€}W|€€?€+T€€€99̃Q€=Y€N€~@H€$€€€\d €34€1€€€€€}s!€ql9€€€€6~€tY€/r€M|€€€:.Bl:>4#€
+,%v€€€h€€€Ɨ€€€€;€€€€€@€€€€€€€€€v€2€€€_€€n€€€=€€=€€
+?€yl€C€€7tX€c`€=€S"n€€q4€x€~€€ *B€€]Ud€€€2€€€D€2€35€d€€>n€a|€€X€€ €XÓ‰~K/@ €€G€3GkB€䶇€€o€€^€€S<€H€xߖĮ€{€€€€g8#€€h€€€v€€5罬€€($€€+€ €*€€€pB€€ h€€p€€ö]ݽ€€€&€E€€€€ʹ€€€€iԠ€kbpÅ€9€€€€€€€8nX€{v€€v"€ €l€S0€3Q€€==€€5€€€ ^e€€J€p€€C€€€€&€€€l€,€€€(€D€€X€€€9€€€q`}*C\€'cBX€N€€:€€€ €€€е€€F€C€€LM€€&€€#€ J€€€S€€€€M€4Jl7Fs
+€€€€;"{€N?€€€€€€€
+€€€€M €vi T€W€k;k!€€€pX€ȼ€E€Tk€y€€M€x 0€v €€\_ €€ƌ€yР8€C€€€€€€€€p$X€€+}€€f&€€€€Y€;€€€€Û™&€t€€€€€€c€y €€€3v€N'€ €[ݢֵ€C;€gq€F>n€€€€Pa€ϒD€E€0m€€ €swx€d €j€@€€€€€v€€€q:€€`x€€€&€€€t€&Y€€#I4*P8€ @#Z@q€€r€/I€€=€s€€€Z€€€€€M€qp€0X€t€€€€i"€€]wV€€€ €€€€^€€0=wAÔ€€€€€€€/€€€h€€%6€€€€rYp€€€"vWskNG€P€€t`€ea|'l$€€€€t€€€€a€l(€YLk}=€€€Z€€€ʪhR€*F;€iGn€€€€m*€€4 .€€w€€€€u:U€e|€€€Jd€.€$ዛ€€€h€€€€n€€_€^ €1€<€} >=pl€S€€QW€€€€€€€+€Î’5€€€€`€€€€€M€D|V€€€€€ޞXn€Mk{E€€€€c}}Τ€ ukc€R€A~€Ey€y€€€€€€€€€k€p
+€€]"-€j€WdB€IVp €o€`#€+X€ufv5€M€€€€€€€€ =€X€€
+€€€€8€€Ҝ€€€Z€€€Ù#€€d€€VF_€€K€€€€[€G€€€€€s7l`€€€:+€v]€QRדĕ€€}€\€€€€€€1€€€€&€'F3€€€€€€€€€1€€€qs€`-a(€ṋ€)€€չ€€€@E€€E€€j€,€€P€€Ei€€a€7€J€€׈maQh4P€€و "€?€m$/€€0€W6A€€ €€>€€€(€A€€_€ €l֫€€€€t€€€̛€M€€$€€P1€€€K€fwf€x= 8$€"€€2N€sÏ ;<y0Z€%€4bAW€i€€€&€€yw€N€
+€€€€€€€˃€€ €zEAtl€€k6€€€j&€€€B€׺€d€'€€& A€t €I&Ï´]@{E€€S€€€&v€ܷ[w€|€>4Lq€Uz€8P€€€€€ p€€€-€`€ €€Ԝ€3^€€I\€€€€L'€Cf€€y@€€4a€€€J €€YL€€€€|€lY€€d¨֦f'S€0#ʺ"€€I€€ €d€d l€q€€€€€€€€€V€€€€p€€>€K2Å¥2€G€€sa€:€€R̶€7me€€€€nI€@b€€=@€# €$Y 0€€ -p€€w"G€€*C€€€ʂ€##€€€€€]€€@€€C[€€€€\L<#€€€ӯ€v€>€a€€€ €U~€€͗€o€aN~€€7Kݭ€€€8N€/€€[O€€€€€7l+=€€€€€€‘ܪ€8€5€€/€€€€Z€€€^^€€€$ 쎱W`€ €€€@€\€ €€€h€0€Ö’€€€€€J€€ ]€!€€€/€TQe€€ЂḒ€Ƕ€VAa€€€€W€€€€#B€€€€€E€€9€€€#7@€€w€€`€o€€€€€OU€€J€€!€€€€€Fj(€"€4zD€K€D€1N€€ଇJ€pv€b€'€@A €€7€w@€lL€€ ,€€O?€.L@€€€€€€w€€€€€€€p€vTu€€RB%€€€A€'€€€_j€€5`T€v€€€€€1€H€MB€€€i`I| FØ´#Ù’€€ڢ]€€v€€€
+€i!Þ Â€<€€€€rA<L€€^€€€€€z€€)€a@M82€.€>€€>sC€€€€ׄx€€)C€€:b€€S€%ê­ˆ*$\%^y€€€€j€S|Îl€4€€€Jmj
+J€XP€gZ€€U€€0€hn€$€€€€Lt8€€(@ٜ€0€€€€X€,€€€{€€€€€€Z€€Ay€}_ € €€^€j€€T€€TEo€N
+€x,€i%€€U€€€€riL-€j\€€8%€€€;`Qq!€0T€€€T€€J€XAP v*C€€ڢI€q€€6€c€€3)2€€€€.€€€€€b\R?[X€M€€€_€آ€ɚ€u€€€€€€€켠5 ^€SDã—€€*€€C€P€ܣ€€€€€€€ܫHF€€€e€r€r€˽p€W€̎€€C(e€€q(=€€€€€€€€V€%e€€€ Ýœ[c€ɇ€€LDY:H55€€7 0€€eT€€A€FK€Dq€7\€€€T€€€~"€€€€€l€€€i€x€ Ľ€€5R€B€<€o[€5]€@h€€€y€€o€'^ Ћ€€]€w€5'€€KB€€€~p'€€€€@rř€ݣx2€,€€€d{€€b€€H€r* €Fpl€€€€ oD€€€€g€€€+cL€€€9 €:€€^|€.€€€€€ ×¥x€m!]lÓ€: 1€~€HK€€€€N€€€,€D€€€ €N&.T€€€€_4€`€t:€€+g€^M€€B€È«#6}
+Cla}€_6€[%X€€ٱ€€UZ+€€C€€6]Ö©T€{€€€€}e7uׅ€|T€€€;r€o€(€mU€Q€€RE€4Ixwp€s?\֦€€€€€\€o;€€€€€N€€€€$;?€€ڦ€€€\€ €6€L€肽6€€"ܯ€€€€R€)Þ¬C€€):€@€!€&€tm€XH b€^€€€t€€\M'0€€ǜ€9"3€€b€€»C€€€@xQ4€Z€€€ €€€€€€€€€€ 8e€+€6€€€€8€€ €€€€€[h€€ ٿ€\€€€<€$€A€A€d@YF€€€DVJ€"€\€€$€11U€f€c€ e€x€€[€3vC|€€€Z€€]€€7€€P€f€C€ €€"Ňq€€VdgOx€€Π€€€Lr€nh+M€€€€1€€€Û€€€+€c€€€€G€€€€Ή 0€$€d€€€jxÞ³<^ €€6€€
+€&€[\`$O€€€P/€r(/Y%€ k€T€Kܳ€1T€I€v€€D$|~€ €z:q€g€€€R€€€<€S]€<€>€>€f€€€A€€€0€€t1€|€p{€w€€€€€€Ѵ€-XHv€€`€a€u€€s€€V€A€€€ly€>€€€b€(€9B_€€€(€€[€ €5€€€€,€€yz€0€€€€€€€`€j^€€?€'€€€€€lC,€€€F߀€€€,@ǖ€€9€€€n€"R€`€?M2q€sI€O€€c2€€€€u[ez%@€.€€€€m€€€€P€9K€€bO€€€€wP4O2€€€€YHN€#;iNF€€€€G€€€"h;f€D€ƹ€€m€B€€€€>€€Lj֘€€I€n€€€€]€Vb g6€€€€T€I€€#H€€€€€%€Ö€€h€n€€ǂ€ʆM€:€:€= €€O
+,€Fl7ol;8€€€€€€€"ɫ€ܞ€€|2|v.IOfgW€€€€€M€€€€er€H€&€€@€€€€€Nxdu€€€€:€D€€€ޅ€_€€$t€€,V\Ï°B>€&Ș€`€€€€€py€s1<€€€.Y€€€}uZLn5€€€€€A)€m€€€€€g€#f€€€(pL€W€.m€€€€ï¶N€€z€€€€€€€€€€€.w€€€-ZK&~Q€_p€€~€€#€ €€€N€K€l€J.T€€€€Zv€€€X€Sj€bs€G€i5€@d€€7€!€€I€€}N|و€€€/5?m€ €€€€_c€€€€5€7p€N€€E€ `aJ€n€€€lT €J}€'€yh6€S€1e€`s6€c€?€€!€F1€€k€@€
+€€€%f€ɤ€E9 €8̕€€vö€Z€j€€c€sj€€Ac/€€€€-9?€I€Q€€`SƸ€€€Y€ь€s€€€€Įk€Ɩ$€G€#sH€€p1€`€€%%/n€€
+€{€€€g€SD€d€>€€€K€˰€€€€€I7{€ܠꚚ<9€ u€€€€RE€a7€€j€€€&€fUUO]€B€€€€€{(€€mQ#€€:}q€ÜOLNE€%€€VÑœh?€1€~0€€ |€€€Tis1_€l€€کH5€zP€p €€€7!f€H€€d€^B€€t@€€€UH€M€€Ƹ*0€€€~h€€J€€S
+€t€€€xIQ€ €€[`nZgA€€R罘€a€Ey€Zǘ^o-€6€€€2€X€€€cr1€€-€€€b€€€BO€€€€۽/w€ €€|i€€^€ G3&€f;±K`€€B€€6€€P€N€Z
+€m€dh€€F€€€€€0`€2F€€ jy$ҫ€€ yr€\>[€X€€&z€€xx_€€M€)4CT"€€8q€€r1€nV*€€Yp€_*b€€€€c€€N€g€€ €.€La€a+b3c1€I-€D}€A€€%€€h€ È»s€€€Ñ“62Y€€!lc€€€€€P(`€€l€€€v€=Y €:T\V3€b6D€€€k€€€bF€K€€T€Fd;W]0|€Rt€€fY Ylf€kOA€€€ €Ҥ5€x€€"€€# 7€€€€€€€ϵ€€€€l€Z5c€€€€V€vD€I€€€r€ €*r€€€€U€wu %`€܈€€xP €xډ€
+!G€€c€€€€€€€R€€,>d€T€ 3F€€€€€صE€€0€Z\€0€tD€a)€€€€°€€€H€ÎO€€€€€€€ €€u€$€€€€]A€-;r€€€L€€€€c€>€€us€mV€iq€_0€€€€Fp6€Kz€€@€R€€€A€ €vt€€€€G€g€b€i€€€3€€€Gz€€#€*hcQ€€s€€&Kl€|€ €€€8€o uP!442€€a€}K€.€P€€€U€9€€€pV€€m€<€ €€|€€€8Yi€€€c€€€€Yy€7€€h€\€ €€€€ޱ€
+uiű€#x€€€W€E€€+A]€R€!€ €Ы6€€6€Mچ€@€€€€€(E€€ؓ€€{€2€z€€€/H€D€€A€€_dJ4€€€(€|€h€€`S€{'€{€H m
+^>€€€!"€€€.D€ €€€€€\LV€€'v€k€L€h €z€€€€€€j€ȯ€T#€bi€€€2€jm€l`*|€€U€€€€:|4€n
+U6€€€€€n€v€€p€€ʿ€ a3€€3€€ M€€€w€/;€/3Ì€€€€ƨ9€€0€€O€S€€`t53€€€€€JY€9/|€€€R€~'€'J:Ȫhb#€c€͸C€€€A
+dS€€v?€k€XY€€LQ€€f€D€}€€3Jq€F+s}€€3\€M~<X0€€ӷ@€€ €€ €€@€€ݙ€€;F€€K%SY€€DX€€€€O€€€€€€€€;VX`€€€Z€€€ €e€OvB€€|€€€€ .€v24€e[€€€€j€t€€q>Ó¨v\€€€{€€€€$A€;€e€€€py€$\€F&€G€e€€nn€jxy€I€€žj;€€€€9Y€ϫgP6'c€€~€€€€@O?€]/ ؚ€&RO€€€iܾR€c<rk7&€€€€€€*Õ€€€€j€€G€€€6€€€w€€g€€€Õ€X€€dt€ €€€€€ֺ€:È€€€)€Qv€dy€xn€€€€{臰FxB€n€(,t€€€]r€€m€€1.$€9U€€€€ã²Â€&€€€0€OM€<€€€ €j-*€u€€€€xAk€€€€c€w/€€€€3SĶnz€€i€PU€8<€b€뵫€o€T€€€l€€€€p€€€€€<[[€€€4€_N€€J€i*€€;T€m€€<€€?€€#€€\df€;€€Y €€Kc€€V €€€€€1I?D"€€?€€€€€€2€1(KP~€ €€m€w€8M€uk€5€/_€€€€€€Q€a.€€€M€';H€o€€d€.€€Z€ €>€G€€€][d€Ȟ€€€x*€Rk4 €2&€꺿ۡ€€€€$€€?€e€€€|1€€漈€€Y€€€€7€y€ҩ€v€Coج€€^ \€€V€e €€p€iD€€€€c€€€C€ԽEa[€J€0 €€€?.M€€Ô1w€tJ€€v€6€€€ε€€€€5€€oh#6LM.€~,Б|H솹Z€Y€€€€^€/.€r{€€a€€€p€€€€Sڭ€3€Ň€~€€b€€€bI€€6€U€€Ww*€€€`€€=€€T€€dS8€€€€€a||€€€€@Õ­gI€Q€ (€€[€WM}v0€€€€€d€O€e€ȵ€O€€€€€€€v€S€€€w|€ €7@€U0pÃ¥Fx€/€nvV€ڴ€€j€€T €€x€€G1Ù´`ʱ0z€€ŤLL€€€€C€€€& i€€€7€€€ €DpR€ߦY|€d€€ €?€€€€€B€€€€~€&€€€€€€€€€€e'€!;€€;€]@€€\€€€€€]€€€€€€€€€€0I4Y
+ $0€V^€\€€€`€€€€€€Ts€€67€y€bf`T€€€€(€€€Ov€€У€€I5€€€~>€€n€€v€€€€L€2€€jo€€€ €€€€€€€~˨€€€m€$€P{8u|/5?€=`%€€€Ɵ€€?l\n€€zH€)€j€€$@€€€€E&€€\D€€3€€Q
+€€€€`€(€/@€ƫ€ L€€3.€€HjG€u08€a€&0€9€€€" €,@€u3-€t€{€D€B€Qe)N8€x€€€€[€€€€€e€€-€L€(d€""S€u}/E1Ե€"F'€n€€2l€€of€;€|3€b€€€€€€؄€€€0MÆ…u€E€p€ €Ô°b€€>@j€l`i€€€€E€zr'€€#R*€2` ,Չ€2T€E€€€P€$v€x€D€€g€t:€`€€€Ǩa€K{€B€1.€u€€CK&AB€Jw€_€,€€€€€€3€R€€>€;P €IȬ€~E›€g€€€K~€z€€R€0 €ο€€Ait.€€€a0 €kZ €0q8\֠€p€u€H€5LmWoX‰€
+€P€€€€€Cia€€T €Ò“jf€ €ô%€p4kCI(B€€cs€€YS€v€͢€€€g$€€€5m€쓓Lvc̾=€,€;€€€€€€m|g1€E€€€>€ €€0€ӵ€€€Ø€€;€€€ ?€€y€€NmNg$b 扬q.€㉶U€ €Ԕ€€t"p€l€f€c€€€€€W(€Û€€€Z€€9€€€3-€I€€Y€€€~€€€€#P׶!.{€]`iD€X€€
+€r€Jd€kܧSÉ€t€€2€€\€€0vh€A0€17 €Ú~€€€€€[€V€€r€€€D€€a8*€€€h€€An€,ˉt€PG€€x
+8ç€[Q#(X€Π €Au€F:$V7€€O€€/€ȹ€pQQОm€€"€/€Kgbg€Ͳ5€€R!6€€€€€m€€"Ò±€S€"€Zyh€€€j€1€€۽€€€€€dxÅ€Y€ @€F€Ѕe €
+€[h€€{M€€T_v€€P€;C€y0€€€d€€€€v€Ök €€.WÉ—9€we
+€״€€€, €^Tzy€]€X€k€%€€B€\I&q€s3v€€ €€ri €€€T#Y€: .€K€q#$q€€€ʓ1V꾆€€€F3M€€.€~€|up€"€€€€€€1i€(mg€€k€€4€j €€}&€\€€€€€€J2€N€€³k€€9€@6ɱ_OnC€€€b*B€lË®&;_sL<* €"€D
+4€U€Cϻ€€c3€€7j€€
+€€€*\;4`ÞH€jY€€€sN€€6€ì¿Â€=it,€g€P€€€*b€y€-ž€€ke<€€pUfR)7€€\€xa€€-7€uj:€€+u|€}Q€҂€€€σ€€€x€Y€€f€@€ڠg€С€$€€?f€€€!€y€Wk€a€t€c԰€U€.m€€&€m€a&F€'se[€'€€€E|€Du€848€Z+€]hU]€€+Z€:€T (}q€)|5€I@€P€€€*JF€XE€hУ%€€D€€€F xD€€"€€S€~€|€€€€€€€gA€€(,€e€€€è€ǯ)@12€€€€.€Y؄€Xv€ M€L€€2ri€€€€€€^€H€,E+€3€ €€€€2<d€Z€݊ɔ€€€€ €0€€€!.r€i"€€€B€3; €r€E€&x€L3sm pRa€@$n€€€).€:€_0x€€dSLp€€T€€€.€F€֠€E€EË‹{Õ™G€S€f€€€€*.Q€€YT',€€€€€u€€M€€Χe€곽€€p€.€qp€€€
+€@x€EZ€r€€€ €-Bp€€;€߀€M
+€p€g€€€\€€0€B€J€€€gW|;€j€c€@€X€€€€€k€;€_€f-o€€€-@C€€mu<€?€ɕ€€HRWnSR|2G€€k€Żn€Ozم€"€€@_6v`_€#Z€€8^€d€€+€€€S€€lw€€€€€b€@9mX٠€€€C;€8 U/€^vng€€O€Z€tff̀G€VG2€€;€$€|W€D~€€€ti€m€?€€V€€€4€€€S€€p€€=cS€>€!Z€i€€€7P€x€,5€€c€`€s€€€9!€,×€+z~€€.€$t€€i €€€Oլ€u- "!€€w?€J4s>'[K€€€€2€:D^€.€€€€0€€€€w€€{_€€B*€€bлP€s€€€€€€&€€1k8O€€z€€vw€€€€€€C€&€V€'€c€y€€
+Ò€€€€€Y€Tn€QWZ.*i€g*t€€€\hl/€ w€€€e T9e€+@€€€T€€€\"€€€€€€€€4€€/{L:QM:V€€€€qi€Y€€€€€/€€6W€€~Q€€€€€'€€غQEj€_€€€€po€ۧj€$m€{€€€T)€€€€€€€€€S€|KM9€͜€€TU€1c65€7€€j€€>€iG€€z€€€€+XK€Q$
+€~*€€%€€€K7Å° €no€'€€€€€wh€FË<€€[€€I€Nip€v['€j€€€yÙ·Ó´S€|&:/€T€/€3€€k€x€}€B5`€€€m4€W€€D€€B€€f€+rK|€€T€^€0€€€€€€€€€G€€€ΕW$H€€€Ҹ€€MA€!fA€€l€SvM€€:€ǿRl€I9 m$€Λx~€€y8d/5€i€€ €w€€n€*c€€€2/<YG+€B
+€€€"R€€€&€€86b₞€€6€€€€€*Lx€€€€ €€€l€€€€€€Ë·s€€C3&ه€€;€€ k€Û¹߮€€€€ €ӶO€€€,€€u49€i9€%Ⱥ'Z€€ €E€€2€y,€"g€C€€€֮;€/€€€-kk€uБ€9c€MPh€Q:SO~h€€|V€€€€>€YG€Es€}€J"E€+€€€?€€€,h!€€T9€€€€\€€o€|ß“Xm€€€€€€S€o€ئ€3O#%5€€6P€€€i€€€€<,€€€ @€=€€€M€ w 1€€€X€c€z{k€€€€€€"€x€*€€g6€€ٮ€€€€€y:€€€H€t€€€Y€>€€*€€€`v€€€ €€€#=€Il-€c€€€€€5€$€:€€PzM€r€1€+UD €e€hw€€|n€€q€€fyKAAى€€%€^*€Dmꑞ€€C€κ€z€€8 €€€tPa€ut€€F€A€€>*€€E;€€€b{ €€.M€€H€€€€: €[!€€€Eu€МJKN€€€€€S€b9€€€\2H$€9 I€)€€€€FjQBh\€€€K>€\€€4€€€€€€ߠ€€%€€Ħ€P€€€_€ӃQ€6€€€€[€€€f€€€€€€a€¯€Y€€€€}€€€€€€~Ë´b€ě€€€€€€€€€E€€J€|]v€,k€>€€V€€?+€€€€€€hY€€€€€{€€ r€%g^V)€€€n€€I€€K€€€5€€€€€€€-€€n>€AÏ•€€O#<ZK"!̪Hm€o€O€€€€6€€€Q€"לw€€mr€€€€€ d€€&€m€€>q€9S
+"=_€€€?€X#V€ɹ€€€2€€€I5€€ֺ€€ 6€€o!Hjf€€F€€w€_€ŧ|,`€€€UE€€€€&€€€€€€9€€YU€€€€/U€€€€Z€€€€€6}*絴€7xJV€€vU€֧€R€*€€i{€K[5€r(€^€€€[€€€>h I€]€€O<0Y€kf€'5a€F€vY}€€€*E_€€€P€€q3pbX€^/€€€ c€€€+€Xrc€۵-€€:n,€_€€€:"€=E^€=€€c€€€}€1A€€~€€v\7€€€€€€€Bݬ>€V}z€€€}|€J~i֊i<€< €~Gjy3€1Y"€o!€p€?\j€_/6€€€€€€=€€Ly€lz€€2€€6&€˃€@€€LYzy2z€A€BA 6€ €uE€xg:€€€€D`€€i€<
+Z€c1€~€€€ȇ
+€€7€"s€hq€z€€bg€ €€v' "̃^€Ԍ€€4H€ &€pzp€€5€(€#QԨK€€€}€HqՂ €€o€\?뵬D€7€ €€w'€o€€€€€€€kV\e€N4€€)€€€€v€€z€a€€|€#€Y€Эm€zݗ€q9€BJogŀ€9%z€)A€L*€€€c[5}9 t€€Cev€€&€D€<€A€€d€3€ #O
+\€#8z€€€%€€GY/€€0R€€€ͩ€€ۗ4B3€€€si7€€€4€t{€8€€€4&€=M€;€yA€H€qA€J긕VKqu€€€€U24€€o8ib€€۬€€€%€
+€
+2t3€%€E{€€€S€`V€;K,€9€-€w€€€èœn€€Ò€۸d€€€{*€R>€I&\{€€l€€~€<jE€€€€€/
+~hԎ€€€Ɉ,ѶX;hÖµdJ€€€l€€s)_K€€€€€<€*€€€€g €€È–I€€8H€€€3j€n/އ€€€€G€a€H€F.,€€€€n€€܄8€܈8z€8€€w€€€€"€a€€€€2C$(€24+e€€xk€`€|1€€( €€€€j]€L6€€€€€l€€€€
+€z€€€€^€Ƹ€€XT€?€€i<P€€€€€S
+€€_€)€€€x€€h€O€€ !ga`€€l€]€€€Z€R€@cm€Gl€€ €€PekO€'€
+€€€€€€È€Ãa€€0€!€s€€ €€Ħ#€g€€€€€€6€,€€B5€€Pȧ C>P|€R 1 €€€Ԛ2€ko]yH~'?€B;€$_m,€€€€]€€G€@€-€S€€g€b=€€4€H+ €1J7€i€i€€€€oS€€4:h-7€b'€€€€€A#€_€€;VÇh€€ T€€i 4€€xɮ€l€H€€U€€Z€€,{€^€K+ }ю€€€K€q€€€€€€ €€݀€8 €€xj€Ei€зSV_,V€Je€w&€xj€€Ȁ€€n€€ 7€Jyr€Z&b€L<€€(€€€€J€€€-€̡Y€}
+Þ‰@€€€Us€€€ǎ.€€€€5n/€€€€7€€ .q€ËZ€iUE-O€v4a€€€€G€-€ߋc€퀋€€€N€i€:'#€1x€€€K€€€€€€€3^4€7n'€€€|5 t*nZ€€€€€€Mb€ ÖÓ¢h€Km#€€€€€*GF€€w€€>€€?Q €F€S€YCʦ€|€i6€H€9€/€€€t€̓ €€€€€Ui€€(€w€€€€-€€€g€UaT[€€^E醟€r€[HKY}s€R€!`8B\!%€#€€€&0€€T€€€&€Q€ €1€€F_€;V€$yzx2€€Eش€-a<"€V€ETa€€>\€€€pm€€\€<G€١€€€€N€€€€€l€lE€SI3€H2'€€€.€WG7€T€\€€Y€€€MOs€&-Oc$Ä¥{$€€.
+€]$!€4n w€€€lg€,A`€}€€€€€pV€€€8€€r€€€斖5€€€€@€€€z,BaTit|€€€€'Ϲ€€g€€€€€5D€Pk€€€7lI€€R€t€W<N€€€p €k€Sk€€L€DX:€€€€€€Hq€€3€€X^1'PkR@€€€
+A€€€ €€€(€=-€i[€€18€i=%€0€€B€€ €€!€[O€/€e€€€€0o€2€€€€€H€X€€$Y€~Yj€=v*€Ǯ€r€rPP€zP€€€€€€€5€€( ^€€C€€-j€€€€L€€€€]€€η\Ô¯[€€=E€ߴ€_.€€€Í€Rs?y€"€J1€€€]>.€€7Y0e€€€̺€€re㕡€€1f€A€N€d4€#€d€!€€C€U.U5€€€I€€€€€u€u€,#€t€€€€€T€J٧€+ €€€€2€lq-€@VF]€€l€€€E4r€5g €~€€s€b€€€€€
+Z.΀€€?€Fp'D€€|€h€{7¿€€ܠޫ€€€€d €€G€€e€H&8€Q€i€€9€V€
+€>€€E€+Ogk€ˎP€P€€Ә€€:€€€+€€mi7€€€€Q€€X$€
+Íš9U€€n€*-€`VA7Av€;Ü©x+€€€€A€€€+€€Uk€<XS 4Vj%€€L€>€bC€y€€#V€€3€sÒ½nd€B€~€€JÈ©4€€€z€€7€€€€7Óžn€€ܻY€H€€€s€q€€f>€K€Kf€€rA?€€€z|€.€f€€`€`=€>z2( €€€€€€7€€m€€Ѫ}t€€NO΃€^k2€[y€I€|€€€€€cc€G€E2€€€V_Vy'JA€8€€X€W1€€ݳ€}€O€€DT€€.9y€€V€€€'€.€7H€€͗€€Z€e€€€€!€€€€4 €€€y@€}€6Wm€€€$€1^U€'Ä».€=T€€€€€<B€€F@€'€[€€€_€jF€$€M€€/€€€*ik€€-l€€€€€€€'€€ɱte n€=€€y€ €€€ݎY7 €€€ŲR€€€Zq€\~I€}B€հ€r€Z€Aq&€g;Y€'€€€€˥,€€€+€€u5€€/&€QX€#€€I\gi€7\€€€$€€8€Ή8€'>€€€€€€€(g€€€cm€g€€k€ €m2€€€€€}€e[€)€Kzݣ€=p€9 U€Ioc€ȑd8€€€€€f€€€>€€2€E€€€€€€€€,€€{T€ }€&o€€€€u/€€%z€}#Kܺ*\€`h/€€ruGϨQ€€€@€ 0%€€VJ€E0€(€€€€€€8s€ laW9$C€ァ€€€.€€C€G€€g€ư€Β€€a=^€>s €=:€zHo^k€9€Q^'y)€€sk€w\ps€€€d€À€€⽎B€€€€&Q€D€/g€[€€€O8€€g€€€:€+ €€€H€w€€:€A€k€6 €`€€€_d2#q€P€goI€>6€€€^€€H'€€€ 4€[€N€€AÑM
+€€€€€ €€b€8€2ѧA€?€€Ǖ8
+m(€€t€7€E&KTl:Mebvo€€L€€ux€d€€n€€€€€€B€€€4[ޜ€€P€€'€;4@Å®cB€€€€G€07+€w'd€€€€€€€|€-[€€BnLZ€€€ €€€€g€\€,€i€`#Xڋ€b€<É·,*€€%€€]€€kj€€>€&€€€$€€s*c€R€€E€+€€_"€BzF€€pb€%S aʶ7é ¶r€€€.€€€A
+€:€€K€1:€€€X+€€:wò€€€h €#t€晋€f€}€€~€׬B€€wJ1€y
+€€€€€€€_€€€€=€.Ұ€Ӊ€KÖš~€€€C€Ay€yICQ€€-ت€€{`€€YT=.€€y€:€BdOÓ½V€I€l-P€<€€tk€~€€€€€h€€.Xu<HqJi€d€€€€`€w€A{€€ho?€€'€OË”c9€դ€b€>€€€ €€€€Éš)pȓ€€"E€P€€€€€_v€3aÅ”9/€D€Há’Œk€<€.1I€E€€λg€€tl_j>€$€ G€~{r€€€|"9€,€€W€€fA€.O€€€€o€×Ԫ)€|€.€ @a€€€G€€pt€;6;€aH€€€Q€ Í—,€€€p €c€C|L€`€€j4`€€€JY€Q€€€,3€!€kJJ€€€€ €€3n4)€ f'€H€Y€€€N$€€W €r€8hw-€€€€] zdж €€€ €H€t€rf€.€2ls€€€}dx€×´X€S€€!€/€Ӵ1€€€:q€;€4GXs€€N`€Ȣc€`€u€U€€iA:D€€€€I >7€j€[R€€€€mТW$€ܦFÔ€\ݳ@€6€€*€€$€=l€3€€ N€€$€€6d=y€h ц],€m€4:FL€€€K"?c 1U€€r€z^s`+€&€€€€€bDą€М€€€̒߀€fs€€€d€U€€=€€t$tu€!€€,€/+= 6€€€€€M€E €€ €€€(€;€€2€Į+S{€EЌ€€ L€d€€Ë€€€|Y€ €€9(€poZ€€Q!€K€€€Fg€€_€"W€€ €N[QV€€#€,€€€€Ke€€€€)=€€Qj€€€€€V€X€[€€€]'€€€€(€߫€i€€€€€€€€EU€Qt€3€€Yen€€€ii€ €€[H€€€P€€€€€lNݘ€$€Z€g̶ؘ€T€€w€C€€J€o €Y€€q€0€y(€m€SÜ•€^r€€€€&€€€€i€ €€€€€€€+€€ _€C2wK
+F€€PU€c€€RY€€d 1€€€€]€€€'€,€>€€(:6V€{E€€,v€X€€ €€€€I€€'HÂ€í©½Â€r€€5c€€Z€ɛ€Vy€?€T€€€,#1€,€7€4€€€ €,€€€€€€'€B€€€[€€€€(€€€6€C€€ݘrJ€HX€Iۢ€k€€€€|B€€,€yD€€v€€I6€\9Z€8L€ňS€O€3g€B€_€-E&€f€x€€p W<ÓcJ<€F`€€@€4€€/;é¬Â€#m+€X5€> €Xn€€€>x5-1€*€ €gD€€ETAǃ€€€s|€̻€€€˒€€€€€€€sw9€Q€€<T܋€[€-f€Y€€T@€{5l €€-:€uP€Q4h€x%€ڂ€€ V€€€€!€r€3€€X$ €0€!€G€.€I.€€€€€[€&€€€c6€€€ج€€Xi€J€_;s€€Smcޡ€ut"=H€^€=;[€O€€€€€¯)€cÈ0€€€€ Gd€€Q|3€€`p€ S€€€
+2.€€:)€2€€F)€L€0€06)€€8€€F€ €</€`k€S€qFwN€\N€€€€"€€€5€€0€7O€€\€€l€k€Y€€Ǭ€1S
+€U*€€€dO€v€€€€€€t€}€ܧ5€€€€€€<I€a€*
+€€SS€@€€€?K€€€>iH*0(€€€€€€€|€n€沉€€:~Z€m€€_€'€v€€€€'€1€€€€ (€€>I€€Q4cuWˇg>€ȟ€c€-€ €€€€_€€€€€\w[x€r€€X{u,U€€€€h"€x€;€&GJ€€€€aÊ­l€€|a€€€€G€€,r€€€a "€f0EÊ•i€)R€F`€j;w€B€5€~€€€_#€>|5€€J€Q"a€€opV
+€s ('€P€€€€€€€C€e "€^€Q€€€€€€}€€€€w€€€€€a€t€€€,€]€€R€€|u€€9л{*€dj€e€C€Mq€€€ €€}€€_OC€€€€L]€€r€y<€€€€€`?€€$€aY€a€Q€€n €ge€€€€€€~€ѿ€$€€€€€€€t€€€€ €-€€]€€= R3€Zg€F€€ԡ€a€€E5€ڷc€€€€€Ø’:€€*€€€EK€$ITH€€€€apv€n €€0Q€€€b€€^€;Ԣ€€€€J€y€&€€>€€)€€U`€€€Vq€>OÎœT€€€i€€ļ€€€kr€~€€€€€€ €€h€€:t-E€€€=€€
+€:z_€9€€€*B€sÍš1a€€€@U€Q81€.€€f[€€.€€€<ǘ€€t€€€€"V5€2Â€ÄšÂ€í¾¬&€R:€U€ޭt€}€ke€F'€ @€€€K*€ƃ€€€€€]*€C M)€€;k€6€Ḷ€€€c|€f €€d
+K€€ྚ€t€Ԛ€b)€{ͤ{Û•€€]9€ ߻€؅€]q€k*€|ïšÂ€Â€]€Xg~€Բ gq€€{O€€€:€۷€€€3%€Ǝ€U€€n€ u€€:€W€€< €€D2€€€€1€€€
+c€€€€(5€#+€A^r€€€nı€€=€ė€€miSGT€Vݾ]w€€D_6@Z€€ L€"€t€k€€€l1€S€'s€|€€f€€
+]€lc€€f
+*€€€H€€€*_]2€€€€i€\J€€6€n€€,{€ 2^€Fz€€}R€€€gj€C€€_€€5-€€€€€ie_€-I€ٕR@$M\
+€%L€€€
+g&M€€#€€€ €6€€b€€d€€%€r4M€€€€€€Hϗ€€Ho€€t €€€/€€=Ƭ€€`=€€€€€2?€€s€Ì€xp€€€OupL€xFf€€€1€€€€I€€€€€€€IJZ€€€€k€Ƒ€€€'€€~w€€b€e€€\€€ig€€€YxL€{€
+€€:€$I€m€€€~€)€U€€=F€€€-€€€€઼€€€E€€€5€j€€]€ޚ€i€€€KA€€^€€€€Y€r€ʖ€9-€j€€€7€v€€€=Kh`€O7!€iR€€€y€€٢€€€93j€€@€a€={€e€n=€}ռ€€€€-&e€€€]'7€f~€a]vlL€1€%€€"Tq0Dڋ€€i€€T6€€yx€H l€€R2e€ą€€€=;VN€€ <€_{€€\3€€€€€e€E€Ϝ€€€€€͎€€€]€v€€
+A v8€€€R0€D€T€_3-€Nl€€r€€€ڣd"€f€~#€]€Ðcq€S€.|Gt€)€€€7€€€og€j&UU€€T€€Y€€+€P€€€€€€€oQ€Ü€€€€€€€€{Ϫ€ €.BC€< €h!€$㸀€€}€i€€€€€uz€~€rd_€Jt'€€u€€€€€€`€€€
+€€€€AJ€€Nb€€ًLl/€€z핆 €P €€€L5{BBCz<€]€€€2€ Q@€ZRI€sM€€*€€€€€j0€!1€€Lv€%€€V€#3(3\€€€€€b€v€€T€}€€z€€€ݶ€mäS€€€€q€€€J€5€€PS€€)e€(€€5~npY€€€€€€€€Ľ-€/€X€ e€€€+$€€< €3€€bF€
+€d€q€€҄€€€€€O€€€5S€€̞\#€€€€n-e]c€€€€€€€€l€S]€jc€J€WR€]h€€#€Q€€€€f€{€Sz€€5̼Ԭq€€-]X:&zOL€€Vн2€^€8€€ iB€4€€?€€1k€< :€d€€ €€€€7_€€̦€€€€p€Na€€w €X€€iv€ī%€€a5A{;h€3`€%€€[€€A€v#lm|€€€€€5/€]q €€€(_€€€p€h€U€€G€€r€€%P€v€€<€4K€Ѳ€€ €€ieᛊ€!€€)€€2€€|5€)?JU€€€i€d€€€€H€€]rO€@€€€J*€u€€D]N€%€€p€O&€0€n}€€€€O8@€€€€€64€&<$€€G€ft€€M€€€G€*YË°Y€'2€€VsG€€=ne€€M€:He€€T€€€5€4€€K€E€€t €€€O4p~€€€9€€€€<€9;-€€€€'uy m€€€€s€j€*=€&€€€ŗC€+W€€=€€"€x8€€€]7€S€7€L
+e€qJpI€]8CtS9Y3€:.€C€€H`e€24b€€x%€0s6€€zH*€€7€M€€E=€ZW,€A€%s5€€m6q€}€g€€:€t€)€€€€€O$€)h€D€)€S€€€a.E2€€€y€€€€Q€d+€d€ۆ<€€€€€y€ € k 5y€€€€m€#€€€€瑌2€5€%€Jg 9€€€\€€€=€Id'€ݛ€€H€]oX6€FYqj^€€{j* SH€e4€€k€
+€4€€€€€€ €€6€Z€jh€(h€€"#C€€€Ë€e€€d€€n€€€€1,€€€f€€d€€Q€l_€-XV0' 7 Ç­8€€<M0j€€7€R,€~d€€€d7€TQ€€Ջ€<€d}J!?€i%Y€/ݻ€€€VQ€€r6J€9€€€€€Q€t€o€€զ€€_€€
+[
+€€€^`.€ii€m€€€BPM€€€ €€;€€€f€€€€nA€€€€bL"€€€€€_€<€1€€K€€.`€ €:€€€€" @W€6 €€E€`b~2€`€á±`€€€€€g€€€€€)€m€ϾFÒœ&€€€€sɀ€€˗€ €X€NIi€€}_Wn|€€€€y€ՌjM€€q€6€Gj R€€€JM€{6€€ܜ€ᠵ€,€)h€€€€Z€}"€€1Rj€€€gr €]€T€8€e€€€:k€ w€
+€F€d€€€\€ €€€€€:€c€€€€€€J€7S€€€a^x€€€,€R€yϣZ,€€a€0€ €€c€j€€€€€5€€€<K€"9(Z€€€H€#€€€€=O€8€=€x€€€€H€z€e€R€€€>X9ڎD€'€#Fo}!€€ transcheck.awkscNT€4E€€€TEXT€€&M€€&Mv€€N€kQ€j€6J€
+€€€€€(€Q€€€€€€!€€ am€€€P'_€6€€>€ €€€/]€€€ €€3B/€€
+€€C€€
+€€'€€€€€c€?C\;€€€€€?€€X$H€$€^€€€R€€€!_?L^€b€€€Z€T"€€A€€j€€D€0A € €€€€€€~~€€^_39€€f€6À€ģ€€UKK€Ƅ€ transcheck.listcB€D^FT€€TEXTMPS €m5#€m5#€UͻHQ€zF€P8€€~
+ ӑ€€f€€0"€€€g€ʽD,€€=€€ €€€€€^€€€€B€€€€€3€ɉC€€=D€€€x€€ weave.chck.listc€€E€L€€€TEXTMPS €€€€P€€€€Rm %€vbU€D€*I€€6€t€€€€€2€€F:€€L€ €KI€€€€z€€€ v€€o€c€€€T€@€;€€G€€TD)#€€)€€€ʙiD€0&€€b€€GR€€p€€# €4€€YQ*p+€3€ ,€R&Π,€:€€€"̲2€9€*€€K€€L*Mn€€€vў€L€€€€€I€€I€&€O€L€€L€L€€mN€)€€€9Pm€V€€€Ϯ€@€۳qj€€#(=?€€€€k€€Q€ €€(€€€€€€ €LQjV?€hAhpf€ NW€x€ `€dez€€'€<_€€ʲ3B€€€pr€#€€1rx€z€€ ;€€€€€A?b€€+€€@N€€€F€'.€M€pr€€O€J€€շ€€E€Ԍ`2Hٜ€€€€€9d
+€€€y.9|€B€LV$^€k€€1€`€€\€0€F
+€€d"D€€&€€€€NO^€駟€€€}.%d1€€CX€->€b€K2€!/5€€ ̊€€€d€€D €N€E€R€8(„€€G€K6€g€€€€€*S€v;օ€+€€€€€
+k€€Z€ ?z`€F€qg€€Ú€€B€€ €€€n€Ü"€€€€€Vjc€f&4€ȪȽ*€€H)9-€2=€Sɋ€ܛ€€€,xh€t€€€€€€絮€ɻf€€AÃ…G.m€€QD€,€€€€€ €€VHo-€€€€ €1€€€€€€ I€€€€B í€h€€A€€ 5oC&5V€u€iܚ€#r[€€4b€€€ڑ[:OրBO|nR€€€8€6 x€&%%[€€)€c"€5€<Cm,Q€9€M0€€I€:RQN€€€€+88€)iH€€K€y2€Y8&€P€"<€d]€€€ \€%ʚ€€XJ€€U€€€€€€€fP1€€
+€; €ﬤlO€€J€Ӡm€€€K€z€€€Q€€€€Ö€XJ€€€€€€€€€€€T€wm€ €€€€0€€€€{€€€;€V€€€N€Y€aj՞€€€$€;€:€€Z€_€<€h€€N70r€׽€€o€€1ß²Ù¹c€€€€€ź€€
+:€€€€Xu€€€€u€e€#q€n€m€U€€z€KM€€€R€€€4€T€7T€€€/&jAu)}c€€€€sN€˲€s€o3€€€|€Q €€€;€0€ٜ+€d€Av €Ў€€7j€€€€€€€g€€cIN€o@O€€G€€€€RS|awz42@,€"!€€k€€z€ €€R€€t€€6ٷ€€€€€€€€ €€m€€€€ <€€2€`€.€=@€€€2"€€T€€€tt€Z€8€€€€M€QM€V€€€^€ݺ€€€{"€€€€€w_€[]5_€€ €o€$€€€€€€u3€€s€€z€Y€€ԙ€€€€€w€€€c(j€ zg€€϶V€JT+ z€€Q€€€€ #€€€R€€€€6€Gu€€€€€
+€~€€?w€׎`V€€c€v€€€€۫&€€y€U€{€P€,#D<7x€?€€€|€€€O7€€€€€ΊȆ'€€€€M)p€€€€"Ǯ€4€?]€€9€€€€€€€€€€BJ>c€X€€7€€€>€€:5V€'1€€Ēe€q€Z€[{kx€€€.€;€#€]z€
+weave.rsrc.listc~€FTN€€€€€€€rsrcRSED€N€€€N€Z€€!€`#D"*z€ȉJ€€ȱ€/Sx€€dÉ„-€€€YW֗€€s€€€x€€(€R?€€€#'È€€rx@€€€x€Bw€€F€€€J€€€C€€€€€rT~€#€€€S€k€ͺ€_€€5at€€6r€€€+W€r€€€~K€+€BmP€YuU€dj!);;€€T€2*€€€3k€€4r€vG€€€ˬ€h€lV€g k€€€€€q€x1€W€XU5€€€€€€€€̎€€€V€Q;€€€€ʃ€€w€€€€€/€€€)3>€g€€€}L€€€€c€€€€/€?€ɳ€€c€€€€€€Û¿)€c|€€€X&€€€ocS€€€€XJ€?€€c€s€e]€€€€€a€€'7€:€%€KQoC]€z;€r€;P€€`€€&€>€x€€€ €€€P€€bY€€4€€€q€€€€f€y{€€€€€€€)]`a€€€S€€€1 €t€€͂€€t€€m€€vZX34€€.€€M€€;€zh€€ weave.webc.listc0L€€€€€TEXTMPS €m5(€m5*€€%€€}D€€€€vbUD€p$€*I€J%&€qV#€€€H€0€€;€€A€7€€€€BI=C€@;€€7€€€€2€Ut€&N€€8€p:€T€ €J€€€q&צ€TΔGͤb€2€b€€AE$€€g€e€€€:€€€sQ€€€5P€8Í™
+KleN€€€
+€q€€€€5€OuQ€€猤€€cO€Fz€€€lG?€€A€€€e€€€€€t&€X€ $w€€€B €€ 9b€€f€€S€€€{€YN)y<A€€€€€€^ߧ€€€€f€€€€'€k€ €SN€gk€€€3€€€€€ A?Z€€€k€w€€€:€€d9€€%€<€A€€€J€A€碴€€^€€€€€€[€
+€€Kp€.'€€cgf)€€€_n€p€€~€ €}נ€-o€p€€€z€€u; €€QBU'N€€$€€€€A€€_>€Ru/€€$€€z€s}€R/z€9>,€ҹ€€`€€€< B€й€€€€ժ€uO€€Le€€€2K€\€*€€K€€!?H2€€u€E€€-€k€€a€€€/€€€€?€€R1€*€3€f:(€€ҡ^€€o8PI_€aOg€껧€%f€i€€fɲ€|€nl€€€€0z&€@€€9m€=€dM=]S€€e1XS€€K€YRh€q€[€€6€€^C€€€€0/€€[€€/€€€€€#€€€{€€€€W€Ï€o)}€bG€{*€Q€{T€-€€}€€€'€€d_€€(€€V€Z€(Ô©.r€ǾΨ€€>€.ya€€€:€ݡ8€7Ds€€€iL€wN€G€9€€~ €4€€€€SF€ۺ€ €€€€m€=ڼ€€€€€€€4€€€€~€s€€€€€N€l€€€KÇ‹t€ €<ZZPC€ Ë¡
+€4€€6€€z€€€€?€€J~€€7€\€€|€€a€€€€]{Q/)r|xy€€€T€€€h €€1€€%)€ᕷv€?k€l€€ԇX€m€€Bg€€<I€y€€p~€{;€€€€€€#%t ?:€€S€€€€k€Mc€6€€€Z€€€ot:m€€€€Ȳ€|V€R€;u/Q€€€€€€{Q€;€€A؈Ò€€E€-€&&€€€aI€€€€Վe=€H_՗€€??5k€€€be€€€€€vuvÕ¦.€I€€T€€z€€€4€€zyqE€{\€€€R€€?€5€o€€€€€€EXq€O€>€-~OSU€€GU€€€z€€^m€€VF€?2}€..€€€€€`'€3€€~€q f€€€€€€€€€€~hS€€€€9M€]€za€€JÜ»k€€Y\dX€MB!k€Ǜ€€€~€|€€€,€T€€€€€€€€祤,h€€€€€€€a;f€ €€€€\B€>€€?€€}^€€€€€u1€€iP{3K€|5€}€|€n€€ €Ew~€€€"K€)€v€€€K\`€N3B€5€€5a€€Ë„v€€U\€G€€2€M@%€€€d€€€m€<,€€Mi[pQ€D€i€R€O€€€€€€€€€€€€€5On)€ €€€41€Y€€3€S€u€<#€t79W€(ß°|Þ½WrB€€€>€ @€FP€<;v€€€}€€€<3Lj€€€€€ƛ7€€7€XL€€€€€€€O€€}€td€€X€j€€€€€c€€€€€.F€€Ô…s€g€!€€€Q.9tܗ€€€€€€n€Fv€~€M>t€Ւ€€€€€€V
+€€a€€D€€j€€€€€݇~TR€€€€ŮL€€V_,€ܥ€o€€€€W€j€ €€€€€0q€!€€{€€IÖ³=€4€Hb€€€€nt)€€€€€€ €€€€~<O€Ұ€98O~n€]€ €€€€qpf€€€€Ƨ€€}_*€€fا€€€€€€€c€€*€€€€€B@€`x=€€€q/€€>€€€€Li?€m €€DQrN€ €Yܢ€€€€€€q0€@}€€€€$4P€€ zc€*H€€€€€€€€€Ø”31€o€m€€<€^€XW_€€€k€ €AI?€`€v€€bn+€€7O€B€€Í€p€€ €€€€4€€€zK€D€|€m€€<(1I 7€€@€€zgs}Ü¡+€Nj€€€p9TN€c€€>€ֳ€€€€€{€€?i€€€€uP '€€6€n€}[€€t€€€€ $€€€€€Sm€;€€Ҩ$€*€€O€S€€€€€€€gR€3€i€€Y€L,Nm€€x,ߕ€€€€€€mQ 熙غz€€€G€€=lƇ€€8x<'j€€E@
+€€ €€Rw€€€€€€€€€zN7`.€€׷€6&€$g€€ٿv€€€€€€ @€ 1€€€==)€U€€€€€AF`€€[€_€€0€=€€L=b€[€؟€}€l€€ÕsÒ¶€€~€€:€+䅾€€k,€€€B€€RÞ‘-NJ€q€n €€€€€€ЦL€€€€7*+ S€)b&€8€€€g€€€x€€ €€€€€€€ f€٧€#€9€€€^€2€@€ €6€H€ᆺ€€{'€€€?€€D€m€t8$>€޵m€€€g!€7€€€€
+€M€€€Rˉ€6€€N!€€j€€):·€uI€,\ €q€€€H€b€€€up€€ in)€D]€€:2~€ě€€#€€€€€-&€€C€ €
+C€€€\€€€”)Y€y€€€w=$ .€$€€€€€PA€€a€€>€€x&€€z€{ 0€Q€€4 ݈&wvm€€qd€Q`€#>6€5C€€€€D€€€€€?€€D€€js€m€€ݸ<€€3 €밫A€€€DY€€€€€n€P6u€j€€t€|€€€€3Y&€I€€0pFU€€Ҍ€/J€@€€@€ir?>pE€ 9 €#D€Kh€Gϸ€€€€€x  Ij€€QÄ
+e€€y€to€!€€[Z€(:9R€ x€h€1P5}Qj€€€fД
+G€^€p޳R7€€"J€€Z€€䴅v€JMG}€€€€Wn€€Qblβ€€>€€€]€€Z€:€€VD(€)€€|€€
+€€`€
+^€dԈGh€€l€€ja€}f€1n€€€h"€~€Rxs€;}C€
+e=€|%V3|Eׇ€€F€€q€€€xG€€'€€N€€ؘW€€m€V €€€K€k#€>xx€€a€€sÏžH€€€€€€€€€€€€€€]€"Æ€€€Gޣ€}!)€€€:€$€4n€۹€/€@y`€$€[€~€,€]t~\0tB€€€:€̀€€ €s€Tu€€€@ 6€€€€0ÙŽ}€"
+€o8€A€€=|€€€@€€Ƞ€u€€{€€r'€€[O€€/ €K €-ɬ€€€"=dA€€€5܈€€}€€€€€€a€€€€€€U€ i{px€0€€e€€€=€ €/\;/ß¹lA€r€ [•€€€.5€z[€}(V€€$Ì€€~€!ᕀ€!(€t!€€€6j€€€y€€€€c€Wc#€€M`€Þ\€X€b€€I!1€€E€ʊC€`€€]i€€y:v€+€n€>o-.€O€鰼€€€Q€ €~€0€G€€r€H€€˽7€JD€}€€€W܇€!€;\€mS€€€€Y€RNO€D€s81w€€y€@€€E€<DųN2#€=€€ԇ€E€€€€t€€N€83€€€v€€€€€€S€8€M€B€€€)l€€€(@€4[€ a€€P€)€0€€@€€f€p€€€K ×·m6€U€=/^ٻ€x€l€ل€€€dtRR€€€HZ(€`€=,€€H .€hf?€(0€€G7H€j€€:€€€t9€啈d€€9>€€)aDV€/!€Dc€€C#€\€€כ€€s?]€€d€€€oæ»–Q€9ϡ€€G€€€€€z€€€v?€€-€€€o
+€iV€a€le
+€)€`R#€Xo:€Ö°]€€€ˢ€€€€€q €€4€€€Oė€H€V€N€€f5€fۖ2$ue€€€€e€_r"x^j€€I€€€xuRJ€(€a€€€E!€€-€€sq2€?/€w€y}ߧ€€͌* k€€y€p]€>|€j[€@€€€¸€€!0€AÊšg€€5 >€x€Ƥ€$€j€<€&€Ku€~vV€x€€€PR€U€€B×p#Ì€€:€FK€€€€RL e€<_€€€|ĵ,-€t€€Iz€€€Ë„qg€^͵Ha&€D€-D€€%€€ļ€€s(€H€€€€€€€^€€€,€-€$€5g€€f€5d€@V€€€H#DT€awA€;€€x€{€bƇ€]€3Þ‘#€,€\€€^í³¬H€€€€U€€€€D€€B@€<€€€ʊ€V€&!€Gt;€€€%9ky€€€p@€"€hg€`Z*€€€VÖ–>€m€Ep€q€€h€i€H€l€b8.€€k€€€€u€€€>€|€6€€€I€€€R€b$ €€€€€;€€€€€r€{€€€2€\R€€€׋b|€€€€€€€-€€ӈ e€€€k€%w€€ R€€€€N<€€1W<H€u€k €a€DrU€8_@€=€€€&€L€}€+€€€̚:,S€€X€€€€ Z€€|_5€'€F%c€€{ €â… v.uv€u€x€y$€L€€€ €€€:_€ÆF€€C€MoZ€o€€€€2 6F)jK€€€#€,.Q\<Xf*gy€€€jg€S€€€5€/€7hÉ£vH€(€1€| €€ÐX€FW<Ö o€p€€p€`׆€€€€€Y€€l€B*€s!€€n€€€/€€n,Ö±`€€€€+B$€w€€€p 4€€€€€€y€€N€€nꄶ €t€€>€W€€€€€€€薛€)W€€O€_€€€€>€€Z€€ĸ€TJ/€{€€€€€€w 3€*€w €€€J@˳€€€X€€€'޴€€$u(€È“?,€:.€K€€K\x =€[€ukb€€p67€€n€€
+_×­K*€ox€=€}R€#e€W€€€€FH€€€K€€U€؅€€\€_y€`€€€;€l€IC€ €v€€>liHo€€€+€P3gnDK'
+€b€B$€€€€.x D€
+D€€F䥯X€€€j3€(€€€€!%C€€fj€I€€€(?*€o€€€€Ԙ€K€€ǂ€€D€T€am€€eE€O8€€/;€2cv€€FP-Y€€'*IXՑ€hހ:
+y€€Ê٦|H€R€j€€p€€BÒ€€aN4w>C€Si\}^Z柕€^€sn2€€€b(iT€O8€d€€g€$ޞƼ7E€–tM€EUiJ)€"(€$h€€€€(mz€C€€?€@|€i€€€a€Y€€Tv{$u€^€ EY€[PÖ¡o€€#€1_€M€6€i€€€#O€€X€6f}ϧ€€€€€€€€3€g`€€€m€€€€€€€€ €€e€w€gz€€€nd1€6֩€' €€~Ê¥^ %[Q;€€€€l1€j€€€hTW€€€€€€竲ѯ€€€€€0y€€LÇ€pk€D'HYR|€y4Q€€ *€l€€€€ܗc€€b 1Q€m€&€€>+Q€€cP
+WR€[€€ɹ€B€9€€€j"
+V$€€S€ɱ2€Z€d€€{E%€Qa€H€€=€€[9n(P€€€€€€酃=€F€€\€€€
+€w€-{€Y,@vZ]€Ï€€€€€€k'€€€%€E€S˵€€
+OÊ€t€A€50€c鎔qdC;@€€Y€O*K€j€€.Ùª-€x€€ܹ€c€$€G€
+B€€yڀ€€nS)€€$€€K€€/€=€€?I€€€€€/'Y€Ԃ€wÊ€w€Å3 €€J€~€e7P€2*mk(€}€k€k?€Q€€G2J€€€~t:€€zwH €€€e€€€A€€€fA€€€S>€%€T[`€€ €g€€O€O€)€tf€€Gn€9€€ZÜ€]tYP€أ.€P€€dX€m€€7_-)*o€€=€€€4@Å‹! €€m=kv€-€€€€€€€|DK€4$€€ €€€,€€€€€€s€€€H{ €"€q€A€€€€€DP2$€€O€}€,€€€]jjK|j€€€€N€€q €€Z€S€Q€+9€€F€t€€1,#6€€€;€)6€#€€€€٪d#€€€#PP@oBh€-€€€z€+€+.€vBA€Ͳ€p€({lh^€l€
+€€V€€€€kw€€€€Ÿ€€f€0 €€{€É€G€S?€€€€ONCXw€|ۺ€颯8F€fbH€q€u`€€€K€oK€€€2€€Ûr{MR€/€Y^^J€j€3€€€€€#H8v€,€€€€s€€€f€tb5€€€€i€€€€×z€(!l!\h€€€€i€€b€€jA€€(+€€€a€ €€€"€ר€ k€€€p€€€€€&€3`€9S€€N€€X'€B€€€>V€a€i1tj€€€€j€OÌ…€D€>+€€€€€~€.
+€xKP€€€־ .S€€[W€€M€촦yqRw€" |€;€€~%€€ €€)[€€V€€€"Þ€€ť計€€€€€Y€Eß«gz
+€€ã¢D#.€€€DåºÂ€Â€Â€€€o€L€a€€bjH€€@€[H€Xu9w€€€Di€\7}€€€\c€Pl%€€/€Z€5€€€€^€ri€€€€{€\?€u€Vu€bE€€€5xx}Z€€* €€€€o€L\€׶xo€€€Y€~`€_€p€€€|€€€€€sŽ€Q€n-€€€Teu€€€]VP€y€€€5€€1 J€2€{V€۳€€k€€geW€€€€Sx€L€u€€€€Um€&€_€€€€€€\€€€$€€€€}€×€€i€{€€c€€€€]€€€€€€Y€@€€€_€u1;€€€6€U€€€t€€€€€jV€G//€€NURE€€.€b?o€€)€€€€=€€b=€gȲ€0d€€y€€€€€€€€€€T7€D€€#2€K}€€€F€€d€€XLZL^XB%
+y€€%#^9l€XҘX€x€€y(€€`€€€&€
+€L€€€€ Z€€(€`Y€€€n€€€€€>€€d€€<€Ã€€€j€€ €€€;€€_Y€Ӻh€m€U<€'€<€&€€€€<]€€€ €W€€€_y€O€€€w€?€'_€€€f€€Mj€_€€ã€€_€€€A]€€€T€_€€[xFxVk^€k.€S€e€€€+D€Я~€W8€b/€ٜ€(€/Ùš €€€€ӊo€€<€€€sH+€€€€]n€€R€<€€€€j€€xÚ R)y€F$\€^o€€؈€€x€€€o^€WS €{k€Û€€€€M€€€€€€+€€€
+€Ç€no€€€!X€*€€9€vD&€/i€N€€€€€ZQ€A€€€€€€€c).:L= €?36€€?€۳J4€LJ2E€€€€€€€pí·¢>ڊ€_۫€H€€€v'€€€€ €4ף€!-€€ٖmHС2j?€€`×€€{;Æ€)E€€X# e €€h @€C€€€{[j €€€€€6 É€€s€€€€B€€"€,€€"r€€€^€֦€€)-€€0L !€|1€(€g€€€€I€€L`{€€€} €p3€€cؠ€5€F[€|€0P€€M€
+4€қ€€+:€€3d1€€€€€I&{€€u€Tm[€€€G7€bK€N€€n€}Ŏ€vk€ތe€J€€ €€€r€*+ (7€&AG}n€5Ä’Z^€*€€K€€€Ќ€Cg€˳€€<€"€)xx€w7€€€€€€€€€€€€€€@€€'>l€€€1R€€!I€Û`€€OBUz€98€€=€{€'P€€o€
+h€eu€¦K€€€€0aP€€€]v/)Sh€€€K€Yk-r€€u€€&€€ʶu€g€bq€€1X€€?€€€€€€€(s€€/€€eb€R€)€€€шJq7|R€s1€ f€
+Ö*y€€A;5€€Оu€€€€€€QV€/€€o€Hl>E2&€r€0h€B7€O€QE€€ICF€€€€/€^€€€€V%€X8€€€€E€€DGUٜ€€\\j€€3€o €L€€e€v
+€D€€€;j€~€€6€€€q€€oaC€$€fF€W*€€,4X ]€€€J€>€և€€F €€nVm€NH[Tv€€€Ucv!€
+€ €€m€l€ViX€)€'€€€€€i€K€0€€€€€€Y €€8#s\€P€$€€€€€LX
+_d€r€€€€€€€€€Gۘ€€l0X€J€>€ 5€">Sk€€€€CJ€'Ɣ€€P€€€€€€.€€G€€JJ.€€€N€6€€€pٗ€W€˜€€€&€H~€€€ra€€€€€€{€a€-€€G€v€€€€€|€,h€€€€0;€hl€€(€Z?€€€V€€€I€€€3€€FW€€+€ €U€€€€mÈ‹hۋЗ€s€€€€Ѵ€€W€€y€vy<€i€€€ME€€}€€€5€€ €f€i€2€Lr;€Khˊ€€€€€o€zc€q!g€€€€€/;^€1u]1€qc€€€W&€%€€€'€ 2[€͟€€€!€;OUvy&€€€U<€:€€€1€%€G€€~h€€€€€&;€€)€€4l/€L€T€€#^€€€?€€y!pt=(0 €r'}'€ë“€嬜€Mk #$€{FY[=S€O€eA@~€€ ed€=v€€€ ?\["?+€€mZ_t€
+€€>€ؕ€i"€€P€xG€f€€€€€`€€fw€Q4€€7€(€€€€€@€€€i€€ €€€€€O€;€€i&€9`
+<ãœ8_€l;€€1&]}€m€€€€€€M€€dX€€V€✛€Mb€€€%O€2.€ [O€€Ė€fg€ߌ4€€€׵€@€€€€€L'€:'q€€€`€€€ljC€€L€€Ž7^܄€€ݲ€oÖ¦k€)€€€€ €BYa(;KK€€€X}€~T€9T9€€d€6€€€€€DH€mzÌ‚x€€/€€€.€€€=b€€ €€€B{€€€,&̳€ €€̰€6H€€€m€,@Fa€bH€€4€€€'€x€€Bd€|€€ €€€ €€€€+€F8€m*nضl€0€%;€TWA€€n€€R0^€€€G€€P!€€€J_€€€€y€€€€J€€HF€˫€zI€6€34b€€a€€4€Q8qZ€€€I€€KK€W€€€]€.€€K€€q€€€€~€€€€€%ϱ€€€€€E€€€€V€Ë€€€€J|€x X€€:€€C€€gΔC€#€Q€€7€M,=8M§€L€F
+€€k€e€€3g€€P€MW€з f€m€' bV€€€C€%€€a΂b@€qL$€M€vN<€"€€ <€€R€v€€k€Gu^€€€B€€€W/€€€=€€€€€gÏHd€€€€€b€QK€€€ €€€M€3W€€€Sj€€!€;€€4-n€z€6€u<€)€'z€€€€€€V€€€=€o[€=€€i€€€€€|€xÍ”V
+€5X€H:G€Yv€€zZP€&c [€€€m y€U€Ò°'€=QÄ—=€]{€5d]Wxީ€€€|€isN€ €
+7b€€€B €€€T€& €€(1e€d€v~1€€€€€5€€{€€€E€€€z€€€€€€l€€€G€ ~T€"ka€a€@Xn€@F€B1€:3€€€€€€€l0€q€-"N€€r<€€€=€€€Dde€S&€€€h€b€€ >D€ń€€€²:q€€UB&Q€€L:€7`:Z.€€€€€d€€€€€I€DŽ€"€Dow@€€6€ot{€>]jg€&c0€€€e€€=€€€€;m€9€€0vG€
+€6.RԦU€€#€ v€V €€g+s€h€%€€€€/€€j}>€€.o€€[E@€m€€€€(€€€tz€'€`€
+[ 7i€€€€]€€€€€K|€€€€€ɾ€u`€[€3€€ٹIY€€€j€€i€€€€w;€dx€f€€_WWg€9€€T=k€ۄ€€€rj€N€YY €b[CI€€€!r€3€€]K€q€OПo€9€댹 €€€€€€€€€=u(€vÈ€'€€*N€€/€?€T€€€n2€h{€9€€,[€€%p*z9s m_ÔRID0h€€€€€€€
+€ܽ€W*€g3€€htvw€€€\\€M€6~.€>€y€u[€s` €€€D€€3;€c1€€€׶€=o€:€©K
+Y/@>€u€€€j%€€t€ M€€s€^\€]€>€d 7€}NdkE4pFxV€\EtIwQhT=€€€<€€B€€€j'~C€Cr,@€w€i€€€€€nt€خ€tPŹ€€€?F€€€T€€€€€R€€Y€€B€€ €/}H€
+€׃U€*Cծ€/U€H€€€A€€€€*U€T€€€€KU`€I t€6€€€;+U€€€€€€_\JA€AIVDd€, €M€\€ܷ€٨€4€€€€%Fd€V€l€J€FT€Yۚͩ€֕X.€€€€J€E*€&r€U€€€€\€I€qr&);€€)\€€ܘ#€€€M€=€€€i€€€g€€€€y€€%m€N€1J?v€€֑€$€€€€€c€t€€€€€€€€왕6€€)H€€€€€~B)€€ЦμC€B€Ví£«€€€€€j€€XeeC0l€:€w€ €€€`€€€F €d€€j€H€c€en70€Ϩ€ €€€€N8€OË– €€€m f€€€€ɡ€m€€ €
+€#6€H€<€€WA8€8€€€`€€V€iH€€8V€€€A€ €cM-€€€$€ €VÄ€€ €h€Z€€Ӵ sR<;€O€€€1€€€Y€`Ø›1}€€[$€€ڔ鸸€쬪vÙª]€€€€€€5€M€ €?+€€R'€O.€€€€€€A€€€€HT€2l8t(€€€€{€w?&€€€€垨P€@€€[]€q€;#v€c€ų|€3)1Pm€G€€€cmïȉj€&€d0% €{o׶S€TvÜ£8
+sX€€<€|.€Պ€€€€€€€V€m €%€€cX€€ҫ<€€Z6|€ҽڒ€9€P€€€€€€€*2 SØ„:l€€ €€€€v€p'+
+ I€€Z€€p€€[€֞_€€/€€H€6€€}€x6€۵€O%˶T€€€\€ӆ€1€€-Ж€€ZR€€€€}VP€€€€3€
+K€ B2€i€JC€€H€€€€"p€ €€vm€N13h)€ V€€Q/0 yf"€)>€=€€[€4€€Y€NÝ™I-:€PhK*€p€€L2€€a€g€€€ €€€€H€€;€ޡ€€.€€3€€xu€€€€ײw}b€€j€N;€SpΤ€€EO€uc€x€u6@
+At-EwX€€€t€$ۥ€ &>€€,€€€€ m€R1€n€ް84€€'€€€€€€"€db€
+€€ҸĴ€+€€z€L€ €€[€€[€€F€]+€€€[€k€FhE€€W€€.S€€ѨF€€.€P€@5cn€x1W€/7K`€€J€Y€€€€$€€YD"Sx€€€tI€€€€] €€J€€€€c€€h€hR€€<6 N€PA€î¯€€€{€€€->€€€_#€€r€€€Ä€€up€.€€Af€€2{€)€nd€€{€3>€{}€€€€€L€y€٬€€€A€€€€€Þ€€r€^€p p€€ ,€€_>|r€€ry€€r(€€N€⡕€€:€S* €x*n€€€x8ϯd€€€KD€€€€€3€€yJ€RW€€%€€"Q!€tc€€€€}q'€€yp€B</€€si€z€ €€U€H€5€z€w€€B€G)F€h€€€€€C€a* L€;ÖŽYL€)€€€-)€7€?€€_€d_€n.€€ڀ%€Ok€€l€@\€€jr€€€U€_€€#R€€Q€SԜՀ€€€€€€€|C€"€€/00,s€_€€Â¥X'€€€]€€7€]?T€€€€€€!t€€€€€U€€
+€)€€€/omZ֣€7€2€ €fJL€sd€€<€^€€€7ExJ€E€%U'G€€€€M€€€ζ€d€m€2€€[`€b×–€€oa1`:€d`€46€Kd€O€[€\r€€/A€€€M€€h€€€€€U€€P€~z€B€rl€€u€€>€€€€€B";R€9€Wk€€€€€b[€€€€e€€€€e€€+r€€r<€{€€C鹟n€€cm€€!€SA`€7€€I€C€/€ €€kx€Zt€^€€€€_€€€€׃=€s€L`€- u6` €ۣB+€e&€pH€€h6[G €WA^ G€ʭ€ބ)j€ €vr3U€B!P€D€€€>"J"€f€KEQPLb€€Y€0€ˢ€€Xь€
+Q€€[u€€€€t€€€nX\€W;€ONOqa€€V€€€€€€€h€3XI€€U€D€€€€€€€2€€€€€€€€_€€Iҳ€€€+€)€€€]€s€ ߀€(€€€€€€€€X3€€_Q€>€{ệ]€€€€€€֪D€€€€€€€€€x€R-€x€k?€€Ue€I8~m€€ €!€€QL9ǥ€֭€[p€€€€G~# €€€€€€t €o€€S€&7=€ƅ!wD€€)(€hsr€€€r€€uk€[€€€€E-€6I€€€a€%€€€YI€$€€€N€S€€€Ζ€pGP€唼€€a€€€2€€U€|€
+;%:€€€€€O@Io€€€/dG'€ €€et€ߪ€y6€KF€€€€7€''Ý€t€€Ȫ€q€€E€€)R€€i€!€€µxR€D€Ҧ€}9€4g€#Ç©*€€qEy€i`S Ve€€€€€€QHL=€€'€aOOR€€€#€P€€]i€€st.€€€€@€€l3x€€C{€h€bV€€€`€Y€]&€€aah5{€AGz€€RAð€€+€K{€€Γ €M€ N€_€)€=€j€h€B€€?€€V?€€€€a€th9€H€€Ci€V€ld€7€@*€€o۽€OpJ*€)€w€€€€;€€€€g€n€€€KJT?uQ%)€ (}€€g€k€€€€Iw&€0%€B€€a€E€€O€s€mw:€:€€"€€+€،€Û²edb3İ€€u€€€R€y€€€€z€Q@€`€€€t8€€j€€€y€€ Y€€€n€;€'€€€û€€g€€F€€ePB/f€€i@:€€y$€Ω€€>@€€ɠ€€.U€€€€x€b€€U€€€€€|€TDd_€€€OiI€0€€€€€€ sM€;…€€(5€C€€V€€#€0€Q€€/i€€/€o€a€€€€*€'€€g;6€€6?uN2€,€€q€€>8 €€" €€_^€ €`Ǔ€€x€c€۾€Z3€-J€ €*€Bm€c€€Rp€€n€7€ w€€ HwX"€FFF€e€<€€F€€€h€T€p€8€S€w€€€€ٮg€l7€€€s€3€U€^€€€€€/R€ٹO€€#€€€J!€t€€.>˹р
+w,€€h€-€LQ€<Z1€€< Uf€U€ €€G]n€qz€.]5_}DK€€~4€€€x€'€|€uß±6€€]€_jg [€8G€€€€€6€o()€€€/*,_ €T€€Yu_€€ʃr€c€€€€A3|Rp^H)€&€€n€BFހ€€€M€€j€€*€>€€X€€€€Ϯ€t€€"K€DqYG€eÇ©_€€€€D€€(€€€V'ߘ͙€l€€O€e€9"3€€€~€€€€€ €裰€0€€€*€€h€€L€€€V€Fq€vÏ‘f€"€€MטZ€~€€€E€€v€%€€=(3B?2€€€€€€€ #"|€€€+€€х€=€'Ac€€rf€v€âœ[2N€.|R;€€۞4?Ôy S€榎€€-}€!&€€x€€ے㇪€€€€S€€ €€ʙ€€&0L€h€)€G€VO"a|=?€€€7€€ϵP€:~y|€49€X€
+\€0€@hm^€€€$€A€3m€€€€w€3€€€€€€ _(€€"€€€,bV€€OΧ€O=[y€€€€€Q€€€€€€€€ €W/€~K€€/vP€D:#€'-€€€€€NDQ€€€)€gt€€Ĵ-%tn_€€p€rvCu€·"?61€y8)z€T€K€Ë€€ڶ)€$,€€\-€ €€M€kbc€€^@€\3Û€€=€€/m€ߟ8€€> ËG€€€€"o€m'?€u€,QRl#€bD€d€€^€€€}€9+U€Z€lVD*S)€jN€€|€c€q€$E€-[€€욞€'€€€P=€€^z€@"q s€€æ_‰Ö€3~k€5€(€€€€€€ Y€€I-z€m-€ə€{€q0€€c~8BXl€€€€9€€o,€€ €a€€_5€
+5^€€T%€€'ԗj€rk€L€€f{x€X€€-€€€€]n'€€w€ 27bK€€€%€€1ë$€€€€s€€€€€N6€ٔR€€€€€)€€A€ €R€€4€€3€€Ѷ
+€€€m€J€€€ơ€~€Z︴p€€-z ) K€€€€n#ٛ€1E€€N€€€€t€6€nD€p€uą"~L€ €s4€€€y€"
+€[€€G€'€€o€€[z€€€€€€€€€l7€;€€\@€h}<€'n€€€$/€ €]€€+€€m€\€€€Uf€€L€|€€€€#€e€€S€K€a€-€S€\€T>l0€€€€W€€€€;D€d €a€€E€€F€L€b€'€€€UZ&uXfV€€4la%€%%:€ €€€€€€€:#'€P€€]€ €€€€+Vr
+ͳ€€
+ T€@+€(($€$Ոr|T@'€U€I€_€€,M€2€27€€€b€€€Rk€€€B€A€€n€€€€€?€X3€v€€4n€1€FD€A€L€€r€€€q€€€€V|€8€€~ V€3€@€€|€€€TB€`>€€
+8€€2JÞ“܀€€r€4€C€€€2Cv€€+R€G€=€-€/ZPhX€`4h$M€€€i! €€€Q4€€R;€€€#Ì€€€|f%€V{€#<á‘©/*€G€€v€€€U€J€€Ħ€0€Y€€€€"€>€€Äf<g€€€€€Al€\€1?€i€€€ DT€€€ѡ€she€1(€2€/€€€€i!€€€€a€€6€=̖€€
+ €€€8€ €€€ €,Q(}bh€m€€€€€Duc€JV€€c<€^d€€6€€€q€€€€ €թKRN_€€h -[0p€J€€€€0€E`^)€€€ €ӆ)X! €€Er^€e B€€€€€€r€€V€€@
+t|€;[€€S €/A€€ €A€i€C€€a2€€8X€@ €€€EV€€ [€U€€ʤD€€€€D€& €71€€M-€€€IJÕŽ€g€آI€q€=€H€€Ҏ €zN€€p€€c€€€€€ܩo€€d5:\€ €€3ǀqA€Ebu€€€>k"6"Z€€>wq&H€ Q€€€€f~€GA€d€€€€€u€ʟR€w d €€%€€N€€€€€#/€g"€3€!€iՅ€ke €O"€He'€€1€€€€'@€€€€f$€RÉœmU€[€€S€K€M€{q€€€d€=€{€5"€OG]€€߃Cc€€)B€m]€€€D€d€€€C¿€_Q3phs5€j€0a€XC€R€€Q€€€n€s+€9€2€€CdklJ€€?€G€<€€€ €oÍ“Qێ€@€€Ü€€€€,j€R€€2€€ .C€€€€€?€€€€q8 0€tS€ €€€^€e€€O€R'€Ǝ€€€]`€€.€€í‰G߃€3€€A€€+WB}e8d.&s€€L6€%€€2€€@€€€ZF€€€€g€ )0€€L |€€6€/€/€€€*€€tpC"€€€՟€Y€E€ €m€ €€€€€€Α€L$€€(€n€>ML€>h€d€€#€*$fI[<#€`a€2r€?€P}E/a€€3 €\2€-Ù€ }€€bI€̀h€€ŋ6€€€€€!€I6€€ !€€SIFde€m7N€s/€pפ€4€€
+d€7€€+€00a1€€K€€?f.EY}€€€€*€"~€,S€Þ¹, c`/K%} €€€k<L€€€€X^€€€€Ӭy€5Y€€7€€€€DP€)6€Y€ίTi€€€€€€Ե€€E€€€€€€iR€ RBE€2€€p€-€€€ €]€1FhT€€|8j]€?€WUK€€1GG€€Gk€H€€€V€}€€€e€8€€U€€a€7€Qg€$€sJ€€1
+€,߀(€3€€€hB€€€+€€*€€5Gh€ €c€;€€}"*f€9€€ €€€€€ "О<€W€€€c€6€p€^NgT,"lY€€U€€€€€€€€€L€€N€€*.€yN*€€€€ €Ğ&0Û€rÖ±MiN€€ :b;€$€d€€€1€kv €€€1Ua9€€€n€€R€^€Us€ [K)ឳ€Y€€€ T€L;€Lg€p€€N€ƌ
+€B AH
+€q€€€€€€Í€&T€€ۼz€%:€€€TFlj€€€ ̬g€€7€€€z€0C€C€`€~r€N€:€թK€v€F€~€€€€€\€€'r€€Z€€€Ggx -'€DPvsG€F€€€hf€cl€1£€a;€€rcl%€hM€€€3kTr€U€I€S€€€_€5k,€
+8WD€Ь€€€€ 64€g&h€€1€2€€€€ $€t€c3€€%€(€€EI,€A€€€ €€s€€
+€Bb€€VC\€€€€dq1€€ȉ4J€9×…0€€€ ,€€€MÈ©P"€٪%0€€€86€}€€gu:€O€€P€c|1&zq€|€D€€@€€€@.=B€€€ëºÂ€Â€M怀€€( €€ý€€+V8;~}D?>nRxɘ€€€€€€@3€Y€€€€€]€r,€€€k €{€€L%€€f~R€
+€h*3€€€€Ä€WXus€c€€g €€V€tHÞ‡€h€€€€ޑ€ŻH€!U€€€(7€€Ú€t€L)#€m€ۛC€€)2€~€Fs€J[n€ÇOݩ€?€€€€€p€}€Өz€6W€BE€Uf,€V€€€€; €uf€>b€ݾ€[F€€€€€€8€€€*€qo&G€€€R|rkF€€A€HX€€#€€€mu€Ê€Z€U€d@€ũ€8€€€7€cJ€€ i>F€€sd€€€;€€ydo€€q€€€G)€ر{ €€:0€ؼbmU{€d/u€
+€~€=c€;€J€€XRR€Kh€ %€€€7v;0,€€}€)€€†JRS€€Y€C€И|tDDT+€Ty€$€ €(€€3€[€>8r€MY€ҕG$€f€€9€'gI2€€!€m MyX&€?€98€Y€K#€€€€}|lh€x€y€€€€€€€ €# € I€€€=€€`O=b€i€5a€SeEA€€@g€€+N,€€bg€€~€Ma€v@K€€ {V4€=}€eÂ€Â€í·¸ÖŒÂ€Â€Â€Â€E€€€5i?nf€4€/IUN ]€€€€^&€€€,€P€֞
+€Yf€R 3i5(€h€4€€€€€€g€€2-€]m€€B€`€€€€9€G1€ʲïµÂ€Â€}C€€€9€€€j€(€\ €€"2[€;€€O.€€e€€ᛡ€€€€€aE€LL€.9€
+€ ,€*V€Z€€!€€̔ʄEr+€€€QO€€€w)e,€/€̆,€€p€:€'2€r~€€Z€IG<€€€€€€&
+u*€4K€jdw€€R€i€0#€ gȄ€'€€S€€چɴ€@-:€6z€a€ƺ€€ €rÞM6€€€€€/R€€€€€k€€Ý€
+€p€€WBo€}€€~€* €€A€B€€9{uS}ăq€€€€€, €a€Y%€h€w€̽€ 2Y<€]x€€€€€€^€€x€<{€€K€€€€V€€ €€€€€€6{€€V€€Æ€Q4€€,€€€
+};€-:€€jÄ‘\5€€€Ú€Ý€PCc €CVW1€y€€:l€€€€€€ Vâžš€@@€€€€€~I€{€Ջ€€€€ €€€€€€€M€x€SJ€2‡€€€€
+#:€€€F€€€zQl€P€c€€F5,U€€ €F€Z€"|€€€G#w-€€k3{cy€9|€€€€*\h؇€*h[@€€€-€€€€!€€jl^€€€ 5€,]€€€w_ l€€€€€VI€€0€XR꧀D€€€0,l{€]€Ư€UNd3€5€€€€ѻ€fL"€€W€€|w}mI€'mhE€7z€€€t=€€€D6!€tq.€ €U4€_€€MN€eDc€
+a¡[]G€€y
+€f€ 0m€r}€ƛ€A€€€4ii_€€€€_n€€T€nvM€i€€7€ € €Y€€#C'€€R,5€€i .€€ € !€€r€€!€ెĂ2€€€€€m:€6€€€B€€e26€€9€€€€R€€x€x€}_€#ϰ€€ d€J€X€€Z€hY €€€ #&L/€S€j7€€€€€j=6€€}$ €" €€m6€€€{€€&,.€€€€ h/.^*€€€j€€€€€Պ€€cKr=5€Ƃ€€€x€€€€jq€€€€ /Fm€€€E}U€*€x€T€€€€€cTms€3I€€C€'~C€€ "€.€*€€x€€D&€€J€€€€€bV7G€€{€~*€c5€€CІ€€€2:<€0Nሶ"€€؉€€Z€y)€3v`€€€B€T€W €{€8€ޗ€[€S€8Q€N€-*€€€|Ȁ€€I C€cdC^€€€a€Y€>€,€>?€€€€€€<$N"iх€P€€F{=nÜ­ €8A€€ _€A €€j9/
+€€)V€-€V€€%İ€t^€m䧺€ְ€ن€€6Q€€€a€n€㖺€€3€Bw€Ng€€z+€€|^€D€(€w€ڃV€€.€J€€*.€€€€q€€€ €`l ?€~€T€€€€€̜€€€€r"}?(l€€€^€€}€ZhXF1M€€€€€[€€€8t€RX)€G@€€@€€€m
+€€]€€V€€'€r€}€8jQ"€€ކ}€€€€€€€€€€F7€g<%_€kn€€€ W?€^dN€X |€€B]€€?~Ptê¢Â€%ȳƞf€€€=;}€€<è¢Â€Â€@I'€"€Eqw€e8€Sv€L€€T0zz€€€€€+€Y5H€€ժbK€€x,€€ׯD€QÞ 2ÞŒ9Z€€gح€€€€wS€[s^0qq€€C€€€€€€i€€G7€S€Ã€V€€€€-u€€գ€€~€JlV€2€€€f€€€Evő€€sG%€€e€€c€€{€€€€€jÄ€T-x65€€€C€€0€€r)€€€€€3g€+€€-€s€€b(€#€Q€|€€ZEqÜ€(€z€f75O€GOx̀€€€:5€€<€1kj€€€€LA.(€>€€€x-€€y€7€€€B€Y5€<[J€F €e€6'TÔ’mI[€€€€0)€^€r€l€*€a€൪O€6€€ME€€€€?€Z<€I.€€€€=Ô€€|€€4€q€€^€[€€€]€n2€Z€y€€€€]€}|ï®9€€€€€€U€PHØ€zÝœ7:€.€€vp@Ì™YKX$ї€$€€v€€ZIN€€Y€!s€€c€€M€€ٿ€€=€#€€€€q?P€JpABL€K€.س€€itx€€€€I€r`r(z6€€o €@€€b€€€@€l
+>>&:8€€Ԧ€€€9Fe€!€€€U€x€€ƻh€€€€&€€mE€G€I€€€.K6D3€€€€€}+€€)b c€|€€€LÓˆ€ȇ€.€X€y`B˶€),,l9€Z'@€€€€€w€€|е€T€BaGra?Jsr€3€€€€€=# €€±<€€€y"€€€M€€E€€€&J€€ U€S€ngH€*€hd€Y€€f€€DŽ€€i€€€€€&o3€€+€Am€h€€€Ԃ€|G27€€€K€/€€x€3€Eb€-€€c€€€,€€€_l{䨄:o]A&g€I€nVw€€Zk1€2€€;H€€!€p€€!y€€ €€€€€.€€ €K€TŞ€2€€€€€€€€H:€€€b€€€L€1€€€€€>_€ 6€€€€€€€€[雅€}Gæ Â€Â€Â€Â€m€:€€%€€5€ €[T}€>€$€€vR€n€]<Tb}€€€3"€8y|€€€€c€7N€€ €€K€€ 6⸣€bCY€€€Zn&€€»€MC  €q€€€y €g)w€Y€.€$7~€€w2€C€<Hۦ€€€mYo€€X€LB€€)€€€a
+€ €y6€€€€€:FB€€}€€€>€€63c}€a€t €1€€&jD€8ɻ€€h !9%€€€€€^-)b€%€
+9_bh€€u€-€€
+D€€€QFj>kI€@A€€E€€€[€=€]€C€\€€€R€€S1€€€€+E€€€€€€€),Ф€€TGadÑ€€rv€Xw€]O€9q€
+€+{€€`"€G€Þ€€%€€€€€€€€J€3k€6€€4<€€p€€x€sh €lz€fJvNS€€€€€€€€€{Ò…a€_€J/xG€`y€lw€€su׮€€€€$€ e€€€d
+€j€Ο~€z€€Ԫ€vV€€€€€E<E€€EH €E€€RHC€€!1l€H€w€X€փ€,€€€uKK€0€i€/:€_4€P€€$€+€€C€N€E€€€€j€€E^€€ "€€€€Ƒ€€€€3€d€€€ؠd€N€wT€W_Õ­O€€;€€€Bd0{€h€è¦Â€Â€6€&€+G+t€@€€60ÈŽ€L9 €€z]€€?2"€Q€€ק€^[q€蟎€x€€€vϘS€€{T$€€:€€€€ r(€x9€ԡ€`€€€€uá‹¿U4F€j€iYIgi_€\ï¢*€(€hAB(X€T*V€€€€€€#y €€€€€ic€€F?w€ڟ€€m€€Z€[€€€€€€2€€€r€€€€g€q€€€€'€PT€€I€R€€*dw(^€ZAIx€€f€v6Y(AQ€BJ¶%€v€[w€>€oc€1DZ€€EB€€~€۷€Us€€€€_€€]H€E€€€€€€€€€.€ѱmHk€€7€t.€€EG€€P€8^€# AyG€0Y€€€€g#€m€€€\€V€€Z€C€dk€tg€€€€+€a€ €€€€*3)€$€€Rh€€w€€u_€;€€€€v€,€I€ €w€€€]€h€€)€€W\€!D€2{?€x€€€€€€€€|"€f&€ÎX€t€€€€,€ؼ€€€€ƈB€€:i,€€_^€yߩ€{€€€€€€|€€F€Uγ5€€ݺ€€€>€€=€€A 2€€€€€H>WC€jX€Pc€€p€E;€lY€J€s€D2€,€^€€dOk[€V€MoÂ€í¦¿Â€€€ӀjU€€oS^€€C€€R€+€)n€€€€R€Z€xq\€:€V€N€z8€€€_€€€€€_W€ou€€€€€>€ZÏ‹MÊ©VN€€€ʩ*1fh[<]BB/€€1b €€E€€$€G€€€€5€€d€-U€€(q€b€[Ql€ "-1
+Aj€e? ;€'h€€€'€€€€8€€\C€{p€€KdaW€8$Z€Қ1€€€Ġ€€H€€€€#F€€€r€€{X€Mο€€€€€€€ È€'€5 €€,€&€€€€€:€w<|+t€€€@xf5€iȦ€EG€`' /0€€ u€€€€€!€€€€€€€€D€€ӂ€€€€€ͥ
+-j€3€`B€C€€€€63Nݗ€€€€€Bc€A€€`€€-8\|€:k€€Z€€s€€i€ܼ&€€k-€z>#/€€(dil X€BZ€p€€r`€E*€€!gb €€€S€
+€˓€2H€^,€€€H€€Y€}:€e€€"€€! €%€@?€€ 6€€X€N8LF\€€}€€€t:)€€€s€DT]T€€€€)Ô“y€€V€#Y€€€€G€€€醻`€€€€Gq4€€€€l:(€0*€€z"€ÍD€^€k-6€)€]_€xr€*}k '€€€t€jw€€4€=€€+€€|€p15O€§€ݼ€EX€=€b€`€l€€€€ouÂŽFx€€€)€€@€€t€€€ۼV6€€O€a€̲M1*6^H€ MÈœK€€բ?€q5€€€€zU€€€€€4€igx[€€Is€€G389€€8€+(€AM€5!2Eǰ€Sñ€QR€€!|€$ѕ€m€N€€:€€€€€€€H€U€}\€}~V€:€ n€€6%€€@€€Ui4žHQ€ €MJg€€€€6€@€€€€^€€€t+€BF€€€€€F^€6@€€€€s€K€"7€XP[ۀ€vG€€€b€€4€€@€Z€€€€€!Ë o€€€X(Ø;€x€€`Q€Af4€B€€é±Â€ß‘4MD€ Ö¬,r€ €V€ ${€=€€€l5 €#P'€}€ [€€_€E}>€€&H€€E€€f €3€z€€\€€Eܣ€~1ӄ€X-B€€:2€Z0=€€=_€bO€€)€€€X(€€€>ۀ„€€€€€~€€Wͯ €A€€€€}€0€"€N€tt\€9€€"€
+*
+€pO€]h-6H€€/€€€€rs€1|~€*€RY€b]€;U€€€€e€\e€€߸)€ €k€ ޮ€€&€V€u/€qN€€-R<*€VX€U>[C€`0kv€O€€Ù[€TD€€<€€€€E€cب"&l df5€€€€€?)€€€p qZ€}Q€€€b€#€€M€;€€h$€€€€€€RXs,U€€>$>€€yd€/m~5€€kk €€€€wc€y/€€J87(!€$tx€€€8€€w€AtԲ€€c€€€<€€b#€€l€R€Zb€€Ck€}=€€€€`€€€€€€b€€%9€c<€)€p€€€€!€€?KCk€Ό€D€€ t€@
+€ €E1AY€8D1XI€€ݢ€€?0€5€D_]€€€€ġG€u€€€^!€€It€€€€#€€€)) €€1€€`€€€iÛ‘Il€€? €$&JE€€€Y€>P€yX€€€€$€-*Rw/€MsrNH€+|€€€€tCcw€w€K+ Yz%€€ˑ?q(€AK €D€ٵ€€€D€€#€E€am:Ô¦#
+N B€i€jm[€€€`o€€€9&€€[€-€€u€\t€€ €€=€n€€,€f€p €8€O€€€*;€j€€€€€€€€R\€€€;l€€€€€0W€.€C€ 50€€€€€€€€€"€B\€5€5€€€r€:lxx4€h€^ү€f{€3€€q€+€2k€bN€€o_€`€€NK@€€(C}€€€|-€73I€u:]>€n€3€€Lu)uGikx`r€€7N€€ԫ€pߪs€€.€€4M#€€R€€<I€€F€€ s€8€€k 3€#Q}ٮ€$€€b ̋E@D€€€€€֌Ա€€€€€)A€G€L€`€€€€uK;€€!4€€B[q€€€*€€G€€`%_MVrSWe€€€%€
+U€€€T€€€l€*€L⎴€€$p€€8€42€€€x€1€€€k$2}€.!€"€xO>?€€€€€R ʣ€€€q:€€€q€€€-€y="€drat+oC€€x€^€/€z€€€€€'€€€€2{.!W€€€u€م€ut€€6W€{A€€ ĕ€€8€;€€Flp€€Ԝ€€m˄€ €€b€€v€?€€€€€€HG€€€B€€€(€€'€Pt5€€€+2t+€€€i€€€€ޯ;`€€€€€€3€€€€1€€€€a€h8€Wrk€[ 嵹€€€&Q€€€j€+Bo€`d€€€B€€<(€{€:HYy}€V€€N€€ќ_€€€€€€€ף€€WIɌ€€_€]F>l€KS s€€€PJ?:/€€€€€€€A€€€€€€€€/€€zT(€€Ù‰v€Xπ
+?E€€=1€€ٯfW€€€€ҧ2€7€wM_€€€]4€€€€€€s€1M€€€€€€€€|J€€€€ܱ2€"€X!hE€€98€i%ƥ3€193€ €60^€€+W€G[€€€YM-€€€IΚ€
+€€€€Lg|H€€€€$€€޺h€€/BBG€€€€25€ _s?€;€€Ч1c<
+€٣€.€ndÞ¿qw€+€€€€€€€οT?€!oa€€€€:MÆŽwl€k€€€be\€€€€R*3q€€€€Xn€€c€€€
+]€€€I €%)€€€8€X€€€)€€€€€A€z~@#(Q€Y€€€/€€€€;|€€'€/#)Z|,€$F€>;€*(€r €$€€€9pRb€€6€P€)m€€)"€8R€€Ut0}HW€€ $€y€#]ۡ€€2€€G€T€ #f)e(lV2Dĉ4€€€<€€C&€5€9€€€€z€Vo€b€Z€€~€b3€Å€&)m€€C$Ö¢"#i€#€€€Š€۵€ђ€@0€b&€ f€)€|€z€|€€1€Q€€€€€EV(€[€€y€€€€8€€€€€€€€€#€O€ʇE j€€p€€€€€€I-C_€}€OX€ Hۃ€€}€€k€4€9'a€|C€m€€€€أ€D€€7maJ;€U€zbD€€!}€€Lљ€qG€€€€qF9€s€€i€ߵ€Y€€.€€€MhTT}€€h+€f
+{€_€€#€  €h€€i€΢€€H€a-H€.€+ OP€€6x€2(9€|€G R€€€€€{€€€€p€€t €Z€u1€€€p$€8€€€s@€€€€€u5j[r€ €€8a]׈G€€€$€€0€"€€F$&s€讑jU€€oT€X€€€D€€€mR,€_€ [€€'Rj8€Z€€q€€€Gf€€€x€aÃŒ%€L5€NJ۸€6€€&€J:
+l€€€€H€€/"Q€€qYW5&€€€€˹€€€€€€€€vß®`€€m€Ƥ€€-€€€WV€]uoBdJ€€%€ݳ€ }(€€€ €€9e€y7€€€€€€€€ i€€€€v€S_[<=ß»^j:€d€-5€€@wI€ߤAq€€€ݢ€Ĩ#€5/rY)€hDÈ¡_2€>€$b*?€S €€]5€{|€€€*€B€€ZÛO(€€i4W€J€J€轇v€&€9R€€4€€€€k!€p€s€€€#€K€€Ҙöf€E€€"€Fk#b€F€€\€€\€€Z€T€€þEJ€€€€h€€€\(€ŊiI€`€L€j€D*MÖ…Å€€@€d€€€€ը€Mjpř€€L3€؄P€+€!Z€€€€4€€v€€L€€€ €'- B€€€€€!€€€5j€€+gÖ•s€€€#€€&€€€D€%L€ €1Ŋ€€€p€€G>€i€€E€€€€€)G,BUf€z€€su`€€XOR€M€€I€€€€&€wʺ"M€fQ&€€€_€D@€v€c€€ef€.Y€€€€Ûº';8€z€m*g €€+=Lw5VsT€€2ߪ€e€€h\@€,€€€€€_€€ʭW9n€ JJ€€ €#ѹ€€o€'€€€QI€€a=€€€h€€+p€€+€;W€€Wj€f€€W€3€€>€€€@Īd€€@€L+€€N€[p(€€€€pT4h€€€€€€€ €€t:€Wd€€€€{;€G3ÿW€Ӡ,Ó‹,€€€€q€€;8F€bZʡ€Ԥ€s
+̀€€€€€€€€^€€€€I0_€€mt€€ðg€:nN€€€€.|€€?€<€€%€€*€-VHt81€U€€]xNH€*€9r=€#>Y,bGe€€€€€€?€=€x€=€x7Rf€€^Z€€€€€R€€^Y€Xt&€F€k5€€B€€€€r€V.y€.YM€u€€@)€Z€€|€€q€p€<X€€€€=$"€€ u€€A €€@Õ¨€M€@€€:€€€'€`€/.BW€€/€ nK~i2$€q€€€€Ԡ€g€G0X@W€[\~h€€€I€W-€€1€€€€&€€€€L€r€A€€€$8 €€,€€M F;{b)€€q€€€€.~Ouqj€6-Ia|€o€€9;€€€N€€€€€€€€€l€`€€€€5V€iuL€D !€€R€€1€S€*€v€b€€€€€W€€=:WE€€:€€ Tfye6ȶ€z€%AR€€€€U ?€€C6Mh"2cÔN!{€&€3€w€€HnP€€€6;€Σ€U€€S€zr€y2Wm€€#v€-Sb€€Ùµ€€ € ,sD-€€€YÊ‘O€€€!€€€€€Ĩ€€ϡ€€3W%8#€A€th€pT€€€N€ €7€€€€G€€$€I€€€T€pjΒ€+€֫€$N€€€L €} -€€:b€a(?E€€€ $We€)e€b€2;$/QҞ€€€€J4Ì«Md6€€j€€€.€W-,€€€€_€€€€L|€€€)€\i
+te€€@€g€WQ#€~€€O€'€6€=9€P€€i€€ 2€€€€f^€€€-€€ld'ML€€€€€€DOM€€iG2hU%€€?NƜ€)D€€€0pÜ…G€€€,Ên€€€€€;a€)€€€W5×£h€€€€€€€j;oR€&€ĸG S€6€L€1eTG€€|
+`€€€€€"€€D3€k€C€.€n€ €ѓ€5W€`€€4€<"cz€h€B€j€€€€4u€€8€I$$
+€I€€l€€€>jƜ€€€€8€E€M€/€€$'€€€€]€*<{5+!€€€6€€4€€€€€€€ €5€yÕ¦4€aV€€€€<i€€̣€查€c€€€ ë“€€€58y&€€m€€€€*7Mf€€pI€€ÌQ3׮€€€€h€")flӞ€€€'€€€€€q 1€€{€€kA€<Q€€€qR€€ݩ€&$/F€€€Z€€€4€=n€€€€7ߘ€:%h €윩C\€̼€€bo€֯€R€7€€Dmp} Z€€€€^€Sz€€?>F,L€€€N€€2l€C€€FÛº'€#NW0Å€H+€€%r4S€z€m€€<€€€€sOR€Z€dX€G€Q €€&~€X€ߡ€H€,%j a;5Gp
+3€I€ܳ€€SD€€8Tr€€€j&€U9€&€#TS€K'A€l€€7€€@€€\€_Lv€a€€€€ T&@?T€f€V€€€€€2€(€€0I€€O6€ €€:E>ހ€€€>€€€€(ȷ€0€€F€€€m~?€r2€\m€€€€€€xkO€€€uZIf€€r€~
+AA?€€C€E€M€ €€p€{€€l<ЙI€€1€€Qh€@L€-€€)ß½#L€g€€€2€&€€€€o€8€t€.€ ?> €|€c€JÞ¦ ^€,€?||€7€€A€€ß€f(a#€,-}€€Ya€pê¨Â€CYÛ«€H€Z€€-€=0€i`€bqb€€_€€€€€)22R€W€\€{€ʺ}€D€ €4€fi&€€.€€!€€2c€€€9{V1€s€€€€]€L€€€g€@€€€(3)€K6€€€!R-2'1€€Ĭ€.€`]€€€Jh€ o€€q€R€€s€w€€]€€y€€€€`€€€€€)€)€€r€€J€Y(€€B€ €xK<4€E€
+)€jZ€:€԰€fb€I€€!Tu€€Y€dp€€€W€)al_`q€€€€€€ €€&€€lZz€ €€)€_€ֽ]€r€€ €€€€=€€€" €€9€S^ä°ŠTݪ€€$€€€€Z€St€€ɑ€€==€ӿ€€.;SÕ¼X€q€€€%€€€%€Kp€€€Ã€€ϓ€€€"€€c-€€Ű€EW_@€€Ч€€€,€'€L€q€€p€;€H€€€€€€3€€€
+€#V€1€€€€=€€€_€€€€€€r€€€€Qt*Xo_€:t>€€`9€€€[€€€z޴€N€€€Q€ c€€[€€€€o€€€>€r;€€€€ €/€€=D€D€€#€€€)d€X€z€€yy2q`]€€€€D€€€€GB€€€€€€€€€€VvÇ¿6€€ɉ>€€€€€€R€p€dTm€Zu€€1€€€/~€ d€€€2ÚŸ€€€\€€䄈VÜ’v€€/€ €€€€€pH€€y83€€€K{<€€FW€:€lG€/€p€€1€€dw€S€$€~k|_p€€€€€€€@€oÇ´c|
+€i€€s$€ €,{d€€€W€/O€CI}€€/€€}€€9€>€€€€€kL€€z€X2€Uڌ€J€dZ€%,z€:€/€ € ÈŒ r?Ù‹ >V€d€€ǃ€€€`€ißžy€b€€ €Xc`€€€_€€€€/€€#-€+¨)€1€€€€€€e€€€:Z€€y^€€€€^ G€pxO€4€ uK_R0€qvd€&D€€€ȥ1€3€H €P0€Y€€€€€; €x€€r[€€-B€f€€g€€X7€€Ҭ€'€U!#U-€€Ն޻€TJ€€@€C€|ߦ€m€1€ Wuce€€\S€€F€€$3€{,€L€€€€b€D€3€€€m€€Sm€€€€^€S=rW€j8| €?€€?€€€4T€€€€m€€V€E€€€^€W€€€:>:€R€D/b€Z€|9€Ô×¥0€][€€
+€~Ȯ€VR€%€€€€<€<€}+€€€€{€L€O€€€€€ @v|€€>b€€e€}€r0+€~€@A€€LhOd€€€€ €€€씮
+C€P€€T€€€(€ 6€€|@=€'€€G€€€`€€€€€€i€oN€~T€€_€€€T€€U}€€/€€€€`€k€;i€€'s€€€S
+€L€€€€z€€Ӛ€~K1(€€dUi€€xp-{€N2€R€m9]€hZz!€0È­3€€€`€i@Ô¯\€€ޗ#€\ћLJ€!€€€€€ʳT€Q€€ڪY€€€6€€%€€€€€€€iL[€€€€k;D€a*€€€€€t€ w€u€€"e€€jP/%t€F€€€€䵯>€ 9€€€ €€€€€!€6NC/€€M€C€€2€D€:€€€pV€€%ih€€e,2€mh€€€€Cw€€Z9$o€@€€3_3q)S€;€(€€€€ S€€€€B€€x-€€€,€C}€Z) €€*;€€€€z€€€€€€8* €3€ e€+€G€W:€G€€Еm€€€€€€€*֒€€Е*c$d€€€€.€€#€xD€cÙ–€€€€€€j€€1 2HL€€H€u €޾О(D)o€x€W€;9€L?€€{€€_€~€x€I}€6A€@f2€€ԟ€cy€Pl€RE(V€€€€Eg€#€ €6€9€ '€>€+{€1;€Zψ€Eβ€ X€F€€€S€4€€Z€€.€€€=€€€A €a€A=€€' 4ld%ie€€€€@€€D€€€€€;€€€C€i€K{€€€€€69€Ó€<€\€p€€€€€~0)3x€€€i€|a€€€ע€ƫ€€€}€€€€€€A€H2]€€€€€L€G<€5€€€{$*P€€<€鰛j4€%€€€€€6€€K€€+€€E€_ €&D P€€汤@`€€Gdn€?€4€c€€€- €s`5€€}(e€~€ €u_(€€€ȿdA€"€€.€t#€€/)€€8€€€ֲt)K€!€€hI<0€v€E€€s€uK
+€Dݺ€€€€!€€€BW+C€l€€€<€%€CH€€
+.La€ MMa€ Q1€€€€€F!€Lj)€&€€€B€`V€ €€€€€t€3€€0Í€€€ҲB€ GE$CRx_'z€+  e|€!"-€€8€€€ j€?€€=%€€€€f€TN€€€#€0€5€)€L}€€€€[€e€€H€€€€€} €€€€V€€B €€€€-\i€€€{€€€9€€€-€€8 €@$\€€€#€Kd^o:A€~ciÑ Â€n€Ρ€€€ï‘>#€HH€n€@€$€)€ 2€€<€*€€!/*€€D€E€€̚€j€Q€€€€\9ȱ€€8€€{€0Ë€,€€dszh€l€€€XI€k€€€€Ó‰v€€€i€x€€€€€€€^Jhu€€&Z€O€€€€)€€3€'€>f€€€p€€€€€€€Y\p€r5\u:)€S[_SO€'€€€€5wy€y€yi€o€'c€A€oE>n€@V20€+m€€€G€A3+€€€֣€y€{1_€)€€€7򀀀b€kѬr€m€5̃=u€F€v4Ý‚8€B€8€€€1€8€\€€€€€€3€€X€x<€€s},€€€€R$€$Q€€€L€ }R€Ȫ€€€1\h"€0€8€ur€e.€i0€€N€|€€D€Vd€€g€#€H€cCTg7€€au€€<|Pf€ U€%€Bt€(€€É€[N€€€ k<o,68%ؑ€$nXf€€€€€Ԍr€Д€€ܔ€G€T€8C€€€€"€€D#Û€€€€€~]](T€€]€: €€€*€€€N€/Q€I€€| ?\€€)bʡ€€v€€, Lkì”±|€€*€€g€€€€€=€J= [€i€F€€€|€€j^€€€}€O€€WH^€€3€<€€M€UZ€€€sϷ€€[5z€€€€€ 쥯€GÜb€tґ؀€R]€>€€ €%€€€€n]€ 4~€l€\€€€€ €€€Ta_€€€xد2 €€SdPQ€ʫ€we6€€€1€€€€€$*G€ +]€?€Y(€ז#€€k€?oG€€€€|=€y\eÃ¥y€€€€€€|> W\€€ W€€P<€€€€€ÖGxvV€#9o€€I€G€€a€Nx€€€'#Jh€m€€# €€ €U2`n€ {€€Ma€舋€€]7€8K€(f€B€€€9€ȟ€€b€€h€ €c€€W.€€€8u€€KKJ€€W€KD{€€Kß1€€€z€€€X71€.k€€T_€€W €€€€U€€=&€€€€€4€x(NH€€€€M<# Z€K€€h€|.vS{-R€€G€!€€€L€k€U€€€€€B€)€u&K €€(&€O€€:j9@y€-€ €vKl€€Qe€€ €€€~1G€€€Z€F€YY]€
+€l€€B€€t]€P€€E€€͋;€D€€%€H€€i€2 €3€<€
+€€€^€€€€4&€€€7€=€С€€ €y€€m€€€€G€€e€€4€€€n#€€v€SV€)€r€X€€'€0€[€2
+*O€€€k€€€€€/€Iͺ€€€$B€€€Px]€€€€€Jm€€€€€
+€ f€`@€€#V€€<Bn€€€€€€x!€ 믤⃙a€€9€ H€7€F€ϣI€€ZΪ€ŵ 깜€€€€9€6€i€€€)o7'€€;€҃7€d€cy;€€о^`i€€&€€D€F-H€€€€z€€€€€*€€y€:c~€a€6€€€ Y€BA€€j €!"5€€€€d,€^E€€€Z€€€~^€€€+x€ؕl€S;€€^ѳ=o€€€€^€*b(€:*€dt€m€€؉zP€V€ €€;Ts€€:^c€$\€=$€ ǃ€€=€$2. n€€€€(€Pp€p=,€€y€h€€x?
+r'€€€nH€ tÑ1+€€T€€ACeSfb9€€€&€Z
+3/&C€€gP+€.8€̄[' -poQK€€€€fD\€€€€t˩€€I€€=€~€€ €o€€€K€€
+z€+€acg|u€€€D€/[€€D€€^€€ ڮ€ )€ +€€ €c8Z€=w[€ €€ϔ€c2€€2N€€=€OM€T€€r€h€
+€~€N€€nk€R€€€Q€4€R€€ €f€qM€€€i€€K.€ ۗ€LW€€€r€yd€€7€€€H€€€€€/~€H€€T?L€뮫"€1€
+€Xg€j€X€RW燹€sÍ<h1€€ٌ>UBC€€P6Wo€ €€ᥰj/F €€€€€u€M€€?4€#€W€:-€€Yn€€]€՞`U^L€€O€@,€€€€6€>
+}Z€€NwU€€-yEz€€1[€bÍ–m~€€O€eTer€~€+€€€y(€M€q€h€]€Q€RX€N€WDj€k€€K6R€⌽€8€t€ ^~B€€€€Ao!BD€€_€€G€€ .€*€5€jBN€€k*B€€€€€?€ €€€j€!€€€€€ €€b€z€Pt€€ €,€€S€€@€€B墪&H€€€€PU1N_€wG?€€€€€€€suu Â€íªƒÂ€AcY€, €/€€q€`€€"€€9*€€7€€A€H€€C€Û€ArY€ i€€€€€€€€€^€c€gUK€€)€]~6€I€U€€DKһ€&€y€7€X!€ aw€€€5%€€"€€€(€€€€YP€€x€€€x9€1€?bb<4b€`€P€_€€€(9 s€€q€€€鬚€'Ce€_€€Ub€€ €€8ØŒ€€€2€€€׾€€€€/€€€N"€<(}€ W€y€8sɧ€r€€€Mˎ€%€€€p:C€E€G€P€b&­€€^€]€HR
+€"€A €Л$ K€€€W€€€€€)~@W€€GTT€}€€€€- ׇ€n0N€€+€A€€PԹ€€Dih€:€€Y€€€€€)€UHY@~€F€J€€€€€€G€u>€€]€€7m€3!€_8€€D€n€g*ϖ€3€^€€€€a€S:Ù{€€,JK€€€g=€€[€€€€€€H'€b€B€ϛ.OVwD€w€€€€6U€€€^€#
+€€€?€0mw€od€S€€€Ѣ€€b€€ݔ€>H;˩€{[€'€€l-€<-€€€€€Vo1W''}€€€È·} €L €€€c€XD€ȶ€ €€U€D€€€€€(00€V€€୮u€€ܻ`€J€͒€€€sk€ř€O#j€ j1€€€k;5€€K€Tc€kV<=€€ؼQ€R€€<x€`~W €€>€̩€€D3€€y€€€€=b€Ң€€€B€€€$€€SaJ€€€€€h۱€€Ge,m5V€€€L€€€€€e€€R€M€IJE€€€€I€€$€€::€E^8€€b[€€[.J€€€€@Ý¿af€h€6o€€ͣ€€#Ö¶4:|X€7ݣ€€=c€h€̲€#€H€C€ǫ€lAT€€€.3y€7€oЇ€7€A\€€`€v?^€h€p€€€€z€؞€€P&€p€D(+zƽ€€h€€M€nI5K^€"€Ee€b1€V[ €€A׵€€€1€€)%S__€#€€€F€€o8€€CPV€#a€€qh €8€€€€mt9 € €^€WP€qpZ€€c€Y€CÒ¨Q€€͘€d€€'€€rhQ€€fR€݉DǦ€ꈙ€I€€€fE€qL€€€€=€:€€€"€᢭ €/u€1€€a€^U#9€PIP€€k&PZd€e€du€€Ple€€c€€€㨇€˟€€€i L€6€€@,€<v0€!€g%6€€€€f€D€€€v.€5€€L€(€€€l*~_€€€W€€€€7(x<ɕ€b€&Q}i€€Vm€€t,€j€[€C€€€#"€\€€.€Yw7€Dxμ€T€€6c€€)7€€€€a}5€€6V€(f€€€€+€€<52€€ ªԀ€€€€QN€€€€(€9#u€€MaE6€€€yN€!Ù› €g'€€mz€ƣ4q€ڇ€€1x€oA€ۅ€€€€€€€€-€%7€€u€€+€€8€7€íšÆ–[}4€^€6€€E€€`€v€€Ь€AIY€€€€€ДA€€€M€€Qd1€F€€€t€€€z€t€€}N€€€ €^F€€)€:t€€g€*2_€FÔ€b€€y€€€!€|€ ]€€€RV€\19€€€€€€b€€€€3
+€^€€QJ€€€mj߶s€4€€ -t €'Â€íª¯-€T€=€^~U€Y* ruK€€€{€O
+€>€€U€>€€€+€€P|"1O€P2$€€€€
+€΃€^€ԆB€€€I:]I€%€€€Ц€6f6€-€q2€€€L€€€€ў< €V€${z€€2€o. lν€=Cj€€€H€9x€€€r€€€^€€€€I€€€€%q% €€ €€€#c2€_A mE€€€€ř€R€yo€ €xŃ5(6~€FS2€€€€€€€€€€]€€€€€V€l€(lQE̺Sx€€8\€€I€€D@͓k€€T€˼€€/ٱ4€€€9ݖ€€1S€€H€€€Hb€€8@€€{€I€S/€€€€€€'']€\@€P&€€g(€€€]X€€€>€€€اLB
+Qpç’¹Â€Ú Â€ 4р€T€€€-€Y€DH€€R€€ۨ€2€€_€€c&S€I€0€€Í?€€€J€+"€-€LJЪ€h€€€€c€€€€`d€€€_ù€€A#€€d 9€oH#€1€K€<€€€I"wYϤF€€€€q€n€+€.)€p€FfY€)€€9€€O+&€r€QmYK€=€r€€aI€(9€CCj€}r€€€ Q€,Óž[/bX%!_€ͬ€€€-Úhpe€x€g€€€U€€€3=€vྜ€€"_€€€ί€BØ€€€€@€€€€€€€€€7#€€€€`p€€.`€€c€€z €€€4Lr€€ȧ€€€dmp]€€1€#€@€€€ʤ4€{[G€€H]€z€!€\k€-x!€mZ€͚€w€€.€€€;Tl€€E€2Ց€#€€€q€Ö®@܃a"s€€€€,H0C€,<€€✲€€ -€€l€€€€C09€€€€يQ€€q€P€€~€€C€ץ€C+Ä€}€€€j€€D€€((/€€€€ €€€€2v€€€€€f€€ €€€l€ )€%s8C€ =€€€€[€€€€€€€q>€)AxzÊ€N€€J€#€€€;dM€H€>F)€Zϗ€€O€€mc€Y€€d€J8€&€<€+H9E€€qk€€€€i\€PX€=j€€€y83ᦑ€€I€h'€€ϡ€€€^€€€~€€€IW€h€€€D5a€W@
+G€j€F€pss€€K(>==€U,€ H€ϼ€€€€m€€€Vs€S€
+€€€q€q€[€€€2€3€m€8(€€ /"f€€€P€€H!€€G€~€e Tv€G€€Ml€2€Q€_€N€€(
+zEd€acN€€{ €:2€ ۲€€8€€!€Ct €€`"r€ €€gQ€€`|€7%G€|€B€€€G€?€7€€€€ޓ€#Z€€€€€擫€€€€€€t`€€€€{€€-€$€€IpU€"€Ǟ@)€€€_S€^€€Q€€DF€€qI8€€I€€~€ꋛn€€_Z€€€€-*V€'€€€€€€9<€hiK€n€€B€WyW€'q€€J€€e€[€%
+L€Z€€€\€X€kk?€K€€q譣€ZY€€€:Mvu€ʪ圪€ €€€€€,)Q€\€€€)I€9R€T€r€€s_d€}€€)€€d€€€€€ C€t€]€E€€€€€4
+€Z€€€x€€ik€v€€ w<€_Lç°_€€[]€€€il{;'€€'€€€:H8Y€€_€_Y€A€€PZUIz3f€€2€€i*Û•U_€ .JX€€3ɠ€€m€|€€R€9?€WH<H€€ΉRonN'€€€J€€4[€€€^€d€€E€י-€€€€€5€€v€€€Ҡ€€շ]€Q€€€€L€jd€€f€€€€€€€€%€€Qdžd€€0€Е€EA€<#B€e€€tß²H€070't€€Bp€€€`3€€€ a€€€6y€\€7n'€€€€€€€€=€€9€@3€J4€S€U€'/€€z_€€#€=*\€€€^€TbI€€€8€€€p€jy€€€+P,V€€E€l-e€x€€R€v>€8€€f€€"5€*€€€€€€o|€z€€_~b3€a%€!f€"ËȪ€0|jRW€€~kN€3=7 € €€€Z<€F€€€€€€&€]€€9S_7€[ € €€65€v€€€jÒ H€Z'€C'€€+€7'X,€€k6Y|€€€€€S€L€}€%}j€€\ʢ€\E€€€€:€€K€{€QBH€€€€€ˉ€€D€-U[€o€"S *€€€p(€|Þ¢;!O€#{€€€V€€Hh€€5€€€€i4&€€€ %€€[€€€€€j[€€[€€rS€€€h€bAJ(-€€€f€€€€€€u1€6€y€C€€€€€˛€LJ€€K€m€€$€€€€€€2€€€B€.ZK7€#\~í‹Â€Zb €€۱€=x€݋€"€]€€€€ۂ€€€€{€Z€%€€?€€z€€}JBq€€'€*€€€€€€€qܨ €€€€€€$F€€I~J©€,€R|A€€€3€h€#€Gq€U€€+€Ζ%dz €€€€ €f€€€€€e>H-@€€€€€€%sC€€]?€€€v
+€N€€€€€€6j\€8€€€%€€ €€9€&€€Ƶ7-€F€_€Œ€€€€€€€€€€€€€€.€s€ؓ]iŇI€€S€€€R€€€,A€€€€c€€J€tr€€u€€d€y€F:€a€€€€ )€H}€€c€€?€?€&7#?D€€!€U€J€€€€8߶€p€B2V€+€€u€̒€€LZ.€€B (€ vZP€)€€€€€EUq€€z€]€Q4퓷%Q€€€€€Pe€€}ͯa巗%:€+€€€€%€M€€i€kA€€€€[€€€+һP€€€€€€€€Sql€€€€s€f€ّ<€€€€Ww€€€S€€8€€€5€€Xa€€€€J€€€d€€L€^#:G~j͑€f7€€x{€f€F(&84g€@y€€?<I>B>v€€€
+J9€€0€!1V€€x€E€€]€€€€J€€€"h€€€^€h€€q€€i€8_€€š/50€B€€$€s€€FD€!€q
+7 ݀j
+€€€€÷€€€c)(M
+~€€€ĸ€q€Z€B€€€Ý€0'€€Ӯ#v€€€€€T[^hz€€E3€b€N€€WV €€€ €7€A#€9€#€]€€G€€+€K€€sY€€€€€€w€€c͞€€r|Ѐ%K€€€t€€r i€€P€g€"y€€8f€S/0ً€T2€€€€€€}€T€Du€€ݮW €€€_f€€&=€€€€€k;c€E€#r^d €U€d€6€€€r€€NN?!6bdc€€ʈl€p\!€€Ө€w€€€€€€'€€€-*€?5h€€€€p€€€8€€€€&I€€€€€)ޫ€b
+€€€€€l€€Mo€s€€
+€[mkOH€q'i€DZ€€z€tu1€fP€€€%€€+F€€lP€€a€J€€€€f €€€€€k€€€g iRg€J€/€3 a€€€?€a€f_ 8 A€€€€€€i€ €€€a€)s€€W€€v+€E€ZMS€€€€
+J_€pٮ€€h€i€€€€€>B€€I€€[0€_€W€w¹€€€O€€`€?€*€Eh€M€€R!€€€"€;€€€(D
+1BeB€j€€kX€€9€€€€€Kݔ€kp€€?€€€g€rD€€U€e€ &€€€€€€€€$\Z€f€S€€€€c€k€€€€kS/ €D%€€€€ՙ€X5€_€L€€€€€€€X€€€$€[€!€€>€I㩅€ €$€€d'r֛€~N€b€€€€€€f€ݣX$w€€6ţ€&€€+€Â>e€€v€€€U€޲V_€݀€*V€€€(7€€%ۓ€€-€€T€€ta€Թykn€zU€ q€€€&€€D€y€p€%%Ax~€{)ãš¿(€€€Q€€)€€€ƌ€€€y>XA€€´~0€€€"€€Cw€€T€n€€€€€t~€€y€€0€€€€€ €rnW€€€|ԙ€€bJ€G€€J€ui<€€€1€A€Yio€€€€r*c,j€€€€€^E186€€C€FD€~XMN€€€&D}€ Y^HƩ€W€2C-€@€RA€
+€0e€ֽ€€€y€€€c€~8׎€"€Q=€€S ږ€€N€6a7p€€qxΧ€ ^Xo€€€€€€/€€€j€€:€€€€€TbQ{_=l€€€[€i€€€2€tOlk,€Ҳ€^-l€€€€'€€€4/߀'€v€>s€X€€€€]qe5€€d€H€${Ȁ€€€€f}Yq€€_Pz€k+€ €")€€€Kl€5w€€R€€X81a€9-€F€*w€€€p€€}x$€Nʨ€ZX€̀E€@€€J€l.6€M&€€€€J:€,€€€bM€€€\|`o€]~r€JBI€€!€W/€`\~€r?€€€) Ҽ€Ú}ì?€J
+€€x€ €€€g€Zv€€€%wa+€hU€€€i€9€~u€€€€Xa.e€€€€k€#€€1€t€€k€€ €6ß‘>€y€9€rǰ€€€I€^M€€€€z€)€Gr€wÂv €€wB€ۯ0€l6€€€€ѫ€€@€?z[€{€t€€Z# €9€+€€ܪ€€€M€p€€T€€-5€U€f€€€ O€u€€€uK5€P&4dFz€x€€€^€€F€€€ €f˶8~$€€€€'€€ska2€€ f€€€€€V)€|€uϑ€€T€€#€€€_E(€d€w€}€€€€U|€K€€."4€S€!X€€€€{q€Z€€€ €€€€€€€€&€q€dx€€j€[RjB}PgAKg`r€ MÔ b€o;€€t€€2r€G€o##€€—€ע€?€€€€€h€€پn€֧€€.€€)€#€~€€€€€KI€r€€$€zm€€酑€€€€f€6€.F€%€ €€h€O7€€€2€€1€€M;€-€€q€0€€€€€€€€8€T €^€a€`€€€*U€€€:X=€.@€€-^E !€}€€€€8jcG€ !€Æ$€€)o€]Y€e~~{=aw€{€@6+€fF€]€C\x€\€€€']€€€>€ȇM€€V€€
+€€€€^xQ€'€kw &€I€-€€€€€€€*€v€3€€€11$€o4%€€J6%€V€`n{,1ú€6€€Ըr€€e€t€€f
+@g€€Ij€}€@€€!?ٛ_X€pag€u€Y€gf€p€
+Τ€Xs_€u€}€ǖ€l€x€€[€|€Ї)€€b€Œ€€FT€Jԗ€lBbܛ€b} €€x€€€d€h€q€\'€%€/€%€$Tc(bo €€ €€€np,€ZD€€1'3€uÕµ>€Ï€_%€€€.to€^€€. €€ˀ€€#€€@€#€Q€€z€[€€€,=€€€:`€€.y' <91(ß” €1%`€€€Dw€€%€y€v€0#€ ;€{€€€n3€€€`€€C€€u€SUK€!€€8€Z €Y,'€€(€e€~€mw€7€€M^€€€€€€€Ҹ€€€
+P€̥€+n€€2€X€€׮€€€€€€+\k€@5€€€ɼH'€€*€P€5:€<€Q
+€E\q€€€b€€]€€[€\A(€,€€/€€€€€n€€€,€Rsh€lO€;o€€2€.B€€€^€.]
+€tqLÓN€kq(€€}`]€€€'u€€€€€€@L€(€€9 Z_t€`;
+ €€€€€€6#S~P#H€*I€€j€€Εf€\€€WR€€€=€€Ó€€€€€€.P€€€V€Y dHS% eܲ€ڞ€€€ Zp<Xm€€V€€€€> B Æ‹ €€xÂ€í±˜gfJM€6€Ria '(€Pj€A€€f)€!Z€ €h€€€k€€H4€€E€€€#l€€X,€F €'€Å«€p€€D<€€€V€5€'€ >€€€#€€€€ €p€h€€€F}€)€€€]Å»€€XÜŽ€€€|RJ|€jÈ…u€Q$€hЫ€AaKP€#€  +€S€֠X€ճ !€Q€€€zn€€X€€!€€yUÜƶ€J€Y[n~€€€€`€€€€€Їd€€€€a €€€€€€-€P-€E€1&€€€= i€C€€+€Ӆã½Â€Â€€€€{€€€W×?JC€€€€E€~`€€€eoig€"?{€t€€+Ï€X€Ԏ<€€€]i=€€€€€€€€;2<€€€€€€€j€€?€5hJӦ€I€€L/ͣ€€ּ€€^€€€6€-€€€€k€{€€€€x€ €€鵷€€}€€€s€κ€A€€^g€€lz€-€s߃f€€uo€€m€€׼€Moc€۸€m€€o€€Yc€€€€€€Jku€€G€;€€€€~€€€€\]€€€€s€n€S€€ |{ €$}€€€€€€€O€€€€€€€€4€€?€€u€e,€€TDee
+€€W€€€€€PX*{W€€€f€)€zQ€€.€s€Toq€€€a€U€€€€5g€Q€7€v€G€€€€;€vqkk€^€€€€€€ຈ€5€€^.#V€€€ p
+;€€z€€€â²pM€ݽ)4€€K€€:k€€€€Q€ D€€€|€z(9€€€#€G€€€ € €"€ h€€€ €d8'€> J"€€€€€€F€:a€€1nxO€LE€CeÝ£ €S_€€€hA* €&€Qw€€Һ€ݡ€Ţ €€װś€€ȸ€€€m!i€T€€€ €€€€u) 8F[u€€u€WÙƒZ€€W€kY€€_I#€i€b#€€׭€€]€Ͱi€|€<M€€€Qt€dr€FÔªf€;T€€Sf€€€J€€y€f*€€l`€€€mQx€€|N€U€7€i€$€\€U€€7€$f€@K€€€g€b€€2k€€+€€€<€€€€€iM#a€€€*€P€TY€€y€my€2~€€M€r€f€€d<A]€6€'%€
+1€Tf€A=-Y&€€"€€h€€€€8V/€L^€€Q€€vD€€€€`@˸K€G€€8€j€€€€7 \€€€%€`t!€€F€j€€€€€?€M€€ €"€\€€€pz€Ŭ€-€€€D€xDZß±NS!i6&€€K€(#g푼 p€Z€€€;jx-/"r€z€€€O#€€€€€k;€("€i€
+h€)€r€#€4]=+€€€€ą€4P€ 6%0€܅€x|€v€€€b€l€jm€Þ€€€Rq€JI€ϡ€€€€€]€€Ob€ g€yHD*
+€€2?€퟊€€€z€€E<%DX€€,ţ€€ÔV&€H€#€3K€€€€€3€O€€q0# €*€9j[€*€€>t%€€€€€€€D€€H1€€t€V`€Ç€€lu€l€€€|Ý;€—€l€€€€€€€€€€N€€{q€€[L€'km ?f€p€r@€€€BW€€ cZ=€r€€€>WUEV€€@r€€V€cj€€I€€TϜ€P€€€DW€€Ӳ€l€!€>MMc€€€€€€^_#
+R}vƾ€@o€rR€_€e)€~€€€€€€O.€s€҇>om€y J€€BU€€iQ€<€t€q2B'€€€€[I6E€€]€€ €€˰U€€wgP䙈€€B}€p€!c,€€J€€€€€€€€
+€i€O€€€ŴE=€€€€yDQ€€oH€gФ€=~€
+_R €!ᗦ€R_€y€(€$€€€+€R%'g[€€€".XQ€K5&€€A€6€€€€€€V€€€Ev€{;/€€€€€gW€ €%Gr€€o\mK€Ќ€€€RԿ€>~€€€€€`€€7€z€€@€€f€€z€€/GR€€€€磨
+m-€€€xbq€ղ€,e€€€z€€€٠jl€P€WK_€€€=_-€€€(€€CZf €€€€€€Ÿ€€u€Tm€u€€€>€d)vp€€-PK€ëz€a€w€p€€€"\€€€CP€€Q:d€€€€€\€€€€iH€c<€€€€€
+O>^€Ú€4|0€€Ç€5c€€€€)œ€4€I€€€N€P€VI䤉Ģ€€\€R€n€€€€]€€€€€ܕ:c.€)€=j€2D€oX€€l]J#sj1^b€€€R€€€€Z€ €G€€wM€€€€€@ꔂqY€p€€€€o€Êa€€N"€a.a€€€b)€€ƌ ,€€€k€#3Ë›o*€!€8€€€c€€€€€webheadebc.listc€€N€€€€TEXTMPS €m5!€m5! €€@*Example. @c WebMakefilelistc€€€€€€€€€TEXTMPS €G*€€€Ey€2€q€€€€€€€vbl€ϡ05^€€€Ao€)F[o€€€€€ €€#€€%€ €A€tp€(€€a€€€€€ @€ڎ€€€S€€€7Ck€€€gEqÝ™|q€Ĉ€€€l€€€|m€€1€Ý€c-€€€~<€€s% II€
+Ó¸iTP€>'&€f€(€€€fr%_€,€dPg%h^?g$€Cf&O€I3}q€q€€~ge€0€9!jCt€'4€€€€M^p€_€€€A€€)€€€€V6*w€3€:8WrĘ)J€€€€- €,e NW€x€ `~+yJl=€€Ȁ€€€pz>€€G_F€€J8€p
+€€z[}W€€€€|€+#h€L€\ €o€ €€€Ox€€p2€€SB€€Z€€€€ €€€€O€}B€%] €€€,V|€€z€€€€€€L€€*%€€i€€^€€€F€R€€4€d€2O€\(€H$€€€t,$€0Q€t(€G€8€Iqj€^€€?€|<€€ӜI€h€€€ZHh€€€€€M€kzÉ¥?]2€€€)€€\2?€€€&x
+€C€€:€€€€y€€ywxz€€€{€Y2€€\wO_vO€€€€€€y€€?aɲ€€€€K€€u^€€j€€€€u€]€#e€Vx€L€\€€€€€€€)€€?T€€&:€€͡€;€c€ZbK€P€€hm
+€€77Q€j€€€€€€!5|:€QC-c:€%€)€€€€€&Lz풽€€H€#3€ 5€4€Bј:ݳ€€€€€$€€ND€E€L€*€<€p€€ dA_€T"€J€(€€€€€€Y€€€€\Fa€€€€<€qn l€€€€U€€I
+€IL€X€€€€€TZ€€Ԫ€tÓ€€€>€LB€€_€€H €€9€€p?€l€€€€.O€€€€€yU-È¿d€€E*b 6€`0D1€2K€1S€ay €{.}˺€€€u€€€€€b€*s €€€c€p€€S€'[N€~;€€vVW€{€€y.€k€€€msU€€€€2V€€€€€./{W€€€€€Y€€€`b€t €€b2€vacNG9€d˸€€€€v]иFm€u€€0€y@a€$3$€9Æ’1€R€|€.€e€€€2€€M-€€vff€YS*€{€N:€B€€€{Z€€Y€€€€€ja2€U€€h`h;€€m€€€€€€€€S€€Q%€€[€mr$€ @]w€€ʹ€μ€€€"€€€€f-?€€LÈ8K€€€%j€ʫ€€€€A€+jLȖ»9v€€ -8É‘v€6€€€A€k€Ӧ€o€*€E$)€€€7i
+M€2Q-€€A€€€€U<`€€X€^€_f€€€i€Y€€+FJ={]€€4QBj€€€f€h*Y3i€€Tk1S€M€€€€€^€€€y€€Yg€HL€ €€͗€€€€j4€)€LR€€[<.f.€D[!E:{5€s3x€€€X Y€€<€:€L<€P€€€€8y <Lޢ!€€;.€€ y/Ÿ2€"€U€%S{NGiZ9QJE€2€$z€.€€€UQ €€€0€€UwF€inI€€€^Ǚf€€|€GidVs€€U€€&T€*[€€€,mAUo€€€€
+€€ m+iWG€€€Ø€€gJ€€^€&€%€€€[€€€€Q€?h€€€(€€:>G€€€€€–RWi€+€i*€€€€€€€&€.af€€€q€[\€x€€€MA€Ղu7€i€€`€r?€€€€€€yC€€€/1*q#j€.€€_€€€(€€€;$€
+€b€K€(\€€€_€€€_€r€}€€a€€€€ܧ€y€€BP€€>(K€8€̳€.€>0€ €€€ $€2€€€-n/€€Ih~qf€@$€€€€C€f€€€2€€€€.t8€ܳ€)SlQ€ii€€T€€r€l€€U€€€K€0€€€€<€€€€€€A€€€%eS€€€x€o׃€€€f€s€€€-€?ׅ€ia€=WAv€€€U€€
+€p€€€!€l€7 ヿ€E€€M€€8\€戱wÇ‹"?nlQo€$€豃<@PO#€€€u€S€€€€g€$€1N€t€€€€7З€Q€€€€?f€€€€7€ €c~*€_:€€c"€k€€ t€<€€€ €
+€
+€+g:€@]€Z€€€€L€€ WebMakefile.unix€€€^€€TEXTMPS €m5%€m5%U €€€q NW€x€ `v+#G[#Ô‹p€€`€€€€€€=€I[€'?J8€O6X=€S&€€€GMr€l€~€Օ€€€€€6€€7yN8l€ 61€)Yh€€€Tk€€€€€€€€€4_€;cK€€B€N€h€€€B:)l€Ӊs&U€K7J€434€T;€€€X€€€€€qґ€Ś€~€4V€€ *€WF€€€€€4€€€€€€€€€€sI€€R{ʔ€€7€€€€€€a}€m€€€€€\\KÒ†
+€€҂8€VyGR€(kt€€7º$€€€€N޽€qr€€^€W€€€'€+)ndr€€€trq,€z€*€I€€€ӟώ€€€€€€€€€€€t€€€74\€€€rv2K`€€€O€_€OH9€€€€\€€€Ox€˲€Þ3Å€€Z3/dIfAe]xU€€>€U€€€€*€€€€€v0":€T€€L=€L€c€w€ €ia%€R€€€€G$€€€H€ʴ€€CHo€-€W€€€€€€€€U€ 0xd):B~]!€0`AkS€JE ;€tr€€€€k€€€ܔf)€€€09€€ €h€€A€€€\>€€#€€ €€N;€<0I€T5Cʳ!€G€K€x€€€€€€=Ǿ€€ K+JT€€€€€:€€鄀L€Ԫ9€¼imCߴ€A€€c\J€€h€€€!_€)P€ybWa`f€€A.€€€Ռ€#3€L)7"€€N!€€|€€€{S€L€9€v€'€€€sd€€€d€€€&@€€B-€h€€7 Sfm€(€M€rI€*€0€r}"|E€9$€€M€QU€T€€A€€€++o€€$o€*X€€€k€)€€€€t€€$.€€€€€€€€€Õ€:€€ -n€ €X.€€€)€q€€€€€€eG>W€€€€€€A€€"€G€ByEۻ€s€4€€€€bz€*€€€€€5€€.€ €p€€€ €€€€€€€Q€6€Ƨδf€$€קg€€w€qK€€ћ€€€€€€€€x3R€€fI€€€€€€q0€ s€=€€S€-V×€€€€€€€€?r&€U€€€€€P€€€€M%€i€[C€tHË—6|€%€€܃-SY#€€€€OS€O€€~)y€5€€0€;-A\_m` $€€€€€U€€€i€z@€€Ð}€Z€h€€00€K€C€€€€Mc€€€ {€€au[ќ€6L€€6s4€2A€€ €)-€Y€€ZПi€€+9€€F€_€"€€Ū€€€CД€€#mS~\j€: 1€8 €P€€"5€ZIohKV€8€€6€€7€€@€€q€l€R€yk€9€€€€ձ?€5֙ǽaT`#`v€€6H3€€€څ7,(Qŧ€=]€ x€€3V€+€r+€€€-Æ—I€€€4K|q€€€?€€€€
+€ҳ€€[€h€ܬ€qT€€M>}€X$€€€€Æ°i}>m€q€qvC€t5€€€X€€"€€mY€jW€€€W€l€€-€€c€€€€€Z€€D^€€U€w[€€q€$€?NoGË€€ۛ€W€€ €€€YKCM+€€X€;€B€€€€}€€€q€Ù€I1€׬z€v.€!9`_€€€j€<€%wO€€
+€om€€€€4/MF€Ճ€€`w€f:}€1B~€€€{k`K€ٹNNǰ€jK€5)F/€€{€57$€֚€a€ij%€8€1€I€€€€k€€€€}€EQ(€x€ɠ€9}€€€w€€< ; €5€a>€€€C€€]€€€:€€€€€k€v€nz€€ €€t€€a;€€K€m€m€d5vXЅ€€GZ€€b€ʠ€+4c8Co.€€'€€hP€<€]€ €%€A5o€ _/qִ€v€€€I€.€€€c€c€€€€!_k €€€c€NQ€诋@€?€€xV;€1-ü€+UU4<€€p€-0&j€U€€C€€€€m€€€€€€€€s€€€#:€%3^Z€o r€€€€`€2€h4j€GÔž€#€_һ€€€€€€€€€ u€\€۱€€ €(€(jÅ®}€€qH€p"€€€webtailfile.unix_b€€€€€€TEXTMPS €m5"€m5" €P€€@*Index. !! SpiderWEB €ourcG€
+€^€€€€€Q€€Q€+ճ€ penelope.unixA€€€$€€€€€€€€€€€€€€€0#€ a.spider.unixnix€€€G(€GTEXTMPS €m5€m5,€ €(?j €O€€€€G€[€€€E€€>€€€fI€€?€E€€M€€V€€€€F€z€€>A?b€€€A€+€€€N€€€d€€€€€&cN€Jn€€€;€H€€$ 3€€€g€€€X|€€€€ĉ€j€-€€€)ĉJ€L€€8LS€2S€€?h€S"O€/€:IA€I€S€
+€c€€€€N€"€€d€h[€J€~*q€€€€?y€€€€€P€X&*Ê„$€€t2vB r9P€ЗB€€T€B€€€t€€€€ €r€€€s€€U?€)€l€€A€€€€€ш€€€R€|€€€'€€€€€|€€0€€3€^€SC€€€€ZvF\^€Y&€]q}]0€€q€z!o€`F€€€Æ€@€€€Ld€€Ò!€€O€JS1FÂœL€€H>T€@%€C€H€Td#9€)€€€ޚ€dY€sE€37j3X€@€ €
+€€'i€iq€€3q@p8€€€€X€q€r_€€j4RK<7v€€Pe€P€€f€#€Ra0
+2€&€€€ "€do€€ň€!۪€t€w {P€€c€€=€k€€€€`y€€ t€€ۮ€€€€q€€€€€€€s+€€[€€F€€}1O€̑/6€ddS€{€€oau€'€€€€>F&€€H€b€cv€U€ ͵:€$€€€qxR|€€LK€s€€s]€=l"^€qc€€<L0 /€Wr>€oi€€€[€ €'+€€€7k€€ٔ€€_({*,€8Xx15€€€€#€9€4 YG|-€€€և€m!€lР€€€€Q€s€-€€6S€U€€Йo?€€+v€€v€€L€5
+€.i€ï€€€€€|€sÚ€s,ʲ€€L€S€€€€€€S€b€€ €€Tl€€D{K4Ŀ€€+("GP€o€I"€+Z€v€€l€€€€€€"Ob€",=4X€€D$€€}€€80€€Zx€v€L€€€ €V€€5#€t€S€€€Ø _€€~€€i€€€aBÝ¥_€€€@€€€_€€`€ۼ€€€W€Z€€H%€€p€5h€{€€2€€€~;:€M€€€$ڼ€
+h€B€€€PcO ,=̱8€q€ԋccS€€€€€M€€€:€€W€o€&€:ip€€%€)€€U€€€€€€€.€q"€€싓€€[r~k€€€€ޥ€Dv.€aC€€܀€&&€€€ÅV€€€P€€€€€€€4€€€€€€l€8I€€bR€46Ҽ€€€€€L€q€y€€c€}€€€!Ò¹Xzh€€€€Bz€($€C€€€€kb:21€ؗv€€€u&[h{€n<8€՛€=Q€<UJ€T€ €€j€€TQ qiM€€G€€€€€=rMWÙµMD€\€€€€'€€2€€€-s€€(
+.€u€! €€€C€€c€€€y/€XR€€X?€m€L&€`€€€€€<t€)€;€Y€€kV€`€rڭ€€€€€6€f€ €LV€5€e€€vA€€N€€€KÔšÍ0€twY34€Y€k>€`€rgn€€j€[A[_€=€€~€XN€Ҭ#€€+€q€€€}€€€+€€€€€€€G>O€€€€[\€por€€Q€€€€€\€Q€€.Ý ?€C€€P€d€͈€g€€Ҽ€aL]€€€€€ٵQ€͓K>V#€€{€€€z-L€€ɾ€z €;€tÚ¸p€€͔Rx|t€?€\€d€€€EÕ’n€@€€€ȸa€€f €+v2€€;€€$€€ €m€€`€C€€€@€2€€,€€€&€=0V€€€÷€z€€€ €€c€,7€€FwK€€AHc€EM€|€W€w€€BM€€€ ٜ€€\€€t0/€ז€g€€_€€T€€€]€&€€ç€€\€€€܌€€>€€W€T€€T€y€€~€u€g€€.€R€€€W^€f{ä¿}€s>Po€ީm€N€€€€_€€€9 €€j€€€YM€€ gi€€€{€€e€>€I€€t9r&€€J{€€€€€€n€€U€€?0€€€L€rN€UÒ€V€€u€Ku%_€4€̄€€ǥ€j€€-髳€ST€€[ €€€€JyN9€€a€_€iTig~€€€€€72nI€E€€€€€€>€X€€l,€6f,€갩:€€4s€€ǘ€`3>7P^€€€%€€€}€€C#€ Ҵ€*9€€X€€€A€y€€qy;€€x€F€€€€€€€€€€N€€€€ls0€€€ Ao2R^I*U€i6Mc€#€€ €€J|€D€€€€ߖ€/€@€mfͬ€v€€€ €€€€€€"^€{€€mV€€q€R,€w€€€ݗ€!;€t4]€€k€€€€!€€€}€€}€€€aI€ €€
+>)€Uκ€€€€€€ €r€m€€'€€R€uR-(€붳€€3€€P€€€€€W€eÓ˜6€€€€"C~€.?€*@X€€o€€€i€€€€z€4€ €€€#_ /[€€ξ€qݒ€=€J€+:€€$I€€€)a€€€€}#€€€€€;€€€€€€t]E€€:€M€€€<€9l3sɞ€€Ǫ"f€€7X€V€b€€W€̾0kK€bWm`q€m€€€1L€€€€€€1€.€Ó4€ROF€€\Mw€€(€€i€€P€ €€€€\€€M€€€€€€ "€oi`€€ϒ€€€ €€ [€}v€f+E€4)JÍ4O1Ó¨|€€€)€€€K€€}€€tTH:€€<L,"€Kr€€|[r€€8€€l€€ €€€€A€€€87€A-€Y€€€b€€€_F€€Fq€€|€€W)€a€kÌ›t€€€€€լz>5*k€€#)€€€b|ff€u€€OÉ•€ޒ-KtUI7'f€+€€€!€̾y€€7ItZ;0
+€+A €^€€߶K(€€U€35€€[€€€€c,€n€k4€€(€&0€Z#€DY|ĥ€€€€jud€l€<'W_,€>1€\€€€€Q€€
+srj0r€O=€€C€€ 簾€€&€AF€€L€€€€[€ €W€€?€€զq€F€M€M|v-€€€{G€-€c€ €€€/9€+€€Z{€€j€d€€U€3€€(ta€€€€€K\ €€E0 €€€€n€€t=Ap€(jZ€'€€7€Z€€>`p'€€n€€
+€
+U?k€€€€€€Ƕ€€€u€!€q€€€~€^€"D€€9€5€€>€`€€€€€={74€€w>€€€\ں9ogA\€€€\€{€x)*@0€€€Y€€v]€(€€€C<]€.€]|€€N-X€€ a€bD€€€€9€€€€€<€S€_0€€€€o€^b'€€€ |T€f€B€cx€€=v€2+€€}:҆€=SIdi€€€x€Ԝ€M€x€Gd€D€€e€€€€=€,€1p߆€€'}ڹ€w?€€&€d€€lD€X:L € €€:€-€€€€K€ r€€$W€:€€0qͣ![Kٺ€H$*€€€€
+"€'€ €€'u€€ makeider.unixnix€u€€€GTEXTMPS €m5€m5€€€€€€Q€j*€€!€'€y€€pG€a€;€€
+A€€~
+'€€7€;9€€€>€A€/€y€€€1€>€€€ɴ€€€}€€ty\O&'€}H€ɗ€€|C\m€.€€€€€€€ucw(€€0sj€ủL|€€€9€€€€€Ht nesting.spiderix!€(€€GTEXTMPS €m5€m5€E€j€
+€€ €<€#€^€€€€ (9JVrt@€EV€€%€€€€^€€4`k€€Q€~€z€K %€P€&9J€Q2€dDɀ€€G(9JVB{€€\€&€€€x€€8l€€b_h€€.€b €a€t@€€€Lp,€€€€€e€ S€!F€€€7€€€l€€zNR€`O06€:€5F&'4€€€€ӳn€#LN{€C€i€G€€€p[€+ll€€F€l€E€€z€€
+d€U€€€0€€€€€_€ܶ€f[€€k€J€l1,I0v€Ha[€k€€T€€2u',€iW€i€€€€jN€€/I€€€€€€~<O€O€^5€€Fܢ€€€€€O€7€G€€€€€ processed-a.spider€€€€GTEXTMPS €m5€m5;Q IC€Qc €O€€€€€u€?€€€>€€€f€€-€Oh€}d€g€r|€€€€€€€z€€'€G,P€5€=j)[/€€-€I€€€[€€ߒ€€M€<€+€U€I/@G€€€4€€€€€€€{€€ީ€XE#'€€(€€€€€4€€/c€D€C€Ǫ€9€€€€€L€€i,]1P€€2€0€B€X€€?€€€H
+/€€I<€€XJ1€|)v?€€€€€€€3€Er(E€D2H€€E€€€€€€€`€:C)v\G€g€ bH€€X€€€€0€€€€rS€q€€ <)€d€€A€-€€F#R֓CH€t€€€€€€€€m!W€€€i€€~€bMe€€dvF€€€I"€]qq€1€ܲ€€R€
+€V€€͕€m˂'€€DN€€€yw€}
+d€S$€Jԑ €€B€7€d$€H€€`€€l€€€€a €Qo€D€ €€€
+€€€€O €i€Lc€€€H€8QÑ‘8€ €€tLd€€0€€€b9€j€€ €;Í¢/{ߎ€€<g€#>€€7€e&€€€€Nd€ض3
+GM€V€€€ €N€€k€€T€€€€€€€€*€€+7€m{}€€¤€nfIw)f€Z€€װ€t€€€4yG~€€'#€r;#ݼָu +€]€€€Ds€€€€]5
+U€€€€€4€€€(R'€€€€<€uf€€€€€€€€n€,j€/€€€€€V!Â€í­†Â€€€€}I€pA€yI€ђl€€l€F€€wz€Ͻؾ€bl€€1%Fz#rL€€€€€€?€i}X]"€z4€€8`t€9€-1€VkS€U€€Йn?€€+f€€v€€€€€
+v€h€€/€㦫€t€€,Ú€c,€NOE€€€#€<€€#Y€c€bÖ‡5€ߗ€&#՟€!€€,€_@9€€€€"€tA€€€€=€€͗€€€F+w€€€`€",}€€*€€€s€€€€d€p€€€€€€'€€ €d+W1ҋ€8€+€€%€d`oP€M€€A&€P€€€g4h€0€€€-€Cw€€4€€€f€€2€€€g8€€h€{€\€I@c€€€[€uM€D€K€€€L€€€'€>L€8€q5Ó‹ccc€€€€€t€f€:H€Wi€€€:€*€q€€E€)€€E€€€€€l€0r€€€€ #€€r€€0€€tS3xg#€3€p€€€€
+€0€€ԟ€h[€ZÒ’4҃€9€Y[€€-'€ł€M€/€F€€€€p€0qb€€€<€€1€>l€]€Ò¹X€PcoDÓ…t=€$чK€€€tdb|€b€€QW€ת€€€,Z€xp€+7€€€y€€N€€^@gՒ€€/j€ܚf€ώbw€€€€€5^e€6s€{€€Oz€e<3€[€R%Qd\f€zI€ 4€m€€€€€€y#+[R€.[o€6[&€€Zg|€6€%€i€€s€€ᒕ(€+€vK.€`.€€-€T€<Պ€$3,€€,_€)€€r€Z€i€€.Kƌ€9€€c€G̕€€u€€OTb€h€€€w€€G.€€€+€€1€ȸ"€
+i€€€F (p0€{oW€$X€€€€y€€€€*€€b€{€€€€€€€ꬎ€€{f{€.€€€€€܌€{€€€€€€€€3€_h=<€c5€€y€€F€€€=ܲQ€A{€€€€5€€R
+€v/€€€m€€tq^€€Z€€n €€ €GNX3€ €e;€€Ä€V€Ln€€€&hS0€!NRD €7L€a€p€€uw€U€€h€€€@€93A`€€€€M&€€€.aRcPc%€€€5'€PU€^€]€M€€€eCM€|{m€[€€€€oU€€z€j}€€T<€ €€€€€€€§€7J€€R|K€€wk€+€k?s€€È–z€k_yy€€€€€€€€€@€&z€€ :€€V€€€€€k€€T€€Ak€qFn"€Y\€€€€ja€O&i=€€€
+€4Wi€`_€hX5€<€W€;€"€€2Õ‚?AN€€r€€(€€T`€€€*€€p€€€q)€€€€E€€€1F€&F€€€z€y€Rބ€SNx€0€€€4 *€€?xY€>﵌k€1E€=€€7?€O9f{A=€€€€€:lÊ€?€€€€1€8€L€O4€€l€p€gYz€€€€HC€€m€B€€€-N€€€€€Yղ€€€€t €Z#€ū€})€Ҁj=€ x€@€€l€€€`€&€eF€+I€
+ "€€€m€zÄ¥)z€ϴ€0Rih=€o3€€u €6€f€p=€€€€€€€€€O"^€{€€MV€€q€R\€€€/€€€!;€€h€€a€r€€€€p7 €€€€€Ow€€€€PS€€BqS€,+€€nY€>€€$€€€€€€>/u\€jAF_€€€€1€€€€Ϳ€?€ɛƴ!€€'€€€'t€€€a€ǿaz€CD<Zד€!€€6€ y€HGu€€€€€ €€F_€€$€€W't€€€*€o€=\o€€€€€`+€e=€)€€€€ 4AJ~€i€a€€3€8€#€€€€€^aQ€[€€€wSm€€¤-€€]€€M€5€€€O€0E€3< b€€€1€N<€€€€€€€NpP€€x€9AE€;#€€}€$€€ .>€||€€€:€`€^C€€6[z€€€5€€€€€€€pj€bTKc€4€€€\€€3€ʗ€€€R;€€€€O7€€
+I€Z€€€€€€\€€€5 wl€թ€€ޡt8i€€i€>€djS€
+€€u€)7yã N€JA€€)"€€Z€€k
+#€€rGy"€Z €€W2€8J€€r€€€€€7g€F@€€y€€€K*€€╶€€€€_~€€m@v€€W€€o-0€p€€?:€~`M€€{m€(€U€€~€€km €>€€f€€=€J€M€€Pڛ€+€€€€€k€ji0?(€Ö%€€ڪ€€K€€€€€€-] €€j€€'o€€#Պ€€U€Ek€€v×– ^€€=€€6€€Zx€{€€PA€rm€J€€€~€/€m€[€€
+€€.€F;€--€€€v€X[€u€ €.€9w€€%€b€€€€€€€€€€€LG€a€€€Hrr€€E€)W€€€O€}L]€€ €€>%@€€€€Y(>h€%€‘/€q€ϓNn€ƕ?>"W€€€-Y3D€€t€q6€̙+€H€€9yY€;ᬦ€DC€a€€€ͻ €€b[)-€€€>€n€€€€k€€€\€Ӆ২€U€€ '{E€€€€k€:2{RwxB€VS0 Te€€09%€€⑬*W(j€ F€€֠€€x€ €}Ì€n€|z #€oq€€\ɋ€€€€q€€€€#€€Okp€7€>€wQn€€G€€€v€€<€€[€€L5€€€) €_y€€€/€`€€€€€€€FO€ #€€<€€?€€€Z\€N€€€€€€Bs€€d\PӸ€€-€€| q€r€€Ø€€€€=€2 ,€c€
+B-€€g€ *€Dh>{€€€Go@/€€*W€w׃€€ݡ€€€€޻€gS€€€v€€%Y€K]xd€r2 cL:€:€€l€ΒY€e€€€€û€?€J1€⽳L€€€e€€$hS€€c€€€€P€aL€ €R€>q€€3le€y€€€/e€Z!G€€€€€\€€"€P&"€x€€E€€)€#€€€€H€€€€=€€}2€R9€"€6€€€€$*€n€€€€J_[€€€€$€d€€LD€€€t€TrGæ•Â€4C]5p€ ~G€(€x€€*'€€k€€€€€PD"€!
+\O!/€}b€3s€{8€ scan_annotations.awkne€€GTEXTMPS €m5€m5€€9
+NW€x€ €€ȯ€$€ad€~}r€€€z€€€€€P€€|€$k€#€է€A€P€€ ؓ#€LA{2[ €<€€€2x€€J€᷄€d€€!7€Xr€ʹ€€€x€€ы€n€.J€€€̻€€B€€jO€i7€w
+q€F)€€z€Tx€+€ 8€|M;%5€a>€€(U€1€Ks
+€v1€]€€p9€€\XG€L€€€€€f]Gb€`€€;€€m€"€.€€6*€€"€€€=F€S€€3€!€8€5€+-J"€"5€tOv€€€Kt€€<"€€a^€S€)€OuÏšD€€P̧6 n€LÞ­^€q@€*A7€€€€€i€Pj€ i€<erk€"=ŘN€-3€€\€PJ€€€€€€€2=€B€ €€/q€_kjt/€kc1€<}€€9€apu€[8€€B€ѦD\€€€€€€H€G€€€7€K€€€=€€'1d€g€CAM_€)d€€€ٱ{€€aU€€z€M€€U€J€€€€€€€z€€€ѯxHv€׮'Kم€€€|€€~€€€Psթ€€M€7€s€€€c€j€&€€€€tAË¿GM0€€€v€€€מ6€w€ SpiderMakefilens.awkZ€€€GTEXTMPS €m5€m5€uzl€ Q€€ €€€E€€ €}^€;9€€€>$€€ܑ€ɧ€]€@€€€r€B€€€€€€h@€D^@€€. M€€\€€x€,€€€ڰ€€CÚ¤Z€ €€€C€€$€€€ €€€€€0€|^€€1X€p?
+stacks.webfilens.awkĪ$j€GTEXTMPS €m5€m51R€Z€ N)y<A'LN€€€'€8€M€ZY€6%l€€,€=€%€WN€X `}€€€8ގ€VN€€€€@}€€M:?€4€€€€'€€h€€6#€€€€€;6€€€9€€€€2In€(€€€€w€€€p4N€€€n€砛€lP€qV€fs€€w€z€D€(€y€&€ls3€€Q2)r€€€7€a€>€€€L€€m€Y€€€A€€€[7>:<€V€€(7cuc €zh€€€€€;€€€€€Y€€€€.€€€6€`B_€€h€€l€€YG€€€€€Ml7€€€\gY:€(€€€€€€I€€P=€u€D}€€€Q€~€€<€€V€Uy€€€$6c\€€tҧ€I€(`€€t€)ey€€|€DNj€€€f€ €€€p€€LG€€€€q"o€€€Ԩ€~€-€€€€€*€j'&€3€Y}€€€€ n@€€€L€9€€N@€€€I€Qdf€ €€*J@&€€€€O%€€,T€€€!o €f€.x€F€rÅ‹90Ý¿jk€I€3€F€€€€€€€€€ɀ~€€:€_+TX€^"€M€€€i€Jy:€ €€€z€J3`€€X€€؟€ue€€€<K€Ehj€+BXa€9€K€€`N€6€@M3€s€ͼw€€€8€€€€+€lW€€€€6È™C(Y€€€€K€tZ]S€B=€S€3€еB0€F€Q€4ʽ€,.€€€€€]€vÙ¨])f5€€€ c" €ϰ)4€€15€€€€asf7€n€€€€€€€€€mE€€ئ5€F€€€@€R4Q€,:€{P€l€,k﫽€O€S€HP€M€hڋ€!€€B&4€€0:0€€€¢,e€€ͩ€€€uhC€€ €€-€€pT€7€€€€W€€€XRt9€€€€€Ԡ€!€€i€LҤ€€#€€€€,€€€€ J0€€€Mfp€6€€€$€pF€€€€0€12€€€€€€w1,€€€{R€€€€X€€W€e/Mc€€i7€€ €€€€€p€ €€v€€F€*5s v€€€I€€h[%:/2€€€€€€ܩ<€>
+V€€K€€€a€€`€€_€j€€€8\ĺ*`€€€6€Kh&€€€Q€€(cÆ“|€XN€€(€ӫ€€€€r€€€€€x€€€€€_7)€(€€€€߷€€€€€€€€€}tÑš]7€€NÞ #€Ou€sv€€f[€€€\ڠ€€tRc€o€€ €B€"€1\ÐŽ_€ʟ#u€R€a€;€M€U€Sd€€ܜ"€DyÇ©#Cğ€|d€N18<8'€|€-z€v>€€€€BA€.€€f€€€@m€-A€ي(H€h+XkNi€Y€j!€<!€#X€+7€€ܽ€€ޞ_I€€€W€€€€G€ €€€|€T€€^f4<EP€a€-€€D&€k€7€7 a€€€ €€{ €k€Z€€@€€Db 5€€€|f5w€ë‘$€ €€U€I€:˸€)r€-€€€€€?€~€€]€€En€ €]P€tί€€€dpyd T€
+q"€€`€€€x€x€€€€t€€€ v€€€U€CN€€[€€rW€€€€{€Y& €€i€€.€€€R€€ec€€€-b€^- €r€M€€y'€€a€^€r€€!€€0M€€€#€€€a4r€€S€€€[m€.€U€A€€€EezF1€1€€A€D
+Wq€€€€€=€€y}€€€W€€qIE%€€Q€X€€lk€€€ 4€€0€'€€@€€"€t€&k€ܔsc,p&€S"€€D €z)€To€€€ €€€ €€€€(€€€€€€€€Xdi1€€,i€y€I#€-€€9}€i€€QK€€€€€€xYe€,^X€H€€€̀ӟ)@€i€ 'VB€€<€€€n
+O€y7֗€w6M€o'A€€*耶0€K€€K€B€X€.€€€\€Q€ؽ€ 66€k€Lg]ydl€€ؼo€€€€€t€€€€OQ€Q€Tx€~D€€ €€
+€€Ox€9* €€H€€€!€€8Ta€€q€/€€€€€€€C€€L€\y€€€8€;wâ­/[붭€p[€5?€\€@€€€~W=l
+K€EVÆ€€€?ȉ€7&K€€€9€Ne/_€p€lwD€€€3?'€'€€|pA€V€€€N€@Q%€€€€€€g€Q€€€le€€€GN4,î¯Â€Â€Â€Â€g€€€€7$ %fK€€€l€€{€€€€]9€€€€A€ S€€€ €€€€€r€*zTd€ڼ€@€GJ u !b€€(Û]€€I€e€€<:€_c8€i v€XÍ°€!€€€,€€€l€€€€N€€,WA€=€:€€m€s€zJ€,€LEN€€eq€J€'€_€&G€€€€}€|€€€&v€엖€€7"€€YO€€\n>St(K€dV€!€r€ 0!€€€€"€€€€€^€UÈ‘-€~K6pMȳ€f€`€€&€hCC}€€€€€GtIW€|S>?€€€[#;€€#*u€€eH€€€€€G€͵€ή€€3€€€€qR,€€l€€€€/3€€€€€€j€R€€€€3 € €"F€]€€~Rq€pl€€kTdۓA€€&€j|€€€€:€€€€€€JY€sf4ACw€€8€€c€T],€€FÖewA€€R€S€qa€€.€€)-Sz1€€m-l€H€€_€€k€€€꬚W€E"€Z€F€ €€t€c(<Uq"ȽDR€nb-IP€RcW€ѕ€s€3€€€.)€ t€€jUQ l€ €)€^€€z€V€ٰ%€g€/LI€r€€b€U1€€p€ "€€€\9/€€,_sX D€€?€4A3'€"€€€€€€kq€s€|€€€{_€€€€€+€€€?€€W(~C€6€€€€€€€xnQÎ~{€€'€v€€:"€9€€€€€7)W€€€€€€^€€2€€[\€\KP€y€+O&CÊ€4)e €€€€€!€%€k€U€K€€€€€€z€€W€E€d€,-€€1y€(yBuD]Q€i H€?F I€€€D€€€D€€N€M_€a€8€€)o€€݃^€€€€b€€€€ R€€N!J€ji€€oG€€0d{€!€[>€N€€8€f/€"€Ób€JyC€~€€€׆€l>€7€€€DD€€€€€K 8€€I€€J€€€_€E= €s€€])€€€9€7€1j€€5€5n€[€€€x€€e€€( €€€€€A€€€jd3_€RA[€]€€€j€€€N y€Z€€ €-€YP€€OZX€€€€K@y€€€€€€9€8X€%€€€€0#zU€þ€8€€€€€€ϰ€€XO-€1€€Q€hIh€q€[J*HX€_€qo€AE@€€€)€€_{€8€€€ca€€€'!)€€€€€|€I€€y}€€Xƅ€}€€€}€€ €5€€N~€E€€€$€€s€€B€€ކ€Lj€€€vj€€€€€€xGb€O#€2Ge€E€AZ,\€€€ €3uO.2e€€€>€fK€€)€ >€84€j9Ac €€v€0€-€€€ €€!T€dau€€€,€HN€9€1Q€€/=€60י€p`€€ڑ€€€€t6€€+€€*T€#- €€s(MU€3D€ €€€€`€.,€€€g€€€)€e€~Y€W€T€€€^€Btv)€)P/€W8D€ؚ€€d€3 €"€€)€€˟€€K,J€€ra€Y٪€€€t)j€€€€€.€,€ۇ[?€:x€1c€€3=]JP€{€@€G€s^?€P!€€€* € -%€€9€KS.€€O€€€€€xLg @€֗€€€€€8 z1@>A€}X€*1€€€€€€#TQ%u€N€€€€~€€߮z€/€€=€_XP€€€"Z€|€ <€€€€P€Y€r€€ʜ,!€€yp€€<€p€ (ÅW€€VA€b€y^€€€4=€Ï€€€z0ɸ€€€€€ВG €€I€0€€€€Ҽ&qʬ3n€€^2\€Sg€€€€€€=O!2€€#Ov€~€€€ъS€€`€€J€aYa
+Ҍ€€Cu€Wm€€€€yW€L€€€€€€€lu€€8a/€€€€€S€0[€㩨Q€.€-€€Du^€€€N €€€'-€-€€`e€€1€>€€€€€ml€€€€^_€8€€€€€
+€ z€€€€/W!€€ÜPP€€?€)pq€€€R!€€€SnqJ~€<€ν €<,€€1.D€s€)€€0€c€€>[€€z€,€nf€
+€€€€8€€h€!! SpiderWEB €ourcG€
+€€G€€€Q€€Q6-f€b README.webfilens.awk€€G-€€€€€€TEXTMPS €m5€€B€€€Uӗ€€yG€vbU€($€#€€€dD€€4=€nG€€H€OήI €€€€<€€PRÏ?€€€X:l€€#€€ޗQ/@€C€€G€€€8€DIJD€tH
+€an€€UiB€€&+€€| e€eK$Sr1€€€d€ €>Y€€U€}€l€€:E€€V€€LjÖ®W€J€€€ €€€€g€€i€€m4€e€*[me€u:€€€€sFR€>0€€€€,Ì—9€€€`€€€€,>€#€€L蛟€€€€ֵA€€€np€h€\M€ c€̹~€т€€€R NW€€€7€5 [€OOÛ”Fn€€͢€]z€>€mɈ€€€€€ym€€~€€€h€€€€€€€>r[€€€€OÏ·n€hc€€€€DM€Qd}€€9€€lm€@€߬€.64€€v€gjC4X€ €€€OJ€C€i€€L€€$€vPn ա€ԯkM€C€dRg* €€€ߜ^_\€^\~X€'€PB>@P€€€kg+ll€€ߋN쌫BkØ»>€€LpFm€1€@€$€c€`}€B2€€w,€#€€€€dmLKX€B%€€W?__€€€v€€€€€l+€€]€€€4€-€€€€€)€€€€€€€€`Æ®//Y€€ €}Ö±Ʀíº—p€€q T€€€=€€€€ %€bg€+L,€z€€€€~+€`5€N€€/ $€k25;`€?€;΀€€€s€1{[&€€~€~€€€€526€€€ €€y€`€>€€3i€€Ǔ€€˛_€{€€€ l€bH€€€t€9s€f€3€€S€]€€;€GB€ء2.€jV$€#v}€€€€(€€qP€€€€B€+€c€ ;€€{€€€r1€1N€/X€€I~€€€€BU€€€€b€F€.€(€o€@Sj€sl@€€혡€€7€€€Y_€+€€€ O€%€€m€N €€L€s€€t€@€€€]€€>r€N€€;#€ABe€€^e€e €€>XL€€€€€€€€€m€€€~€'€>€€€ €u€€€€€|:S€€ݕ€€€Z'€5`z€m)€m€€8€Z0€>q€f>€e)^h€d€Sa"€QV1M€€S€€€Vl
+€€`€€€/LAՒ€€p;€p9€N€ >%`€€k:X€o€i1'€€/,{x€€€X̡€€B€€€€€1€€S€€€G€€€A€PԮѼ
+V€)f,€L,g€r€z€€h€€€€F€€"L{L€'Èœ>€$,s3€€€€E€3€€€€€#€p€€€€€€€€%m€FA€TA8€%€€uy.€/€qq€M€+€L€€}5챃€=€%E(F<qm€€SQ :-€h-€#I€€€o€€€15G-€€€€€€61€6\€ {^€@cJx*€Io€T+g€€OjÅ­h€€€€U5iM-€€€€S€Z€;IO2n~€ĺ€{*\€.€YoѢ€a€€€€A1€h€€9€€V€€€~€€€%@:€€€€€€yU€€€€€\\€€€€€8JÛ€޸€Yɾ.€@<€€pd_ÑŽj€€?€lKЋ*€€€€€ 6Jx€€€€?€€hct€€b_[€Y8;€€\"€ÂJ€€€[€;z€5 €€€€€€€L€qH€R€ֳ€I€€€€€€€>€>փ€€€€JT5€€C€l]€\5' U={6€€>{€B€Lf€€€yM€tm`€€€_€€€€:m€€€-l€€€b€[€€>€q€nX(Ƿ€€€&€€'€i€k<€€˂€€€g3€;5€€€€€z€<B€\€;€$€ΰ€€€<d€Y€€H€GN0>s€€ €€€Q)€€€g€8|€€€+€€€€ؿ€€€P5€€ܞk€VvS€5€€€€€€X6€RV@€ʑ€€€€€›€C&€€r€€€€A€ d8€€'Þ¾?€€€€a€€€€m€#j{oG€U€€€€ €€€€W€€g2ܪ€5rKB4€€€€€@€€XYJ€g7€€&_F€€€€€€€p€€f-q€€gER[€{ƹ€€€€€€n€€"€€€€€€€z'%]h€€?€€*rÇ€=€€€€W€€€€€€C W€€€tL&€€X€€G€n€8€€€BDEè·¨g€C€€€€€€d€€€{€€e€Å„Vۖ]+q€€Z€aG€FsI€€K€K]`€Q€€€*€€€(A€€'?6HRW€q€€~
+Ò¿|€€€(€€€Â€FI.€Es&€€€€€€€}`€z€€m2€:3L#F0€: -z컩€A€€Ք0€,€€˃zqD€€€=7AÊK€€€€€OXc€€€€˗€€C€7€€|€×€€[€L× €€w€€~€€ۣWÏ€^€z€€
+README.MPWfilens.awk€$€3r€TEXTMPS €€B€€€P€€€Y€€€€€,€vbl€€€4L € €€€€s€€-
+€헧kRB€?€€€€€q€€€! €)€€€€€€V€€€€i}b!V€€3rC€(t~€uz€€W€{'g€€'sh€€€€€ €€€€g€0fi=Y€3€€€~n€ug€€Crw€(€€8-€€y&u€€€€v\!JÂŽI€€3€€!€$€L€€S€Ƞ€R&€€€€L€ 1€*€=€f€€€8€€1?€i€€€€€t&€€€€Q€ €(€€€€€€ €LQjV?€hAhpF]
+N)y€ `€r€€$T€g€€€€_€€€€€€€E('€ 8Ȁ€)€y€€€;~€Tq€0N€ p€aN€ro=€€€4:~$ݱ€Yr5€;]€€Y|€€y:€€€Rl€f]g€Υ€6€€Хw[/ۖ€×n€€ €€
+13€ZW€ZsE€6€€wL%€€€s`€ՔX#€'mG€ҞUt^€s€€Z€€€Ф€€€M€|€ce€€€€€€€€5€iEѡZgddR€€[\€q1~ˡ€4€€΅€KÅ€€zI'$mE'€€Bl€|€ €€€€A€ɔ€Q€C€€ki€€$€,€€€b
+€€€yL$€€AȪ€€I€€€€[€€W€€€€€€'€€€€a€CXtF€J€€€€€€d€€}p@€p€€J€€€€=€S€C€{3e€+e€€€€€€€€€€&€<Hï¥@K€>+€%_\€€€€€A€€€€€t€N'B€L€€€#db€'b€s%5€%5(EF€€€@K€b€€!€€cmÂ!#P€9€€{€€E€2€`H€€.ȪPΦ\€S€p€€€ʈ€€ €€֬€vK€€€y1€!€€]€+€
+€€>€€€€wSh€lߖ€+}€Ŷ€f€€€€€,€€ p€ԇ܄€€€€{€€€€ €€{€|c€2(€L€-Ó€€J€K9€jXB€O€ €€È€€s€€€^€€€€€€Y€€ҙ€׉€€۬€q8d€€KʵZ€€]7€r€€W€€€€€]€tf0€€J茦L€€€ĭ€Y^€7€€P€€2€
+€?€A€€>€€ €€€
+€i€L€€B€i€€€l€Vo€ϵ5Ø -Û¬K€#€S㥆Mq€€v€€€€]2€€H€4y8€€g 6P€€€€v€€
+7€€€€0€€€q0€€c€K€Zp€w=)€€e€P€8€ҩ€€l€€.€€€€rĠ€*€€€O€敔w€e!Æ„G€^€€s€̹€€€€€€l>_n€€€m..€ִZ,€€y€€#€€O€€€€\€e€€T€€۳€?€%€€€€€€€€ܛ€€€€€€&€Ӈ€VE€€T €€g€€#& €l€z€z€v€o*Ź>€€€€€€f-Ä¥K €v€€€€€6G!4€E€€€€q€ ϱ€€}€b€BA)€€k€ނ&(€Hdz€2€€€€7€€€_^€F€€€r€iqu6[€€€€€€€k€€o€W?€€-J}€€€€g€C€\pl~G€B€ ssl.unix€z-€>(€3€€€€€€€€€€€j
+F€€ makeunixPWfilens.awk@3r4€3rTEXTMPS €m5€m5m]€€j€Q€tH€€€€<$'€€>€€€K€€€€€€€€€€€al€€€r8€€€݅€€€€€€Z[€€€€€$L€uI`€sG| €a6€€€€a€€€!P[*€ s.spiderPWfilens.awk €3€=€3rTEXTMPS €m5€m5€€t€1 N7y<A[/€€ݦ֖€€ܖ€f[B€€9v^€^€€&€€JV€€€€cx;€€u€€&€G+P}€><€|€m€fE~€€d€€G€€€€@€€€C€€€`r€€€€€ͷl4c€2€x€Ny€€l€€€3€€T(€S€€}€€€€ €t€[€F€€J€l,S€$I€&R €d€€€;€#€
+€€€x€x€)!€8;<y€€€€^€€e€€%<q€€ ^&ә€x€€€`g€*€€H€€€€XA
+S*t€ U0€Y€q<E$`$&P€€<{€0€€€€Yg€8€€<€X€€X€€€:`€€<J€€u2y!b€€€(€€€~0Dɒ€p€y4jx€ )€€€4 bQq€;Dd€€€€€">C€> €€D€ܗC%€€v€€€€݉€€#vA€ /€k€€€_T€FA, €U€€5Ч€O-€ٽ€~€€€€AE2I>€€<€€w€a€`|U€}€€0<€€€€{€C€€x€wC€€€7%€A€>@I€€€s€iÙ¾jÙ¾j€s€0€€€X€€CѺ€€ €€h€0€€ €€(W€@€€"€€ú€?€€€€€ؘ€€}€F#€€<€*OE€J€€€P€€b€*€y€B)/€yQ€€€>€€€]€W€€€ €KfaS_%€€N€€€_€€mW€2E€€\€(€ޅ€=€p^€s€€€€€€€M€€%€€€€j€€€F€N €U€-€€€€-j€! €€€€€€l€€
+€#€|U€€€€€€€í³˜G%€ €€€ €€€€7€€}€€X€€€њv€Ҋ€€h€ִ€Z€C€o€€€&€€4€2€ܮi€€€€ mĹNn€€€€€€€=€€€€e€€^€€&€{{€ח€(C]*+€€€€€6€hv?€ €
+?<|€€=€YNĽT*sX8.€T€€€sW€.€€€+€9{9wé¸Â€Â€Â€-PP4€n€€€€€HE8w3Y€հ€€hP€^€€p}€Q€p€'€W€. €0€O€]€X~€KB€€€w€€ €€Xq00G8€E€€€P€€€€€KxU€z,c€€€€ۗ8€€ }€€€Ï€畎€€€€€€Z€ €Q €jM€FS€^)*`€z 6€€v€€€€I~€€€-$€A܃"€'"S~uE€€dc€KS€€(€€€€Eç¡­LD€€á…¾€aZ€€€2€W@€€€€
+€j`€1€I=T€€L{2€z€h€€JA4V^€FQN€€Mm/q€e€€€8€إ0€€€€€^#€€€TH/€€€€¶€ce4€o€€c"€ 6€ €H€€؃6€9€c€€Fc€€a€€wn€€€€€€m{€<€€H€X}\€ M€6#€M€€€̆€@€f€€€€(€@?B€<€€ ^ƨ€8x$€.€€PJ>[€uh€ €킛€€y{ €r€UX€7€€€€5xf|€€€%€€€l Ù‰{€5n-€l}M€€ €|c]6K€{ €€Acˋ€vws€€>€2€ €€€!€€€€€€f{v€ٙ€€a €€s€F€€I€€€,€€D{€€%>,y€€])€Z€€rٟ€!€w€l€€€t€€€€꩙&€P€h&S0€(€€j€€€€p+}bQy#€-€€€c€€k€€€€€L€>€€<kS€ÉB* €)D€€J€€E€€^€h€`€ǘb€€€{€€€€€€€€€ß¿`€-Ik€@€+€@Ul€€XX €No]€€€€€€s€€€>€C%Cj춚e€p€D%D€{€ڤ€€XN€€*€x"s€N€w~€?к€'€€BÚµ €€€aMKh€YM€ڻ€€€*O€€€c€€ӗ4€i€€€ €ɔ€t)Ei€r€€1€1K۠€€+€€E€€*€Qĥ€€€€lnP€€€k:€€\€€€€m€%Óƒ €€Y€€€€c;€kJ€€qp€
+ €Zr€€|64A€€€Wce€r€€ǥ€€z€€, <€DB€*€6}€€hM€7<€Y€БcSw*:n€€€Jh€€foY€€€€€zU€UvM€€€Z?i€€€,€€-Zm€€r*€€uH €€av€€€#d l€€€Tu[€l€%Nr€\Mz€€*€#€e€€M
+€7`€_9€€€€€€onU€Jŷ€Ƕ)€€€€K€€€€'Uc€p€€"€€€€€€6}=€€ŋ€2-€€oj ,@-pN€x€€€€€kf_€-€aƄ€€&s>€]`€8€€o`s Z€€^€€€€€€˘aHň€96+ n€L€+FU:r€?yDbL€€€KI€€]Ën€€z€Nk{J€f€€D€G €n€m€ Z.€€B€€€EN€€€€Я<k€k!€€("€{՛€ €*e€Of€|€€rc€S€e$€3€€U^€04€qL€€€0€€J€%,€*€€#€€y€€€€€`€€€€€€!! SpiderWEB €ourcG€
+4€3r€€€Q€€Ql`€H€ webkernel.texens.awkʱ3rT€€€€€€TEXTMPS €m5€m59€Q€p€€ N)yJ€€o€€€€P€l[€J€€€€€€.€:€€Y€3€€€€€ €59A?Z€€뺾I€Wqr €€€B€€€r€r €€€r€€€€€€`€<€F€y€€€€€€€l:€f/ˇaj^€€ž€€g€€€ [€0€f€(€(K[,€€€€t€€kzYnr€d4€GYa €€€)€<€€0˭€S€€e€€k€€€€€ĚÏž€€€_,/€€-€Q€€0€€a€k{€€ќC[a€Nn>€@€€͛7€€€€€€€I€9€€S€a€ €€€Q€ӷ€€M%V€fÂ€Â€Â€Û Â€)3€€€€ã½Â€Â€W€€=€i8€€€€#Krx€€1€€€€€|€€€€€€€~z€€<€Ov€€Ҭ€(€{'N€€€€€€$ €€€r€€€€Ľ€8+€€ €€^€v9€yq€€€€gl4€s€€ €)€€q€?€€4ܹ-A€€-€€M €€€< €€€iצ€€b€P€€DF€Y€%8€€€yQ€€U€^€WjF>lG€€37RD€QsS€€€l€M€€€R€ebe €€dx€€bW€(€€6P€€ €!€"V€>€€€O(€€€€-q:€€$*€€'Ȏ€€O€M€€€€ €C€€+t-€€5€€€€€€€€)€€@-
+€-E7€€%q€€€|€€աN4€`€Y7<€€€QX€`€€A€€€€|€€0?€G€€vr€ zq€€€q€2€€8€n€8€€€q\€€€oG€vlÎÏ¢2s€€€€jì¡Â€[/€ A1
+#€cDk€<€~C7€€Z€€€€ 3€Ҡ€€L€€€ €&8€y€€€m€€)8€aG€7€$,-€^lsh€9{w€J€€"€€Ԯ€I€€l€I€€€j&TÄ…9O€€O€€3'"A€€:€€ €€€k€q€w>€R€x€)<€i9E€€€}€F€E€F€€€%7€€€€€Dm€O€€}€\€€<€H€?n€`€}€€€z€e€€€EO€u€€€€€€Hp€}€€€€<€Ñw ~h/y€B€€}x€€€v€€K€€€pڎ€%b݄€€€'aP€€ €3]€ЊB€€Tw€\€R]€fI€€^-ZÕ£l€Õ›^S€€€€€.€c€€2€€3€ݯ $U€g1t"7€AX€:Fq€€€€F<€0|5€r€)a€h€€lh€ׯ€p.a€f+x€€€€ar€€€
+€€ €P€9+&k€€/€}
+ €€f€€wp€;€욧/€€€€G€€vM€€€€€€€€s€x€|€kv€€€/€€€?€€€€€ᆋq€g`€\€€€666€€€)€IxR€€€~€ €}€ ˂€~Ƹq€ Ú¨uz€€€#€䔀€€€&€d€€+€€E€€€>6€jo€€€}€€€U1€'_O*y€€j€<|€€€€<€€>€€\€bqÙ–\€€€€€€€€7€€€7€€"€$€€[!€€8x<~~€€Վ€€€€B€€€€B€€€і€[[HN€XG€0€E€ ,pt€€€׫g€€€[W€€€`w€€GP Xm€d€D€€$C€$"€]—€Z€€ €€€+ >4€€ €€܆€€"€0€€r€)4\€€€€!€*€+A€Xq€Y€€w€R)$x€€€$€€Iv€€€€:€€€€€qˀ€Lµ4C€€€€>\€޼X€ K€/Þ¢  € FȾ€€€€ܔ€€€€M€rH€q €€P €€*=€€$€-€€ע0;w€€€u €€
+[Z€C€€^b€B€;€|€€€o€f€€€€€€€€€€€{@€€€0€€O€€€€)€€€€)D~W2K€s€APn֥€M€q€P€{€QX_G r€€-u5€k$€€€€p€T!€€ԭ€m€€i€€?€i ̼€€€€A€iO9€€a€$€€€€z€h6Z€€_ ݨ€€>€xpmY€O(M€€€€€pD€€]€e€€D €€€€١D€ӶߋtI^€€6€€€a€€€qJ€|/€€A3€€€z€€x€€,€7€€d€€€€$Vi'€€€g€€€€X€m€€AL€€ €I€€V=€€€R04L€€)€€€F€€€{€ÞZ- Lgx€|i*>€
+g€€€€>'^€@€$Y€_SU:?9€@€€€ €^€€(€d€€€€€`m€€J€€€ή€€6d€Da %€WH€€€€M€/٤€€V}€€€Dv€€}€d€Fa~€€k€\u:€ưDz€i€ Qz€€€`G€G €77e{€€l+ €q%-€D€Z€Q€€؂r͕€€€€o€Ѣ€z€€Q4€€a€U€€e9G€€#€\PJ€yn'€€ْ€kf&€2€X€rj+€€݋O)€i€m€<€€€€€(€€€€)€€$€€€€€€2€Dٗ€€€;5€€?KK €Yr!€О€`i8%€[LM€r€€€€ €M€€€€€€€€€€€€K€ €I€€€p"+=€Ho€€€€€'\€luË›;€€€t€i/E:€ €€€+€€UK€€c|€€J€€€€€ € !t_AO€ €6€a€H\$€L€/€|€Y=€€t€׻€€B€€le€€l€L€߅€kn" {P €€€7ÊŽt€€ €€q€€>T€€€5ے€€y3Z€€€/€€!€vq€€€€€€€€n6F€€€€VzÈ€€u€€€€ €€d€F€3€f-€€7)€€€€€€Ѳ €€T%z€€€€momnnr`€€M€€ Ѐ€€€€6uʯc€€€€1nsΰ-€€r€€€€xo€€}}€€B+>`€̹€€€€P€8q€€€[€0€.?P€%(r-\#€€zFPB€€€o|€\€€€€€€
+5€:Z€#€€L€€€€ͻ€6€€€€C€€X€€
+€|€O,\fQ€€
+T$99€ €`€€t€z€@€€€]€€€p?€l€€߉€tÄ€€2I^€€@.U- m€€h
+€D€€€{€2€\€u€€€€€€6Ϳ€q0€€€(€<Ge6€7€p€€€[ ƚ€q€€#€U\€€€橞T€€#€w`€€Ul€:*s€€C€€?]v€€€€<€E€Nd€€m€€€€€€A€€€vзTU€%#€4@ O€€€ _"€€榹uGNb€C€x܆€}€€€€€€L]€ D€€X'€ R€NI`€]€%/€€€]Z?€€㫎€o€m€f€7:pT€z€€€€{\@g€€=8€>€2€€L €I|€€€ €€ €€i6€ €|l€=vR
+€ €{2:G€=9€€€jH€€€=:ݺ €€€i€€L€_€€d$€c2a€€€€,!€D€'€{M@$qJ€€€sb€€€€€WGd#:n€8€€€ S!€:xÚ•6€€%r!€x€z€€ €€€€€€€€W$€ & €,í»•%€EW€€Ï€€€€€(%;an€€€€ €h€€]€€€j€nlOV€€WE€ԓ€q 暶K€$€vG€(€]PQ9€XEv€oX€/€€]€ €Vu€€ެ€.€G€€%`€€zh€€€;6€J€€:<p=6€€€<€€€)€€*€€€€€rwËZ€0A€H€b€4€d5€€
+&€G€`8,€€.ƕ€ ?04L€y€ €1€3喗€k€€€w€€O䣖€g€€€€v€€srx€_€jY€€€{9jm€N X€€€z[a€€V|%{/€q=€€ €o€R€R€L€€x€€€€g/€€<ae(1€8I1C€€:€€€8€ €€K€J€k€€.€€€€~rI€€€€F€€)€€€€`|€Y€H:(
+Pa€€€1€<ƔR€W€L€€€\Ԥy0€0?€€€€€€€?"€€€€d€%€!
+€J:€%€€[€€ucDC€€ €€€€w6€€€ T8€€6€[€b€j€€€o€€6nW€€€€€€€€€€€€!x€ q%€.€%€€€€€€P€€3 €.qÓ¡@ɧ€€€€c€€j3g€€k€.AQ
+€Da)€^p€€lJ€€}€a#Z€9€קRs€€U€֨S€SE€€4€€€u1N€€€`€€#€€i€ V€€€AU]€G€€€€€€D#i.€€l€ €"ٸ
+€-€/€€'€€Y€€€€€p€€I€$€€J€h€€€€ Q€€€€xd€€€,,՗€€€օ€[` €€€7€H:€€7ÔŽ€"€€΀R€4Т€r€€€€€>€[5€€wr)w€| €2i€\€€P €C€€E9€€XЂ€Y__᜖pn€D€€€Ç>`~€x€€}.€*`€؟€މ€J€ހ€€H€Z€€€w€}W€€€!€€C#€X€8€€h€v€€€ €€€€€€€"fL8p€x€€G€3g€"XX73IN€€€€€€AmA
+€i€E9€h€Y4€€€7€€€€jA@€€=€€€€€€'€€\€€€I€,€e€€GY2JMu€€€€)rJF€R€S€€€€;€.€€€u€|D€4€2€€€€€€qAjJ€€%€€€ȼPO€D €€€xG€6€"G€G€F€s€2 €*#1€€e€s€app!7>€€€€z€\€D€OV€ҩc€ =€$€€€g&€E€€C€+v €€x€oS€€ٵ.€€€€€y€€;.€v€€€"€€-(€B€ €O7d€:€ €€RQ 9€€3I€R;€€cc{€€€!2+€0i€€€$€€€€€-€€f k€'`€€€Or€€k2€5w€y€&€$fO€€h€&€ €+€!€€E€€|€€JJT€ €€uA€€€€ڽ€€c€' €a€€€ €S:+»k_hU@s€s€€!€,€€d€#f€B€E€€€u€D€]€ʮ€€R€:u€p+ОL€K€I€€€€c2V€€€€€涰}V€€€h4€P€€g8€€€€*ܕ€€€€}wr{€=v€e€€s€€ €+b€€ :\ €1€€UT=€
+ €g€.€P€€r€€_€QÕƒD8ȅ€€i€#€€€K€h €uY€€@€€!€€rF G€2€E€8*0€wH€R€~U&՛€€/L€or€S€€€tt€~G€€<€€7€€€€€?€€_(€€€ǫ
+€?n޹RU€F`/%R€€ Ǵ€8€q€€€€€€€R€ €€€€€€€€€3€€W€)K^€€jo€m€€€ €€M€JE€ X €$€p€€>O€f5€€X€T€€p€s€€.€€€€€€ݽ€se8€<L€a€1s@€e€<€ubg€€€€|_€!]€€€€€€€*;\~€€MP€€W€€€Ÿ€€€PBƩS€S€€kq€€v€€i€€wP0tEp€"̆DQX€€€€3a7€[b€€v"€x!b€€€€`€
+W€$
+€n€€ݱ€€€€€&€p€-_@€€€MW,€€:€€6y€€€9€€€Zs€€€€v[€€€€€h€€-€_j€€ C€y€(o€X€€A,#€%€€5K€F€€M_€WRo€q€]€ Ψ€"€€6€x€€€€Õ”€J€€€H€7€ޚ€€X€€8€݋€:]€€ d€€€q$€%€6d €[€€g@€€a €xҖ€r€o€€л%€€/€€€Y€€{Yo€€€@€ǘ€?m2is€€¢);€k8i€€€€€€€€€h€܌~d€qbtI€~€CH€€뮩€G€€u€J€€€u€1€€)N3€"`t€;-€€€€WԴ€€簢€€€€ €€€G€=lp€|€€Y)e€€f _€€€N€€€€5
+y€€J&€(O€€5€€V€G€€€,€€€yoW€n€€D€€Ϩ€&€ €€VH5€€&€€-]q€€€€o€tQ€€€y8Uίc€€€54€€ק€L€ R l€q-€€€€€€€ڽ€€€€~{€€Ã¥ÚdK€€Ϝ€€>€?c€v€€c+̀€R5x-€(€€MR,€€€?I=€€2$p/|P€€@ꢉ@€׃b€€€€m€€A€€5#o€€€v€€[pM€/€€€C1€€l€!€v€c€€€€€٣€Hx1@€€3`R€€UP"€~€€€yvAj€W€€u€b€^€}€€!<Gx=€€nO^5€ €€BY€zo^€€ €€S <€€€€€€€€d6€€]v€€x€€QY 2€€kfd€>kR+fnE€<A€€naG€Y€€€€€j€Ui0€|€ǩf€C€U_€€€€e€)€t€.6€€€g€€€€L€*€€<hY=€€{€j€Y.€€ €AGÞ%Q€€€€3}€€€€S€[k €€€I€zz&8CKV€`l€5+€F€5@€€ €f€=g#/w9€€€€€" <€| €€€€€€qlj €4YZ^€!! SpiderWEB €ourcG€
+>(€€€€Q€€Q€€4€԰ awktangle€$€€€€€€€MPSTMPS €N€€€€%`€Sd€€€"€€ ?€€+3€QN9€€€le&€€€>7€€M3O€€€€SN€€€€€ͶO€=f€3€€/€€.k€{|€€MpQ€€ _€6A~^ ?!€m\€€(w€€s€p€€ € €Eȶ €€m€la 9dy&€€€€.€€.€[€€:A€€€€<H`€€€€9€€€ €ؿR€W€5€M€€€&€€€€€yEa[CGgs€€€€nn^€J€o€€€Ά€€€و€€V€€€€€€€€|€~U|€k€€@MKgc{S€€W$~€€)S
+g΂€€hV€€y€€€€€€€€€€€yusk{€€€*€€€€€ 5:€ .O\€€Q€jt€6t€€>€€€€W$C-€N€€€€€3€2ԉ a€€€€w€€€€€ €nķ€~|o€€v|€€€N|€€€]€n€w߻€݌€=€n€/€5€€'€&8€€SX1€€J€€ €ɶRs/€€?€€€€€€€y€PM[€+€€€8€€y € €De€y€€€5€€€q€€€€<.€]|€€<^€€€€€€€' €€z&n;€@€W&€L|€€y€{~€<€€U€€<j€]€€ڜ+€€<n(€€€%€€€+€M€€€€Ǜץ€W €Y€ݵ€[€€€€w €€€3€€€€€ό€€€M_I€ML€w^€€m?B,€€€ͲY€"G€€t€^€~D€€€€€€€€€ €€€€€nߥ€;u€€n€Hۘ€€ٺ=G€ú€€€M6€€€€Ҏ;€ׯI€€I;A€€€€;€u{€no€v€€€;¨€ߤ€€S€€€68u{€€€%€6€K;n€€€z€€D€eI۾J€ F€I€a€vⷥ=€B€_€€€€NI€m€n€u{€€'M€€€€]€€a€:n€€a€€€F€~Z€_€€€ҎK€€a€€A€{€€>g€€€€Mǥm{D€€:€~Q€ ɺ}#z_a|%€[€7Vt̉€5€_8€k€w€€m€Ӈ€\€€€€_)€€€€€€€€€€€€ƭ€€Y€€€p€τ€A€4€.<€€/*€€€U€M$€o€|UV
+€€Le€0W €Ut€€€€Y€€€€€€€!€€$/[!p€€€嘃€€€Ӕ€€€€€_A€€*€J€€€/ߋ€ €֮€€€€ €+€ Z€€*€€W €€€€€€€€€€f€€€#€€€s€€a€€\€$€z6bbs(€€_€hjm€€€0h€ €€€0i/ €€#!<?€€€v?*€j€€ǵ€i~{€€€€ i€€€€[ €UbG3J\€€€€€=ÔD€J€J€€b
+X€R€vD€€€€߉78ݣ€E€€R€€[Ӄl€+€I€€€/6q€Ћ€€€€ڷU3€€ &€'=\6€#€-ˆ€<T0€€EU€€!€ Zh€€€€`C'€€€€€€€UNk9€&€dWZ€€€@€M€€€g€€/€€ €€€€>€€ ]€F€€€j€B=,€€€lh €x€ B€€|€€€5-€€€5+€[[€:G%€8V€?€AGB€€€]€~€ߵMw€4€€€a!|€€€ €€m€€G%S)€x@€W€Gz1`T€€ ^€€YP$ Je€!€
+€Z€€€€t€€€U€€NÓ]€:€b\€ €O€€€#[[l€P€€;'a€߸€i€€€s€€DÇ‚a€g|€€0;Z*€F€€€€]€€€€ת€5€€#€HN:"9€H€€IܼM€€S€€D€?y€€"5€€€€rH€€"+€z€ €€? €€€b€Ye€€€#=U€H€G€€€Q€yU€€Ỽ&€=|€羘€0Í€€ޗ|€;€0ÃN7€€L'€€“!B5€€€€I€Y€3€€€B€€g€uUr€:|€Jzt€€€€:eBC€€JO€0V €V"€:ʋ€€€ €€€y w€€cK€Y€€@€*€fr 7€€€B€€rx€Mso€W€€j€€€n;jX€ă7Ë•+€Q6€{~傅€S€€€€€€€[D€w€o€€-4Q%€cJ€(/€€€0<€ׂ€`6€€€ɵ~cP68€*€"€r€H\o€Y€|€R€€€4€^_€!Va€uH1U€ߊZw€€€€⪂€€€€€7€a[€q€€€€!R€€n€%3R€€€€c>*€>55€€€€€:€, €€€€€D€4€€I€€€H>x€R €€FP-€€ €/EVÖ¼?€€";€€€*€Ƹ€u€€7€P€_Du€'€o-€cW€€*xQG€ѻ€€€€M€€€5 x€Ʈ€€j€1€<€)€G€<$z€$€€€q€€H€ 2 g%€€K€€.,"€P€€€pF̀€ї€€€T€ €€1x€€€€€€T€z€!€2A€L€€W%€€€Ú€HNr€€€€`
+g€;w€€€LET[5€€ €T€€€€€9€€ 5€€€o€7W€R€ur^x€€€ŊW€uj€59€ €k€€.S€_)€€€x€€/€Q]<%΋€€€€O€e€€,R€[€T€|}€H5>Pde€,€֣⎊!W€3xd€jP€€Ô€€€ €d€€X€}[€€" l"u€an€€Wܨ€€n€€€y€X€€€€L€
+€8E€+ €€Y€€b€{€€€€€€V€'€€k€ȩ€€EU€G2Dv€€yNr爴€€€€DQ€o€€€12g€€5€€:€GI€#$€€E€oM%O€Ć€€}!I€r€€€G€€€€€(U€€€RT€C)€€c €PUs€€€z€+€€€Oy€€.Ny€€a?€a€€€€G<<€Oy8€€8€€€D€€_η€@wj€l€€€€"ST€֊€3Ô·`€€&l€€C€€H€€€i/R€K€€€,ZX€€€Ӛ€€ƹ€€}€š= ˦€€€ӶrV€€€ϭ€~€€v€€`a€€څ2~€€pN€€!3p€Ne€õ€€?€=€|W€Q€I€€:=€€€€ۨ6e€+€*ev€€€€<€€s,€8Ñ€3}Y€]€€?€<eWq&€]~X j=c€׌f€O`0#€€€€ǾR€€€€IJ€p|€1Æ—~5s€€Eo_€€׮{€€€€d€€€Dž€€!€-E €K$Æ€c€Z=€€€€Ejf\D:n€X €?jo€€€€€DY€€€M
+Ù‡nZ€Û€€€zlw[€€B md€€€€€€€u€5€A€)D€]€€ŸZ€|€€€€€€€€€€*45(
+€€€e)€C>€€€ŔΌ)€€€€Ryj€€€€€€<€€$3€?€Q2/€€€5ǟ€9~05 Yۃ€2M€€5€4€]€t9u€€N€3€€ed€€> "
+€B€FD€€s€1]5€€IN€€€€€€€~I€€w€ib€€`€€€l€`n€9Æ»o€€<€p€h8 €€6e€€{N€Rm=€h4€€M€€:w a€€€€\S"€3€€€e€&€e€€€D€€~€&L€'mÛ¤d"J€€_€.€€€8/€g$OHt|€€yQ€€)q€€Lk€*
+€va€€l/3/€OVJP€jvbF݋€q€<€x<ݥ€ϗسkcpf€€€q€td\2€Hh€N'2€~€v€eS€7€k ɽ€€83€G€€€€€€€#€>€€€€€€€â¶Â€ÔŸW€€f€€€€}€-Eu€ް/+€€G€}€*vOYI€ €hn€€€€€€ €€T€uɂ€€€%€€€€€ڲ€5u€€€€€€i2€y€€€m;€€=€V0€€€€€ަ€€+€ Z€i€€%€€€,€€I€€-€?€L€€€a€kÙµ1o~€g€EΉ!€€|b€8*v*€qb€3€€€V !3€€z::?€D€€€€€C[f€h€x€€T€€€6€€CVJbv€_}€€€€F€d€=€€€€€7€'l€[€€€€é€€;€\€Q_??€€€bT€€*l€
+€€F€€€€/s}€NW€D€u€.5Ѭ€€1Rmde€}€€€C€^€+֎P%nk€€r}}x€€€€x€㇅ÿ€z€€€u€€`xy€€€|€€G€;0SL€€€€€€€€MY€€f€€,Ȥy€'€€
+PÖžO€€€'R€€[€c€7€€5U^T€€€aü€i€$€€€a6€€€$€€€U€€€€€&€€`€ M€€U~€ϭ€€€6€€€Z€€€m€€€;€V€€€€€€€€€ᠫ€€€K€a€<€€€<s€€€ €€\Ij€T;q€kM€)x}€\4L+9qUrE€F€€€€€€/"€€€m€€€€€€'^s€€G3€€+7 €N G€€€x€€€Wˉ€€€€o€€€€B€€€R€€īu€u€€-€#€z3€5€€
+f?v€€€+€€€€€|9c€€€1€€€x }€G€^)€€:€eU {€:€-w€€€t:€€€€[)Y)€qY€_€}O€€€M €€z€€p€€€!€€€€€€€€Z ՋZ€Ѣ€}f€€€€T€ܠȧ€D?|^A€€€̩Q€€€€€q€QVmu€x€€€
+ €ЎQ€1l€€€5€ƒȎ€€YNE€€f€t€|!€€C€N€€€€7+€7€€€€/7Fm€€Uh;1€s€$€c€o€€€€€€€nb€€B€C]Ue€7Rc€Hn€ʧ€€WJ€=€w€x€€€€€MC€€AC€]€`F$€€}f7f€G6€`€^j€€5€(€C€€€€a€<€€€€€€)€€{€€€*€€€.€յ /;^ €€€<€€€>€€€3xJ€€€t€p€zJ€€u€AE €€€€g
+€sE€€€x]€i€€6€ €€s €1$€I€K€€€_ U€Ý[€€ڞ€x€pv€€L€]€\€:8€`m>#XI€0ۂfR€<€€€?€€€Jz€i`€€€˷1;4€T€€€€€6€€S€?€P€Q€€$aZK€F€€€}€€c€€€€€€m€L(:*v}€^€€>€d€€S€mn7€{6€2€€ €2€€€€bɵ€€€+€j€K€jt%
+P€€=#€€vۥ€C€U€;O€€VV }€€#(
+Z{C€€q€P]€€€€g€$€€€̠a€ŗ€|€€€U+n?<€€€o3c€€:Y3€€GÓ¸~€W€A[:€@\€€k€€€€€5%\€€tqy€€Y€2€€€z€€€€֡VwÏ‘3€€Ʈ€Ûz€?9€€=I%h%€€€€U€€"0€0p ;€ާ€h€€€€€€}m€%€€€Z(€ZA€k"€€€Dc€8€L€ €$€f€€€€)5f€€[3€"€_R]3o€€€€߿€/€#>€€1€€€€l€8€€€€U€[d€̡a€C~;2c€6C;€s€3€F€$€̤w€€U€€n€€€x€€g€5A€<q]€€€|€[]€€€ ۮ€€ʚ€ +€€€€€€€€)€€€€€ǵ€/wI4€€€€}M{4{1Yyn€N€€O€xÓ¦B0€?€€€x€P€B€3j=€cX€G€+€€€;€W€p€€€€U#S^€N€=€€qx€€ €€\€o€QW?y€YE€sV€€€€d€=C͂€€€€I€€7€bÊ v€€8q*4€€€N€€`! €)ѻ€€€M€I€\€=€-€€]U€+c€€d€I㚮€L€z€€€f€ͱ€<4Q€97€k€kU€€€t/YW€b?€€a€/Ų€€fA€€ޒ
+€WS €€€€€€€€€€€@=Í"€r€lA€<€yf€€Drȹ€€€€€ԯ€̜€2€\5U€€€M=AegAP€-€€€€€bV€=€{€€€蔀€€€€€€€€ €€€C€p]e€j;€€a€€>ߣ2v€€€-€t€€€€Oȷ€€€€t€Ӌ€€€W€€€A€4€€K€'+€y48S€;€[€€€€V€€Ex7€€U€€21€€gW?CV>޶€GyN@€€*1e;€8j€€€€€€3e'"<€€o_€n€tHIm€ed€ڂ€Ɇ€l:€ʆ` €€Rld€€€e€*€k€ߟ€€m{p-€Z€€€€F"b€[€q€|N€w€3owa€€€0p€ €€€€€|€€€€€YÆ´!ҋ€€W€€€€أ€€€ses}#4e€€€]> €d/€.€€€#€€€€^e€€€n€s€€qV$_€€WY0€€€^€€:!€J€€€gJ€€w€€Ҍ€W€€h€w€€€O€b€C€Ù¹M€€€U~Ñ›W€G:g4jw4j€€~€€l€€8€tn€3€+se€€\Þ¾vhNǹ+€€bDv€€/€€ê¡U€we?€€€€€€€€וBTU€$ɡ€y€€._g€ €€€{€8€~€€U€q~€Kä¸Â€Â€Â€Â€€€b€€+$p}€~q€8€BU€<ʳ€w €€€*€€&€€H€€€€b€€P€€^J€€
+€€€€€Q€€jE€€€€€K€p€yQ€€Fe€€?€€€2€€>{€G. €€И}€gdEz€€€/y:€·g^€€€€ʿ€€k€> €a€€qd€2€€YʱHgl?.;C€€O€j<\0€€€€€؈€€€€Ur€€€w³*€€:^€#€VD"€ €€€!€/€€€€tT+€€€€€€nj€;%€€2€€K€€€€€o€€€Â€€ €U€}€€€=tq€X s}sO€>€AQ܇^€_€€̒€LϦ€€iğ€€"~€€€N"B€'€€€QO€$1rd+€€H€€€€a€€€€€€0€€€Cup'gS!>€€€7€€€Ƅ€€]€€۷€7€€€ElN€ꮋ€€€€9/W€€ €€$*<?,€/€€€ю€€€€aU€€^€€€€8€f€€€c€;€€)M€€€&u€6€Xm|OBr€€ y€€3Y{€E€ꔳ€D€€€€N€ϞrX€€€€p€€€€€€!€Gz€=Da4€*P€€€/€;€e€I€KÛ»"€€b€€€R€€€
+8_k€€€s€p`(0€€vF€€S€€€€#<e
+#o€€€€€Y€363€K€j€m€V€8R€8Ss0€€€B€A€€€ ϯtA{fT€€€€€€€zy€UU€g €€€Ը€€Ÿ€=€K€1€€€€l€_B€ƞ€€'D€€€J€[€'?`>€#R|%Ô•#K€€€,€IU*€YF€3€ €CL€&€€#K€€s€k€a€€*>€€€€€€Fs(u€1€D2€€€WM€yP€€o€€€€8€€ϠR€B€lO^€/€,k€€€K€R>€€€€nRl€U€!€O€€€I€€€€€^€€€€zu€€€€€€€€€Ǣ€€0€€€ó€€€€€€€q3€CV€€6w€i€€€€€O€F€}6Ò‡|€€€€++€€+€F€ؤ€€KE€€€€*=]€c€€€€S€o€c€€)P5.€€€Rq€v€&rE!W€p[€€}s
+~€€w€N€{€€€€C€A€ D^ €€€kv€€ €9€€€]5€€%€]€^€€€^€€€€€R YU€`o€€€€ €€€€€J€2w€€€Fߚ€€€;y,¹€y^>1€X3€K€€;%€Ź€~!2)z€;}€)€c€9€p[0˜]€ڬ€"€€€?@ÑŸ#l€€3€ѵt€Q:f€7z€€[]€€€
+T€5€€€U€8€€€?TFB€€* €€€€H#€N€€"E€€€€F€1€€€7Z€w€€€€֠€E€€Y €Jq€G€;4€€V€V€<€
+5€B€ L=9g€- €€€a€€€€€€€€€
+1€€€€]L€|r6€€€A€U€€€:€w46€B~h€%.ZS€€€DR€[V|€€r€€€€N€€€p€|ĽHߪ€+֡€€O€€€€P€€H€€@9:€€Du€S/€8€X€€@+€€U€9€е9€€P`Ä€[h€ €€Ӌx€€€Oq€€rXg€~9€#r€}2vu€€!pj€bB7€= 60r€€F€€€1M€€€_€€€€G€C€}€YF€€FÕ§bg€€U€ؒ€T€{€>€|€l€
+€€€€€€€Өo€B€€7€l嶖€€€€€€$+€Jd€€€€€€F€A€4
+L9€p€€€n€€€€$€h€€QM€€;€^S€O€צ:€€€tX6u€€Pgq=[#Z`€ ]€(e3p€€€€€|k>q%ʀ\€€€J€€€€c€€NsP)'a€j€€€~X€49€€z€ɂY€D€€€€K"€b jZЬN€_M€€b€J€€16€€€^iOOc[,S€€(€DP€\€€>ڷ€~€€ig뜚€€€€;P1€e€R€€aa €€€\€o€€oЛ€x€€_€€€€v€€Do䶚€€€€€.€@Zx€!€€€@€€p€[€P€;€€'q€;,€e€x€€€€€\C€e'x€€ٯE&€€2ah€>\I€Q€ 1€€€p€ײf€€X`€ Ä®9€x€.€{h€€x0XBÓ±]w€€€€r)€€w€A€4€y€€f€X{€ €€€€€o€g€ 6€€x€€€.€I€€K€9A€)xç¾Â€Â€~€C€s cM9M-v€€$€OL"€?w` €J€€
+4€€#€€€'. €€€M€ O€[€8]ef€€O€U€€€€€gS€f0€7Ƴz€?U€€_W€€€W;€€)~€€ZU €"U'€€~€€m€|€9€T€Ff€4€€O€ZVD0ȸ€€€€€€y€(91€h6%€€0€€zH€€€€€€€]€u€€€€ץ€*=d€€€$;€:€)€X€€7€P€€_€€€p€tM€€S€E€Ñ›"€Y€X€s€/€€5€€8€c€€{€=€=€a9ʀ€€€s€*€Y€€6€€€=|Bj€€qڃ€1€€T€~€€€€€a€€€;`€€€€€€€€€|(s€L]4€€dz€}€C{€€3€H€€€:€/Y4Mޗ€€C€€}€4鄅€€K€€€%Ix€,€Dß´}€€€ٴ€€€€7x€€€=r)€€€B€€j~{€€v€€{€F€X€y/u€€€€€2€ٺgE5€€Bע€\€€€R`€€XF1Ö°X€V€€€-€€b>[€l-a€ €qQ€V'[yl€u#€?Ù°FD[E€€*€8q,€p]€*€p€S€X€€,€€dk&[W€U@=€\t€€€€€€ׯo€€?€J€€:#€€7K<€€€€躯c[8k\I€€€€,%YM€d€a=A6x€4€€€€€D+€€2€V€€€<€ €f€W€€€]€SgH€€€_Go"+€m€€-€Y€pg€I€\N€9€€$€:Õ¤8€?! .€€€€€€€€V€€€€H€r€ٗ€\[€€|Qj€v€€€€€€€€€€€€€€D€91€€€~&vB€-€Y€€%€^€€€€l€€F€=on€_qK'€€€€€€@€€Q^X€€]€ų
+Y€€~€}&t|a€|t€K€M€ $2€P€w(€e€Tzix€;€fm€x€€)C€9€€€€€i€€€€A€`€J+€G'€€€€€€^€)"€€€؄ €-€€€€
+€*€x€6€€JU€€pz€TlM€YA€*€€$€s€'€€€€yÀ€€>€€€w,GG€u€iΘ€P€%€€€J€ǵU€€=qX€1€€5M€€k€?3_€1€ۂ€€H`vq€€€€T€€7€ 5_€€T€/,€50?€;€€KǨ€_z€€7€€>€V~€€|/€tAx€zÖˆ^€(€4€€ƺCF'€@€x€€€mY€i#€€pS€| Y€€€z€G€ €€€$€€€€T€̀€AnƢ€r€Z€€€-€>€€ €?`EJ4€R(O€€€sK#€€€3€€'€€€9€€€_€MW€€E€€ €,€G€t>vx€€y€€€€<V E{€€[€k€€E€w(UkD€ӻ 9N€€€€-Ǩ€€€€j€D€€I|€€>€^? €€€P?u€€@€€€m€[$€€€M€€€€€€€T,€W€€*€H*i€€z€€Zs€ *Tlv
+̰€€€d€€€€^V €g|e€€€€ǚ+€€+€€€#€|€x€,€€€€€8€O€]
+€€€>€P€€&g€2€€?€€H:€€€=Z€€,€€:€€9n€€€_€.€Sß™n€fc€w€vܧx€€hG€€€Я€@€€€t€W€oF€ €€e€€€€#€Ua €朗nU€€e€€€€€€R_€€<€׾z4€€€€€b€+€Y€€€83TR0 m€t€€=1{4€€€Ô¤€€߬€̜ €€6€€€€€€w0s€fŨ€@{b€h€k>B€#€€D€3€€)z&=€€€€€L€K€€9s€zpI1€€€J߬€€€o#€?€/q~Æc=E€€x€€9€ї€€ (€€G€€dz€v€ɕ\˰€€.5€7€w€€€*€€€3€x€€n€€€€€€G{€€€€/€>€W€€GUq€c€8€o€€€}€€<€€€ؔ€€9€T€€y€€:€e€5Q€RnOa€M€C:€Nb€€€ij€:E€€K€€€U€€CK€€n€€€g-€€_']&Ǵ€<'!€0€€€€€€W€Z3€€+€€.€f5v€%G5€€€€€€qMaP€€€€@€T<€S_G€-7rm€€ڞ€€|€€€P4€€€_h/€xYf €6€€M€Hŵ/€€€€Uͯ€€€r€}d}€)M€s€ʉ€xV!i€€n€AMy€€€n€€€I€€WhhLg€J
+q_Di€i€€€€q$€€x€+€P€P/€€2€4€€)€€z(€%€Z'€ȼ€€€32€ €o€€€$€€€€Uycld6€.€€k)gkTUI,€y7€€` €€€€(€b€€U€€b€*€U€€€€€ufa€ء€&€0c
+€Y€€nÖ€'€€_% ^A*;€k€€€€60€M€8g+G}0€a€.€7€r€€€€S€_wS€€€b€×€+€cc€€ۂ8€€€€Ü™hK€ N€€_ €€€€8€€Ka€€€€(€€€bO€€,€p€€&[€e€€oy€€U€_€€ €G€€,€€€€^?€&€€€r\G€S€q€€/ L€u9ff€€2Z\>€€€€€d€€€€€€€V€,WE€ਧ€€€€€v<]€€y9Ujɧ€€:S€€€€u\Icx€e€ 1€mr€€€<€3€*Ɔ€l€€€%€#'€€1?€X€֪1?`Z€zP€€Z€h€€€€XY€P€€€€rc€€׺€€F;!N€n=€?€€~YK0€#€€€€€-m€y€€€€ €đ€€€5€J€€€c€!€€^€€€€y€€€€€Ǡ€€€봯m>€=`€&;{Ò¶7€k€€W0€srӑ€`€€8€V€€4€€hT€L€}MV€€O€€€Q%€€d€€O€E€€€xO€€€Ө€HT€0€d€€D5 E€€€€^d€€O€~)U€€[>€€€*Y(k€€€€O€€E€€6!€ko€€€'QűHTq€€€€€y€G9b€A€x>ރ€̜U€T€6€"ˣ€€€?€€Ý€Shi95€pz€C!€€€€€'€€€€lR€7€€€€€Za[€φ€€Y€+€€`€;€€€€Dr€€€-€e€€ѳQhgP€€€€€€€u5€o€[\ €€\€€:€b€€[€5ap€b€*€
+€€ €z鎛Z€€ +€€/€tme5Y€€"€b$€€€€6€€€h€ €$j€#€igz"€€x€€(€/€€€^€~@€;€N-V€<€€€I€€T€5€cIz€|_€E€Pu€€€€€€h)rB€€€€€€V€3€€f€T€€?€/€€̱€\€$€€€€Ö€€y€€ҿ6€€€I€€€€€€UE€€€€€€X€€If€4$€i€
+€Q€€b€€~€€}'€&€€€'YEmt€
+€€H€U€€Ëc€Y€€06D7&€5€Í…Y€Q€#)!€^L:}€o€plyTC€€^E€€;€Fߧ€$Nl€€€X~_€GY€(€€뙘€€€€E€Z€€€€€kFwm€€€g€\>€̉€<a(€{€€U€€€u€i€\€€3€%€€ћG€€€T€€€F€€€}€_€€€€€ €sA€€€eÓ©^€€€rM€yOXv4€€€,eo~€€>€v€€€€€[u€oj€gC€€€€€€€€p€ˢ€rasgS€€a€€r€€€€nѳ€€€€€€Q€&5sx€l'€€€€€€X}Gdvd€*€€1͈h€€€?€€G€qE€[€<]%v€€€€5€€€€+€€€7€g€€€f€€S€€B€€€\€€Ɉ€€€K€NÉ¥h€A€€(o€Jړ€^ѱm€g€€/€%€€}€
+€€=t€€€€bϳqO €€g€v€q€€U€€+€`€€
+~€€€3€€€&Fމ€)FX€€m€p€€-€€nX€€|[€ Ù¢T1>€€€FU/€€€€"€€€~€€S€ݼ€€F€ ( €V€8€€&€€€€a€^€s€Äâµ€^Me€l7!本€,Ý™€€)~Vx€€>€ q€x€€€€wL€Ř€€€E€€€w€€€€1€€i€€€€c€/QG€€"€2Z_V€€ȥ€€l€€s€€*€€A€€€€_€IV€pu€€˱!t€€ €€€€ €;€€€B€L€H€€s€(€€+€€€€#€€€ht6ϯ€|€€€€OÇ´1€ױ-L€2€ç‘€ €€7€1€2€
+€Mr€€€€€X€+€€rf€€z̶c€€wvq€€2€
+I€€s€€fy"€€ڄ€|€ʀܧ@*€€˚€X€R€:f*а€€€ €€€ޱ€€€b€w€€c€€"€Ŕq€2R€=€€€ €)€L€€y€7€€S€€`a€o€gcl>2€€c€€€€€€[13€€O€€€?ŊKB€Ǔ(Cxkb€(7>%S€€rc€€€r€€S€x€/€€62zJ€xF€€=J€€€L€€€3€z€}L€ñ€^{€$€€€m€€€!~€'€9€€‚ €q'€1€EQ€€7€€x€9W€€€-tY€@ή€q€-z<s賞K€€}€€€€€€MB€€€h€€GKC€€s€:-ђ€Ec€€€.€y€\4€€L4€€O€€€
+€€]€h€€€€ €€hv=€€€€s€€€3€RÕ¼s€€€€3€2U#M~S€€k.x/k€y€€€jG1€%€9T]@€€€ZÏ·1€=Ɔ€c€€€>€Sh€€€€h~€m€€:€}*€L{€€`ã¹Â€Â€F€€€€L€€€€€Œ€Q_Ö…~€.€ _€€}]€܉}m€€7˫€f}€Â€í°¹Dt€sa€ M€2€€€I€€€€€&˰€€h.€sݱ€Z€€1€'€.t9W€€.O}€€€€€w€€€ct€€€`€;s<€3€€€<€€VЕ€€<€ :€€C~€ O€n€x€7A€O`€€€ Fs€M€€€€$)m€€l=€€n€Pi
+B3€€€€æ½´/€_€,Õ´u€L€€€€€€€€sL%€\€€>€€€o€€7€€€€=€€€=€s47€€€€€G€€€T€n€€ht`€X€€s6q€€@€c€ܞ€€€€}€F'j€f€L€hf€€€ lP[uM{x€!U€ɜ€Oߞ€o€€/€€fpjC€€$y@zSNï››y*~:CV€€€€€[Aq€3ZC€9V€؞w9€€ €€J[F€€€se^ϳ€5€ZV€Fsa?'Í Â€
+€€€€€ 2^~€€€/eM€Z€&Q€€Ʀ€\#Ô¼5€U€j€=€€€€€\U€v€€€nx€€Ù)€oI€€w,€€ €€€2€€q€1#L€Ô€rËߢ€€€€€€`€fܱ€؈^€yRۭ€v€~€€€€Y€x€w€€zMt}€€€€ʮ_Ty7€€€3€€?WY€f€;€Oxz€€€€+€x€€o8€T€H€͘e€'€€1€€s€€t€€z€€<€€8€F{€€~€;B[y€{€€€~€€ﻇ€"€€{€€f€€€t€{€J€g$~€€€j€€g6€€€€=R€Dx7+€€\G.R>€W~6€?g݄€€€y€€€8€€`€r{€€€Gn€€€Ñپ€7€·€€pVr.€€I,€€€€H€€€€QM€€w€€5ѿ€€€€~€t€!€쾟+k#4y€€€€€"€>€€€€>€€V€€€€€e€a)€8€7€€C€€^€€€O€W€€e€F>}/€׷€O€3 >€€ی€pR2€€€€gg_{€c{€€ €g €€€]m+F7€L€€€|v'€/€wO€/4€nl€8€€€€€S€€€3C€,O€@n;؇€t0€€€€wk€yK€ ؋€z.€ݣ€€€v?€€€btMx!T0Ô›5€€€€ۑ€€/F€€€€vt€xQv€ €`}SscK[€€ɇ]€€w€}}€€Ղ€€<\0€4€cMÕ§$8€€k$7Ɵ€{C€€€R€J €\€H€€T€€H 4€K&€€u€{€€€e?€
+€:Ѹ/€Z"€}€€€€H$=€D€ۣQ€€€f€?€€€€<€€€8/€7q€€ €€O€€€Np€i?"Ú²6€v€6€Am€r€€€€€~€R{t0€<€€*€`€€ €€Z€€€t€€€€€m€g€€€W€€+Y€€|Z1U€h€€H€cӞ€nP€z€f€€€€M€€YA'Ś€=<€€s€€In€9;€€€]€€€€>€€ €€:on€€o€ ;€FV€€_€w€€€ €d€€q€DÌ•}]€S€KF€€€€_€,e€|€gX€€ €€=€]dU€/C€€҄€wu F€\m€€j€dE1=8€€A€€€!€<€Lh€q€:€b€€€€6€T€€€€*€€€<€ 4€€€`€;Q€€p€€L€j€€€5€€|€z9]}€/€kf\0]n€€€vy€€ /0€€\€-€w€K€Wu€€€€ßZ&€j팛€[i€€€€€€P#Û¬H€€€€€€€?€Q(k€CWt[€p€W€€€€4€€w€€€u€K€M]€0k€/d€Ź€€ o€_^`€€3€,€E€€ۣۛ€€€€WM&s€€d€€€€€g€%€€€6€vL1€€MɎ€$8$€&!€€䈻/€&S€€b6€.€€€8s<€€[Mf[€€w€i€)€l6Y)€€€€fN0€-q€K€]$U€€€j€€E€€€xf€€€ €l€Co€Y,iH€$€(&€€€F`D€7€€Y€L€ł€6€€s€ M€ɔ R2M€V€q€o€y€Hղ€l€€x€t€€s€€€W€€€ь€Nq&s€€€€7€O€€R€L6d€p€€€
+K}s€€f6€ǣ€€ €€V€€€|L€I€€€$pC€€Ba`f€€6R€F€.a€€g€€Q|€€N=ĭc€9€̎€€ z#91~R
+€{!€(a €€€-€?W€i€^,€€€€,1Y€Mv€EzΨ€€ €d€€q€€ €€XfÄ€6Ñ”b€€€ғ(t<€€5>цTLF4:%€O2€€ L=€8€T€E€€<€=!槷€€;€lF€€€g€€V€]B0€"€\€D€€x€€g€€I€g€4!€€@€€€:€€€€5@ ^€€G€€€2T€€€d,€€€2€€V€€€g€€85Ê–€€_+ZR€€㸔$j€g€€€,Y€h€NDF€Gšf€€dJ€C@€^$K<:€0€Q€%Q€L€€€g#4E€€ €€€PO&€€OF[2€5€€^0€€€€€`aw€6€1€sF[R€ٙ€pSÊ®Gpvp€r㹼€€€v€€)-€€4€€€b€€O€€p)€€€,€Q€8€€Q 4€€€€b€€g7^H€`€€€K€€€€€€€€%$€€$h€€€X€$€€ 1€€€€&€`#€€k@kZlV€/€€€t'€1€€m€)1€€€cP€€@O€hN€€€€n€€€iq€€K€q€€€€IS4z€€v€h€€If{|€€!€t€€€€^U+8(€€€€€€€3€€€€€[€v€€d€3€-`€€?€\ÙŸo€˴€[-i-€f\|A|k|N^€USU€E€€[\€€J€€զfN€€Yg€Y;€€€I€€<k€€8€
+k€5€€€€€€K€€3~G€€€L€u€ۭs€€€€€왩+[€3€€.€kRͱ€V&'M€4+€€€€€6X€X€_€€柒r€€q€Ֆa€]€€€€[x߅€€€€€€€€€€€€€w:€€2/€z€5€~€€R6€€ޗZ/€€Z€€]Ö¤k€%dդ€€m€h€u€5€FÚ…V€€yI^€€€'^€€€k€€;/€:€€€|a€€"x€Z$€€€ۓ€€_€€qi €€u€N€€x €€€€ WO€€€€m€€€€€€[|ܰ€`€€Õ€\@Sgf_€€€€ W€qӀ€€iÃ…!€2:Ӭ€€C€€€€1€w€€€€g€€€€€ JkKW,€Ef8€Ɍ€m€€€€LLR€ €Rq€€ފ.€€R€€Kqm€€ 3€pKÈ€€ٛcH~€f€€xͭ€€€ €€€€€u€ze€D7€€€jź,€€r€€b€ς€W`€€€€e€€7€€_€€L€A8€€€€ €€€^€ɗ€€€€ż€€6D€l€€€€€g€€€€€€\€2WM€{Öª$z€|U[€€€Ìϻ€=€5€|€€o €€€~€n€^€€6Z€t€€sfÆ£piR€ޚ0j€€o€淸€€€€㸫€€&€€M€€€ھlau€{IY€€jnW€+€€€_p€x€e€€€/€~€€€€€€€€€t€^€€€€€:€€€€[A ½g€>€€욒55€€€€s€M€€€_p€€+g€€€€€\]€€€€€€JJ€€,,[€Y콦€ڊʪ€€kj€,€€€€e€]€€€Ն€M€>€ʖU7€€Úƒ€€€Z}€€[€€wݟ€Q€Y€/tW€€z€€b€2€!h€T€€ E€/VpEr€€€€€%€€€€t€B'S)€€€Jk{€€̚€T€€€€€֮€€€€€€€E€€€Ñs&+ׯl5+-
+N€S€€€€€_)Y3€€€€R€M€€€€€€N€€€+€}8€A)€€€}կ€€€€€€€€€€)€m€J€€#N€€(U€C?U€€€
+2Z€+IS€K€+ z€€98T€T3€i2"€㾣€R2?,€€-8€€K€€s€€€€€€€€/€€e€te€B€€€€ƥ€€€€(€€X8€€N€t€R hkܢ€?:€€"€Z EM{(t€t€€!€€€€y€Ҽ€€€€,T>€€€€-JSK€€$€ M
+9€€€€€€€ɓ'&NQ€v$:˦( ٵ€'>€€5VR4€ƭ€h€€€€€€u(€EN€@֑€`€Or€2€XF€/€€q€g€rB€€Mp€€Dg€€(€◑ǚ%w%€€Jv(7S3€ڻMy€':o€Y€€€€ޥt4LѠ77€€Tzɕ€83l€€ȡ€!Ԅ€kk€€€@#\K€&€€€N€<.€€+7€ɔ߂€ڕ €H
+€€!6€ӕ€[_€€€0€E€#€€T€€€€€bjG€ՙ0€c"^:€€8€aO€€8€vj€3€m€€€€W€t€€€#ȃz᳔€€€€€Β€+?€€ P8'€€€€(z777€€€€|€E€€@€€`1A€€€€F€€€€#J€€yuaEWk€€€€€€Am€€[€'€(€ FyLp€€
+BH€#N}@€€HՙNB€lj#€€d€€mE€€€€€€€€1€€ €y۸€N\8€€q€8i€€€χ
+€€;f[w€Z€C€€w:;R€8€€@P€€;h€€\€<€4€€9€~a€€€K€v€%l€+€€€)€€€€€bQ€B%€€ha.€Õ"q€€€2€€<€€yE€€!€\q€€W*€€€κ
+0€€Iot€€>€I $€x€€U€JG;$_a€€€t>€4€€€{ €€€Ne%Ä›ÍBʼn€eT€€€Z p €G1@J€9<xwG€yj€€€€4€€s:Z€€u'!UHB!€€M€4O€1€<1€€٭GC€v?€€€€€VG
+U_KsS€H€>€ۓQk€wc€Pə€q€€€€i
+'€€@8€€<b4N€2€#ejS€ &u(€€$.€€W€%€€OuM."@G€)€€N€€1cj€\ؓ{€vL€6€€o€€f€€uw€€)x€€
+S€L€2€Y€Hb€€S €€€x€Z€pj=€d$fJFG€' % 4€€c€^€Ԉ€%D€€1]ho€€t€~€€#B€€€籺ȬǜGs€I€€€€€€u7€€€€€
+в6€€€€^€€Θ€f€€1c€€€=Ӧa 87;€€€€ع€y€f€€W9V€€kR€€€ږ€€c€;OG]€'€ ڻ€€G€NB €€K^€€-k€8€€€€€aWs€€€ٻ€|€l€€R€€€8€€`V€€+PmO€€€$d€O€(i€€€€€֒.€€0f€0€fZ1€€€€€%€€|~€€€€3NV€mh €K€€€€щq;J€€4€€ 9]€b€€€u€v€[1€Ŕ'@ €LHƈN5b€€€lrf]€€€€€€@€r€€r{€€~R€€\;>€€€€€|ə}€n4€€€@#
+€[€rg€d€€oÙ€j:W€€Ï€:A€€)€F€€€̣Gn€E€3I€€€€€€G€&Y€1€G€k€{€€p€MÆ€; €4€€€€1€8€iǷ€€u€9S€k:€8€€€€€q€T€P,€€€€1€€€€Tb2€x€xMÆ€)€F+€TcoRY€ 5€€f€f× €h€5€€B€€5€3€7€>€€&€€€%€p€pZ€1€0Ó Å€€_€ €€߫€€€€1 z€€a€€a€i"€pv€€{Ö½x€(€♴€€€€€'€€€€€{[€€€€L€€&€€€ Z"€€^m € €€=G׎€€€€X;&o€5Ø‚)€q€€p€n€3€€a€)€ܸ€:€€dN€€*p ]^€ks€4€€s€w€b€€;O€€]€€N/€r9|€€€€p€€€€€ԅf€=ÞšL€€B€€€`€€԰€€ă€6€€€€€q€8€€€5
+€€€€€€€€G€€€y倀4€€€€€€€€R€҂ €€€€;€L6l€q€€:€Q€€B€:y4€
+\€]등€9V€c;€L8.Dž€€/R€僚Tq<€bx€/€€
+և€€E€€.)cu1€=U€x]̇~U€€u1?€€€l€€>€y€€€+€6€€€€y €b€€€€€^€\^€Q,f\€€3€gBe€€~€Z€P-xW€€Az˩€dqN=J€€€€I€€2€ €€(€JwL€€P€נ5€€U4€+€(€€€€€€€I€M€p€:ZE.€€€€€€€€#€€€€G}€€ß€k€€z{€E
+]€€€€€€€fe€€€ €€lx€_L8€€€u€=my€€€]e€€]€€€C€€€€N€Z€€?Vu€€€€pć(€8O€yk€€€€€5€€€5€€€ 6i€uΧBÖ‹6P€'€€€€€e€€€R)s€€\€€ €€€€fmi3 €8€k€€€ iOw
+.Ö·g€€€€~€7€€C€€€€€=€3€3€€nÅ¡L€€\F€.]€m#e€EXi€€€ m€€X<€*T€€€$R{€€€€€ݼi€€€-€€|€€Z€€[€€V€€dDN-€€a-2=€{€€€7€G.K€_Òv6`t€{!|€€N;u€c€?]€l€€.;aɉ€€€€€=€s€€€€oÇ®n€W_€€W€ €€7€=t/€€\€€c€€ €f€b€o€·}€€ˊ€l€€Yq[€€€[€`€€€€=€€!~Â€Â€Â€í°ªÂ€Â€Â€Â€Â€`U€˗`€€Û€A€€€€€€€䛂€€€€€€€uUO€€€IWW€LPo챨€೴'S€€q€=F€€€€€€UwO€Z€€P c6b̄€ד€€€LR€{UWÏ¥jb€€\€N€o2€'€d€v€Z`{Rk€&€€pX]€€€€€€vt'|€g €rq 6H9€~J\9€(]€4€dH.€e€€€w€€,€€V€5€A€€€GL€a.€|L€eb€€])W,[€]7€Z€€A€_z€€w8€€€rpB€€ʷf€€J9 €€€€€€€jt€€€€€:€xC€€€T_€€€L€ZƓ€K3€€€€RH5)€O€€>€€€N€€k=€€a=€A€€€€€!G€1xK€€Vâ” 0€€€€>€ډ€€€@€T€b€y€€o€€@y€{Np€%8Z€kŀ€g€€W€E{€€ƃ€€Pw~]a€€€€;€.€|€ T€(€€€€€6c€s€g€€</ #€F濱kG€€} €€€F/€€€nv€~p€~€€€N
+:€€€€D€€€€€€€77€m€o€€;D[€7)€6؊€BFW€^\J4€Ŗ€€€€€€Q€.€4*€€€a€o€€€ĕ€€€€€€R€€€€&€;€4€€€s€€99€€€Ex€V€s8nU~x€l€€€€8S€Ð+/3€€{H{€꿑c€N€\€€€€'q€€€z€'Rq€쒮€€\€t€-w€€€7€} €€/?N)€€€/|C€€€PC €E€g`€>+BNb§€€-€€€D€€ֹ5€#€€€€7€k€€1Z€ <€€d
+€€Å™A€`€€€v.y{€€GRo€M€€€vb€pQX €=€€Jz€€€V/n€$€B€^€€€€€€9€€€€€6€ۓ€N€3€€V€ň€€l€ѿ€€€€€ެ€€€8€1€纰€€q<€€g€€€G€€?€€€b€€€€S€€1€Q0€pB€€€€€O~€g€€ €wJm€€€€Kd^€€Y€€€б8€€^€t€€z:&€>]€€€Y€i€]€€7€&€€€#€ř~€c€€?€€Vu€7Η€€€Sq€sn€€^N@/€€"€^€)K6€' €4€S€AǶ)ř€E€Ì¡€€kF€€€€' €€q{&€7€€6€€€:}\€i\Mw(f9o€z€€€€€€f€€€€[€€€€/0€+D€yi€vK€€€€€€€€€)€sÓø€€€\V€+€k€€h€€%€€wj€y€/€€Kk€€€€c€49e€€ԋM€€\+€9€€€4ܾ€J€€€vÞ‘;€€<!d`€€C€Y€l€.€€€n€<í–¡¹s€€€€€€1€D€ed€B€F€€[€€€z€gpG€€ €€.€€€(€J€€\RcH€€€€Е€€5€-€€€9€g€€W€QgS€€Kx€€€€E€V#€€j|€;è»W$a€e€€-x,*€€€€PB€€Ri€€m€€€Ng€x€).j€€}€'ҩ€€}€.€|€J\€y*€o€|€8€€ՌY~ €€*€W!&!p€ZT?€Й€€€L-€€€€BU€€)v€€ €€J\Z"+1^€j€€€5sZ€-`'b€LJ€€֣k€ùC€€€€€VMH€%4€€M€!€:<R`€€ٙ/€€ñ€J5{Jw€^€€6€€{J€{I;Z€ݑ€€&L "€ƕ`€€?3Ñ€€|#€:€€LLh€ˊ€€€€9€E€€€€nMo€€€€5€€€€ͺ€w€€€x€€€Y€€€$€€€B€€,><Bw€€q#€€Y0np_€= €N€ €€y€۴˕€D€€::q€b€€z€&F&':€€€@u€a€mm€€Pq€Z€€€ €J€€€#€€€€ř€€w€€s1€€[€€{€€C9)oȭ€u€€€€€€[€XaN€€€€c€AL3€m€€TLxK€€jE*m€YcX€€gm€;y €Kќ€V[€w€ Jn€{r€"€æœ(Z€€k4€)A€€€/?€€€€f€€PÑ¢€WP€]€€€÷wh€j1€w[€€€w7€w€v€€€€€€y W€pn€€€€b€ٯ0€|€€l €ÉŽ.Å‹vRM#€€€Ӟ€€€~€dU€€\U€€^€l€€€€€€€€K€€'€ܞf€€€Q5p€n€€€€€׋€FV€xF€C\{S€+o€޼z€0*t€€o€h€hr!޿€5€€€€;€€;€~ÒŸ5ySGiOk€@€=@e€€€€€€=r}€€3:p€i€gcM/6L€€€:/jj€I€€€-€MÚ…`€€u€€\ȼ}P€y€€♾€ijJWe€ _€€Þž!F€ €€€S€@F{€€T€€s2}€>ʻ€Lޔ€€€€€`€PFކ€~o€€5€€va]€€€€€ I€€|S€:€€0€d€Ft€S€V€v'€G€€€€€€ <€((B€Ú½>€€Su6 €€T#€C€€S1€×w€€7A€1oG€€7€ͤ€€n@€€€€€€܃-€€€x€:€3€ €{€€€+P5 €`&A€P€€€=€ե€€×3\€w]€i€]F€nv\2€€€S€eW€\€߬j€*a€€€i€€€€!€+~€ \F€€€a€€?&6€V*q€€Ó€€(€€€€J€D€m%€€^$s€€€V€-€$_ç‰"€e€ €EaA*Z€€9A€>|5€bG€}€€PØ·f€\€QVd €€nv€$€c€E\€€€€t€€8€Ë€€€€L`€w}€€€ €€n€g€~€QLf€T€S€€1€/€€j€€€€€€€Yc€€€NB€('\€R€€ʬ€€׃:€€€ѻ€q€U$€Z}€&€€F€RG€FO€€€€w€x€Ua€€ f€€€€€R€€€6€€€&5€ۨڣq€€vn€€Ñ€Cf€ٽH€€€<€P9€€PN€€7€C€*y€€€€XL€€̂"€+€€€UÈ­@ϼX€€i€6*€H€€2`€€X€s€€]3i€€1t€b) €€€€ph€€€€€a}€€€€€H€T€!zq"ހf€€P€€€€ba H47C*€€€S€€MÚ€q]€€Ƞ€â¾j€1e$}€;€€€€[Û¿@Vpx€۶€€€€{€&~€€t€€N€€77*€€++€6{€/€]€`qiy€"€€€€€
+€€ۘ€€€Vzܘz€€6€€€ܰ€7€l{€€Xf€g€Wd€€€t€€€€앧{}€€€€4ᨗz€it€"€€cK€e€€x€€€€€;-€i\9€€€€n€€Ǥ€€d\U€€.€€€€€ujq#€Y$€m€] €"€1s€ݮZ0€d€€€€.€€€€?€€^€zM€u€€ €2€Zd€`€€!€€ܠ/€s€€€€€A9€€€1€^€Z`Q€no€5 r€€€?=9<u€€H|€€€€F5A€db+*2l+.€̙q€~o€ K€€€/€€0{€€yA1l €!€€-€€€:/G<€€|K€€ €ވ|€.€€€m€FG€€y€>€€ކ€Kd€€€|z€_€c€€€€€€ЈtY€ €/€7S€€€€€€€€}€€u+€|t[8€1mÂ€Ï Ú«Â€j€€€fR}-€^n€€r€€€€v€€**^r€Rj€€y€MEe€€€ B6€€49€'ToЄj€€€#€t€€x€€5Å–€€€ƒ€€€€€€Œ€€d#G€€€€(€€€€|€.€æŠ!€ #o€€€€€€A€€7AF€€€[4€€!€€€D€€#€€€N€€l€ €€Y€€€f€b€€€€€€_@Õa€X€kJ=7a€€>€9€€w€€<€€€€h€€€€€€€€HU€l€O€X€Լ`€ €€-h'€-!€€€€
+y>€B€X€€_J€€€€[€€[€€bvE€\€H€€€€€€"€o€J€љ0€n€F,€€KÈI,€€€€-€€€€€Ss9s€l>'0"o^€~0:€MJ&ʭ€Br€€€€lW€α€€€€i;€f[oG€€€€€F€6€€q€ €€€|€€€w1€#O€2€!DgF€øzp0hO€€a€€c€€€€Gt€#Ì«1ÑŒuQ€€E€€€<k €g€€/€Ř€p€€€€€t#€j€€€€€€€€€1€`€€?€7€€D€?v€€N€N#€XG€.(€|€€M€@€€T€€Rs€€3€t€€€€€€€9X€imI€4X€€T€€D\€tNK€&€€0€b#€€€*Fx€p{}€-Q€ȳZttBc€7€€€€€m€€v€€B€€[€€Dz€€+€€€€€,Ks'€€BDOK€€Gs€€L~ €"€€"'€€4s€.€€e,€^€€zt€€1$€€€f-€€€€€€ȷqc€x€9€€€bNZ€€€€€`€€\€2/x
+Ԛ€Cwy76€€}€€1€€€-€€€k€€?iT€Kb€6<€€2€(=,&€+€€<€5€€
+€€E€ €€€€€€r€€€7€€€Qc3€€€€&€b€€V€D€€€Y€€g€€רd€J}p C!e|ݳt€€[l€€€q€~€€€Q€€€€ݦ€ٺ€lؠ€r€€€7€€€€G€€]€€a€€|GA€ȅ€_€€
+#€€vECSUgT€kM]€ӑT€4€€€€P|€€vnh4€€)qKက€\€W€;>€€€Xߛ€3€1€€k€€€€€U€BJ~iHų€€P€€€€€€s€fv€>€ۗ €
+€+€L€€€€Rp€2€l€^€€m€
+n€€5€€o%B€cK0>U~€U€€€N€€R˾7|`0€H_L€D €€#€{€Tf€P€c?JW€€€€€8ı,€€\N€XJ#pۣ€ !꼱5€€€c€ €9C€@P€€€€e|€€
+d!^U,€€€֊€€€8€ʢ€$€€%G,]€X€€€͛q€€€o€€o7€X€€€l€,€€€€ 2€07€€€*qz€)t€€€PW€X€€€1€^€J€€€€e€€€iY
+€€€€M€€€~ܖ€ÚΡ€ޗ€€€D\M_JԜ€€€€Ҝ€ [€€€€€+[Fu€€X{[=wӵ€m"oÚ¯Z,€O€€€€-؉A€€t^€€)i€€&L€P€€Ll+€Ě€xÖ—(F€;€.€€€€€€€€%€`pI$€A€€€€!€ B€6€S<€2€€f€^€/€€]N€͛
+€]€M€€|-ZW€w}€c€c€€€ €€€/I€[lV,c€N€€_€Ô€^€€€€€]€€N€Z€n€ J€ш€€9€˺:€€թI€Rw*Õ€ߕU€ѹ€€€€€€€€€€€XYУ€€e܅€€ɸ€€ֽ%~Ü­O€€>€€€CEN\D,€€!O€€€1C5€€[€C€€jpӆ€Ċm[1aw€€A]I€€€€.€€>}L€&<€€ €€@€€.€€€€€€)€€€k€€€€cX€7b€S?)j€€€€€PE€Z€j€x>€€€s3€,€ €"5€€qD€€i;€ €p€€xY1€€*\{Mn€€€h€€€+€€€y1U€A€<RW =€€g€&€€€€€€7€67€€€€€€ҟW€/l€g €€+€#=€€€€€€^€{€€€ €€€€Y€ L$€€ƸÉۘ€1&ЛF€s€T€€ٮ€J1,Ww€€r€}€]RN_€`M€L€
+€€N'€̢€€€€€€K€"€€€56A=€€Z`€€€€€4m€€€OJ€\€€€D남X€€<€lx€6G0€€(:€>gA€*4H€ €Ջ€€(0€#€€€€€$€Oh€DI€€?CuiR€{d#€7D(€ޥ€€€ €ʉ€5#€.z€äªÂ€ x€€F€{€e7€€r€%q€€€O13€}+€*;qYv€€€=\u€r€w€3€€D,̒€€€€€QAg€€|€P€x€€€€&€€€€€]G1e
+€K-€€$@€R/e€j"€€€HR-+r€:!€€o€€n€€U5ع€O€€/Qޜ€j€€€€€$€€€€€€€€€€rn€€€,€mΥ€€ߤ€.Pa€€€€€a€~€]$;€€€jɳ€՘ p6€z6Fd€bdI€€1T€[€zw€€]m€€€€3#Æž€3€t{,€€€€Җ<^ad€D€\'€€€€€€0>Za€j€€z€v€€c'€@€<€€€;.€€ R€I€€9cN/M߰€€€€€jE])€€€€K€SW€€kwAi€0€€+v€€€€€€S죿~M€$€3€€=€€|Rgs€€vb€н€€g€X€J€.ɼ€€r/€y€pui€C€€ €€€€€(6aì«¿9€M€7€€Mt€€~€€€j?p\q€€€VcN_€€€A€€0€cY:g€ UG3&2€wH€€€€€&1€€vZ€!€όh€p€$€€"€X€w7€.€}a€€€€f€\|€€s.€rzɲ€€€€€€€M€_qÊŸ^€€€€d€ ÝŸ^€ €x~5E€嘜€€p€€&€€€j€F€€`€€€b] )_Ã¥=83€ۧ€€C€ut€€€€ͺ€cf€€G€€*2\€d€V€u€E€Ѱֻ^€8€€€€€€€€€a€*€bb€W/ľ€€~ €Ì„C;'€`€FЈ€p€`€€'4)f€'Y?:€w
+€\€€G€€€€x€J€{(F€Q€ >Bre€k€€€6Ż€€»€€€€€€€t€€€=C€Ì€9€t9Û€€l< €shF8€€r'€€€ ;€vTE€5]q €€MZ€<€3€V9Mܺ€€gQ€€~0€€€€€v€T€€.€€€:€JQ,Cj€2
+tB€٩7€€i€€w€? =€Y€b€€њ€w/€1€€€€€@€€€€&€zxe]€}}€€€Q€€Q?€€€7€€C_<€oL€ €€€4q€&B€G <€€€F;ÑŽN€€-ljR €5t€Uo95 €€€€€€S€€€€r<u€P€-€€ €s/€'P3FV€€3€Uߤ€$H€€€€@€6d€€€€]€L€€€€€.€:=€€€a\}€H2Rai€€€€#€S€ޞ€€€€l€K€€aX)€€€U#]U€'gX'v€Ȋ€ɹu€r€€c€_€€€a€€zÕ”`€€z^-€ z#;€6t€6M€K!#ed€O1MJT€ 3&6I\€N€7Zß·(€€€€€€€€€g€9€Ys€€~pj€€€€€€>€f(10€€w€€€4c€Pa?cb2€n€l€€€{06€€F;€€)v€Ä€€€k€;€:|k€€€>S1€ €€€€€€cW€}I€€€[€:€€€Q}/€x€U€€e)^€€O€€/u€€,€€2€A€€€€7€n€€@€+€a€€€€e hSJY$€H€€!?5€€€€€ᇷ€€€H€€€(€€>€0€:€1` ^ 5€>€€[€€浚€,€/ €€Bn&Ò‘|g€j€+n<S€2>€€€€€€€̱ܟ+€o€=€6u€€nl€X€€.Ge€G2)=€€€€V€€ۉW€_R=q y€€t\gy€L€€€€€qxI/.€L€w\Uj€t]€9€&€ovY€€€€€ez€,€ۈ€|/€3€u]OY€?^pwh\ hG€7bK€€€€H€€€€€€fF€€yQ€v€€^€€€€€`€€€` :Þ\Z€€€U€€€€6a6€€jM)=n3SWV1"€R3€M€€^z€z€<€$€/€6€€€W€L€Y€€6f€€{€€,€€€P5ף€€€€`^€€}+n5€€€€V€+XQ€ *€€O2eN€€
+/7€€ €:€€`;€€B7jp€€€v7€€€7€€€€ €+j6€y€€>4€€)€€€€N€€€€€ܨ€L€%U*€^€Z-J܂0€O€"
+`€̓€3€€X€€€€€;€€€€€€€Z€€€뵙€€€€0€ݮ€€€ΉO€€[€E5J€€€U[€,!-€€S€€€€€å¹€€€€1KHǨ;a€€€€€J€}€
+€€z'BMr €€€7€€€€nyĮ €J€{€&5o€B€B€€-€€'5;€
+T€€€€€€€C€€€€0€]€€! W€ɇ>€€€8€e€€€€€K<€
+€kÞ<€€€€i€ƌX€€2V-€Ws€
+€;q€m€€€€€€[7:€k9€{"€€€€€)€€€OPx€€/ €€€€€€\€~€€€€€;׷€€€€<!p€€€€1€˿€t9€€NÏ€€€6?;€€€G€€€€€€}=rT€€€€€€€€€-€{y€€€€ë € €6mG€€pQ€8C€€*€€fY€I€€V€d€€k€!d$s€€€K€pʨ€9€wC€i€ȋSsV€€€}€i€dG6€€€k-€d\k€'€ Mܵ€€€€GÌœ8€€€/[vn€x€€€-9V€X€€}=€€5ׄC€€€ €;€€ص€€€€€j€5€€€;s€_€;.€[vi€€aM€€€4€N€€€€€ܘG€€xg€SkAm€€€€'€€€*€5€€,[€€j€X€€k(:€nM€i€€ m€,N€c€€AY€n€u€€€€€ƥ€֯`V€€€€cﴋ€€`€V"տ€€€€4i#6€7€€€€€€€€w€€i€P1D€€€w €€€€/€€{€€€pFi€k})O€€€€€€l`=j€€€ €`€)&F€ €b€€R€:=E€\€}_€€€p]U%z€3h߯€€xi€x€€ؕ€q€IiOÊI4Y€€€€LµH!€€˷ X€€ =m€€€€|€€ €€€€€€7€€€ؼ秀€€g€ؼ稇€!€€2\f`€c€€C€}u€F:€€П€€G€p€€€9x€€Ļ€€Ig€T*`.€,ͭ€ib€€(€€€a€ €€€L€A iq€€"y1ј€€€H€€è¤Â€€€€€€oÄ¢{€I-€K€€al€€9xK€€€€"€€€€ 
+€€>k€€€€8€]*D/€-€€u€€ €€€o€€€€ €€€ €€€o€€€€]€PBl€_?€€1QB€€o€€€€€€€€Ao€€€v'€€TR€/€m €€cz€€{€m€€r~€€-€v7€}€€6s]€€€~€€€-€€€,€€)²€€ M€7€€€€€€ߌ€|'>€C€€3A_->/€€"[€€€[n€€€#€fW*€€€€*>€€g8'€€3g€h€€
+€íQ6€€6€€5€ €€€SK€`16N[W€.€XWS€`€RkM€€€p€€€€€€ awkweavee.SYM'JUY9€€€€MPSTMPS €N€€€€%€$)}€Y€€€ €€kek€ir€)€€g+€€€€€€\€f€)€|€z[€€€€9€.€€tKm€u€€€wr7€.+€̓€€Q>w€ ۦ y€[€€€€"€€€€|a]B€.rH7Û‚|€]B€ '<Ï…C~.laÛ…m€€€€€V^€gg€€€bץ€x€#€z€€€€€€€€xV€f> ç€nuI€€t€LI€DHT^qs€€€€sV€(+€€NgiØ°nCK€€€B\ZY]€€"D?8€€3€€€€€cl€e€o0 €€#€€€€qE€€B%€/jJ€D€RQ|@€:*€J€w €€*€x€.i €€€€MK*€..D€t€€3ejH€€€€€€Bah€€WU€€€€|€€€EdY€=€€1G€€X€89€€K€€€€t€K6€€}€€€[kܫ€€<P€ӕS€3k€€2€€)€€~f€€€€/U"€ڬO!€€€€€y\€<€@€€%€?€€>€€+r€€€€מA €€€hE/ €€@' €€€NJ€K€€t€€#Z€€y\€<.|€K€[€€{€€€G€€€+€€f|€€€Z|€€{€[€݆€€€€C€ܒ€7E€^R(,€€U€Ց€t€|#7€€U€w€€€€€€€y€€€€e€€€ݩ€oR߻€€€=*€€d€€€€€€€€€'€€€€€€€€;€€|€_€€x5^€€g€€€€€{€|'€y'€!€*€€m€-€:€€€)€z€|€€;f€|€€x€€€€˒︵€€W€€€€;€Y€N*W€€€€€€€lW€.€T߷€wJ€€€U€N€€)L*€€]+ߺD€ݬ€€€€€€€€€€0€€€€Q€F}€[€€|€€€€€|€ժ€}€oW€W€F€:€€f€€>}yo€€€s€€ݧ€€#€€p€€|€€€*(€1€€€€ϗ€€€V€'~€€Ak+€ߴzo€€(€+€B€Ѕ€5€<€€€R.:€€|€€€o€€€€€€T6
+c€€]yo0€€€€€m=€€= €€^?yY€€}€"@€€KS.€ w€.p !$€~€€@€xo{owk}SCSk Qj}mE€€€C€x€€€€€€€€€7€g€wu€D€~ oUg€€€ -€@W€€€€€€€%€,€K€C_€€3€zU€k€€€€Ž6a]6z€ €W€€€X€€€4€€€€€u€*€€ׯoi€€
+t#€!€€3€!f€?P€!T€€€€{X€€€!:€€€p/€€Ge+€€.n€
+!€€Ӓ€г#^_)€€K€b€,€0€ =P€€`€}€+Wx^E€€€:Q|€€€€€€€zM€€qN9€f€€€ #€€ T€€{;Oe€€8T€€ €€€S_€€€€€€~€€۩€€ߒֆ€NoN€m€|€精€€€€€֖€vF€€^€'€V€MqhCë…£K€€€€€€-q6€€€!€€€Cr€d*N€7€€€€€H€:€€z€€€€a€€€€E*€j€'€ _€#€>G€€€P€%{R(f€€€€y4?qhG€굸€?€€€h€q€:€€\@ÓŠ L+€ֶ€€€€€€o€/€n"k€€€€€C€H6_:"Y€H€'€$ܺS€€R€;E€€>€R€€oq€€y@$€V€€a€€€˂€€5€€Í-€\BQc€€J=0€s€€ye€€€€€€ 5<€ӿ€€Ѓ€€€W€€{€n€€€€ 3€|€€€UfN€ϲ€0L€-€S"GG€€צT€F€€€€U€7̉L{€5M{€Q€7€€v€€€n~l€c€9€€€W€ Þ´Gx€€€€9€€ €+€€t€~Qs€ST€€€€€€€U.€L€Tj€:€*€ €€l€€€F€€€ €6€0€/€U€ €€€€€€!k€€%€€€€ȷ(€€€PH€€€sį€€3A€ь€€f€€€)€€T€€€[€€jde€€€€^z€/>€€€ €c€€eG㮼€"€€p€Dܿ€`Q€G€€€U€€€€€om&v'€€X૾8€W€€3€€8€€€€€d€€D`olǟװ/€$€€:€€k€€%L"€X€€€xÆ“?€71€Q[€€k€€€i€€/K€7u5So€€T_€Z€%(€ Ɉd€€€ q €€€€€~€Ï‹6`KETKUK{WSCO€€€€€€h€€1€€€€€€€€W€w€€ €՗€V€7€z^€j€,€t€|€/€z€€[€7P€M€€}€€pq9mg€€€ї€€€g€€€c€Q€€J€}€€=€qh3€€€z n-r€€2€G€:€€^]Q€€T=€€€€G€€гJ€€€"Rw€.v€€€+€€€€ˇ.{ܣ€|\€€$Ql"€€)€3/Y%€"€d€€s€€z€D€€€c€€)€€A(€i"€8a€<SJrDÚŽXDK€(u7Gc$r €€€Y€€N€€QR€€S€H€€€ L,€$€d€D€€qr9€€K€FQ*E€€{€=€€€€€c€[€€x€~€}€q€X€€€2€#]€{€€#n€€˸G,<b€=€€€€{$€#A€€g€€€P€€W€€€ =€€€|O€€(S€€B/€mQv€F.^.€€€B€€€%Kls-_V€€€ Ӛա€Sw!k€€,€;J€B;8€€jVu€S=r€8€€tYٲ€e2~€$s6€€*3(€ €3€EccYr0t€€m€6)€€5€€€€€ €€€€2;€k€€'lj€€d8€TQ€7K€€€€€S€€(eR€e€€P€X€€€€€ f$€€`€€€€€~€{€D%OX€€€ˀ's€€€€_€€€€w€L€;|vÏ‘%€B€€ê–¢K€€c€€c€€sp} €<€q€€€}U€z€€€€&€o€€{€€€€3€
+€€kl€[€€€Ӿï’Ž€€5:€=€€€€ï€\€€€€€cN!z€€٭m€€€€5V9=&€"€€="€€€€E€5€€FDZH€orcJgÄ”n€€x€o€Rq€€€.€€€€:3S})V€%€>^€|€€X€C€€ID€q~L€€v€€־KB€€:€€€1€+€€ _,€€N|y€kBD€1€]€€€€€€3PU)€=Շ€€a€=r€7 |6$€€u&€1€€€ͽH˺€"€1€NL€€€Z€>€wm€€"€€€€€w€€€/Y€€ϊ€€€X€€€€z€p€y3pY€€|y€w€͘€€€€Y€D€€
+€€|'€(}€€v€/€>ݾצ€€m€[€€€€?€€(€€-€€€€€€̼€Ϯ8€€€c€a6پ€p€ }€u€,)€k€€`€ޭ€€MEPcI1ґ€sA€€m6d|€ӡ€€{k€ZgߌhM€€j€€K€€€~ߧ€}*€R€G_€.€€€€L€\W€€€€=€€€
+wЛ€?o€Y|€€€€€=€Z€3€;€]E\A€€Y€€€€€€ = J[g[O[C{€Ɔ€€€N€€€€€€<€<vNuw;€ ȣ€Vp€€€8€c€€S€X1'€o€€€߾€€|€€€d€€I€€€o€Î€;€5€욂$€ۄ€€€M"€€[€€co!k€€€C€€€€€€ȼ5€€F€€>€€€€,DF€H€€€€9C#€q€U:C#€X€ko€R€€€€€€Ȼ
+8€(€;€*€>c~€€€<~€€`€€€€€\€P_€Ä€€
+ €€€1¾€(€O€€Ʒr]€g€ \€€Y€€€6€6L€o€€:€R€€€7€@€€€}u#~€5_:(€€F€€€/€V€€€€€€€
+€€><<7؅€b"^€€܀€rnp€@lʢ/€EgmEA&€\A€^B€€v€€€(/O€f#€€€t€€A€€€€>€€€[€bH€€€u{€F€€gH€^Z€€Ro*€0€€€,4€rW€І€€u}m€€cG}€€7G€Yr4€€7+€7€|€<€zǀ{€7€€€€€>߆y€€@5€€eI 0€)€€k€&€j€€~€\籣@ɡ€€
+€]€€€U€€€€][Q€€€€1{4€€€€€5€hQa€€ZM#€€5nĄ€€€B+€!€|ϱ€k+j€ܷ{€€€ګy€€€€p€€€€€€€€€€€€t/:+€g€
+€@€€€*€~€>€aVtO€T€^~€8€su€€€%?h€€
+L€WÕ¶G€u€€€€€H€€€}€T€€€€j4€c€@€X€€E€{€€€f€s€"€€I*xÝ‚z €-€ڣ€*s'{€kU€c€]€€ͻ€/€h"t€2܊€`K'€€jw U€^dǨb€S޻€€€?€J €‸€€€€gTj€€(#€/=€r€(€*t€(<€It?t€€%€€QY~ u€€B€;€€ʊ0€€1€do€ȧ€€>€8Q=€+q€€€€€'57S €€"€€,€G€€o€€€Э€€€[05f.€€b€€€1,€€ל€€€€€d€€u`.QZÞ»t3€Ex€. €+ւ€A€€g€€€O€€€%:W€€؛€%Å®b_€5€€:€3€€€€p.€u]€oX €uyx€€€O€€€€s%€ €€€k€[€x€`v€€L€]€\€zq€/€€€x€€J€€€ >4€"€€i€€€€€€y€€€€D€e"f€€~€€€€֪m€€€€(€?sQ€Q€€&bZK€f€m€m€€f/FÇ”S€/)€ٙ EG€€€Ï€€€€€€€w€€€7A€g€€.€dÄ›2€€€€|ե€€€T€€TWV€]€(:{E€vY€݄1D€€X€€NA+ʇ>W_€€€€RθF €"D.€]b€$€€€L€n€ɛ€|̔€9T$J|€€|€€€X€€p2g€€€1~€€"f%€V€]*€€ܵ€{€€€5%\€€xEYqI€vd*3€6€€_b@€5b€"9Coh€ €€0C€€ٳ€%KVU€€@'{€U€
+€€^€8F€€€:CG=€Q_=€Z€€ a€€(€€€^€$€€7€€€€S€€€€€I]€Rj,€[€o€€€dUU€%I€€€€€€:€5€<:€03*€>+s€U_"2€€€€€C€ 1U€:€€]€+€"€€>?€€>€€€€l€€B€\€׸`€€€€˺€=€ K€€€E€O€yYyoּЈR_€€€€i€€€€€€sK€€á{ր$MO]€vh€ €
+z€€€*4€€F~|€W1m€€€€7++€~T(~€€€3j?ܯ[€€€ €€<O€€y€€€б ó0€€€u~€€€|a€€€€€>€ €>/y€]€€+ѻ€€€€Y€€€ɣ€€%€€€qG€F€By3€€€|Ø¿ €€w€=€˵7€'a€€]€U€⨬€€€€zz€€0€)€ €€€ɾ}€€=€€{€€ѷ€€/TVx€r€€€€€;€,€E9€€€H2©,€+$[€⒋Ct}r€qCSWGGWg=Í€€r:€,~€%sf€s€=`{‰€€r€%€€€€f=€W€'U€DÕ›z€/€€€€€€€€W)ʜ€շ€o€€€Rè”u€X€{€€€€z€j€€uk+€€?€{2Lؽ€€€€ݴ€ױs)€/;?>€̾נ€ 'tÖ¯;€V€€A€4€€€€_€W6€€€€"€1€€€€€€o'€€€w€€€7€eHnX?
+€ym~€W€€۟€<€€€
+L€*֚ €96>gK€}Q€€€i€€€€ݹ€€Z€k€€n€€€7€d€P€€€mlM€€€RC€i€`m€€€€}y€€€€€€€D€g2€!-"&€€ €€Q€€X€€pf€€V€ot €€€€€€€={€ƪ € Z-€€€"€€€€:Z€{Z[ꛠ)€€€7€z€$,€€€c€m€€€~A€€AO€€~tp@€{€€€€€/€€€€€A€€#e\€&€€2?€€'€€€C€€9?3GeK€€K€ܑ€T/€GiZ"+€yN€r€€€g\Z€D€n
+G |Tﲞ-j€M€€}W€Y€^€{[4€q€G€]€ʊ€€Y=C€€Ԯ€'Y€P@q€€;
+Q€U€€€M€fx€8۽2[€€
+8€€/€€㼗€f€€€Ï€€"€y×€€€S€€€€€z€€€<€}€x€F€b€֩fr€d€+€z€[YK€€;€€€y€€p€€€€€3€€;/5©΋㌪€(€F€,€ 0€€€€€T€€yma@̄€€ >€€V[€€Q<{.€€€€]€^€u€€_#€iL€€ PY7@1 €9<K9€UÆŸ€€!€€€€€1r€؄€€{'Pr€€€vóR€|€/€4€€€k€€\Uc€€€|0€€€€r€€O€w€g €(€כ€€ Oo€€€^€M€CR€€.6|€/€zM€u€€U€€€7€€P1k€€=€€€€yz€€€€€€€E€€I€4€?G€€€!\€€€}€€G€9
+€€€mkD€€€.€B€)1€k"xx€\€€"€g€€€fq6Ll€喝XØžUmØž€€bgt€#€€€€€W€?€#dtAy%Y€€Q€|q€€€y€€€y€ShÄ“=€€€fs)€G^€h€.€u€€`€(6€Ql€l€€@r€€;€€]'€va€ᔳ€d€€€A€€g€: ׂ€p€€€\G€>€€Z€¿€d€'€€=€e€€€€€€Y/3@B€€€€p€C€_T€RL€€
+8o{׆€€€€€Pp:8ԇ€̶€S€k€ÉŒZ€2€€7€[#€Y€-23€I€պ:€€€#p€€€€€€`&%€€€€€€€€wg@{€W€€€€€Hl€<媬€1€t3€깣€€a€€€€€€€"€K(€ؓB€€u\[€,t&€€€€€€u€*C€€Qx€€*€C€k€9x€sh€€`bՌ€À<gp1€+?l€
+€€€€PlC€vt>€͞t€E€>€:€€€SU€U €"B€€p€€€€ €€'€€O€€f€€€€3 €Ӧ€€€€€o€€€M€MQ€6€€€€€ €€h€€€€jo€A€€k€€˿€€€g,€€<iU€€9N €x'G€€€€T€€€€}2W"€€5~€dlRe€€€" KS€1q€T€€€€A€€€k€ղz€€Y9,€€€TN;€€D€€#3B€€€5€€=ư€;€€N€=€€͚
+ €€€ig5yŧ
+4rkv€€ €h€€ӮUÅ’ZRZ€\€€6<V_€€€*0€*€€н €w)€€€€ *5€|q€€€o€€h€€<ajz€€Ob$€9€N%Ý€yq.€_€&Ewr€€€`€?g%G€€€€C€€€X€u€$i<€€€ԟx€xe޸€#Qm€€€t€(3€+€Ë€€€Q€€€?'y1€zƸ€wN€Ce$€€€€J<ÔŽT€€)€€€€'F€R€€€u€€€€€€€€V€€E€€V€€€€f€€w€€P€€€}$30€B€ N€#NÅ«S€€Y€b€3€Þ€#€€qx€€AT1€€€zBD€€€€€€{U€€nj€€o€€U€€hNM€I€€nY€€€e€A€€Ò€΀ j>€€H€€IW€C€€ɮͮ€€C€€ €w€hM€Ue€L㋊€{her€€cN;tmV_:1€€M4A€€€€<€€€€X€Y9€€€D?€9l€y€€€<€K1 €€€~€€€ G€€€֧E4-€€€>€?€€ €Wn€Q€F€€S€QU€(€€\€€€€€۾I€€€xI€€D€v€€€€€€%9[€€€€€€€k€€J€€t3€zÆŸg€W€4
+€r~€€€'€n€€€€$€p€€WM€€+'€€€€€k€ب€<€xY<)€ճ€€lմ
+€*L@€R6€7€|\_€7€S€€€թU€€€€+Tx€€l€c€JT€A€€l€*€€€&€€€|€€€7€<€€€y€€FO€j5x€€]€e€€€€€ -€€€€€#€€€ h€€5V€€€€Ѻ€€€j€L€^€€€€€€€ €€fcK€Lj€ €€€u€j€€$€ j3€€€1(€peI]€€x€Sn€€€€€€R€€€€€€l€€€qW€iU€€+?€+€€€`€*͆U2€ה€€2€e7€€€€?€M€€B€%}I€Q€ €€€€p€€€e€0Xhq€F9€xs;€=€€B€€w€t€€€N€€€7€)€€7€A€4€ysk e<€f€€€€€€5^€€€€€|€€€€€€4€<€€3"€BS€€€€i€~€€€s }u€p€€$€O€D€n€€V€€€l€@9j€€€'€€MD€&€i€W€[€€D€;€€€€\€€€|€€d€€KY€€€"}€€H€|€0AK€I €UFXHC€€€€1€Dh€€€€!€"6pOs_
+c€€8H€€€€C€U€€€<6€h%€€€€€I€€؊€#€]€U€'=€O€€U|€(€€L€€€r€R±n€€hy€"}€h€€ €|€€€€dt€€u€€w'y3€Vz€N€ DX€€:€7€€:G€ K€€€€€H€€U€€€=xLj€€p€€-€€R€W€€€€xkɬ€ع€no+€Ur€€€€€€€]€hkI€€a€h֕€ٌf€€k €€€>>€V€€€€€€dm}€VZ€€}~€€€q€S€q€ €lɂ€>€-hRBb€b€€€€€€€€_€Yx€€€x€€€€j€€€(€€€€b €€€€€_€x5€€€€€€€kT€€€€~1€o€+€€Zd€€€X€€€<€€R€€uXl€€"€#b.^?€€€/€/€€€W€p€€€€ϯ €Upv€€%€€€€€€UB€€P €^€€€=Ǔ€€€gЩ€€€f1€ᛨ€€€}€€VD€€€J|)U€W€€€c€€€*€|€[(g<FBO€J6€€<v€€*€ʡ<€€€0€)€€t;_€>n€q<€/€€T€>K€><Åϲ€w€€)€€€c26O€€<€€>€Oϔ€ƩY€1y&:€€)€[€€a-€d€€T€€Q€€€€€a€€S€<8€kx'€⑩€€3€ú€€€>€€€aޘ€€?€€€Sq€;€/Iz€€€€€€€€3€c€j0€€?€OZX€€€I?L€xrxp€f Q€€҃3V€€R€oL[8€€c€Av€€€`1I€3߀€€1€€€+€Q€€|€Oe€€ <8€€€€<J1€€€Y\3ͯo€€€w€AW_€";€€€€€€U€R€€€M€€:€€=€[Nz*€B€7€€€€!€€jZ€€ib€€y€€€€^€€Ц€F€€€€€€€€€P€S€€a€€7€€E€€€€^s€€€/€€/€0€€R€1M1ß¼;&r€€A€€€€ x€4€q€6O€€c€P嬲y€€€_€jГXG~4€ƫ`€|€\)€糅€€€w€€eC}€8€Iu€9€€€€Uv€€€3P €U]€ )Sv€HØ«U€lu€€€C€€€֬€ܪE#€G€€>€€Í´E#€Y)€€€Lz€f$€€s€€>€0€[l€€*X€m€€C€€€€:6a€ ,52c€H€€€€J € MO€€€€x€€€)€(€€o€f1€3՚€XfKKt~y#UMK€+,ɒ€'f`€€€R€€€€Hx
+€€R€(&€mwҘ€€30[L€€M€B9€Г:y€>u €€€;h€€€€€Q€gw€i€r€€1m€VZ€P€€Y€€€UP€@€€€_€f€€(r<€€€Ƙ€xt€€Z€€€NݶnR€)€€€0€€. €'sh€uJg €€€ €E€;€ᱽ{]€€ĎFh7€€]C€xg€g€/€ €5I9€€ D€GfsÔ“3€m#u&€`€€4€€€€€0+dR}b1€[j7lE€€€W€ x€4€a€d€ €€€€€ïZ€€V4€9€€€€Vu*€m6€X€|€€€潄€;O€€€€د€€[€€€1€€y6€!€!€€€+€6€€34€(`|Jt@G€xÖ€€€€W€€j)y€€YQ;9€€ €#[€N€ €A€€p€€G9y€V€€€W€4€€€!*€€€ÉV€€=€qU€{€Y뀊/€€1€€f$€€€€€€€€¹€ €}€€€€ludq`€E€9\€€€P!€€$<€s€z€$1€"q€|€€€$l€ ;€€€Y86*€€֬ǺUl€€Mz€Wm€m€nh€€"V€\€Q728€€&€€€€€
+€[€€a€€h€€€ޜ€€€€èŒc€€€€o€=€€ak6sc€€€Z€s€€˦h€€€€0G€>q€€€(c€b8ν'8€€ѵ€Q'f€f z€€€G€g€g€Z€u^€€#€+B€Sq€EemÖ€w*€Ņ€€€€#€€B{€F€€gK€€€€|ሯڜ€]bRo+;€€€!f€€€€z€1€#=€€Y*€€€€L€€N€€€€€l€€U`€€P€€€D̳հ€€€€€-€€,+}u€€€[€,_9€0€pļOQ€€€G€€€p$G€€€#€€€|€x€b€s€€5€€€9€yp€(p€€y€|€€€€€€€d€c€Ma€S€n€d €M€q€€L€a€9€X€Y6b€€_€€€496l?5?€€u€€(g€x€€s8€&€=2€W€v€M<€€€Ij€€€:kT€€€S€€€€>€/R€€lQܕ€.€€€€€€€€ Bf€€€ m€€€g€€@Qۮ?€€€€+€€€;H€€
+€
+eɘ-e€€€€€MG€€€€€2L€€€€€fd€@0<l_€7ȹ€€4€u€€€ӱ1=4€P€ⳜX€€Ê—l2 €e€4?9€€€€€€:P€€(€€mE€€€€€€€q€€€€€€€€€#€#€;{E€]i€z€€€€€€€bO€€€ҿ€ €€€qh€6j€]€€€=€~€D€b2€€€^€€€7€€<€€P€ix€U€^€€ =€VE€€gU€€O{@€25
+€€=€3w€€€ujS€E€€s€c?€€JϚ€=O€€€(€^uRf€€=€€€'€€gTl€-€<Ɍ€YWp~€>!€*F€€€u€€€;d'$~pT€€`{c€U€€€X9€Q€\{€€ €(€ €€5h€wM€€r*ޣ€€?O€<o/€€Oœ€ N€{€2€€€€€x€€yp*€Tl€€€€=6€€w€=€x7M€{`<€5€€<WNE€€n€€<S€Xs4€€z€63€€GC€€€€t€€€€€Ô­€€9€o€b€€€7` €€ v€T€€,€&€€y€ս#GX€D€€€MM%€^€€c砫€S€P€€€Nu€Y.€O€.w!€.€>€€2.Lb€€€€u€/;€1€€€€€iÌ“`8€€,€€€€tË°[Ù³z€€XU€ d€Zd€#v-€€#2€€>€lh€€€€€€p<€€;€-€E€
+€€ q ;xR1[X€€€měr"s€€^~€}€€€Z€€(€4€€x€€€ho,€rz€^t€?Ή€x€€€€€'€€n-€#€%€M€Q€€q€d€yS€d/€€€€&1€ͥa€h#.€€"t€k€€€€_H€€Z€N%VH€€€+Ņ{)€X€zSx"W€Kd€X]€(ms€@E"2^€€M€L€€,泰€L(€X€€€€€(Pǖ€1"€€€f€€(€€€€s€€€€€€€€V]€€o €€€€MQ€€E€€€ €q€M€/€€€m€i€ݪ?
+fˈ€->€€y ;€€C€T€;K€TF€fO€xd€Ѣ€Z€U€e€€€cDU€mN€{'p€&J€(€€€€{['€}G€€]R€€€ۃ€O€5O€€V€G€€׷bo€Yn€€t€€[€03a€x€€v€€0€OQ€€€€ ꎓqe€€Pi€=€/€€€€{€€Ʒ4i3€do€6#€€,f
+€€xy€՗#ñ€€d)€€u€€€W+€pO €€€€~u7€u€€€€€€€L
+u!€]€€bP€€i€VB€€ϘpWs€L€€€€€€w1 €€€€€€€ €€€€€]pN†€DR€€^`E€ro€3`L€M4€€U|€€ɰ6€€€E]€€d G€r޻A€€V€M€m€€Y€€W€2;€€7€g
+€€7PM€9jc€NfB{€2 €€R38€k
+v€^€b€€Z€€,€{n€€€€€€V€}€€7x€-1R?7€#€€€€c€B€1€KV;T€(€€a€€€€K€€€ %€€€j€ٚ€G€_CѢ€7€€"a€lP*€x€ ͆€#:€€Þ•w1€ϩ€€€€€€;€Ѐ€€-€T€€€€€Lj=ìU3€Z€fn ՜€€_€€€€N€€fEȘfE€*Z€*€€€ €r(e€e<1€€x'€D(€2€Ĉlf€€1€Ұ€€@€€€v€€€0X€€€f9€€aP€€€)€+k€a'€_3€€,釼 p%€]C]€€p€€i€€5r̼u€e€€u€€€,€J€{€Y€€€""M€c€/bH€€i ؘ€ٌ€€g €€€1:~€€@=€?€^€P>€€$€€xY€€eÞ½€€€€€€ݮ€€€€€?€€j€tf€b€LG€€,Sj]V€€y€i*h€€{€€€€]5€€TN€>€€HЬ€€\X1@€€'€€€€O€j€€/€6€@B€r€Yl€€€{ €€€€~b€B,€O:€C€€€€M€€'ۀ€€€M]€€€5€€Ƙ€€l€€€OT€O€Ca2V#€?€h€€c6o*€R|&€b€€:€Dƚ€ D€€qfy€&€€ĺ_u7n€€ho€€Ú†€€m€€€€
+€,€€€;S5€€€?€€<n€:1g€€ O€Z €ojÀ&ٙ€&/€rKo€€€R€`#€7€€*€€,€€€D3€€Psx€€9(€{Nf€ʷe€€€€€€€€({€€€€H€A€€R€€€o€Lä®Â€sN)€q€Y~ €x€]-€?€Ë€֋€ G9€A€åŽ_/GY€€q€€€?E€(oѦ<\['3!u/t€b€€€€€g€8m€9€{€ιW€€€b€€ غ~€€é¼Â€€ҿF€€€yUucu€Z€˞̫,€€$€€,!€iq€€€}€ x€€€€€^€#7€o€]/i{頇Z€m€ €€Th€ނ€S€/€€I€€ڄ€y€@€€"€€b€€I€€'q€€1€€€2t€]€Ϋ[€۪€€€>€#€€€€€.e€n€€€z€€rW€€€€=€}€챑=xk€€€€€€€Y€(€€V=X€v€ƨob:z{ÔƒU€G€€z€z€€#€!€B€€u€€z €€{p€€zH€ս€€€e€P€€€€=€€B€c€=xo{€€€(€b;]€1r€å°Â€ €evg{9€€~€€]€ѪwG€V€P7€€€R7-€C€K€m€€vÚ–`9€K€€€€€€€€r ~d.€oÖ¦P[o0G, €€@ €Ill\D:€ʅt +€{€y€/€€€|€O€€( =€Ḽ׋€€€WFY(_€€€4€õ@ob€€<€€€€€G€€€€=~؛€€€€N€g€HX4?€o,5U#€€€€GL€€3y€Уt €€ €€€€€<v Ç™{*€I€€y"€€€€!ƶK$€€p€{€7€ €€ѽ€€€€ͰQÞ¬ix€/€€u96LV€€€0€߬膂€€€€€€xTIue{€m€€Æ9€€€pG€€ne]Í™+K€^€€ٖnV7€€€€r€4€€€@€€€*oI;剻€€€AÏ‹dS€h>T€ q;L€x€€X€€Ns€€r€p€;€6"€€€€9~€J€ԨS€9€€€€€€€€€w€€€€€€Ȉ:%€h€8"U's€€€€€y€yQ€€M€€j%j^<€G€€€€€€:€€€}7€3€WG€€1ÇŒS€<€n€=€€_Xv€€U€fv{î“›R€Z€{€"sO€a5€€^€WE€E€H€€€.€€U€ϩ€€Ry€{e€€%*€€€€Ut€J€ 5m€€€157ijxSp8€€IN€€o€E"?€ €€6€g€>€€€+m€€8€€+K€W v€€V€€<>€
+%"^€G)€\€9 w€€Vq€€€e€€€€\€€€X€\W€€€€€€€6m E€o}V€h}€€T€€€֧€€h€O6€€€P€€%WozѦ9€U€F€ M`€€\€8WaVbÖ #€ €<€2€L€r€SY%k€rƫ€€N€€]~€€€€€€€P€@I€%€€€%€/€€I{€YA+€€€€,€Y €,S€ϒv€|€€€€Yb€F`Y€€€€ӎ€€,i'V4'€F*Q*qN€5€€€€bx€€R/i>@
+€€)€€.N€€b,G€Q͈9€'~€G€€H6€`€|€€{*€M€€%↴ €xok€€€qi€€€Ȫ€h€€ÚŸ0:€Г€@€2€v€E€I€€{€w€$2)^€½€€€մW€Dm€n!€3€€€U€€€µ~€/r<€€€8)'€"€c€€EУ€X€€€N€}€O€?瓸€€ɴ€"Ǥ€€€€o€̱€$€€w€€T€€€eo€=U€~€€€€= €€L€~€{€€€{€z€+€€€€€€€€YZN€X€s€€€€€€€€€€I€€€€€€VI€€€-j€Q̦}€€5ad<_€$Ûœu€[€'Y_€_Y€€1€'4~T€€~^€ӑ€qd€:x€f€€O€€z€€/P€€8€€ړ},+€€€€A€€~€IU:8€€€(s€€€de€€n€€F€€uS€€€yJ0€'€€€>€€€€Z€g€Y€€߫€x€E€~€€|€€%X€€,€€€g€€Ϝ€€€UpF€D€€€:€€€€3€€<>€YD€€sի€€€€S €|€w<€€€€€€€T€Y]€ON"€€€h'€€_€B€€'€€€€Ӽ€€<€S8b€T€RO€€€€]g€€rÓ¢ €.€€W'q<S@€r€€]€y€€5D€N€х€`€€€j5Ƈ€=p5€€j?A€$€€2€y#€;|€€bK€€€U€j€€*€Lb#Up€I~€~€3T€€€~Äš`€€€3€m9€€q+€6Ò­2?E{ E €€€LC€.i:C€€€h?z:S€€€(NÌfxyk€8€€€/€}€;`k€]€ b5€`€€€ڼ uj€1S€LR€€\€€g€_'8€€€€€€ك€€€,?€p€R€€ €€,u€€€€'Y€J€-&€€€€€>€7€€€O€€€€I€=€€c€?€€€|€€€€^€h€f/]€€A}ϖ€€€€#€m€€l€t€€€Y/€€€f
+€€XKT€t€€€€€;€€€€€€+N+€€)€r€€j€m€€€vc6)€wP€€TU€€Uca{#{€€ :€dG칓€€4€C€]€€D4€€hX?€Xn€€€T€\M€*€€€{!N€Rdz€'d€€#F€ژ€m€5€€`€€€€R€r€g€€€j€€ 4tv€€€€€{€€Y€€ ܨ€€eX€H;6(€f-€€d€E€T=€€€9f€ԭU€€€€€€X€N€€mo>€<J€€€ql=€€Nx€€uT_€€€k€e*€€€€€>€裗e'€€ €€U€a9€€€[Ğ€€˘E/€bx€ €7€€ {€€ ֥€€C€€ >E€€€€,€€€€ g€"€€€€€€r€€L€[B€8€*€W€Az%€€+€_t€€€€J(€€F€€€J€€y€z€_€€€€q€€€z€^I€€€€ o€€€գ€€€' /hN€%€€f+€€ĜVL€€€ gÛNfC€^€C6€€€m€€€d6€€€€€m'€ Ξ̌v€€]fȋ€>€€[€€d`€€€7ol€€€"]€€€>€€Wr€ €Z€€€$~T€€ yIN€€3g@ €b€%€€€J€€~€W€?浉€€M'Ñ—:€€}€€{€€€ €€€€€€€i€€€€€b#o€uR€%€D€€y€M€€€u€€€"€€€ bNg€€€€[O€€}€g€€D€M€L€€ €€e€7€€ €€€md€€V€ €€r€€-€o9JV€€pd€€F€ €vΆwt€ €€€€3 t-€O€€€2€y€€0€͓€€0€€x€S€€Y'€€6€€€:€t€|€€€{€€€=g€€€€~Ug€C}€€ޣa€€5U€'€€€€q€=ݖ€u/€92€#€%1€J€€}Ъ?ß´7\€ u#vF€€B€,mt€]€"oE€Knd€+%€>3€d€€€€+€\€€€|i€F€€€€0ހ€€Dx€€€€€X-€€€€€8€ml€€€R€^€€€Ѷ1€€I€€€j€€`"ë'kO€€€€lK€d|€z€€€€Û¶€€[^Þ£n€kT€€€4.c€€€>€€DѼ+r€O€0€#*€€"̷€€€(€7N€Z€€€€€n€€Q}€>€Ù î…‹V€u€Z€x5€fU€€€€ۄk€~€€€T€i€ €€€3d€€Én€€€ %[€}€€€€ C€9€€€€C€ƻ€|P€€€€€€€€€ {:€€BbH€>€`€wy€/€dw€WY€€€€€3€V€Tƃ€€€覡_€€€ßE€5gg€o-g€7d€ €e€€u€€rzgZ€€)€€5€€€ѥ€?SX €kּ€k€€€€€€€w€€l€€{€€€€€N€׿€€€zn€f€mK€€ €€€€K€€€€R€€]€€mW€€€!€€€+€x€s€€€€€€l€€€€eU€€€€€€€*€Õvn\L€€G€€/€?€{€€€cc€€[€€9€w€€e&€nR7€€;Ó€n€€€nb€،}USwU€5€[Hk€€€€*i€€\€€3€#w€姺€0?€s€€m<€@_€€€€h€€l€_€)RÞ„1€v€7չ€o€@\'3€s€€Te8€€€€€€`3]€€7€]I€?€FU€H-€3xY19€€€€E€€vP5€>Y€€ €f=G€q{€€€€0€v?€€€޲€€]€€€?€€€(€r€P$€iA€Ud.<€€€€܊ۅ€€d€€€7€?€€m€€bv€;{€€€î»Â€Â€€8€€3€€[€Q€ €"7gX€<(g|}€qgÏ„€S€€€€ê½Â€Â€7€€D€X€M€€=€xi€€Df€؊;€€€€€€€D€€'@€€,€k€€r€€€N€ˠ€€ €€=€€€€€vD€a€€`€ИR€B€p€€G€€€/bc:€t3€cO3€{ O€9€>€TÃ/€€%€€K€€€H€ޠ€€N€€-?€€F*€€7%€
+€S\\€€k€+€€ €)kE€C€z€^1€€€€K*]Y[€€€€/V€€ €b€€ g€
+€ €3€w€ 8q€€€Hw€x€€€zh€€€G€€€€
+€€€€,6yh€€€s€€€€€€€4€_€dlK€€€€€*€A€[8y€˥q€D€[e,0€€M)t_ ]d€€€€%€7€€€€ჸ€€–€
+6 €€N€_]R[€] €€tw"€€X€w€Hvt=>€n€(€€7€wȫ€"€x\€€€(c€~€€D|H€€€]u€€
+€W€€€W€=€€€€z€€€€€t€/€n€€€t€`:M6h€,o€€€€€y€€€€€%sQ€€Aq€4q€1€€L\ €€€€€13m*e€€€B€8lSI €€=€{W€p €€1€u€
+ €€1,€€€S€€ݠ€eWwH€ €ﮧ€U€} 8PT€"Q€
+€
+€€€g€€cdqx€€1^c€€cu]G>€€y€%1€^€;Æ—€€/ـU8€ JToT?€€€€d€€vI{€j{b^y€€&€€R€€x€€V;b4€Y€€€X€ƕ€€#\I€{Ì®v€Ie€1€B&}€€€€[U_€[€€€€€X€€x€€M€t 2E€€Ņ€Ut€Yo k€6€€b/4€-4k#€`€>€Ì€€€|(f€€~<W€~U€€€epހ€o3U-€+€Hæ©€}TS€€T€€€€€&€J€6Pp/€~€/X€€ =l€€€€€H4"€n€€€;Oǔ€N€6ع€€=€M€€€€€€9€Ƌ€€h?€€2€€z€z€e€€@Åg€S€€€€€z8J€q]1/€€NQ}>Ç· €Z:€}€€34€Z€'€v]€Žk`׼€€=q€€€ Z.€€€€'€v€€€S€€€c€€€z4€€o€€€€€ €€ݨ€nVb€!O#?€G凸€Se/€€€Q€0$€€€.z]€€€Y€V€cZ0€q€Y9€€!€€u4€€L€ g€€€€hU€€€g€}FǾ,{€€UZ€P€>)ޕ€€ko U+ï“‘*R+€w€Z€€[k€-_€w€€Sp€€€*€€&€€€€>€€gu€F-€€€Qd/ͱ€j€€€4€a>€€0€E`i€€ Ne€€€˙€€R"€€€n€)€€}€€yD€
+€^€€Bt€€€€&€€ €€€D€€€€~€€Wܧ€r€׌ß“t0€€d€.€€€"€k€€€€€€€€€6~€€€€{#\I€킖7€}€€_€€Y?~€wp€€€€z€€Mn|€w€ᒪ€€p€ϯ;€€_Mq€€€`€€€#€k€&€€€?€€4€€€€€g$€a€/€€€I€€€€Et€€€€3N€€€=cB€€ə€€8€M€€M€5tIy€€€ P€€€€ €}>€€FxùT€yމ€K€€?€€R_€+r€Q€"E€€€€€€=Ä™ €€€€z5:+€€€-€\€€+l=€K€€w€J€1E€T$€€€F€€€q€€P€Xn?€€€zT€€€"€0Q}€;€€Q€€y/€+f€€2€dk€E*€>Þ‹2€7Ë»g*݃7N€ |\޲€]€A€W€€€b€J€€?Q€€€€X}€€€€€*O€W€>dU€€€€-€€€|€1€o€y€}t€l€r€€C?€Ț€#€+€€t]ч€€q€€€€€€€€€€o5V€zY{R$€>€€?€€€€,y€9€€1a=]€Y[€}€€mÜ®}€z=%l€€€S{>€(€€€€€6rr€jZ
+Æ„g€ء1u €5w*€€€a€€€4€€J€€€€€€€p€y^€Vr€ﵟ€€qB€€€€\º;€€€€€Q€€|€€q€a€€€€^€€€>€ȅztײzӞ€{€€€€r*v€1,€Ye€€m€8u€€€M€,J2€Ì€€ي €€j€)€uRM€佢N€™€$M€€€€€€ޘ€w€€qz€xRC€a€€€ €€4€ʨq€€W€€Q€€f>€€ؠ€€€€€€€€8{€OD€€ͼE€YΚwZDP€€VwO€€€€€€€ȑw €€€€3€€J€f|%€JV€hÊ©]#€€€€Ef€€€€ 8€j€€Ή;]€€޹€€8w€€(R€Y€)€€У€€9€€€€€€n€Y<€upE€#Y€€€h€=€€€l€€|€€P9W€€€T籲€Ɣ}@€ھ€ԾW€+€€€I€€W€!€JwD€9€^'5€R€I€ €~€€J0€c€>V€€q€/€u€€Z€U̕€[€VÖ’V€€˶€€€€n€€0~€/b€Gz;€D€=€VÈœT+ €€€Xe€€€j€€€€€KTx+€G1€€p€P€r%Df€€ڰ€e€ѧx€€z:€H~>vs€Hh€€|[€w€S€-€l€ɵ€€€c€€yC$€€€:€€€;<€€€,€€€€€P7€%^€K€J€Gyw€€h@€€*+>€˛€NÅ•V€€Ðc?€€_VG€Q€]ú_€€MR€€€9Ç‹V€€€X0€€#€€P€€G€€pߕ€€€€B:€€*€&b€"ܳ€€€̄f€€JZ€€~€€'€J9€€€5€€u$€€wo넆%€ m€C€Z€K€€€€€€s€€6€x€nÜ¥€0€:€V€m€EU€€€€€^€F;F€€Uc€€€]€€€7€€[€€€€ C€&€€bU?x€€€€€€?@%€€A€€a€€€€=€]lWTVD€€€€i€€€€€:'7;€ARU"€€8€€€€€(€%€€€€€Q€ձ€'€€€I€€€E€€`l€€qt€f€ώ)gÑCW€:€7€€€€+€Љ€€€Q€€WÓ¹^HU€€€℞€€Z€Q€5€Ү€€€€4€O€€€9S€#€rZeŻ€€鉾€€€ *C€A€o1|?ꃦ9€w€€€H€€€€€€|€€€v€€€~QU€€€€B€B€C€I€zFeE€yf€Na€K€€€8€ €`€€3€€€€8R€!\€>fɱ'y€F€€!Q€+€"|(y€€€Jw€€€€ұ>€'€#€+#€€€#-Ø„€u€€€KHÉ‹'€€€s€Ʈ€€A€€€Z€€#€RqG}<€K€VÓ€!O€k€€€€xY^g €€€U€R€€ȭ€J€8#!u€€€ln3€€€€(!€€]ζ5€€€€Ù6R€
+€€€€l€j€€€.Bk#€@ €v6€6€k€€i€n€S€`€€€€6€€y€n#€€؋€=€,4W
+]€M€€€€€U+o€€€€V€|-:€€j€u|
+21€V€
+;€€€€)Pd&k€€B€€sw€€€;€V€€YW€R:€€€}և€€bF€]N€€f€€€€€€"€w够d€€€f€€€€sg€€€€HÛ€ -G€€€€_';€€'c€€€w€;€:x€vS J€€|€€}Ìšp;€€6d€wH€€3€o€r€/€'o€€€p€]€ €Y€€€S€/€€€€€€€x€D€!î• Y€iD+23^€L€>€€Ӏe€[€€€ Bl{€`0€ €€€7b€€x€€lQ€€Yc€€n€'€!Þ€@€5€lXb €X€]7XΡ€€c,€ƚ FKL€!6€\€tC€€h0S~€F€ O€1€`4€€EvZ€f#€€€&€€€xF €€€ l+€ €5YL€4$6 €#€€d€€€c€11€€)€dBp €A€€,C€€2AJ€!€ H€&c€I-€€b€€€€€€1V6€€Y€€SD#2B\8€€v€96€ό!€  2G8€d€Fa€nN8Z€€€X€P€1€<P
+p€€€€€i1@7`E/€g€€€&€U€€€:{~\:€€㨆€t€g#'€€q€eBm€bS€€Y€€€€Ȅ€€€€€&€€@€~€€€t€ €o6€q€€%€0ÃŽgL:€€1f€€<#€
+€i€€ Us€o€3#€€€€ iC€L`€e€R`1€€Tq€
+ш€Y€ €鑰>€€ &€€j€1€5P€€Ø€Ť€'̨€€T€€€€^1€<'€€T€€`&€€ћQ€RCl€)6€J$M j0€L6+ո€DQ€f=U€€@€€€J=€DuX€D€bK"f3Ǿ€E}€7€€€€0?[fʀ-F€Ùg€€G€HH> €€€€b€I0€€V@e&ÆŒ1€m€$!hJr€€€D.`€€g6&h€("€€+jt,PZ"J€ €€€€Vt€mL€$€@€€E€$f€2€x1€€XK<€€€h€€I{€€€€<bC€€€€€€€Vy€'"€€) H€(H€€)€€€0€€€M€€€@€K €€6M2V2 €€€€€€!€4€&l€( €t€O€3€Sj€€€€X€Q€€Av+€€€/€€€€€€€€O€€€G€Q€B€L€€Lm€€E€&>€€€ 9| N€)f[|€1€€x€€c€3[€€[,€&€ɒ€€0€€€0€€€Ƶ€mQcʌ€#v:€f2€€I€€€,€#9€t2€€5€q)€€Ch€IK€t;C4€€w€€€P€8s€ي~5IUBO€€€r: €b€ÑL&P)8€`€Gj%€e€?€ĉv€€€ €qJ€G€'}€€&€€€€}€OR€€€G&€,€€€€€h€@€€2€€&Ρ0€?€€€€`€\INÙ†8€€dSMhw€$`€€€hx€Td€€€!€€€€֩€€€€Z€'GwÎœ+€b4€9€ߜ€€)€€€€L€€1€g€M€€€ 0€ €4j€€€€€QÇ‚FF€€h€!€€€€€€{(€€€€€€€8&€X€€yFS€m€€zŘR€N5€"R€J€€€<s<€Dx€5Æ–€c€€€,€€8€'%[gs;o€€\€€,r€€7€!€€€)r/€€}€"€€€)€€Bd€M1B€P2&€ьf€C€€֣€"h€6@€b€C€€€€h€€<!€J5€ђ€ €€€8>€a€€€€9#€`5&€q€Fc€IoA€€@s €Б€€0Y (bI-€)ތ€5l€€€€Z1€EO/*P=€€€C€g€Z€€h87€€gjR€€0V€hC6€3 Ԓ€|€€€,jc€€Ҭ胸€6S[€€€hB€€!€-€4€`€0!€e9Æ£I€€€"#,€?€ϩxQ€€€ €€q€`€€a3€X€#>€€H€f€x€€p€€ب€1€:1bd6€E3@€€?Ū€'€`ȷ€d€€ͦ€€€Ξ€€€€€€€<€€ԫ€c?€€€IÍœe^t€€\h€1_bN4€€€€Ei€€€€€€€€;€€€Y}€€€€€\€€€€€~D€V€ݚ€€€€€€[Q€€€€€€€€m€€€€€€\s€)%gn\€€€€€13f$Z.6€
+.€€,0[€€O€€€€€3€튷;lg€€€T|ϳ€df8€€ i€I€€€4€Y€çž{m€f_€eZ:€€HL2M˷€N€€€€€\K"€€1{›"€X€̓?E€)C€iä­¦@>€€€€:v€d?9€b<bb€[5E €€0 C K̉€8€€L€$-€~g€€ٳ€€ͮ€€€զ٥ճ€g€€MӴ€€O€b€€D€€Ϳks€€€ٕ€H€6€*[̌€s€ϵ€k€7垵€X4+))#)K9+€€€€ߘ€€€€b€€Ͱ€kO€€€€€:Íž4#€a5[R-€€€€L 6k€€Z:}€弹€€32Ï™a€o€m€(€,Kz€y€E)FÃœd[€yI|B€i^B€€1€€kÉœ6€>€pY\JR€ݞ€€L€2RR,€;€xs€€€€€X0Wˈ^3 d€€"€ڑ€6€|€kZlz"B€B€€Aè…‹'€€€€€B€.ܬ€/€.)€€€€€^€]+€€€?€€z€7€€€€,€€€€!€€€K€€€€€€€€€ݧW€€w7€€}€€€*€€ €€€ʾ€9Z€€€_Z\S€€|E 2sta€j€€€*€€€^K€€€€qYS€.u€€€~€€D€Z€1?Kx€€€€€D€€l€W_€=€y€€{"€€z;q_€?€€€]€€+€1)€G€kK,W.€+Ƨ€e€€5€€-^~|Iy€-€ς€oy€^€€q€%€4€€v€€€'#p€7k€€2€Y€f[€€€g€TO:€Ykɦ}=€,€ B=€€ €€€[€T_€=€y9%ZÚ»p€l€€W€P€€LG€/g~,€€q€€A`€€€\€39€€€€€€>+€€€€e€pA€P0nͲ€€€U€€˪€\cnIQ€9Û´^eK0€S€_€€€€€e€€m €T€€€€M€€€5€€O€€[€ͧҞ€€t€€:/{v€€s€€€€€/€`€€ ~c€']€€€€]€,.Y€tY€r€
+€ʲK€+*/€€€Y€€€€+€|€€€W€{€€[€€ֶ€€€;:€€€ t€€€€€w€€€n€€_€e]€€€€€€%6€€ʒ€N€v€.K€"×’)޶€%€€sf*+:€L€€+=]]J{W€ϖ5S)€R€:€€{€[€€€v€cZ€€€4€6t€Z8€m€L€€֖@€€֭€€€( =M€m€>€€w % €€t6#~€ێ€m+9€€€€€B2Ϋ€€W€8€€({WGG^^€€€€Ѣty9贩€€B€݊€y4uÛ¦ €e%c€4€B€€S€€m€ €/€6.€€C€&|€`)€€€€€ӊjT€UpW€€€€
+^€H€€+€€€m}K€8€€Sf€X]€€€€€€ܙJ €€€€*€€€HDl5`€€€@€€\€€€€€€€s€€€€€€ +'€€'p€€€€€0J€€€Yi €J€€_€̙3€f)€u'€Jg)€ص€€€7€€`€ €€Gw€ €z€€€n€€€€€)Jd€y
+€€€€Y`€R
+=€€€ٟTʈ€€k€€D%%تNEI€E+€€€Je$€€ T€ޮ€€€€€lW€,€Wu€*€- S膆C€B€44Bmv€€ȡ€!Ќ€€h€U€
+€k€\€w€€€€*€€€||ʆ(€€[€S€€Ѓ€@ €€€v€C€€q€€ €€U€H8r€€€P9=A€×€€€q€y€I€€€€ٲ€>€€€x€€€€m€€3€U€€b€%€AT €€€>€|JV€€hj€4<€€ B€€€Ÿ&P€ 6€4€€e}€fѹ€€k€O€Å©q3Ip€€P-mY€€€€€€V€S€l€€D€€€€J€4%€€,€€@CO[#1dK€€v€i U[z³€ I€€g*€€m€ޮ€n꨼m}€€^€C_€_w#€€€€€ €b€^€x€[ß²\s€J€[€K€€t€€pH €Aa3W€€€€j;dӟ€9a?+€\o€€n€N€€v€a€:€*(€֬€hЋyml\€5!q€m€=)€€€€g€€€~nF€d€€6€€~{€Ǯ€I €€mU5€h€€)€|%:€€€˔_KgKÓfEY
+b€€ԗ€̿0O)mi €6€ .€€B€€`€€E€|€€€(Y€|E€(€N€€€;Qӫ€€X!€€w&€3€€€€€#€€:{€:{[€€4 8€€>€h €4€ݽ€€ €vH€oC€go€k€9€€€'*J€E€€D€S€€w€$UTU€€€dt€-}€€€ܻ€|€H€€€B€€€€€€u€€5u/€€ 5^L:€{S€€€{(]Qg\p€H؛ا€€"€O7€5€€€€€Q€€E€9€€|€|€4)vb€€F€u€CeE€€€?€€€nCuL$)€lY€8 t€3€+ж€ݜ€€[€B[v€€€€€€5€ h€€J€7+n€€€€}"€Y€€Ϛe+€€€€]0%€ތ;t€'€€€u€hkn€€ۋ€€` 5€ֈ-Vl€€)€€F€€ڹ&€<€€x|€]i€€€€n€€€`k"€]5€e)€s€B€EI€V€€*€€€4PI€€€€€€y€.€xf€ܹ`€7m**€€€€€%`Ë›s€€`9h €€€€€€€)€€€€€€€€€M€J€3€!€[G€C+€"@5€(€€3%Gk€ç³Â€_€6€yz€[€€€€Ү^€€€VC€€6 &€T$€݂YEUh€{# €€N€ €€€2€|%€€Oq€€+€€[|G€€€€€xM€]8w€dkR€€Fqv€d664€€€Ý­hNZz€l€6_'&€€€€0€€@€5<€R|€0€9€€Mk€6vB:€€1€8*€:€D€€e;d€S€€==3Ú»?€€ €l€$€E€n€h€€€JYU€€€€€r€p^€€s€uj€€x€ɵ€8a€2€€D€gÕ…M€k€mkoƈ\€Ѿ€€ڜW€:€€€&€€€Wo€l€ w€gz€€cjd€€€€€Q€#iO€[qV]3f$ € mH€[Z!r€rŅ€€€Zº€€V€S€v€€f€€€€€€€e€k€€#€€€€ny€€u€Ϧ€D€€€n€rQ€ɺ€€€U|V€€€{€gQ€*'a€B7€U€€@€€F€̆ €v€€@€u5€€€€€€€*€€D€€"€€u€€]}€M€€r€ D]€n€€€ʥm€€@€€Ð6€€7€€€€€Dv8Q€€€€€I€[€Y€F€ ֖€;=W€€2k€€€I€F€€€@€Ӌ€LNd€'D{j+€€€€€€Eg(_2€€:€pJ€, €€€€,€€TwA€|€k€€€€€€€̄€m€€€l1:€$ީ€tz]yu9y€€S€d€g€0K€Ы€€u€€€€W€R€5f€b€*€]€€4€t/€]€SG€€€\_uWL€[J€€€€€€1€m@,€* €€=€€€€€ Xe€€ق€ы€G€€€€93€eL€
+SK€€€q2€€u€€`Ks [+€€G75oZ S€€€€=
+.{€1@b€€IK[€€€€€i&L€€0€'CO€€¶@€K'€gh€€%\€€€P€€€,€\€€€€^€€^€€4v€€T€€€ud€€dR€€M€U€€€%J*YK؎€€€€€€€^€€:w€>x€€€€Ԫ€ €€€€i,u€€6€€€]T€W€€€€}€€IvÖS€€€€D€€€€€Ŷ€w?€$b€|€A€~o€€€6i€p€.€€€a;Ö“B€[€Y€€€€€€`g€]€;.,€€€€€˅x€€€€€€€€€״€€W_M€€T€€ H€€€€+P€€ €TÙ…)]K€[€]$€AW€RbC€€|m֛€,€oN,€€€€?€n€€VÝ€{€t,€(€.{tO€€€€O€}Aj€€{]wX7 €S€n€€E€€€
+€€€€€€€p€ €BG€.I' g€€€2$€€Mly€€}€€"(€€€y€€€€€€yÿ€€€€€͆€€€€mzS€€€€(€€&€€€€€E~€€;€€7€€Q5€
+€hq€€Q€`€€s€€€N(€€l€€[€IXR€'€€€€%€"€€€€€|€€€Y€6€Nl€cޔ'h?€€TR€€6€€€a€t>|€€ €€FE€€€€€ѽ€€]€€Λ€)€€a€€€aC€Ӆ=W€{€Qr€€€cit€€€€<QR€ކ€V€€.€i.€€€
+GJ€€€€€€€€€€'l'€€y€€6€YۣY㲢€5^+€c9€€€K€€€Na€0.V€€$&€Ϥ€V€€W€u݂€4
+€€€$€€€€8€€~€€€b;€€€+?€€€ 苸^€€R€€5€S€€€4l€}Kt€wUtL@G€G€€€xu€€P€€€X$|1€É{1€€€€dqN€J€Z€D€j€€o€p€h€eI€j5€€€€€€2€Q€6i()W€Ww2{€/€€z,s€€€€V€{€€€ں€z€:€€驨€€c$€kD5€)€7€€W€&€>J\€q[m6*I`2x€c€€z1€€€€€;€€:€€€€T%€€€€€€€+Y€€€€€€n€€€'G€€€€€c€<w€/u€€ M€€5€o€€€'€L€€K€€€€A€>o$\w€*
+€?e€€R€z܋€€ €€3€€VFƲ6u€GRæºe€€o€€€€t€l\€€{ܸn€€CS€€€€€€p€€On€Ȯ>€ e€,€€:GR€€(€€RGLj€€€t€S€€;€>V y€€t€h€9€€9€s€€(j€€€C[:as€€€€
+a€#rj€€€2€€r #H€Z€€<€]€€€C€?€€GA€Ӏ€€€6C€€€€€ F€€€X€€€ꭸ%€€€€Vm{t[€a€Cǎ€€€€€€€€€US€M㮨X!€Z€~€+€€ €€ €Pc€ߓx€€}€ll€€€N~€į€u€€€€€€€*z€Ƕ€€€€J|k€z^Ul€€2|7!€€|€€€€o€M€€$f€€€€€d€€€D€€?€€€?€se€ɳ>€€3=U€6Oy€€€€€€€€=%€1€€~€g1b,D€€x€€€y€€€x€€<€€s=€€€?Ó_;€'€gx€€k€[ߟ€€€€€T3€€w4€+€€€ €Cظ€€€€€3.'€5)€Eq €ܵg€A€€b€€€€€€U€€€€Õ€€€€€m€€€TΗz€€€€€€€€€€Ƕv€)e€i€€X=€€€ €\€w€^€>^x€ Z€R€O(f€Tَ€9@)gٷ€€€€O€€€K€€€€€a€€x)t€€€€€އ€2) k€O·.€€€b€d#$æ•…F<€€€€N€Z(€€m€€€TsQ;€€շ€5€/€€€€€U€$<m€ € €€gY€€t€c:x4€:r€ €I€€€€€€3€€€:€€€€€€OF€O€Z>(€€v€k€E€€3M/R€€€€hR€€r€B€€€mt€'€€€nZ€€€€€€R€SȈ€€€_€€€€zoC€X€ SV€€T€o€€
+€€€~€€I€۰€€€O€z€€€€€m/oEW€€`K)€ݵ€6 w€€Z€€€u€<ĭ€€l<)€zǗ€€,a€€<z%€€€:€€ €€Q€€€€€€€Y€^1ޅ€u<€€€€ymjf6€€0€"€ݕ€€[€€€€.9H€€:€€€€G€X€€€=z€€€J€€n,0€€]€y€n€a€€€G€ޒs€I€M7€€P7€y€ѻ€c€€rt]T€€€_€ux]€€€€"8Re€:+j€c€G€€۵>5€€ƨ€W€(€ ힷ€l€TV€ €1€[u3€€€€"S€W€)€€€€€€€=€€ͫQ#€€bo~€H.€yR
+€bog€Q€W€€€v€;OL€€€€n,€€€€l 6c€€d €€€q_€€f_;€Ũ€€€:€€€€l€#€J€q€€€,€[ʶa_!dz€|*€+€M?€C_€€€z\A _€ٗ€€€€
+€'€> €B#G€&€m.)I.€5[€z€Hf^€€S€€€нs€€g€€€€€€tl€=U€€€€K€€€s€€€€€q€îªÂ€L_€uy€€€ ̞€€€(€m€€€S €k9€,€€€'y€€€€~]&€€€|€ߺsVQ€{y4€Ed€Z€&pÄ€g€ID>q€d€J€B)€€€€€€€yM€d€~€ €€Z€€€€Zn€€jAû€€€Æ•€€n€€z8-Qm€V€€€q m€N€€$ʯĄk^F€˪Vz€U+mɴ€{€€€74€€€w'€ި^€€?€€έmP€€€b{€€"e3€€I€S€Z€€$yÉ‹q€p€WÑ¥>{to€;}€<d`J€€€€l€f€}€€2/t€€.a€uJoj-&€J€ XF€140J€]K€kx€f€€Ó€€€skB}€u~^€€Vg€.u3g€gOvm,€F€€|€g€€?€rԅ€€܆€€hgh#€Z€€€€€€ W€.5€ U€€g€X€|€w€€€€K€@€"€€m€€6[€€&€S\`€€u€'€ WÊž0u]€€Z€€€€€€7€€-€€€3od€L€
+k€^€1€€€€€€€m9€€€€ W€0
+U€|€€€€6€w'!q€S"1€jU€:+€€f€2€;€zpR"W€U€€€€]€€€i€€€€in׈€€€€%€T€B€!6€q€x<6€X€€€€]Å»S/€Fh€€*€€€€€0€€T€Ç€€€~€_€ €G€€fÅŽe1€#/+€K€€€Z€€'€€ھ]€9Kw`{€5ʷ€€€€€€€knT€w€pV€€€€€Gy3€>+€
+%€gt'€B€€SЗމ€€C€ub€€ۨ€^€\€J€D€€:ڪ€€4|€ը€€L6TX&n€€€اs uL€€LOg€2|(+i€k€T€ƢL€Ͻ\€s1€€€€€R€N€q€€€€{€K€#€€€+€צ-€€€
+x€€Q€t€€%F€f€<€}€€!m€€ӭ€€gm€€€}<A€l€VSá³¢€€€€€b€€€!Jhμ€!+€q"€€€€€/<\€€3qq€€€€ €>ч€€€€€gw€€€4€€€1€CV€%y€€€?€l€y€€€€#€#€{€€F€€}€#€€€wTvG€€:€I#€€€€)€€€€U172>:B]_€€€)+^̜€€ ]G?€€€€€D€€QTx€€€€ €€€€€€€€€€€<Gl€ڼh9n€€€(Ϲ€B!€d€€`€m€€€3€2€>€a?€˺ySE€€€~€l%€€+€a%€€€ÌžQ€)€€ Ol€€€€€k€€v.X3t€'o=€&€ €€С€֩~Fq€,€€€€l€P€€€!Lc€)Ý#€€€1€€C€€k*€€0€ €@€x€=€2€k€ͻ€Dޔ€€€c11€€€F_€€~w€€1oSͲښQ€€I€€€y€5\A€€ €[Q1€€v€€€€=€e€s€ Ⳍ€B`€€Ë€{g€€O€€ [ e€€€cP_?QA€€
+€€€,€y€u>#il€€€'€€_p€€€}€€€7Z€3]€Ў\€@ €6\€€#,¢ݞ€€\U€z\€}!€€e€v€€Hî¸Â€>€l;fMeW€€̂oV€c€€€€€i€€€(€s€€€€uabF€€u€€€€€€֚
+%€€`€!lG€髷€€€?€€€€G€€€2€€Jwe€€U7K€%€D€€Ô€€bqA!€€ÍFP€€G€€€!€€i( €vdF8€€€€€€ H€ &€€K€8HSx0.€ڱOd R€`c€ 6e€Ӿ€€€€帚€-€€€€€b2c$€€3F c€X€3€€€t€€€€€#€€:€PN€s=€"€€?€A@2€€}I€€ֵz€:€€D4u€F€DL€€€{€=€V€Q€€u€€€€€€€€&€Ǿ€€Iܤ€ą€|€€m€€€€CF\€€ܓ=€€%4€€€€€€€€C[}€€ %8€|0€€€€€`€ҳ€€€€I"€߉sÏ–{€€€ €H\€s€SU€€\l€"U€B
+€€:<€€f€€€Qg€B2€VL€y€€€€h6€Y€]€€€O€€€€cI€€€€€€S€€€€€€ڠ€€€4€0e$}€€€€€+€€^€€K07€y?lw€€7€€€€€ƶ€€€€€_€€€U€€€ZQ€€f€€€e€KV€€T€€_€€f€€a}2zУ€€т€B€]W€€ݺ€€_€G€€
+.€\€€€P€€€\€G^
+{€€^W€€€€€VHX륞c.fc|O€a€€lhb\_w€€€E€A€4€&L€5€mRj€€€€4€€+5uK€-€€N n€1€Raz€q€3€+€S€^)€cN€€€€€]€€€€€U7€€€EJ€ Y/(5€€'€_€J 2S€('€€[N87€€€€€€lØbY€pQ€n/€€€9r"+€€€m€rq5€V€qi G€G&€€B€΢B€€€y€€€€86g€€c€wv€q=€zJ1n €C€€/v€€(0 €€a9€€€€€+1€€€7"€€ €€}€€€€€;{€Pg6€ס€€:€€€€|€€/€z€€€€J<€€XW€€€Y€f€Q€€ _Uw€{^€€€;€€€ =M€s€ҮJZ€SÜŽM€€x€€€€%m€Κ$€-€U€TT€€Ê€=Ø’H€:hcPyE€€€€€C6€€<3€'T/Ñ„j€€€C%Õ¨
+€q€ €k€L€€n€€€€€ €%Ǿs€K€}^€d+G€>€%6(#(€€€u€€€0ÞºU€i 2€21€€˰€z€AF_"} €Wh€a€ї€c€y€€o€€N€€l€ € €€N€€€F€b€€€!€€€?€€a€X€%!€:L5€e€Äœt€ €€€€€9z€€A€€[v€€ق€€X€Լ`€$k€€vQ€-)€€€3€ ~€€:€€€^I€€p€€s€;k€€svÔ 7B-€8€j€緖€€0€n€F,€€K@€I]~€€€€̻)€€1]€€3W€€s:GY €€€€ 71~L€(/Q€Gm€€€6ps€"€p1VDZ€vv€v€g€߾s€€)€3r€€`9€h€€8€0€€1)Ó±Bxv€Ǽ1胮܃n€€t€€7L^€€€._5M9€}5&€€*€W€o€€x€F€S=QE>€,Ɯ€#ຸ€@S€€O€€GO€€€3 €€O€€z€€ €y€.€T€4"J€k€€B€G+I€D
+€He-O'57*€!€ZU/-€bq7)E€€€€€€€7€€€]€€€'€€€€̈́€0i€J€K€<y€^€}U€-€€€-€{€€͆€)"V€€a€`!['v€€€I€Ucl"€€€+€€<€€ €4w€=P(hzZ€`€%8€-2g€€€€€9AD€€ U1€.ch|€y€U€€p€P€€l€$Em4€€p#€2€€A€€RDa€€€ €€և€D'€=€S€€*€€h€€€€H€W€€KV€?€€€;€c€I€ug€€€€|V€€|E€€€R€ €€È$€€"€€ € ݎ€ꄊ€;7€'M€€€€ٛ€b
+€€€€€€% €|kKd€€€€i=i€€,€y€L€Hc€€€an€I€€)€{€:€"€M8o۷€#cs.€€p!€€-߀€€\K€$M€Tl€€€€Z€€€€ €€9€5€€(€u€€}€5@V€½B€%€€€€€-{€€€ €€€E€6'€2€€€€€€!Ua€€€\a€€€>€€€z€€€OQw€€€*p€y&C€€€M€v€€׳rUÆ´ &1€e€a€€€%8€€:€€ފ€^uq€€ € I€€]€€€Q€€t€ENz€€H€€€ €€O߯[€E€€9Z€€]7Թ€h P\€b€x^€Y€€vF€€X€ԋ[G€8>€€aAg€€€V€€!€Wa€CrÓ†v€€V€€w€~€d€ G€€€€8嫄€A€ѯ€€ojoi€€E€€€&€€€€€7€€|K€€€JѼㄵVs€€€_X€k=€€€€ֻT€€€B€€€€€.ڄ€€€€C\€€ Ú¸p}6Ja€€"(z€t€&€6€€Ŝ€r€B€/€K+€vjn€€lF€€W€€Gi€€I€Dbr€Xմ€c€€HUN€C€€€Hֻ€€€€d€€€qAT€€€€-=€€Ê€sh€gl+€€€4€€€€ €Q€€=€*Bv€oLP8b *H€=€€=€K]€€€k€8€N B!€n€€{:p€DZ€ޛL5}|m D7€i€€p}?={€Ė€€,€€H|P€€€€€h€J€€V€æ¾Q€)넱€€(€ €€€€v€€M€6 A€€,€_€€€€Z€ |€€€%2E€Ң€€€€2JJ€ ÜD:s€I€$€€€K€R€͊Vv;€€UP€€€€W€€,€€T€h€€ X €€Dyb@t€€€ڋxY€-E€̈́€€€Z3€?€X€€€ХV<) g'€S€<WX€€gcW€€#3K€€€P€€€€]€€€€€m€€qG2B]€€W!€R€X]}€€€€€€<€€€63)€Fq€$LJ€K€€9€€W{€Z_€€$€€l€€€€€€.€'iLM3€€€4)€€€€€vc,€H~8€%{€7j+€ۺ€€€G€~€6.\%€€€@}€Itq€€|€€€€€5€v"€4€€€B€u€€€ba€]F€€1€x€ʓ]€€U€€€€€€€€j€϶€ l^7€o€r€wS€m€€Va€€€€]€€-z€Z=€i€€R{6١€€o€€
+Ú‘"YweF&)€A€a+€€€€_€€€€€gÈŽ|w%€} €€Jqm y.?€€=W€€#€€€V=1€€s €o€'k€€€€?C€'€€€ar€V€-Ç€{v€h€€€k€o駄€ʽ€€€€BS€€€I*€`q€(€€€ˆ€r ݋€€€€'€u€O€€+€€Ŭ€€J<€€F€%€i€a€ēχt%s€€€ €€€/Z€€[}&€K0€
+€NB_€€~=p€€€€?€€w~€€G€€€€wB €c#]t3x8€€F€Æ´ut E€€+C€^€5€6쎠€Mv_€T€€€€€_]€€Sj€€3T]€bt€`€9€+g2^g€OÖ€€EyZ€€€`€\€U`€€U€{€;€€€m€iȀ]Nlw<€€kRp€€€€b€€uq€m€€7€€9€V€€JVLC€Ueh€ €\€€€H€€o@€0€€€&€b€s€Z€49€;~€€€€eOs5€&€zH޵ͽ,
+€€€€€€€€€t€K€€€M€E€.C€iâ‚­ij€€4>€NQRÕ€J4Q/F€<€Մ 0€m€€}|Ô‹-€=€S€€#Zr\€ePL€f 9€€€j€hkd>€€խZ&€€뉾 €X€]€+€ €€€c€G<€N€€€-€€€€Ւ€j0€eަ€€X5€€<€:ȯ€€€x€€€(€ɨ€€P€€V@q€= €€97m5€€€-€zw€€fOr€€€O€j»`p€6ͽ€€2.€€)€]%E4)€€fȆ8€€I€R.1€y€%€B€€}€€€{€BEЩl€€Lvͷ€€]3zj€P)€€ûh€€€€xÄ›J€+_h€€F€Ϝh€fm€€€"€€o€€E+€€)q€3€ï¾’]€Z|k€U€:€€/Q|Ù—}€€k€*€€€6€3J€€*D€<K ,5€'`Y €j€W`€€€ֳ €5€€€܋+€€zskwA9
+€׊{€J€IMZ€€€:€jyh€C€€y2€€€€€€€€€€€€ n €+€€€0€€€€€€h€€€€€ϟ€Ë€C€5Z$€`€€h(€€€€%-ß…€'€3€€€Gy>€€€€€€€|ix€€L€€€€I€x6€€: [€eR<€€€F(€_)€€€e€€€%€ǰ€\€]€€€|€t€€€€€€Z€U€qy{*€c€€r€f_[€€€ €€€€
+€S€2<@/€눩|
+€€ |€Sw€€K:€G€€€!€+€€€€€D€~€6€€€€0€5€»€€6^€k= '€€€€o€€€€oC€[€K€k/€X€#`%[4€"l€XÛž\<l1RU€€2#€€d €*€€=l>@€€D€Wc€Ѱ€y€€€E€€c€w€€{[€Lx?€€[Pe7f€0€€€n€€7€€€(W€€KCW€eF€€€€U€ZB€€<€Jx`'€€€€€w-€€X€€*€€€€l€ꬺγ€<€€€€€<y€މ€M€€P€€R€€€3^€Ú€|ƒ€€"€€€v€€4€€'f€€€€€€7€L€€@O€V| td€€P€€€€€€/€Z€ €€1U€{€€€€€D€^€@B€€:€W€%€e;I t€€€æ€3€3m€€1S@€€€.€€€F!€€€€€ w€ç /@ݔ€€€€€€^€J"€{€~.oÞ²P€Z€€€oW€
+€€€.€p€*€€Mt€6*€€4HW6€"€€t€@€€€€€S/€h€^€<€}€€s€ l€-€€Ǧ.€.И€€€€v€€€€€€€€F\€XK|F€€€Å1w@X€
+€€€€~€nÄH€)€€€?2€0€=€€€3Q€5€€€X€e€Z€€€€[€^€€ €€€`€€J _g€€€+]€v€€€c~V€€€&€€€€D]€<Uף€e]€€€*i€N*€1€r€E}o€\€s_€i€ڦMN`ZpV8€/€6*€€6€=€x;U2bm€2€!d$€€ڟs€x€z[€w8€€€€I€ȋ€€€€€€€€€€<ڟ€€ۊ*2n4yL€ €F€€€f €€€€0€ c€€NT_€lY€y€+€
+€e€1{€€[пo€€€€`€€€ -€€€€8€Bm€4€€€€2Lj€@€€8€x'€€||͹€€+Q€€€m€4€F€P€€€F%€G€Ѽ€€SQ€l€ŋ€€&€'€€€*\5€[€,€€€J<€€bW€€€T€4I€
+í¾®C€€I;€ €;(+O €€€€€€v€€Ѐ€YveR€€ި€€]!€T*€s€€i€F€,ln€€€6z€]€~€<€€€N€w€ C€Pu/ €s€`id€€€€Żƛ€€]€?€nF€X€€1€+Fxq€VO€€ך€€ }€€€€=q€8j€3€€€Y€€€lD5b€ǵ€*€€!)4Y€€€€€€B!ÉOL€[€/P€-€ho€|€\ €€€B€€ἧ=2€y€A€E~1€Y46€9€€€m#S€€p€>V ^€€}€€W€€7€\ €w+a€€€xq€€€[€€Ig€T*`.€,€D€€€y€€€<€€€€|\€[^*
+j!|€€7|€€<d€C€€#€uP4€€
+€€ga€€X~€€EpK€a€€€U€€€"€p€ |€.€X€ €[EPj€€€€m.€]öA€]˶€€Z?€{-€ul#I2b€€€€O؎€m€l€€€l€l€€€MP&€€€NLW€€€€€K<€€ Pj€€€mF€€€€€-F€S€_Òªg€Q*: €儵€Ⓤ.€+€v€€y€m80€€B€€€7^€€€i€.._V€€€|^€o€€6Zӊ€€e€€c€€€.[m€€Y€€1x€€€€ cptangle.SYMMKF€€€,€€€€MPSTMPS €N€€€€)€€%e€*4€€€ ?€€+3€QN9€€€le&€€3€€€et€̓€€l€€€€€€(w€-€€|€Y€€e€€€€€Z€€Qn€€€;Nۦ €fW€€€v€fۣ€€<7€€€€€ €l€-€€€€€c€-l€ €,€€u€7€€€l€5€#€Ø‘[€€<H`€€€€9€{! B€€-€| €€,€ €45€€m^Q€€€€€*€`€€€W€m€€Ά€€€Y€ꪚZ|!4€€€€€€o[Å—€/7€€€€€€y€€€€€€)S
+g΂€€hV.€y€劫€€€€€€€yusk{€€€€Jl€€t€€€€&€l€€€ 5:Z:[€€€€€€€€€€@€€€€€€B€€€€€€€€€ߛ€݀€F|7€ۋo€€€{+€€€{;€€€€|€ķ߻€݌€€€n€/€1€€'€&8€€SX6€€J€€ €ɶRs€€€V€G€8x€<T€€s
+€€5N=€@€€€#Q€x€<&nM€€y\t€|u€€€€%€ €€€ \€€€€s€€€|€€€€€c{€€Ĝ€€€S €w€ €€e€€€€G€€€W^€s€€㺂€€Z€€€€€€€x͹€x€€€s
+€1€3€€xkÔ´s€1€/}F8€€€€€|€ €€u€€)€€€+€G€s€Y6K[€€v€nߣ€€€^€~U€_€€!C€ݺ€€;t{€n€€aiSt;[€€€vX€_€€ɦ€>€>(€€#z€€€m€€€€€ €€#Y€g€€&i'€€'€-€z€M€m€€€€ۥm,€€€\€qˤm€€€€/€€/K€€U€N0€vH€€€€#€€€€€n€vJ€n{t;€ۛ€=i€n€€v€n€€€€Iچ€€6u€I€~]€€I;.I€K€U€i€€6€€m€€€6€€€€Ai€€t€i'$€€€€|€!X€€ o€€X€U0'~€€>€€€1€іWP€€€€R€€m€€r€€^€€€7$€€4n€w€€8dY:PzBT8Õ?€aX€ €;€€R€€\=x<~V€v€ €]€UY)[3€€€\1H€W€N€|f€€€€€€ΆPgW€€lК€~€cJ€€OS€€K€|u€€*a€t€'€Z€:V€764€l&h€€€t_[1N€€€€€€j€€€~€`{Gg€1€ݧ€~I€€L€€€P€=T€€!€€€L€€0h€
+€€€0i/ €€#!<?t]€v€€€Ú€4€€`Y€€€+ i€€€€[ €UbG3J\€€€€€=ÔDKK€/b
+X€R€vD€€€€?€€€€1€€G €l€€€€€€%€P€€wr€Ћ€€€€wT3€' &€'}€l€G€ Z€U€V0aۢ€€ê€y-4_kk}€€MDu€€X €*€€€Sr€+-€€y€€&€€ ]€3€€j€€`€€€€€@€J€s5l€€~€W6€d€i B€€|€€€5-€€€5+€[[€:G$€8V€?€AGB€€€]€~€ߴ€€K€€×>€€€;€m;€€€€€P€~€€€€€#€0€€€€€€,(€€€€HR-PS
+€E:rX€€r\€i€.E€D1 .Ն€€F€€ѭ-6@€€æ“€€o€ڴ€RŹu€R€cA€€€3€{X€-€ #P€/^€!Ì—w€k€€€€€h$€?€z€€€$n€.R€€€€"ÅŸ<€j€€osy^>,RP€€J€€ÅŸ€g€€V€€€t€€E€EU-R€Qsjn€k^U€g€€€€D€€€/€_+€@s€j€€%_€€1€€€€€ b1€€7€€T€PM€€(rR€€€t€ €P€€€€У€J€\€€S€B€€€€Q€Lh€€€€€.€€€€Ⱥ€€€€o$€€h€€€€€r€€#€€€E€€€€€€€€Ps€€€€W€€;D€€%€€g€ÛV-€€€r€JmX€M€€_€`€€€h€€€€€Q€€€[&v MTI€€R/€˿o O€€€2І€;€€`€€€€= € Y!G€€%€€€€ȷ)U€*MS€€€
+€+:€*l€)€J€kQ€nÕ²W\U€€€Q5€&3l€<€X€^1D€€€€€dF*€€_€€R€SS€€€€È’z€4€€&2)€€i€€ R*!Ò™€€€;ĉ€€ʚ€W]d€€\E|B€€(€€€€€€€*€€€n€Ď€s€€R_/€(?z[€€€Ð€Fc€€€U€Q 2€€G1€€€€€D€€$€€€ N€€}A&ጣD|€SÚ…E€€€UΨ€3€€bu€€€A€4€€€"!^8€jXOc€LP8S€€Uɶ€€6€ €ӟ€€h€7€€€€€]€€€9S€V€a€ƆN
+*€ku€lj€€€4€;&€€€€€€€€€€€«€€/T€̯Sc€ə€^€€€€2€€岼€€€€;€€€S€€Л/€€$X€€€"չ€Hu€€mE€€€";(cf €€wT €ê™Â€#€V€j|€P€,u€dx$€G€R€;J€ea€[ sK€€€z€€€Ί€k€U€U€J€€€€ €S€€€1€€€^)r€€E€׀|€€€€=€€]€EN€€.€€=€!2€€d€s€;G€m€G€$€€€ΑI€!cp€€[(€€€€(€z€€3€H€€€䉚€P€€"$€T€€€y€m]€hN€R€(€^€?E5nK€K€v€€€€€m€€W<{Åy€€€.€<€€€€y€€a€€€G€€€€1€Dx$€=€R€u€S;€€NO@{)(2E€€€8SA} vjo¶);€€€€DJ^€€u€D€^Ϣ€€K+ˡ€,€6Í¥,€E.€qX6€w€€€€ڤg€|n=€#Ç·S€ €€.€€€€€ €3pr€€;€€?€E€€6€€€M€€€€6€P€€znI€€Pm€W€U€€<?6€€<€€s,€m€€€g€€"9€^€€9ewq&€]~D h€F3€€\W`€€€€€e€€_.{€€€$%O8€€0€K€€ ]lvA€[׸€€€€€{€?Y}w€ €|w}KQ€€€1`G€XD€V€€nf€Hm€€€€㦎հ€€€€FØ›}€.(€€€?kR€>|Ê&؆€€€€`€€€€€€jh#€€dGxGР€w€1€ B€]`vÉŽ€ja€€€KT€s€€k€ê€Ԡ(€cX€€€`s €€€*€*€€€€Ry €R€tI€yGIf€€€d^€€ k€? s€`,j€€€2M€€5€4€€t€:fq'}€€€2€ €€>€€j€w#"€9ǘ€€€€€$€€€xw ß»w€€€€€€41€h€X€q€x07€€]7LJ€c8i4€€€A€€€€€Z*€m@€€€€ITY€#$€w€2€€kJd}€€Ѻl€u€c€=€€€_w'€€I€€T2€P €/Ae€g{€€3€'$8 €€w€€€ה8h€Lk€*
+€vAgd€€€€'+%€€S5;€€_€€v€€€#^Owir€€E€€€€€(€€8F:2.€U$€d€_€O;€€)€€€5€€Dk€ԣ]€€€€€ă€n€€€|[€cqH€U€ϫ€€€\O€о€=€€€Joؗ€?€ă€n€€€€=SV3€:€€<k€€€h€€/Vt]€€€€Ai €t€4€€€€€:€€€€€€4€<tN€€€€d/€
+f€€€€€ە€z€€`ے;wlYrg€c€€€H)€R€Sh*m'€@€qd€L€€&€€Ow€€€€€€€€ rqT€9>X0€€€g€€€9€BfTgu.:?€D€€€€€ރ[f€hCx€€P€€€6€€CVJbv€€}€€n€€F€d€€€€€€€7€'€€G€€€€#€€€P.n€€€€€€g€€
+€€€€€€n€€%€o€€ꖨ€ޯKM4€hm€TYo/€€)€€€z%€€Q€€-M$(€ח€ €€<rD8€+€€O€YW€Ö€€€*É—xxT7€ M1 €sD7€W€€€MY€€f€€,€$=€€ P(kÏ'€€€€€ȭ€a€€€[€€* /(€`e€€Ao}€4ÉŸ4 €€Zc€€迺j€վTz€b €^H€€V€AC<7{€z€€€€€€ҟm€<€€*€6|€<€\}€^_€uw"€€Nè™»Qe€lЀJ€Ps€€€€\kzM€뛨€ʠaz€€WP%W$ot€k€€€€€"€€€=€€€*Kz€5€€=€€E\€€€ur(€Ɠ€€€ZNy€€|€€€€
+€€CJŞ€€€U֕{€€€€€ͨ€@ċ*€€€€€[€h€€€[\€€€鞓€}`V€€€€@€€€R(€€€8€U1<7$€€l€K€€s €€€€€i€Xxt€€eqU€>€D7-
+€€€#€/h€€€{€€k#€€€€^€€=€3€-€Φ€N €|€O€€€€€-€Μ€X]€M€€P€a€Vw€€n€€€€ €8e€ €`s€h€ή1-<€츪€r*€64c(@€€w€,>,nW€€-~€R[€]9€<€R€€f€
+m'€X€I€><€€€Þ€€*€"&€/$€1€UU€y#5€€É­\€€€€€J €€€€€e€€€€€R€€€€€.D0#€ |€>€€€€€€€€KmP€Q3€€€1€€€€€6€€€K*€€€R€=7X€€€kA€bX] €€€€€`A€€€3kA€€€€g€€S€-€€€€€€S귯€;*Z`€€€€?SP€+€<€€€€M€D€!d €€!€N€_ڜ€€€€€€€€€€€y€€Y€G€3ge"€z€Z€€€€€`k€€Jڅ€>€In€ZcC€峕€€ԓ€€€ЗoA;4€3€€77U€€+l€€€X€€N€€N€ZKz #EoG€€€€€€rre^€€@&&:*€{€^€€>€d€€+€mn7€l€en€6epW}}Œ€1P€€.€€€Y€(@u€"€€€€mwC€€€fw€€€VV ~€€€€€Jj\€T€bDv€€Y€d=€€4€€€Ò€€€€j€€€€g€€€m€b€
+€€5=},€€€Wz€T€€ €€€]˿/€€€€)€ҥ€€€K€€€ڕ€\€ד€0€€€iu€€€74v€€~h€€€€€€€%€`€€`€<S€/€D€za€v€ާ€h€€€€€€}m€%€€€Z(€ZA€k"€€/Gc€8€L€ €$€f€€€€Mj€€÷f>E€€€€f€€[€€€€hG}f€€€€ٙ٘€P€€2W9€n€€3€€Th€€v<d€€6C;€s€3€€€€I€€I€~€€€uͬK€€€R€y€€€€5€€N€€nat€€"€'l€€€+k€6€€dz€6G€x%<€ €?€=}€C€ф€E€i€W.€€€€€I;€€P~B€SP€
+€€>WUy€^€€b%f€zl€a€眗€'|!vH€€€€€€€+€€€€vj€v€€Y€|€€€d€€€€€€€€d€€€t5Y€€캧€"-H K€]€€4 €)€€w€€д€ޤ€d€€€ €€<z€?Zw'p/€€€€ QVU€€€6YW€€5]O€\€€€€a€ͱ=4Q€9€€€€ZU€€€#€r€{F€€Y€€€ґ,8™,€€[R€€J€!X_€€1nklokkԓ€€€HO€ €8€y€ €€€€€€€ €€€뎷€€ëšÂ€tS€€ €€€€ (€€€E9€bV€€޻€€€€;)7s€W€€€€ €€€C€p]e€j€z€a€€^€C2v€€€-v.€€g€'€[€€Vt:€€X€WB€?HM€€€d€€1€g€uG_K €€Y€J3r€ €:5{@v€Ć€{€ڶ€€O€€€€€(€ €S]%T€#€€6 <A€+^q€€B€g€€€€v€b€€\Fv€-€€l̒€b^€l€€T€€,#€UV€€2€€€€y€€ض€r<€u€€ȵ€€P|€~[)€€€€€7€€€€€€€€€€€€€l€€;€€^€€€€j꫘€€,€hk€€\€\߈€2s€€.€€€d/€€€#{i€ \€=@€;{o€€w€€€€€€€"€JÔ=€€2€ziÖÉ—3>o{[€_€€€o*-€€--€.v€c€€_ {I-€€€4-ڹ€/z€2[€sF€vG€€>€w€€6€€€N€€<€€r€€x€€€ێ€€€q€€nò€€zIv€`_ €b€+€I€€xP€?,q].D€€)I€€Ku}׀نe€z€€€€8€7j8€/s€€w€€h~0!€€€€
+ \€€_€:A€P€€€V€€€혊m€AÇ (€;}€€>€e€oe/€€wr€}€.ʼP€€€€€(€€#€a^€ie€]€€€~€€6K€3€G{d€;!13€@_€Y€€€€6€K€%޹€€k€€<7_€€€€aM€Ã€7l€7n€ €€簖r<€;€€!€€€R5€€5€€€€€2lD€€€€Ur€€€w€€*€€:^€#€VD"€ €€€"€/€€€}:€€€p}€€f€c€€€}€€€€€€€z€€d€&€ѫ+ I€€ €_ß}€€€l€€[€€s}I€€€>f€€€€y€az€ €fz6€O#€LW€st€€€€=ɞ€€zz8€€㠂(;9€€Z€€j€o€
+€€X=Tw€A€"€€7€€fq6€8€€€o€x€€€€€€s€€€€€€1>sj5€€F€€€h€€€D€g€D€€+u€3<€€€€6€f€գ€€€€)€W€€€€€;1€S€ t€M€Hm€€€€|€q73€€€€€ڃ-
+T€€€3%J€^v
+€|€€#€P€t€€€€€u€€€>ҫ€_€A€€#€U€€€€=€€€y^€€}i{W€€P€€t€Agy€m€€€€€€q€l€
+L€€€cڞV"^€€Id€€€)€€Q€€€b€1€€€€€€[1€€€Ӕ€35€€T €€o'<€y€gF€Q€€;€€^V€€*€CI€€€[€{€€€€1€7€€€M€KL€€'M€
+€€€€V,€€€€€H€€PW/%€3€€€€T€=€€0gx0€L€U€€€€AH€€€Zo€^€€€€€0q€h€N0€€H€€€€€2€"}€ 2€€€)T€Yh€€€€€:˚€€€\€€€€g€€&6ÔªsT€զ€€€w€€€€€Ww€{€^ݣ€€S€€`€H€€€€:7€ 6€€(€|€€€€=€€XY€€€i€N€G€ãˆÂ€Â€Â€Â€D€€Op\€yWV€€W€€i*X/'Ò°4€€W€€:€€€€€€€€P€ӓ€@€`€€€6K€I€€E€€&
+€Bؚۣ€€€E€3€€€ ~O€€Y€V€€€€€€4y%LB€€€^€€€ɠC €z€U€O€€€€܋€nw€€€*€€€@€€€3€ބ€]o€€1€€)5€€€b7}€4€€€ɣΪ€y€€c9€€.Q€€B€ €€~€€€c€+G€s€€€`8€1€€g€€€'€ElQ€Y€z€€1€€92[p€€C€€޻U€€€€€=€@ե€€>R€€1€{€€ǔ€{䔄O€€^Y€HçŸÂ€Â€Â€È‘€!€€ €€€€F€€NX€€l :Z€€€`€7{€€=Z€Oe€<€
+5€4€€€zjN
+€€Ä©[€0K€Z€&€€€?T(€€€€>€€p€ԧ€3€A€U€€:€w46€B~̪K\€€€剉4 JlYI€ٳ€1€w€w€€Dn½€€#€E€€j€b€MN€€x€Ý€]M|7P€€€<Q]€€K+(V€(€€€€€€€V̵9€€€€€߷€€ €€€"€_€€7€/+€€lb€/EtD€€OÆ®Np=€N€T,€覹€€€€x€Qv€k€€€O€€€€ ~2€!€sw5s€€€X€٬€€€€W€bK€R€o9€€€e€"€%}d€e€€D}S€n8(€€[Z€€[€€o€€DN"€€€:#€€€A€€€€+€€)€€€€€I€€€嘩€r€€kJ€€€€T'€€€˦NR€,€gvdVX€B€=D€€€&€€|;ßšO\ 1€.€}R€ֶ€X€€j*€$€P€€W€Û€€&€S€^n€@€€€€<|Iä©€€4€€€W€€€€rZ€€nnžW€€€€€T€f€S"€p€€g€*€€€c€K€€€sj~€€# ݉€Y.€€:€ [.€€:|#€€O}€€€€€€
+G€€€\Ad€V@n€€Lܯ3€€$€,<iHj€iе7€€~€€|w€$€|'c€€€,€y}€€€(#€€€`>={sD t€ C€€€J€€L€M€ €|-kFP+€6R v{€&€€€€€€B<,!ul€'@=€=t€2K#%)€Ԛ€4S€€C<IC~€€qh<€€€€€€€€ni€=€€€
+€€€]€€€N€€€B€@ÆšrR-v€I̟€D n€€€€EhhC;F€'#O€GH79€*L€€€y€€€8d€€€2€+€Mz€€€€€€xVO€€J€€€J_€€JcDZ7€/g€€VC€H€ɤ€€d&B(M*b#3x€u€€€€€"d\€€€€€€€1€%'€ͦ€€€€€:€€xz€€!€]€v€€€€€€€*=l€€€Ä€0€+uJ4V9€F€+é‘—0€P€+W€€€€!Q€A€€Ht€C,€5Ñ—Q}€€€A€€€€€d€'0$5€H€,\?'M=€}€&€"€{€€3~€8€€€،€€J€V5€€€@€€€€}€€N€€y€`>&s€L]€r€cmm_€€^€€€=R€w€_g€%€€€}Y€=4€€/€€NX€˾T€k_€€€€Õ蛶€€€9€D6€0€€U€€€g`€^A€€UW€€D5€=€o{€€]~;A€<€€€€€u€UFs€€Y€€w0ע€ilų€€*%€€b.€!€€€&X'E[>X€€|€€Z€V€€€€N€€€*d€zX€ٰ€E[E€€*€8q ,€p]تg/€€b[€€5€€€€*€y& s€€€€€}€€€T€€S€€߸€€€%}c€dt€7€-€g\€z€.€€€,€€9<€€€ €€€ mrg€€€m€I+`x€[€c€P3€+Sxs€>€€Î3€€>€€€tԷ€€€fÂ}€'ir9)9R€€Ftu€Iq€B@€''€7€w€w€[1 ogD€€E€f_
+smmwlfm€Î€ά=€€€s€焊€I€€€ €\€€J€,q€`?€€€lD€€€€€€+n€€5€€€€€€€2€€€K€€k€€€€€8?|€_6€€€;ASd€€%€€]€fM*€84€m`€€€€x€€)€€9€€€€€i€€ҭA€`€J+€G€
+B€}Y€}ϓ€€€€:6€b¿€€_€f€€6€m€€€2€R€Nd8€€*€€€V:€€€€>I€,€ €€€^o8p@€=€g€S€€€€(€6€€ €€€€€9E€€ڪ€zO€=A€€€eM€€€€€€€€€b€€€`{0€€.Nx~€€J€€V5€€€€€T€€˰G €€€6€€€q€€€€aʛ€t€yO~=_M=€g€Y€€€€€5€€<
+w 4uc€)€j€z€qin€6€,€€a€S€€\€€€€€€z€G€ TK`€jsXN€̸€2€€XW€€€€8€b€Ó€"€€H€fS€€€€€€€H€€|€p€€€€?€^€€€\UX^ f9€QD-@€c€€O€€€<=€€SBÑž`€€€€€€€€J€€€€n€B€€€€d;a€q€2:!ǿ€11€€Ʀ>€^? Keq€€:Cz€€€€W€€-€€w€€&€€X€€Ȝ€agȳR<€J3€=G€ZsT€€€аN€€d€€€€^V !O€€€ʬ%€€€i€4€€€$€yk-€€_K€€€€€8֧€.€F_€€P€€€€€€ܘ€€>7G€€YahÛ£€€€€<€z:G€O€s\€+€r€1€€€-€€€€€€N€€툢€€€+*€"€€€€*€€€€xa1€€€€UaU€€>€€€€€[€lɄ€€€s}%*€2€}€€€,xB€Y€v€^ €TgK
+f€€ €€.9[€#€€e€€€a€€€p€[€€€€€€€€€@z3€oU€Lh€&€d€
+€YT!€qe&€z€|€€€€€€ɤ€€,€€1€9s€pI1€€T€oU€€M€€€€€8?€€ў"ft"€€€€€€€e€€c€O2=p;€J€\˰€€.5€7€w€€€€€€3€€€n€€€€є€€€€sp€?M€€G€€€G€€€>€€w€}4€€*fS€?€x7Pm"rd-9€u4€ꫢ €3€ܞ€6€€m:€N€yW€€€g;E€ €Y,q|v€ WѼ:X€€v€€€?€+w€9€€i.
+€q€€$4?€€<x9€>UHW€€€{€€€€€ €Y€]r€љB€€€€|€0€Evʌ€@€*j€ j€€\[}€€L$€k€^)€€€_€^>€Af €6€€M€h€k_€€!€€€_#€€€˕€€€%c3€€<$€€€B€€ֻ55€ &Ϻ €€€€€G€B€€€3C%€€72i€€_€€q€€€t€€%€pO/€xA:'€T2€€p€xe€€z€#€€€?id€€o€ۥ€€|€^€€€`#€€hui€€(o€€QU%€€g€€€-€~€g€€€€=k €T€g€€€|gtz\€€€&Ø®k€€%€c€€€€€S8€2€€€€f xR]€O€€€€€Gy.€€6€€&P€Ǹ€㕣>€0Y€€!€€o€€€€€n*€ݴB €:H€ӱ€€€[€8€€u€€L€€€€€e€€ €[5d€ƌ€€€€€Y€€ü€€dY€€{ÉŠ{€€€€#€ߖ€€€e€€€ {€Ʊ€€,€6€nd*(k€&€{€€€J€€-€€€*€ €€r€€͕€|I€AÄ·Ë¡l€}€hyp€HF€G3€=6€jW@ۯ€U€€ap%€i€S€€€k€գ,0€J-€$#p^g
+€?=#€€€€€€€FY=E€o€€BF5€€€y\#€€€RG€€x#€N~€€~€A€m€€\€~@€,€e€y€€€1€1€€Ǧ€ƑUY€96€€€ €€l€:€[€Y€3€€p€8€w€' €}$€€€Vݥ€8€W€x€€€€€&6€U€€V€hmh€A€€€L€€;€€€9 €€k€a€{€{€€€A€€€^;^€€€=H€€3Ӝ€€€!€[€IÔ¤hT3€€€€ǚ>€jz-€ijÊ€€€c€€D€?€g€€€€€$jk4*€Ø€a€€€€€€Qs9^€€ €D€€€w9€S€€€qT€€h€€G,^{l€'Q€D€€€€dO€€I€€€Q%Zoe€€O€€D€B€a\€€A{L€€€€€€w<€€€G€€gZ€€#€r€'€€€q] €Ѩ€8€€€o~uY4*€€€W€€€}TM€W€?€€8€P€2€oo€e€€13€¹€%€2sV€€lmzE€G€I7€m€خﴌq˘27Zq€€Sj/€{€€€€€€e€€€€€ :€€€_€€Y>€€€jq€€€-€pz;€ܭT€€€ãY€€ɩ€(€€)€€€q€6I€€nQp9x€3Yn€hd€€J€~O€ք€ €€€€*€VT6€Ϭw€€€oX€܀€]€k+€€S€.€€ļ€c€€L?€z€T€;€€~O$€€€/x€\€€ ̒€A€€€W€€€5€i€€€€€€€M€M]€{€€'q€€€Į€€x#€€€9€G€T€€€ݞ€
+mfy€€€a€SU€€;€)/s,;€>€Y€€r€€ €3€€€{5€€=€O}0€a€€I€€N€2{€s€8€€s<€+€
+€€y €z€€~€€8€€iÎŽg€€€i€€)€€u€+€€€؟€€m€L€{€5€K€}$€€€SB€€€6€€€±€€9€<€Q€A*€`E|€€€8€€-€v€y€E|€e9€L€_߀{€€€€€€€€8€fd€Y€xf$€€3s"/Oӡ€€€€U€€€7€I€\€€3€9€€ћG€€€T€q€€#€€€>€€€I6€ €€B؉Fz€4€€€€^€"€w€€F€}€€€€Í€ߧ׮u|ZË¢N€]€€l(€€€X€€>Ö«"€5€J€D€€€€Ԧt€€".A€xN ]€dhyG€€{€€M€-€€€]ش€€€bq€=€#[o€€ΑhFD€o€€€€?€+€€2€€€€*€€€€€<G€€M€€€€z€=€€z€€€4€QP€€!€€\MFt}€
+w€!€€[Lyr€y€€€(€€9€sz€̗(€€+€z€€€€?(€&=€€€`€€€€€z€^uU€!€€G+€$€€€€€€€|€F€oG€€<=€mf€€q€c<=Uta>€€€€˷€ €-€I€€;e€€€#€w€€"n€€€zEK0?{뙭€€€pZ€€€s4_`€€€U€C€€M€€Z@€€2X€넿e€=VFD(€g€€'€ZÛ—x\€Ř€€€g€€€€€€€Ӣ€€:€€_€~€:z€€a€€€€€<€\€O€€V+9€8V€€swo\€2Z€€€rlie€{|€€|€ €€M€€g€`€|€€9€)€€+€=€€1%€€M€1€Y5~€'€€kg€ €|€ul€L€9ddl€@€€Mq€€€L€í€A€T€€€X€#€€rf€€ZL€2'€€
+€€€d`2'-_€-€€€€€sh€€E`+€r€MR?[€TdzFe<k€LsD€#<€A7M€;€đWl€€€€€諯€g€€8zM\>€€€€€€X€<1€€€ E8ZD€;G{6€€#:X€€€€€€ɷbf@€€€€dx€w€j€8€D€[€€Ê€d€€_€€€€€V6Ǝ€€r€k#€€'€2€€€€_i_€€9}rӴ€z€=Ô…{T€€€€C€Dr€€€Q€€€€€€*1€€€€~'nP1€*E€;€€€M€\K#;€€€€|€[€€Ǹ€=#h€X*;/Y€g€€<]2€ht€o'"z€€"Ñ…1€.€8_€€€L€€€€€h<Y€A€€m€€h+€BD€€l€֟G€€h€€т?€€€h%g€I^€~€ DK>€9€€.G;t6Z€ϣ€!€€g€€ €€hF€€l49w€f×£]€.;KN€€+S€;€€€}€|€H€v€Qy)€€ 4€€ʴv €4m0€€ €m:c€€6€€€al€8€ €€€€m6O|€€;Ў€€€€€Ȇ€'~€€f,€3€s€€€€[j€gA€Z,P€€€€/x<|)Mv€€Cb€0€€€*€Y€€e;b.]€i€n€€€2€€€I€€€le€e€€o€€€€Xg€g`€ʻ،€€o€V}d€€€޼8€K7Ñ€Cß¹LoO€€_€€€€f€€€<€]ϳ€=€t%€€€?F€i€€€_`ӀR€€€E€€€E€€m,Ԟ€hc€7€€€ €(.[_€€@bÞ¤î¶b€€!€€M€€€€RM=ß0€"p5€€€*€1|&€L€€u€€BÖ‘wt€€€€€€€€zn€€?{€€L€€Gh$€€€n€ €€€€c€€(SO}€L€€€!€€=€€Sr€€€LW€?a€V}€€T,Vh€€€€3€€{€€M߈€a~€ ƶ€€J€€€7€€€€€€€€J€Cf€o€€C€ €H 9€Xb7H€€3€€d4€*€€|€y=k€kFftxv9€ €9I€.€+€r€€€d€8€€€
+_Êšx€pM€:{€M€€F€yk€€€1Y{€€hv<DY€€ʙnзs€€+€€ݙ€€€€آ~C€€Ôb€€8€>#€€?€€€B€€njoю€€Ur#q€`3n$rlB/€j€€€Gj>€€€1€Wy€ʡׄw€€€*€€€_Ty€7€3b €?UY€€€€€OX€|€F€€€d€€€N!€h€€fh€€€€€€ƹBM{€€z&€0€.€ޑ€€=1€€€V€€€o\€€€€€=|q€G€×€€€€€€€s1€€/ޕ€p€k%€€df€€€ߥ€€€^N€€€#Mt€[~&ϯ€<€€€€€€€€<€€€-7€ꛟ€ƯW€€€
+€€€8€-ᬤ޽€I€e€€€€ԉ€v€5%G€1/€€€€€€*€€G€Q€€3€€.?€ €€€€֣r€€€)j€€€^D`Xo€€€p€€€€€?€€,€€.z€€>m~D€ܗ€€€€€€€€€a€O%€x€t3nJ€€QÉ°z#€Ϯ€vZ€v€p+.€€€V€lۙȗ+€>€N€€F€&V€€/€ {7€V€€€/F€a€O€€P, ¹€€mz€w?€€€€bޒ€<v€€€€u€H€€€€€€€btMx>T0Ø“5€€z€€€H€1!#€⾂€€;p€€ €€nk뛚[€€€G€ €€€[€ €€h€[#T€€XSu€€-9€€u}€€N%€€€€9€5€&MR1€DSNþd€/}>€L€€y€gR€]'€E_KÄO€Xm€DÒ³H€€5e€€€*Ҿ€€]€€€w€^€oyuO6ԧ€€€€Qp€i€"€€V€€7׆)€€€s€€€€=€g.€€y"q€?T)j€X€?€%€$€€€€€R €>€€€.ox€€€€€k>€P9€Ħ€rê±i/_ €€:c€g€IL€€€͜€€x€p/€€z€eAg€0€€x€q€~€€4€W€€€[€Fk€€.€€€€€#€€€]€€Cq€/<€€J€\€€7t€€€3z€ /€€~G€€€€BY€€sW}€D~&M8€Xb€Ϥ€€C€€OV€€)€ Ӗ€<cȣ€€€>€VgS,€€?€m€Ǻm€_Vq€(V€€€€-p€W€d€q'€L€"€€W€€€€|€A€€>€7€53.Zȕ€€X€Nä!€q€€€j-€a{€€g€€U]%c=€4-€€v€ €€5€€6€€]€€Mi4€€€ݼ€€?€Q(k€C€u[qo€€€40€Â€€€x€€€€€r€€€Sg{€3TO€€^€R3€,€€?€€€€{€}€d2€€L€8€€[Lqf[€€j€m€€9ޔ€HN€C€i€L€€ €o2€€,f€€"€o€3Ç“o€€d€€€M€q€&€€€f€€€K0[-0m€€€g€€ER€€aÚ¬f€[P€€€€g€!€8€€€€@€8€€`€€Œ€€€C€€b€8)iF€xs\€%€d€[,nC}€?G=€€L€ %€єnEI€€€€$P-€€fJ€€K€€8?[Pz€>N€€q€g2'K€ x€€€8*€€dC€€*€Σ€€7€;€̦€x€P€9€<€
+p€€€€€iq6€n€Y( €L€€F€Ո€E€u€L{:€o3۩€€u€"'€€s€bAo$'€OJAqχ%lA7€€€€€3€ԋe5]€€€ &k€€n€@€€v3€€lv€"€9>€\ËŒ8p@€&€RL€tSze€€'4€€'Ú€Ɉ€B€€$€I€€}€ɡ€g€€€€€€€'€€€֠€t'€͈€㓓€€"€€€K€@€€€€h2/€9€€#€9 €LX€€#€^(8Q€p€€€h€€€€^€#@€P€€ €p€€d,€€€2€€V€€€g€€85Ê–€€_+ZR€€㸔$j€g€€€€€€€€€=€f€€EX€"U€€€Ȝ€Í€Y€,€€LIq€mÖ‹i€GG! 0€Aj€$ €€IH\2^€l€€Ȗs€€€€€€€€€іLå³Â€ €€v€>€€€Z€'€€bL€€ѾԌv€1ܼ€€i€\iB€x€€€ʔ `B€v€€f€(€F€1I€€€€B€€X€€t €€(€€H `1ZȎ€€€AF€€.€€€€€8€€€€€€(F&$€;%€€€€!€{€8I6€=b$€€€€ .#B€e0:J€E€6€ €€€l€€l€€<€6€€€[m€Q€€€€€'J&@€€€Č€€iq€΋€q€€€L€;z€€v€c€€If{|€€!€t€€s[€€V€WvO€€€Ug€s€€€€€N€€g4[€€€€€€p€/€€iM€Z€Zf͸€€€€€€€€+€€€ €€7€&€_€€€MÍœb€€€b-€vZ€Y€€€y€Dkq€e€kÆ¥i€+`'€d€g8€€€€€€€€з[€Z€3SW,€€gX€]€€ €€c-€€LN€~qV€€mm€α€w€€u€€€˜€€€€ €€€€€7l€}€€€€€€€[?=€€ €€9€€y€֋€€€€€€€€€z€u€5?€eMJ€€\DVM:Y€€ &Y'[€[a€€o€€g€€t€€J€y€€€€€X/€f_|€€R€€€€€€€M,r€+€٪E€€^€€€b€€€€ q €v€L€€]€€;€ǧ€Y€€€€_|°€ W€T\Ԡ€3€€€€+€€€7€qk€€€i€€+€~;JX.€#€€€Dx €n€€€€€€€€֖.€X\€€p€€71€<?N€ P[R€ €Rq€W€.€€R€€Kq€Q€ 3€p€Ê€€}.Ç€Z€߉€€}€€€q"]€€U€8T€n_€€€=ÔŠbt€€*7€€€+ί€2€€ ?€ o>;€€˙€€p€[х€3€^€ɗ€€€4€VO€D€n6€€€I;ER€€U€t1]?€€€=kU€E€€-K€€€€g€€N€€€€€€7€SRH€€8R€N\€€d€€€93€€€€*€€€0j€€€n€[\€€€€€€7€&?G$€>o€€€Օ€%ee €€]€//€€9€ ~€€A€€r€}€€<€€߆€Ow€€€€€O€€€€€ì¼€ €s&€ӿɮ)YS€/ɹt€€€y€€ͼ|Ö§f_1€€€O€-€WRêž¿`a€"€b€U€WWTV]S]S€d€€u€-€€€€^_€6€hlj€€W€€€€€-€€€PGg€€€ܴ€€€€u€3€څ€€€Z€€QLV€7€€
+€€Ƚ€
+€€nV2~€|Q€de1€€€)_Jg{€€€€;€&+€€€€€€€€€C€%2€767€A€€€qt€€€ʵ+€C€JK€€S€>5€%€WJ€̣€c€€€@€7€0}o€€C€€>€y€€܄€ʾ€W€€D€{€€€€€€€€€f€€€€€€M€€ݡ€3€€€€N-t€€€€ WO€€=q€P6€L|ݜ€€y€w€XJ€€€€€€ |€€€€p€€€€k€€€ex€"]€€P-€-€q€€Hq|-€l$N€€SU.€€€€7)€€N.€€€€HQ€
+ݔ€46[:oR€€467€€€€€€€Iiji€p€€€€I€€€\%€€€o€<y€€€)€ԎDg€e!€€7€€€€€Jʃ4nܠ€ €€h%b€BA€\€4dy€€€8s€€(€ȗL€€€€J9€€€&e€€FJtV€€€€€ȣ€€€s€€e!;€€}€]€€€K€€€,@€oj€R:€€€€€B\)€€J€
+\€6€R€P€jB×µ5€*+P€€€€vG€€€€p€|€Ê! 2€€ €veC'€>€p€€C€€v€€ €T€Hu€€€
+€€!=QL€€€E€vL€Kg€g6€€€€€€€€€ o€€,€€*€h!€€€^€ %€Y€3€€€G€€€€c€b€€ €Y*€€€€€ €€}k>€"pC€€F€€ $€€€@I€€€€Zм€€€€€€Y€1p€A+€€€€€M€€H€\€<€€c€€W€S€oǹRu怒P=€€AHb8>Y)m[€€€j€€ B€€€€=>€€<`€x;oz€8p€€~a€€€P€€=€۶€8€F€ K€tv€€€€?€g€ €€€s€€€€€€€€€ç‡Â€n€€€€€€W6€ڕ`F€̟>]€-€XT€P€€7€C€%pPuMC€j€€*3€$€€yE€€!€\vå•—+€€*€€€€Y€~~€€€7€M}96€ €E€€C€€€€.€ €3€ €s4€€-€€SY€€€€@€€€,€4€ml€å€€ €€@€Ãuwt€€€N€O€€8sÑ‚Ä«; €:€
+q{p€dyb€€剩M€n=€€€Ѵ M̶:€€m€€47€€€kC€€€&z7J@ €€€€€€€€*M€$=€€\€9€€€€S;R€6
+"bQ€©M€€€)|{a"€€T€€€"€s€h€<wjnjS;€ž."€'€(€€QT4€c€t€p-€7 €€{jG€ܹs€A €€\X€€<WO~.ؕ€{€€ϟ€€€,G$€1€`€€B
+$@€€€€&R(|€€€h€YeQ€€)€ "€+D€€!F€€r7;k?€o€A!~€€€h]d֣€#€Ϥ€€€q€G€Dnishh\€^Ø‘l€?€ €Q€€€sÑ‘ 3fÌ;€€€h€tH€s€€€€ €€€€€€€€€h€€u_€"'€€(W€tt€6€u=€@,h€"M €|W€<. @€l€ZÖ¢q€!€I9€€€€@c€€g€€*P€H€T€€8d€`V€€)PmO€€s$d€€QҔ€€€€€ݒ.hR€h€€€€1€3€87@€€a›ϭP€i`€€€€C€€€€uutB€G€€€&pj"€!€k,$€€€€Ζ`+T`HDJ€%#€€€D€€l€̺€€-4N2€€€ 8)€€€S€€€€€v|R€ӕaqÊ™}€n€d€N €€€V€€Y8Y€€/€€CM€*8h;€l€€=eB[P€Y€€€^€aF"€€7€4r€€€€$ 2€{i€€€sG€h 7€Ҧ€4€€€€6€<€i'€€€€€9S€k:A>€€€€€qaW€,€€€€^€€€€Tb2€x€xM€€*C)=F+L"€€€€ € _4€oxp€a€€€
+€€€a€a€€€€€7€.q€c€€€€€ 3 €€€€€€€i€[?€?€€€€€1 7€€€a:߈€"€D€€€€€€SFO€€€4€€6L€€€V€€-€€€<€o€0€€€$L!a€€ն€€€p€€€Sg90€;u&€€5Ø‚€€{€V€=&g€€€&#€As€:€€€€9aw€0€[q?€€&€€€€W€€v€€€€k€€}€:X.€/€€€?\€ €H€9€`€K€[€i€\h€ 챸€vc€x€Q€b€€o€€€€€€[€]y€]€€€}v€€€€€€o€€€qtT)v€€€€€€€€e|&€€8€€:€!€€B€:y$€
+Ü…^등€9V€c;€L8.€͑€p0R€僚Tq<€b€€o`€[6€F€o€€.)€u1€€€q€.€ÿ€€€ú€€€E]6€€€€E€u€€8€nF€ €Fjc^€€€€/€#€Ы÷€€€€ŌJ}€L€'Z€€H€Z€€@yU€€€€dqN€€€ de€€keP€€-€Q€€.€Ի€\€Ajp€€<h€w€Q€5>€€;€€€5€€€€u€€܎€€€€€3€7H^€m;y€gF7N€€€€<=C"€n€ĭk€fo€2QEM€€~:<€/&€€€€€€€€€<\€€2€€}.€þ€€€Gq€{-6{€v€H€Mز€S€€Q6q4€j€€€S€€€,)k€€€€%?tÖ§B֋€+€Q€'€€€€­€€€R)s€}\€€[E€>F€€€€O€€€€p€€€<€€a€=;€Wb€ɾ€€S€€+€€C€€€?€M€€€!€Y€€€€€€€€€qR€€€€J€H€€N€h+€€€AU€€ń €€€€€€€\€L€֊ڊ='€€€€k€o€[Þ’9€€€€€€€€€€€
+?r+€€€6t€€€€.€€€ I:€x€[€€€€ل€av’€Yu€ս{q€;r{€oF€€#€6€€j^\)o€€ް€€ €€€€[lm€rK7:~v>죴€Vlb€7܊;€z€€€€€&[€€(m€€€m [€ª·€_€€U€/_€U€o7"a€[€o€n€o
+€NTb€?€֥€€€%€€u€€€u€€€Y€e€Y€.S€^€T+€U€€x€l€Yu€€S€€9€Bʀ3a€€KS€€€€f€KT]€.V3+m€€$€&#~Òº €_ l€€€€€€€
+€€€HY€A€|?€Ӌ€N€Uĸw{€t(€€€^2$}€€z€€x -€€V€5€€m]D€zÝ€€€aQ€€€€ev€\€lÅ®~\€j€R]3€]cT€€€i€€€€€€€8U€5s€€€€{€€^€wÏ«Fw:€H=€€€€r;€€€€€P€€4€Q€x2z;€#rK!ݾ€&€€€7݇€€€€5€€'€=€€€3€€€€€€€!r€7€n€%€H€s€3€ €€q€€q਀€ €L% €€G^Z€V^Q f€q .GK |€€€€€€€€h€€€x€€€ί+,t€€r€B€€@€W€€E€V3€f€}z€€€€<2€nd€€ߵ€€€€؈€€€€€Еˎi€€q,^'r€€IA'€€9€€€€€Y>^€€€&€€M€C€s€€,•€€ v1as€€€€N €€€I€€i€|€Q€n:5*€€€!€o€՚€€ĕ€€]€€€€W€o6y€€€q€F€S€€€y/»€ʟ€q€€€€;g€m€€€€€€€i€Fg0#ٿ€€CT€M$€€2:€s€€€*€ĕ'v€€V€€H€€VQ€K€€€€[nCÇ¡oh€j3|o~€R^֥€€xP€€€PC €"€P€K׊€€€€€V€%ƒѳػ€^€:€F{€€vaÔQ€€r€€> €€%w€€€&€L\€€83€€€vÓ¦'o€R€H€͸€3 R€Nl3.
+€€€€€vaIo€t€€€€€X€€K[f7€€5€€0H€€6€ G€€€€€t€€€J€€7€m0€€_€€ћ€]€8€€\€/€€€"€€€€€L€_€7€€€€€€€3b/-|V*r<n<NH2Y€6€iC€€,€WX€N)€€}€€̋€;K[[:|ѻ€.€€t/@Ǥ€~€€€59K€€€GwR€€ €€€`uq€€€X€€€€\`U€z€|€^€?€e€€R€€€2n€"€BMYrg~BÐI€€€:€O)€€.€`€€l^ 0€O€€|€€€×”zc€€j€,€€g€m€€€tYe€€f€€a€Zn€]€L€€€€€€sP€BTQ€Wi7€xJ€hk€)€€2?7.N0 €€€€€_y€/€S€€€B€€€߮€ꩿ€;/€€nT\€€€€€€bR€7N€*
+€V€s"E€ms€€ԕPM€T€1€-/€€€€e€N€F€
+€€ã£Â€y€M€;€s€N-€+@€€€C€D€ed€B€F€Λ€€€z€gp€. €€.€€€(lh€€\RcH€€€€€€€€€5€-€[€9€€€€W€QgS€€KXQr€֢V€wm5€€€€]€˧€;€P^€<€€€€c(€ht{7E€\pM€€Z€€€€€€€€€TW€>rig€€j%.€Þ
+€€=€"pj5€F€€¨€
+€U€#.[€€€:s€x€€E€³RX€
+|€€€S€€€T€€Kd%ƫZM€€€fNK€€D €II€€zt bb8wj71€ת i€D€€€€€9€PC€t
+€€0;€Ev€8€]€fO€€€k_Ԇ€vO€5/j€
+€€R€Մ€€c~€q%~€€Lty€-߈€N.€€€€€1€io€€f€7;€WÓ“e8|k€z€{€_€€€#€:€%€€€DVf$+ɳ€€JV€>€€ ӥ€f\}kg€€€€€O€€ €€^€Þ¢ €€%€€€€Ä€i€f€Q€€€€€N(nK€€€€€k€€€L€€3€?z>€€|oE"€€k€3)?€"€€B€€€€€{€€C9%€"€€u€€€€€€!€€0'r9s€XkEP€Lw€1€*€
+€%O€jE*m€YcXr'km\€>€
+<Gќ€V[€w€ Jn€€|€"€æœ(Ú´Wi€S€8>€AE_zu€€€€€€€E ^AEw#€7€€€S€] 5€m€€FC€v€i€€?i€€€€C€c.€=€u_€€€W€w>N€€€€€dG€E;€€€y€€i€W€yo€dU€€\U€€^€l€€€€€€€0€€€O€€=€ĕ€zT€€3€6O€^,(6€R€3€v€Ü…y+€敋€Q€€€W€y€ W€€€x€€€€s€gXGl€6€€€)€\€M€=€M€*;€u€€"€€€€a€ €gt€$|€pqϦ€€€€€;€u^ €€€W€`a[`€€€€€€€€?€'tÞ¾(€€x€x€/€j€€Ò€q—:ûn€cBm%€€h€€€gN€o€Gy׾€7€`#€($>A€€€€€€[€s€€€]XW; t€€€uB€b3_ €€;# <釽 €€n€€€€€€ѩ€€E€X€e€v€x€X€ €j&€€H€€(C7€x€xykq€€z€8
+@€€€7ӌ€w#j€\0€K€K=€€<€€w€9€6€€Y€€ U€€[4 €€B€hM€€€€.€<€€€Ⴟ€€€vÉ»]€qÞ¶N9€]€rU|€€]€€=€€N=€€€€W€6€.,€€€A€<€JGXl€€T€Ê€~A€€€€J€€ÜK|ýH€PS€€
+,[r€|€&€ €€o,€€E€h€€H=€|€€€€Q€€Jc€€€55€
+€€"c0>v€.€Ȏ€r8(2€€u€€J€RG€A't€42\Q€ L€€€€wv€€߅€€_~ʌ€j6€1€3€€>€江€|€6T7k4ß 1€I€€€€U€~W€U`@€{=€h+€€ye!U$€Z}€€/€€RG.€O€@€v€€G€€Sa€€W€€oyO€]ut€€n€€€mT€€8OM€6AyE4€€€gv/R€Gk:€*':€c€€€:€ɯ€7.7€€$h€V X€€€€Bnz€€€DžH3€€<€E*€5€€€€€z€€€tͤ€€€€5€€`Pt€x€C€€€€€€t€W߈€€€'!zC%€"m Z€€hn€]€H€€A$€€!€€F€S€€O€€s€"B€=€jÚ¡2€|€€€€€Ўϓ€€`€€€~O€įÉžN~€Ş€S€€J€€ʊ€͞€€€k.X\Z^€Ƚ€€€€B€€t@€l€'€)€€€=m€Ü®q€€ €>ú€_€€9€€€€€€2€€€€uj€€€t€?'/€W€€&€r€c:€cIlFh€€/w fb<€vY€€u€4€€N€n€€Ǥ€€d€ €€.€€€€a€:€€8€,€€6€€خN€}€€€~€€€(Y€%€€€Y޷€'bR€kY€)€€€€V€R€€,n9,€€€€€€l"€f €€€^"fЫR ,ʃ€€€^€ G€€€€SC#€Q€ €ğ€€ө&€€€؊€ ۋ€ăsf€€€€v€R8€€€€m'Ížoz€W€€€B`H;.Zy€€2€€€QÏ·<€V€€{C4oD€oX€€^€€€€m€€N€l4l€€L€€€€O/€€w€€€€z%€€]€€€€€€€㛩G}w€]€_ؾ#€€u>€€︶€€€€€U€€€LS_ €€ €€,€v€€€€€)*Þ€€Ԙ€€€8€€JGW0€€€€€ɉ€P$€jё€€€t€€x€€5Å–€€€ƒW€ €%'_?€%'€B€€&€|€€€€€n€€€?\€͛CA€€$~/?zA€€ €€!R€b2|€€2€~€m}€€fu6A€y(BÖ‡8€€€U€w€=Jݺ€€€€Q ]€€€`=7@€€€Nz€mz#€€€€<€€#€\ߵ€€*€-€ €€3/€!€ɳw Ú‰~K€€cs€B€O€P;€€€€ȡ€€€€Λ€€b€L€X€H€€€€€€€E€o€€€M€€[L#€€€2d€w{Y€eÜӌ€€K€€|N`X^q€€€€€€€0:€(w€ €Q€c€€|€c€'€€€vr€€ގ€€;€€Sm*€ €€7€€g}€€€€1O O€2€€Úzc7€c €€€€7(€€€1€€€d.r€y5€X%€]€€(€€€P}€€€r€: G€€€€@€Rˤ€€ ҧ€ €M€€q/€i#€K€€ €N€T€i€&€S€ €€€V€DM @#€€<€€€€€B€€€€€€e€€9P €€$h€€U€€"€b:;K€&€j€|€J€Kì<€Z€qS-€€€€€€€€V€€x€€N<€€[€€€Ф€€Q4€^€€€€€~€8vҒ€€{0€€€€ FQ€€9c:€€€H"€€ #2i.€€€]F3€€€i€>€v€t€ff-:_€ZÝ‘o _€ly€€€€s8i€€6](€€€RZ€€+€y€˘@€€=|€wS€€€8€€ߴ€%€€y͸€€F€€8 €jCs1S€€€€GĤ|%_€€€€€ÆBg€€€€g€s€6^€€;€€€b\1[('€€u€€641€€O€Ҷ j€€g db€Iì¸%€G€W2€L€€{Λ-_֧€b:Ԇ€€€€€T€€G€€€O€€ne€^€€aô€co€€oy€3€4.€g#€€;
+€€€€€"€W€'kW44UuF's€€€~:€J3€€€c#€WL|€ €vml4€€)qKက€€ J\ €9€ b€o€€|€€€€NS€ޯR€€h€T<MX€)u€V€6€w_€€€Kt€€~!R1㊻€€€€€㰌€%t€€€€;l€€€[€€€ؒ€€F€€€€w€R^'{æ œe߄€A€=g€/€e"€€#Z€€Tf€P€c;JW€€€€€6ı,€€\N€XJ#p)€€ !꼩5€€€c€ €})CW €O~€€€e|€€€B€€Xd7€€€d€q€€€E€9Hs€€€t€bYN6o€=&€€€޻€ݘc ~€€€€€€.0€€€n8M€ޣ€€y€€€$€€B]€cY€a€h€€Wz,€€/€€=€€`A?€A€L3€އ€V€s€9t€€t^€€€€ `5'€€€€4€€)€Vt€€~€€ʖQ]€r/€€€€€€€€€6€7€W-€'€€€€€€€yn€9€€zJ3g€?€€6€hb[a'<€€€€D1z€€€Y€7€Mf€@M€K"€ €?€€€€€njC8l€,€€h&€€€€1Ӷ€€€yS€x€€K€€1€€E€€€€ohT;€€.b€€€€y€i€2&€€€€€3u×…>€€G}q€vE€n'€€€yn€ €€# 4W€€€€9€\€€€)u€R€€€YE€€!.€ €q €€€' €i€€2€€€€€d\*w€s%€Y€€<€€sL€€€*€FÈ“.€}€PMs€€€!h€ipӆ€Ċm[€0€;€€€0]I€€€€]0€|€2€HMX€€ €€@€€n€€€€€€)€&n€€(g€q€a€?€IO€t€€€ €€€t€=€€|€]€€f^YLwSEj€€€€€€v€p€]xY1€€*\{Mn€€\€€€€ €€€y1U€A?XW€y€IOQM€DX€-€€€€€ €.t€€€€€€€€€U€€ [€€C€€€€\zFrvxрIw .€>P1€€€€P$€€€€€€EN€€€M€€€JN€€ٮĔbX€€€€z€€]RN_€€€€€€ €€€N€€E#€€€€€+K€"€€€56A=€€Z`€€€€€€6€~ו#€,€fh€uAT,lO€^64D€#€€G&:€x€n€Lh€d€D`TQ`@GH€€mU€€'€p€€€€+ޯ€€€T€^€€€ €€w "€gPN4_c0€颧O€
+i€€7€4€€€.€A֖€€(€€{€}
+€W€€€€€e€ᚻ€wsÕ€ €€€€݉XВ€]w€€QAg€€|/ P€x€€€€ €€7€€b€)€^ji€&€ €€Rn5"=EG€jYÑ7yt|s@€€4€j€sg€~o`€€€€@Q€ Iz€ €€€€3 €€€€&€€Y€ۜ€a~€v€`
+s€€W€ €€+€"ى€€TK€€VC€l€€l€€€€Ȓ€cL]n€{€9€tf€€&€€€€<€€€€ci€€€
+#€$€€u€€f €~€€l€€€€€1€uL€€€€€b€$€€€€€wۥW1D€€<)€Ԥ3€€€€€mNf€€Vs(€J€n€\
+€€y{€]€4IA€€zy€€€€1€€W€&R€€€L€€O€ln=€N,€`€b€,k}ɕ€"€€€q]N€€E;O€€.)=Tٜ€oj€ۋb
+co€€!,€€a€o€s€Q€€V€€C€.€€€€szc€€€N\€€)€g€e€€M2T€€Pdh€€D€€€&1€€vZ€!€ό̄€6L€€€€€€€]*€€†€ €€&€€€4}€t€}€€€e€W#!€€€€€€bÌŸ^€€€€?€€€?€9€x~5E€嘜€€pUt€€€_€wP€ 0€ €F€€€&_å€p€€€W-€€€l€€€q€€%€€f€€G€€3€€d€Vׇ€V€€%€ֻA€8€€€€ 6x€A{€€*€bb€W.ľ€M~ €h¡]€ €o#hD]8o€C€R€€€IÖN€€€+€€c€€ȶ9€pk€4q€ €€ee€O€€\€€Z8I€Cߦx76Vx74z€_€0€€€X€3$€f€8€€r€€!€F€x6€€F8€€r'€€€ ;Ђ ;€€"t€€>q €€MZ€<€E€T€€€€Y3€€€7€€€€IR€€€Y€^)€epcMXF€€€€€€€?̴€€€€€€€€X€7Z€€€€i 㴿€€}€€€XMu€x=€€€€€^€€f€€€}€O€€€€€T:€€sQ€€ZO€_%€€€1D€xDEI€v€€h!.F[€Ԥ€ j€€€€2€uaY~g€)_€€€O]9&ɖ€^ڹ€€
+Ԍ€€1}F€€€t"€i€-€HÞ†lٞ€€€ €€€.€>€€ZO$€€€€E€€€ی€€a€€€€ €€a€€\€€€€€ S€\5€룪€r€€ €€€nY€79€€Xn€u€€+Ø€C€],tm€€,€_€€€vAOd€€Nڦ€u)d€€€€)&€D€€a€$€&€K€€xS1€{€2€€6€€€€ԊYk€9͚€€€-€fpj9€U€€€€K€ %€€#€T⮘u€t€q€`/a?cb2€n€l€€€{06€€F:€€;€a€5€€5€€Z€€€€€~€b€H€g_€€bW€}I€€€€4u&€;TW#€€^j€R€>€€€xY€>€€:€ԩ;€€ /€€pI€&_n€NLc€f€Ԇ€€V€€.[@€R€"yD:€€€€P€€€€(€Þ²?€]€7€T+€€€p9ꦀ%x%€ €€]€€7€€€e€H|€ؤH€€@€€€;{€P€\q€€b*€€<€€€Y.}€€€i€€€\€kS'€€Ɩ€€€€rTvy$€€€K1€€*€€x€q€+€€€'€!o€€€€s€€€€€€€€qdI€€L€wܨj€tM€9€&€o'vY€€€€€ez€,€[€€|/€3€u]KY€?^p/j\ hG€€cK€€€€H€€€€€€fF€€yQ€v€X€Rg€€S€VW€ €€€` :Þ\Z€€€U€€€€6a6€€jM)=a3SWV1"€R3€M€€^z€z€<€$€/€6€€W€L€Y€€6f€€{€€,€€€P57€€n€€@€N€€€€E€Q€€s€l€€€€)€€O2eN€€
+/7€€ €:€€`;€€B7jp€€€v7€€€7€€€€ <M€lT€=€}h€€S€€'€€€7_€K€Q€€\K€T€x7€Z€€a€€€~D&€V€€€g\k€`€€€a€€€w€€B€€\€€€ Ϭ€€€€v€U€tN|€€€B/€QNKi€€i€€%€e€€€€$/=a€ €C€€,€{€€1€v€€€bl€b_€€€€€1Mrͅ€o€€;57]€]€€$€€€€Լ €
+€mQ€€€٩U€€€5€G`U€€
+€€X€€€膹€ i€u΀H>€€W€I/{€€ €\€€V(_€~€€€nNG5fÄ¢€€4€Bx5Ǽ0Ay;]€KxF5€€€k€€€€€R€€€€"€€€€€{€'€ <€Q€€€X€a€€€e€ٰ_€€Xł€]€_€hnV܃€+n€€€€€:]j€€€€q€€k€€€}m~h€€€_<€€€€d_€€.YNny€€€@w€€6x7l€۴ H €€€q{BU€€ͲJÊ©V€d€€m€!d$s€€?€€&€^€\€Þí§±"/N€Ym€{7€€'y€€";Ú° ]d^kQ-€ €Z€€€€€€Û¡?€1s€€N€_€lÙ¹y€IlZn€€XUc€€€ €U€\€€€&€oOa€Zw€€V€m€€@ €>€€E€㾺e€€^I€t€J€€S €€€€€'€€ NE€€€f<€€eT€P€U€k€ Y€ʹ€€€€€WQt€€6R€kڮ€m€'ß¡2€wPV€€b€€€>bsظ€€h€?K 0€N€€€
+vj%r€טK€NJ€Y€y€7/€tU€€€O€C€ ))€€n€E€€[€€€€€2L€€€€€<€€CY€€ț€€€€S(F€ €b€€R€:€€Dn€€|€ӿ€H]U%z€3h߯€€xi€x€€ؕ€q€iÒž&C&€€(}Ƀ3€€;€$B>w6ß‚`€€/€i+€€€0€€€N€L€€€€{Zcz€O".€'€gΨ€s€€€€X€
+€ 3€€€N€€ھ€:€}#€€S̟€€G€p€€€>0€y€€7X€Ì€
+Ð¥C€€܊€.f€€Ҋ€€p€€+€DAƃ1Z;€H€Z4€!€3€€ut€€€b€_€?€E[€.X€tÀ؀€u€€6Iu €€€W.X(l€€yv€az€€ݥB€€€r~[€o€€€€€6€€ܟa€m€€n~€€o€€7l€€d €m€€€7:CJ€[€€^~€€€€€m€f€€€€€€F%€€<€€€l=€7€€€ß€V€o€€€€€€€€7€m3€5€€€€79:€€€€€€4EX€FS€€€€T€t€€€€€€€€o&€W€Ͻ€of€€€€€€€8\B)€€>€€€€€Q€€*>€€€€€€y€€+Zp€B{{'€(€€€Z֚Ҋ€€€€֩€€Z€€Ӗ€€ +€€Ք.X€€ZS€`>€€`/€€€ cpweave.SYMMM€/96€€€€€MPSTMPS €N€€€€*H€!€ `€€€€ €€ke~&€€r€3€€€€€€€,3€)_€.€€VN€9€.€€tKm€u\€\־€€lYYy€€€'€€€N€/€€¶ €|€€€€€"€€€ 9ȶ€€€€p€€€f[_x€ €\xfl yl€Ͷ€͢€uu}g€u€6/Ö¤s€€e€<€€<€€S}3€B€€[€€ۂ€nUi€€r€{L€DPT]vS€€€€4€A€€S€37€€lm\ÛªB€€€€ů"D }Ǣ€wU€u€t€€4€€€€!Q€€€oE\€C€`€€€]€Z€,€+겪€€Q€z€M€m€€-8,€
+6,€\z€p S€€f€)SC*€€€T€
+€€€Q €YY€€€€€€€gQe€7 b€Ŷm€b€€O€€€€€S€€€f€vd€€R€\9€€ޚ€€平v€,S€€o€ό€q€sU€€.€è€€9+€€:.A€€€€€^€_\€4€€€€P€€^q
+€:€€€€ u<€:^z"€€cy€
+€1u舘€€€€㜧϶T€€€_€€K€"_€n€€5€€~€€€u€݌€-€€
+€€€€6s+€OO€€ €=xW9WGo€[€7j€€u€€€€€{€€€€€€€€g€€n€€]€~{€€O€€;€€€€€€€֧€€9€€"€;€~€€€€€€V€€€€1€€€€E€€€€W€€I€€B€{€€NP€NxY€U€ €€q€€v€€€€€w€o€]~€€w€j€mV€€€!b8.[~€]!€€€€€_~[€€;€ €€\€~€V€€€€)I€€C€€߷€€€T€;O€€€€^aR€€€u€[€€~€€ߛ€€€€€€€€€¬€€€€o€7럒߆A€m€W~€թ߻€w|€€}9z€B€+€€N€G_€[€(v€€>au€€€3€€€€€€€€,GaѶ€€/€€ݞ €}€€?€€€€[€€€€U€JE€-P€}a€€€Q€W€€€€€b€P삊€E€v€W̃€m€€za€ €€€ $€3€€€€€€€€€€€€€(€b€€€'˺€xҕ€€€€€8€ !$€>€g?€€€€€€€€€€V€Ԇ€€€K+€>kCyWcKM€g$€€€€€ €€(€Jo€ь €~€€€€€€€€€g€~F胟€€€€|Q€w€e€€€€څ€€€೅鞸€€%€O6€€€ӬV ݭ€€amksO€€€ €€g 1 €€Ҁ qȠƣ€€€€€b7€ץ€€ w€€+€€E€"€€M€!€";Ĵd0€€ˈ€/N€€€A€,€0€ =P€€p€]˪€€^D€Sڽh€€€_c€€pq|G€€IM빦€€€ #€€ €€S{€G€)X,m€€V€i(o€€6€q\V€€€€2nI[c€W€€€(€€yѺ€€ڮ€€֎Fg€.€'€6€MqC€kEV€H€€€€3€€€( €;€€p€€ JD€T씯€€€€€3€€€]€€:€€m€€€c€" L€ԕRX 2Pú€*€%€ €Kq€R€³€C€siqb€€v (€mq.€€€€ֲ€,U€€\@j€ €Fk{ūBV€€W€€s6€k€€€M€€€L6O2Y€Lyn€[€yҜw€O€€"€€€€€€^€Dڔ€, €O6€€€D€h.€2€€!5€Z€4s+0׫€WU€€€€ౡ€€|€w
+.z€€€e€€€€€\€€€A'a6€̠؂€G€€jjW€€€€€€€€)€€U%ʪ€€u€€)U€Ѧ%€u€€€9a€U€€3€€€€(€€€u€w b€K€Y€0_U€fR€7[Z€€€ €r`>€S€€€s€€€€€€V€t€€t€R€TU€078€€€€€F;€€€€€6€0€€€R€ ֪€W€€!k€€%€€Z€(€(UÖª`Pi@ԓį€€SA€hF€r33 €€€€€F€t4€€€€€€bp€2€€^E/},>|€€Ff€K€]~YeA€v€€g[€€8€€P€(€(z€€€B€NQ#€€W€€\n€€ǜb€€€r€€€€€€QyJþ0€x€j:wÒ¬.ai€2u€€3€€ӻ€u€€€FqX€€rÏŸ€b ƀ€€-}–扻"€€€d€y€€€q€€€€€v}€f׳€gKCVKukGWsc%€€ߢj;6€€€€€€€Y3€€€€a€€€€€€ߩ€*€€~M€,€t€<€?(s€€,€€€€€+€ €€€€Ns€'_&€€€"€m[€€*_€*r€€(€C€€v€o€V d5€2€G€m:€€N]q€€T#€€D€€O(€g{€E€m€]`q€+ €7U \€%€€€K2~&€+€biY^a€y€€.my€w€|€€`€€f@€$€κ[€V\€E(€i€€8€€u€€€€€m€ȖHY€o€€H€V€€€€€Ou€€€Y€€ IGk€€€€(€X€I€D€D€€y€€€€mK€€FY€€E€€;R\€€R"€c€Y€p€€>€]€ѨX€€€2€!€]€F€!"n4‚€hD,"bG#€€€€F$ "A€€€ €€Ð€gW€€€€€LQ€3X\€€€€€€€€mQ€€.X&R€€€€€€%Klq,€€vUe9ÔšU€€P€A-€€€€€?]€€€UmV€€€€€€€€€Q€€€_T{€€_`F)\€€+€€
+J€€;F€€el,K€€R€.€€M*€€F€-€b€z¦lyEY€€€€€€€6€Ʋ7+~€8Ó€՘€€€€€€Y(Τ€€€€]€€#€€D*Wh$€€€€€€€/€€7=€J€€~€~€€>Wt€€€E/]€€€>€19?€Ir\2(€€ €o)K€€.9€8Ùª]€ֶ€X€€€ƅ€€€€€€€€j€€-n_/€€€V€B€{€4€€[€€€ӱߥ€€€k€7v€w_€[€;|:€5Y€€€}€)D/&€$k€~€€€€€v€ɶ€€G€€€|€p€n5^Va€X€+@€:€€€€-€€;>˳@€<m€€€ €€;€€€4O€€~a€dž€E€DD,€`bq%€€8T€€€€;FX€€ €€Ox3€€€Í€€€?(€o€€|€ۄ€€e€w=2?a[€€€€J€r$€y0€> €o€Sł€ €€z€€l€€€brs.€߼&5i€€€^'€Xu€-€:€7l€R€€Z€€€t€€€€YQ€NJ/C€€€.€v€€r€M€e€€€€>O€e7A€O€€&%Y+€€
+€€€€€€i€IS€v€t€C€ܭ€€ح€€€E€€€3€€€€€$)v `sm€€/€,€aΣ€€€%IZ€€rd€f€€fH4XR€ Tl_P$€I6*€€€€€,€{K€F€€ ٚ€€€l€€€€€s€ €>€€G ,;€€€€€O~€M€€::€€U€4€U:€€€y€O€€1€>Z€sVM`Gc€c€€+,€vÏŸV€€€€€€Qi€€€€7v€€o€i€€*€€€€֖€`€!€s€€€€A( A€€ €€yx€€Jn€b€Np€ʛ€€u€M€{€,€€AJÉ­%€€:€€€€Xsj €€€ €€€ "€€+.€€€_A-֊€€
+€~ű++€€€€€€€€<t~€ݵ€!€n€g€€€c€€ };PXh€]€€JIȱ€€W*>I€€€Ify(€ݥ€{€€€€u€~€€€]€€+€\€€а€€y9€€€aOK€€€€,€[5€€ݵ`€€P€!l€€€Dƹ
+€'€>€€*€€~B€€€€0€4€€€\€€}€€i€€>€|]e€€<]WI€4€€t€€€€e€€€*u€ rS€BUx€* 3IOp€€€€€€E€€"-€Uܯ[€ xL€€K€v+€`e€€@o€€!Փ€€€€7€€u€Tk€€€e+€i€€
+€€€€€€` q|€€'s€>€q€|o€€%€bm>€€up€P€€)€€€€snq'^v€€Ø g>€ѳ>]N€€€s€r€€€€€€€€€d€O7€~€P€€€F€€€X €€€+v€n€€,€€€€,€C{4€€€€€5€hY€€?<y5 €#€qC&€o^.rY€);?UWYW€€սQ€P€.-€̹€€€€€z€€€Zߺ€Θ€€pc€"~/€€ 9mB€(€€d€€#C€€€€J€{y:tNÆ’€€€€€ _L6€W€€€x€MK}€z€|_€€€^€€- Õµ€€[ € ,0Ѣ€€FLK s€9>Q@€€*€€€f €-€ƥ€.w€€ku€e€€€€I€€€€€!€p3D€V/€€€t W€.TǨB˩轶€5€€J €|€€€€s€€1*€€€€S€€o€lx:€€q€€1€€=)€€€f€D €€wtuU€€`^ c€€€*€€j€€%Ŏ€€f€€€̮?€€i€€:h€€€€€d€<7€€€€ CC/€@5f€'r€€€'9,Tǟ€+z€€5)€Mk€\€€€w€&|€€wiQqx-\€w€€^x€€€\€s€8K€Y€€€Q≻€€@€P€€€9_€€€€€k
+ D€ί€€€~€J€SҚ€d€W;>€€J€€€€X€yb_N€€L€ݠ\€xv€'x€€€€€J€€€1€Io€ZcA&€-%€;€ pW"€2ڡ~€€e|~s€€
+€=€_8€Ө€€€֒€L€€€€€€€€tL5€€€€Ew{3€€€€y€qz€W{}X€€€{n€`Ll0€€*€€€€b€
+€€K+€j€K€j€)J€]!€p€,gl€ €2€€€*he€€€ AQ€€˪€€5L€#s€€B3€€32}€&w:€1S5€`€(€ €€€€Nc1T€d€DOHg€~OE€J€€ڵT€ݵ€€€€Z5\€€dyyIi9€€€T€€o*€€Ѐin€€ERCol€€€z€€gz€r€€KVVb€€${€€Y€)€2@€€q€8€€€ڃ€\€H€€c-9€€xs€(€€€€€€y*€€P.g€O€€sj&w€ȩ€pW~k€P€%+€k.L€g[€7/€€€~€€€€ࡅ€9pq( Ù™WX€€"€m€€€€€!€€ڼ€!€€B]€€o€€gÒ»'+Ëžuɂ€€€€€q€T€€€€t€{€€€
+}€o)€`€ݗT€f€ ) €€€]^c€€G<€[
+€ €z€€d€€i€^ €-[N_€:€
+v$€W|j€|LN€]Uy€CB€ €L€QÇ€€€€m;€'€€€€€Q€}%€€̘€f}"€#€€€|€€$€! €€O€€€€€(€€W€r}€}€€H R2bEln~€'f€Bެ€!€І€€ t2€-€Cx€J€q€€€ <€€€€p^€,eU€€2€€ }€,fL€S%€€€€€9€€p€€€€(G€Fz€€tU€k)g€I_ۄ*€€\€}(\€€p€
+€
+€-qq€y€!€€>€c€€€€€€€m I€-€€€`€€.€€S€=€I~€#v€ €€€sԯ/V€z_NW€€€€7m€O€€€>€1€€/R€€€5€t~€€O€€郎€€?€Wm6g€eU{€
+g€€2_€€;€€„[€€€€ͫ€:w€€€€€9€t:€€€€EÙO€€ 5€2€€€€s€€€93S€;€ڽ€ޞ€€€is7k€;Gv€€€€,0€зVU€€
+€€b*€98€UBeÛ§Xk€€€€€-e€y€#€€Ü€€v€€Jj€€€€€o9}€K€׊€€ίi€Uj€€€U€€Q€'€w€€€s>€€f€d,(#ߺ7€r€8€€P€Ü…N€cJ|€€,€€€€€% €€€[€P€^tR_€€€€€€;[z€Z€€)€€64€€€d,€€€c€€€j€K€rw€owV€€€€€`€€/€ꕬÛ€€*.u€ÖŠ I€0?€Z~m€[H3svV€l€vq)€;€€€E€€%€s[€€:Wy€7;€Z€D€ne€€€w€€€€€€j€9€€r€€xw€sK<cyv€€] ˎ€€q€=}a€
+€€€'ٿ€(€<K€m€:G€€?€$Y]eNµÔ€վ(€U{€€€€€€Jk8ωZ€w€^L/('€€3?a€v€€€G€€€%€`€€â¡­p€6€Q9(€€6€>׌€2Է€€€0wR€^ €€€€ph€Z€€€€ M^j€€€€€V€Q€OE€l€€]w€€>€{€G€€€/f€c
+€€ї€[ߪ€|Iy4w~€€R€J€€€€'€v S€€Z€€E€Æ€€ €sk)€€€x1]v€€˓Fh|€j€€€ڎ€€ !vEQ€B'W€@d€€€*_€i€€€2€ €€G€€z€~€eU€€ӌO€{a€3€J€u€`€E€;Ef€€€ -&€!y€€.6€5/€~-€}€€E€€€6€€p1k€€e}x€B€€€?Nzަ€IϢ€€€{€B€€€€€ F€$G€€€€p"3G€€,/:m`€0€€[%Z€7%€BwM€€;€€€€€M€{€€€2(6€3€[,ÞžP߲€€€H€€$F€€€<sd-€U€€€ 0㊽€€4$€€/€5€<4€k
+€€€x€m6G€€€-€€€€€NI€%€MZk€€€€*€ €€€x€lQ €r€̗,U2;`€€€Y€€C€^P€k€rסÛ1€֫€€8€}o$€K2€€sÇŸ(fw€€€€ѷ€€€z€€˨N€€€;8op+€€€€€Pp:8ԃ€̶c*€5p€dFmN€€̫€VWVH€€€5€O€€ZW€€~€€\>€€\hRR-T€€€'€€€k)€gz€(€i€€€€*WU€€9€€€Tu€€€€€€d€€€RM9_€€Ƒ€R"€q]e€Й€T€€€€€€€]^€€€+Ui€^ €€8€L€U *G€y€€€ @߫€€€u0€€k(€ab€€$L>€M€ Ye€1:YO€€€€@€U€€€€{%€3€€?€J9€€Z€Nrl€€NA€€M€w˹÷€[€^|"xm€€€€ €€H€€€€€l8€€€o€€)€Â€Â€í²«XiS€€9Q'E€3>€€€d\x4Ó±y€€2€˼!~_€€K€&W€^:Ò°4€€€W€q €€>€€€Ա{€€€€o1U€N€8€.€€ń€/1ĭ€€€z€€€€N€{"€€€J€ph€¾€€€@€€,€ȅ_s€UgЕ€F_€€Q],i€e€€T€n€~€€k€€U囇€M€:€0}€Qp€Q€€€€>€€€c€€v€H€I€<€€&€p sr€J<€;E€€Zȿ€)E€q€€€b$>€b€`€€c€€申7€@i€h€=€€6€€€€&€-€m€e@€€ܹ €o€)€ÏR€C€#€€€€€€H€€€%€f<~K/€€:€U€3-}'€€€g€€€h€dž€h€:€-€€ €ZL€€7g€€3€€oݠΑ€P€nY'8u€g=ǭ€€#7€aV€X€&€[€€€P€€€vt1€€€A€€€W€€R€€€€€€€€€€.yќ€€/€€ JÓ²€€€)€€€bg€{0/€3p€€€E€VW€bؒ€€€€€€€w€€€€H5Z€Eu€?€€€b€^€\0€˘€_€ՓF €})R=€ €€X€ٹ€€ g? Ù‘9€>s€€€€<€]1 €€€'b8ܓ€€]€/{Z€€€€€'€€h€X€€*€€E€n~=€€喓€€€€€}€€€w€€d€€Y"€€€(€nxNj+׷€4ttu€€S€t"€of€€€ϒ$€Q€€ €€€ €v€R€:I€€b1€€Z3wN\€ݓ€_€€F}€€€€ŕ€X]€€€€€€W\€€.€€€€€Q€€€J€€€f%€8€^UTT€€ €]a€Bj€€G€€€€€€€€€€^n1A€K€€D€D€€+F€J€]€€€€e€€-€k77\€€D{z€;Õʞ€G9Ec€€nWU
+~€€n€K€€€35€8ΡÛ€i6€Թ€€€€€€€€*o-H€€AoF€€€?€€€,€+€oy€€€q€Q_Z&9€€€€!€€€@€ވ€€M+€€€€€€€€6€SuY^%€€M€SExÙ€€€i€!M €€ ]€t3€€€€€€€cáš»}]€€B\`!b€€I|w;€=€€B€鳓:€o€€zn€€N€,€epP€5߽€€*€.;i(.€€a€x!Z€€€€€€€€€€a€€€€͠€€رÕ>|€€€k€I€€€>€p<Ma€€k€ڰ€€€؉v€€gF€€BLÍœC€€/`€€>€2O€?A€uD€K€€€)#&€€€U€€_"}€O€€€5€o€€€€€n€
+€€€:}€€y€€T€'€€€€H€<€:€T€ҫq€~=€€€9€€€g?<€l%€€€6€€€€€€€€€€"WF€+AT€^€€€€-€S€Z€€r=@€€€$e€€€€2,Þ‘ z€iCb€D€k€€€C\€#€=€€bW€D€O€Y€€<G€€€I K€€€€€€€0€U€€€=pXz€€q€|€a€€R€T€/€H[€€}ع€i€V|€€j€w˨€)€1€ g€€e€zξ>€€€z€Z€_nD€K€u €H€zm{€N€>1€€€€3€€€€€}€<€€ B€€W€I €9€€_
+€^€€€#1 _zq€€€R€j€€aQ€_n|K€€€€V€W/€€€Z€€€€~€€€a€€_E€€(f€€O€€€€€€€€cb1€€L€€€"_€|€P€렘€€€€€€}€—U€€W€€€׫b>€€_€€u€€€ _p€*€€€ €<OWsx€de€€€qLjx€€€€€`€4€u€\€€€€)€_ON€#U€€ _N€*€z€€R5€u€
+>J.٠€€x€x€v€:€€€€€€>G€€€tPL€c€€"1̃c1€՘€H 3b€€€€Ä€€H 3€X=€M€s€d +Sc1€€€€€ĈY€a€€X€€€€٣ƌ€€7&s€9€€d €d€Y€98Y7+€€€Ϫb€€€€È)€€$€1€#1€€€ָ€Q,€g€1€"1yj €€bLb€h2€>Ób.€ĔO€a€1€€€€ɾ€|G€d=€E€g€$€€€€l$€€ʱ€a€,€'&c&9n€g&€Q9€€€€€€€€.€69€a
+€n€€€€€/€€€kq€€€A€c€)€€o/€€HD€€€€U€Jn@4€€>€&ߡ€;€b€6ԩu€€€; €6€€€€€€U€€€ ~€RLUq€€a<(€TM\€&€þ€€€T€L€[7€X€b€c]€"€F€€€€€€U€ꪈÔ3Q€€€J€€€€€€a'€€€rS€€€ E€]`€€p?€4OXh{W€U€€€€_€.T€€€€€H€O€۳€€[Ur>€€e€]€€?€€%?\€q#€€/€€€`oG€x €;€€€€€6.€€*€} €]€€€€€櫛G^€z€#/€
+€€€€ €Y€€.uUE€€€^Ù°€XD%€$€€€€Éz€€]*€€€€#€e€)€2€]e€)V{€h€€€v€€-Z6€€€
+€€€*€B€IB€U€M€€d$€€~€€€f€€C€`30€€€€ g^ l€sF€€€€€€Z€€€€-H€&{€TT€3€H€€€€€ €€S€5€€€zZp€€€€€2[€D4€€€]€@€vX€%#_L€*€€d€€€%\E€I<i`z€6fi€B€3€צ€F,€€v=€€€€€^ €:i1ꨇ€Qͧy€a9€€€}€i F€€]X€€м@€€€Bz€€€,R€ €€N4€%lf>€ï°§N€٦€€€€€Jw€€M€8YCo0€zW€€[€F€€€5<n€^€€€ɳ€ ~€7€)€€>ރ€"€€;È„<€€€€F€€€r€€T€D€€k€): €>ƭ€€.€
+€ԟ€wFqK €€M€€m€€€/_€€Îl€€t;€
+€ W€€€€*€
+ €€A€€€€€ aS€5h€€5€&€€€"Þ³€c€€€ €€Hd€ €€z€€€€P€n€D€63r€€€€@€€tH€g/~€€\€€Ӱ@/壮tY#€€G3€ـ€€€_Y€€~€€F;a<€€€Ü€xRÝ«~V€€T€N€€K$ІG€ €9€€€€€ž€28€€E1€?€€d€€Ob€€z8TK.€€€€O€€€€€4A/Y€€1€€€<€~€g5 €€€^I=I̬H€€€Ws€.€€ߑu€€¹€€R€€€€X€€M=€Ɉ€€M}€€>5€€€
+€Q€\€i;cP€1€M€€W"€€€€l€€B€\€€ѱ€€b€€€€o€=꾯€W'sc€€€€t€p€9)o€x<€€€€:€:€F€€p€;€9€€ѱ€!;€}€3 €Z€ԣ€€€u€ڷ€n€€€€+€€y€EeoÖ€;€M€Bu€€€€€VÚ½4t€}€€Y€wZ€Ȋ€€T€€l€€,'€Ò‹y€€ϥ|€-€H€€D€0"<€na€€S=€€7€m%€_€€q€D ^Ms€€€,€€\€€€K~k€:€SA9 €€1€€4u€€€€€€€€€€€€€€-€&€YB€€€€f€€
+€X#€€€€€€CÝ\f€0c€b€ €€€I€Y€kS#€b3k€͢Sg1؈€X€$€€ e-ۓ€t€^<:?€ q€s:€€%7€€@c'€;/€€€Y€F€EÕ˜b€€V€y€€}€€€S9O€€;+€€˱u€&€€€€ *€L \=j}ؚ€€ĺm€€€€€€€JC€e€€r€T€€€M€ÿ€€€€€€oA€
+\€~€€€€>€€<€e]€zF€€ la€ M3€ꢭ €h+€€(€!Cq€-Nj~€€a€€u€0I€€€€PM€[1€9ό€/€!X€N €€€_€A€ €Gg€€€cx€ܓ3€A€€€ h €€Of@€€€D€€€€ߜ€{€3€€€€€€bxc€_€€ €CV€ߞ€n€`€n€).f€€W€<€C€B€=€9Ǵ€P€Ͱ€€€€p€ͫ€t€€€€.€€ߩ€r€€ EEÏŠSD€r€R€€$Ú„.€DҮ€PE%6Úœ8€€€€h€u€€€#€€'1€F€]D€ MB⇇€Yo/€€Vi{€
+}F€€€Nу€y€€J€*€€€€€€€2$€c€€/€DŽ€€I€€€€UQVo€"€€;V{k€€N@€€€€€|r3€€|€=€N€c€€d€€€€O€€€x€€€o€d>€`7€o'€UL€c?€d€/#ߌ€|k€€€&€}€€€[4€o€=<€€€ߓ€F€OL€€[€|€P€€€u€d6€&€€WW€d6€C€h€€€€€€p
+€€€€m]ڬlP7U€€m€A€€€3€;ނ€€€€-€€.|€€€<€€€€€€€€€^€€x€€s05¾+s€9€€€}€€)€€€€€$€€€€F€º€J€R€€€:ϓ€€$€MP€€€€€€e08y€€€J€5ߊ€|'€Vʉ\€€P€€T€ €€~€€€*€M3 €€€:€Kuܩ;€€v€|€€€€ q{€Ҡ€,€p€€6€N€€€€€€€nl€c/€1X€€€/€€€€k/€7kz)nL€?€€v€€ [lQOrV$[dD€€|Y€€€€€€<€uS€€_€t€P€ƶ€€€p€*€ t€m€€W€€€€€€-€=\€€U€D€€€€#€€Neűؓ€(€€7€F€€€HDF;w€€€(€9€b {€€€r€€G €f9€&€Ȥ<€w€€€€€.€
+€m€€€€€€€€E€€€ml €wm€ €€€8€€g€€€€\€€.q€|€€` m€8€€€€l3"€€!!€€€€€4TÒ’U€€€4€n€€€€€Ƌ€0C€€€ls€€€€€(Q€|ȣ€(€[€€A€€`H€QWo€€t€k^uW€f}v^€€€€e€^€w€H€f&€€/€Ѿ€\€!€Q€u€€]€c€7€€€€R€~€€v[€€#€€€G7{ih€{€€€€Hk€D€4€Z€€_ ù€xCk€U€ڋ{€F;€€€€'€~€€€^€f€€]ϧT€ !>€ !€%*pl&T€ €W€€O€€Y€€"€€u€P€Y€€Ml€€^O>C€€$l€O€m€€ٱ€Ì€€€ €€D€€€€Ȗ€դ|k€6€}€>€€€)€€e€€€=€€€w€3€€€€@.>€€5 I€f€€a€€7PM€5j#ØŽUB€'G* €gS+€φ€€!|a€€€€€dsܓ€|€€1€!5^€h€€€o€€€€€*{Ò–4€€&€?€€/E€P€F€\€ €€<u'b"€€n€€ M€€€€g€€G€-€€€ +%
+€ *€s€w€€€€ÑV€(€`€€T€<|[P€ Ý€i€€€n€€€€\€8€€.F€qf-€€€XK€Ì€
+€€€€€€€€cn €€€V€€E€€€€€€€€€,€€€€"€€)̧
+€9€€|€o€€6€i@?P/i€]€/8$€€Y€<€€€€€€€€€€€€€€€€XKz€7€€€J,€)€@€€€€ھ#€?h€\3€N€>$€€%Bw€/X€:€€2€€€v€€€åŒÂ€Â€
+€1€r€[O€M€{9:€€€€€€?€w&€€|€€€€€_V€€̻n*€€j€j{D€ic€€€|€9€€€€A.`€f0ˤ€]€+x€yFHGÂTB€m€€€€|8€G= Òº<O€€€€€€€€€€kx €2lЀTX€b=€u€W€€€=€€€eG€,€KWd€>6€€€dW€€€€€jԣ€mj+€€€f€€€€€€€€€€f€G€O€3€€€{€€€NZ€DŽ€X7€€h€€€€6p€€vzs€€׬€S€€€€y۰€5rA#?€€6 €€€€] o!€€ÔÍ [€v€ €_b€€€1€€1€Km€€ ma€[Fë€/€^6€ €Bz€€€€N€€Hu€j €+€€€=U?€FՊ€f€3€€M€€€E€"€€-zH€OQ-W"€vX<€€S€€€p€€€{€€€_v€€_t€8Ë£o€ m€€u€€€€€~€€N€€€V€c€X%€^€€V€s€€€N€€€C€ JTU€€Z)4Gf€€=€€Z&€€€)€€€€€€E|#P€w€€+€
+€€x€€€€6 iu€1.i €JK
+q9€€€€j€f€[€n€€G€bs~ €_€[N€€n# ~€#0Ziq0s€ 8€€€€€q€€bO€€€m€€€#o€€€€€
+p€xD<)^€tq€ ]€ή€ֵ€€€€t€€€€=€€=€{Eoҧ€€€€€8F˯€V€)€€€€€€€€€€€€C€a€z€€0€b€€€€a€€€ˆa€͘e€o,5V€€~#m]€;y€o#€P€€*€R_€~€€€9B€€QIFx€Ýx€€€,G€6%5€5€I'€€€€€C?€€.q7GHo€€€GH7€€`€€ѺH€€#€€HF€€€€€f9€€#€€/Q€€(V#hg€Ð€]/€€|€€a€€2€п€€D"xcÞx€1€€€K€€€€C?z6qG€=2€9€G€€j€€]€C?R7€r€Z€ €"h?€Ð€ncQMy€U#€€0-€€cz€ €j{R€}€€€€€€€€€⃅€€9BuurÄ“a €#€€€€;8€"q;G€]€€€€Э€€ܓm!€v2€€€€€€€}€€_NF€湃"€h?Ȼ€€€FE q_€€F€€€׋#€€€€€e}Pݎ€€€€€F€€;#€A€€€`€€Av€;]€2tP€ۊ€€€]€€€€€€`€I€€€wN€6€ €€€y€ m€€€€€.=>€€*j[ѥœb€8:7AS€Ò”}€€€\`€T€€€T€€ ɗ€€
+S€€7-"€S€B€€]n€]€€€bh€Ct€V€,t€€€C€K€€€€2€B€5€E€€| €E€€€€wަ€s€€4$€;€€Ğp€€€€ €S* €€€€D€G€€-t9€ӟ€?€~€!:€€€€&:6€%€€€€€€~2Ҥ€4{i€V€€cM,€€"€€€֔€€{€€8€€€*€€&l€)€B€€ €M€ `€e€Ȟb€€€Wh ͮ€€€/€wal€€€E€€b€v?€€l€\€2 o€€€w>w€|(€_`€€&U;€€E9€J€€€1€%€€[€€~€€€€Vt€€Bs?oS€n@€€€€€w€QKd€€Yv€q€€€u€€v4€솆6\a€€€M€€kZz€-€~€v€S Ò•kp릶9€>Í‘YĻ€€€€VWaq€C€hc€€.8€q€f€€€Ƈ€5%€^3mC€€ѣ€~L€€ɭp€U€{&€zus€5€€]q€6G€€?_€i€{€€€€€€Dڱ€fiE€"€G€€€€"Yݎ€ €€{ |€€._L€S€€€nD€ € l€€Y€a€s€€+Y€=€€@`O €€ϱ€€€€€ܕ€€ɳ€€П€€z€€/€/'gNUY€€#9€ڲ€M€€€2Ç£Y&-v!P€}U€€€€u)€r€a€2Л€€€€7b!.tJ'€#€€€€€Ӧ€€€€€€€€€?€€b€€]€€of€€]€_€€€K%€€_€€>"s}sQ€€T€€QDp€€XM€€€'1€7/€Ҽ1€TwÙ¥IǦ € €€?€€ €(ru€k;~€€€"€€q€8€€€&9€€€I€c€?€€€-€€o€€€€6€€""-€8jF€€8€€€ 3€.€€}C?€€€€,€~€js€€ÐY/€y€€vy€€'€Aj>_€Tֲ€3€€€€M"€h€n €lAU)€€?€I€$`u€(o1*9€9€Mv€?{`wKY€F€€f€€RL@x'€LU€e#_€€<!€€€€€€=€€€€€€€E€o€€G*to€€ €€4€€<€€e€€€€6€€/U€o{B€h{€€€€ €>€̳G€z€€8€5€ z€n€€€!€€€Zb€$€€€o€€t€Ōs5€l€4€€€ऩ€'€ <€€^$€׫N€€g€€€G
+t€d€̖€€€€€r€€€%€€€m€€€X?Q€c€U5Q%€F€ h€€zD€€€€H€€€€€ €JQY €
+€€€€h€€€€৵c€€€0Æ Â€Â€kU€F€V€€€s.€$€F€p€€DX€€Ax€€€€ÖM!€€€%€€€€ ޽€[&€"€€:€2€€€3|€€>€u€€s€€e@C€X€€0€€j@€P;€Y€Kx€€l€€c€€dӻ€€Y€7€q€;U€M€F€ ~Z€€d€#LAU[€mc€8€€€緙"R€€ȸ&€€€€€€€€c#€€€€€€@trh€€e#€€H€}}(b€€5€AI€/m€/jDRŸ€€݉€€t1€oy€€Z€f€i fJ€€av€b€€ƚf€?€,€€€€€€€€€€€~/€€yW{O€€€€€€|v€€€g€€€Č8orFĶ€€€>>#6€u6m€€€ܴ€6€'€ ?Z€XUQ€€€[ƪJr€€€€r€I6OD€AԌ€ €€8€y€ə!î™a
+€B€o€ M€€€€€L€€4"U€;&y€]C*€€€2€<€uD€€4€C€ZS€G€€€€€€wb&€{€€ s€€ €€€€€*€€€€茩€8:€L€ yl€s€F€;HL"€€€€"9€€€€€€€€€@ovy€€M'!€G敤€€€€B€€}׿€\€€€€s€#Hf€€s€7€ݹ €€]€€€:€\v€€x€€at.€€€;€€0r'€>8€7m€€;<[H€)fg$&Mí»N0Cs'€/Q€
+€"€i]€@WL€t€€€€X€€kl€€I€J̄€b€m%€]m€#€#€Md€Æ1€i€€€€€Iu`€I€ €€mK€€&^€pv€€€[c>€ϗ€v&€€D}€9cZ€щv€5儷€€h€€u€7€€€€kxaN€€€p€r€€0€W€€Ĺ€€m$€0€€€?€b€G€8€b€s4w€;€€€ €4M€m€€€]b€ã™#€ȫ€xR&: 7@€w€€€€€Nv€€€V€wÕŠInΈ€z|v€€€€€€y€€$€#€€€c o€SQe€€{€'€Lݻ€€?€湯€&€)U€O€O€9C€€̜€€KycKdn€€KXӌ⌭€"€"€€€€€v?G9s$€€L€{€€€E €€xt.€ €jG€c€€€€€€y€+FT€Ū€€?€€2h€Ö²4€€€տ€l€€Ğo̵€€€€€€YD€0€€J^|{€€€wc€8€€k€8B€]mzex€€€€€"@C€€v=€€€V€{ €q€\€€7€ժ€1€€7k€€UM€d]ã³a|€yO€€€€nHhgF:€€ +w'::}€
+!€€ 弇€€€€€€@€€€€€'€' T€u €S€X€€JXu€€D€22ei€Y߄€€w€€€€M€Mb€€D€€€6€€<h€t€;Fg€B€€g €qYym€Q€5€uD5'€€u€€jΛxT<y€€1<'€Hx€C€uLE€Y€€ €q€€u|G€@€wDK€t€-€td€€€€€8€nos€€€€O€€p}€€€€j -€2€€€ tt€»]0€+Z€(€Z€(€€€
+€ €3N*€€ €€I€ v@€Kg€3"€€€€'€)€KǦ€€€B>€S 0€€€€]CjO€€0$|€€€€8C€€{7~€€€€z€}€䭤j€€€eLܸ€€€€Y^€vW€€€A€S€gP€G€v
+ßšpJ€€/€;€€€€€{€QFf_€)#€€€€_€}["€€v€€f€€c€€€€€€M|a\Nc.€eB€€€K€o€RQ€€(€.€€Oj~@dyT€:mBkL€€#€€q~€c€k€ˣ>€€&T6€€xۛ€<€Iω€€€ €€€&€€€€#€ń€€€€€]}€€€rƄ€'€]€|€€i|0€€ n€)€€€n€~€€@h€€€€s€x;€kh€€G€€X€_€€H€€i,€€€€H€;€%€"5ç’²]€5,<€€O€€€=}Þ»=]€€€€y€€€p€A€7€ y€)€=€€ԙ€o€xm€€€€-€€p€\€1{€€€€€€€#Uï‹Â€R€€€€Ѿ€w}(t€q€€€ipl€f€€<€u€f€<€l€u€€O€€(€€t€€(€S?€w#€€F€F뇗€€€A€€c€G€€€€€4€€€O€€#€€€€€9€ @W)}q€k€€€Ղk€z
+€]-€Q€€€.€€€€z։€€€€€€V|€I>Ä”Y€€i€€I€€€€-€€€€(€€i€t€U€)€€€W€€z€ €T9]€€&€T9]€|Ñ„?g€ĴGw €€€€€j€7€:€2€+O€€€€U€€€Õy€3;qqT_€€€6€€T €€€€€€z\o€u€K'€€wgX€€€€€€€kO€€g€€`€€€€4Ê›d'u €€€n€ q€i€€sNq0A€SHÅŒw€€6Aӕ€€6€€€€€€€9€0A€€€Z€€;€€h€€€€~€uv€i€/€_€1€€@€N€€ €€ €€€€€?wÖŽ;€LPu?@€€ e=€€€Ѓ€€D/E€€€€f€€€€€R€€€€€€BT€€Q€€€[€€`FY€€€r~€י€€€€€e€s'g€s^€Q€€K€€o9>€T€ €€Č€8€€€€€k€€€ €m>€€ƻg€;€sɻ€€΋€€ļa€S€€€€ Ò2>Y,p€€_€€9€>Û‡€[€^c2€!€%€€€€€k€€\€s€€Ή(n€€M€És€:W€€7Â€Â€Â€× \A€X€a€X€?c?€€€€.|€€$g՞€€un€Sd€€€V€/խ€'€E?€€?€€€€zߘ€|€TN€€€.€€€€€д€€€u€Z9_':ka€€Ý­'w€€€Vb€€€R€€㾕€E€#€€{€€^€i€vÙ»=€€€€€6K€5TmÙº €€€€€˾€'€]€+<<€̈́V26€HG€€7€Dz€€'{n€€€8€€
+€6y€€ €Yh€€ƾ€€€]€7€[j€9€€@€€€€€€€:'€qк"€O€uW€€ €€€€€€}€€vŶHW€ R€€€€H€5€€€gG€b€€€€S€€€p€€€€€€€h€€€Q€€€A€x€€N€+€€€€ة6€€q€_€€€o€u€#€G€wJh€€*b€€€€€v€€i7€܇€I#?ܙڤq*€€|€€€|e€)|€M€^9€˞€T4€€€€€+€€€€o€6q€€€S{€€UQ{€€€€€€€€$€€€€€€S+p€_€0€KJT€骠€€["]p€€€g€S9p€_€,€;€€€€€RN)€€€€^9Îs€{€€^€k(€€€€v€W€€€ w+e€@€€S€w€v
+_€€~€€€:€*€w7€€V€€N o€€i€€€€€)€Z€€*€€€R€€€€c3€€€€SF€€€€€y€€€€I€€€€€€€€€€?꧑€vo€€H€i€€(€€IG€Å€€.€ї€€1€€ €(€+€€{€€€€€€€[)N€塮€€X€€€P×µE€>€€€+r€€%€uG3€€>€€=€€a_ß›|€€ə€€€z€€€€z€€€n€S €}d€n?9O€€€€€G{f€9€:S€{z€€F€`€€€~€€t€€€€€€{}€ €}Ä—€ڀ€#€u€€€l4+€€€:+€€€€€€?€€N€á¢Â€ €€zs€5J3uÝ€v€ D€€o€:€€ €?€^€€cӀ€%€€€€c€€€ƶ€€O8s€'€W€V€€$u€€$€€33€€€h€€€^'€€|€€q€€x€€/€€€]€€忣€€€pﮓJ€7\€€€€NT€{€€€€€€€€Sl€€€€*€€€€€c€U/1€€€€€€i€u€€yKE€€Ê€€€€'Úˆ2€;€?h€go€ٿ€p€€€€€€
+€€€€€S€?€€€U€[€N€€€oV€*O€V€^€€€€^€€€€q€€Z€zl3>Ñ‹a-€€€€€X€ʓ€€u26€€{€€Y€€€€g3'€€€Sx€€R€z€^€ӣ€?!r€"€€t €€Q&$!€E$j]{€Ǵ^€ €€€8€€€€ң€!€ F*€ Õ€€€€L€€€_w8€€€€{€€n€€ի€€€€€€€€}€@€€€A€€nS€€€>@x€€€a€€€€_xc€€ILC€€€€€s4€?€€€€*v€€€€I N€€€€qtj€€€|€€S€€€€)€€€SÂSL €} €€€azt€-!2>5,8€€Ԁ€
+€€€U!€€€Ô€ECjđ€!5€€€gd'€65€rb€€o€ּ€€&€ € €€€€€€€€C€&€S-€{€/t€~ݔ€€K€€€€(Bw|OT€ĭ€€€c€2€€€9!%€€l€€€Z€€€€€_€€€€o€€E7$€/€ €€€j€*€ !}\5J€€€€€@5€ !Չ€€€€D€€€d€€OEIQ€€€S€€€€z€%E翳O€!€€m€€F翣€€€€€€€€€€<|€€€€Sp€ os€-€€*kl€|}€)€UB€€'?t€€€€€€€€B€ €€*?Þ“S€€€?€€€€€€€M€€w€L€F€}€?€6$F€€€€߽G€3ҧ€1€$F€€9€?:€€€z€Y €€€N?€€€€V€€€€€€€€'€€&€€ €€€z€€0€€9Σ€€€Xg€bÆŸ~€€€€o€€€Õ¿r€€F6Ty€[€>€€€9€mK?€€€€ !q€K€€€€€€€€ÞŸbV:€ €€€€€€x€€vx €;!$€€€€€€8kb8€€'€O€€<€€ o€€€€€€}€€߹€€7&€ب€c€€<€€€i€t€X€€€y~€m-€€€€*€€ʼn>€€€.NK€h €c€€䆪€€U€€\€_€€€d%€o€}m€>_9€€e|#€€€€|€,€€€€€€F5€€€€3€€€€iGw€kl€€€~€€€€€Mp€9€&€w€€06€r€*6€Un€€€€Z'€€€€€g$^㬒<€*c€Q€~€€€7XŤ^€€€€€€?ݘ€€€PF€€€€€ €\*€€€€gݵ€€}€ +&€€<y€?B€8€D€H€€€€€€€wÕœ7€OIyo€€€€=€€€vB:gLÌ€M €G€€!q|€4F€€G€H€€6€€ޠ€o€€€€€€U€m€€3€VW€ €€WgLv€b4€€€€€걮?Z€]\€ܟ€€€€2Y€€]€>€€€€€€~€€€€sd{€va€8€Y&.€<€s€€y€€€yo€€.€Ӿ€S)€s€€€€.:€(€€U€€€J€I€Ti€P)€O€đ€wÕV|s€€':Et€€|\€8>€€€A€~€jTN€€f€€g]€V€€€€€Ç€͗€6€w€€€a€b€€€\€@€€€€2|U,€Ff_€€€z€8€€Հ€vin€€X€€j.€€€€
+€€€^€€€s€€€MG€G€€€9€M€Η"O€€€€V€€€€y€75€€€€y€€D€/€€ bÄ#׷€J€€€€€€€€€ݘ€?qY€.€€{€€€€€€€€+€€€Yf€€vx€708€ €€€<€€€€€€€[€€€RdM€E€Vo€€€€€€€&€*'€€€ €€€5=€€€€,€€€V
+€H€3€<j€€r;€S<¸€€€gЗqm €€€€€€€€€>€€wЗ>€€p€€€€€€r'€Z€€€€€€ӗ€€ێ,€~€^M€q€6€€€@€€0€3s€€€2"{D€€€W>€5€€/€β€€€€K€8€"€(€c€#\€€€€ }%€€€B_€{€€€[€€€Շ€gyÄ´'€€8c*c€€uOo€€D€€€€Õ´€€€€€€€z€ € r€€€n:€/€ €€u€s€nh€€<€/]€€H€€f€€Us/X€9a€€€*€j€€€.€€€U€m}%€ߡd€jÔ›e~€A€€s€€€€0€η€€€xO€$5€_€d€€€€>j€<€U€€€€R€\€zO€o€(Uμ€u€€f€t€Ü€W4 ׉€€€S€:€€z€€o€O€K€_U€#€€ܿ€€€0€€k€S€0J€6€€Z€€€_€€€ €Fݽ€6J€W€n5€&€缾s5€€c
+€&IΔ€v€STs€€}ޯ€;€€QR€p€€Ѧs5€€€ST€€̥€€W€O€K€߯Kz€€G]R5T€C€}€\€€%€մp5€€ST€€ը;€~€€Svs5궟€L€S€s5€.€€j€€€_U€w€€I2€IFI€€0V€€Z€€(%n>U€t€€€(€~€߰F€s€t€€QJ€c€T€€X-r€€€PZ€Jr€€_€d}€Q€€I€j€7€U'7€7kh€€€€wW€€€€€€`$€Q5^€8r€3€z9€€_€€€w€ܴkV€€€€€€J€鿚€bu~€€€߉+€9€€UV€^*<y€Ys€K€€€€€€t(€€xM€o""N€Xa€€€€k€#^€A€W€9>€.€€9&€ 2€_€m€€€
+?:€{1€€€x€X€€c€K€7Dz€=€€€€"dE€c€v€k€€8t€>€>XC€€€€€€}{'pCaÞ¯Q€+€€Z€04 €€€Й€V€€kf€n/€€€?€f€8l€?@|Z€€€€[€}€€ n€€€Ë€Ĭ€€€Xň€b€=€€vP€€€€0€g€n€€€€U€€€U€c€Ko€€j€€evP€ev€€s€€v˵€€vP€v€€€W€€€€€ L€M€ut€v€€€€€€€€[€€)
+€p€誷€€€z€X€€€€i€€€W€€€z€€X€rS֯j€€A€ꅠ€€^€9V€€€€=€€jW/€€7€Nͱ€€€€_վ€€€€[8€M€s€v€€€€€€€v€€L~S€€€]^€€€€K?€]€€€€€€&€j€€Y€€Q€€o€$€€€€€€N€tq€?€€z@0€€i€ug€€b€R€€?8€€V€€u€€€׷€€Qoa:@5€ €n€€€€׻Iw€€€€€e€"€€€€S€€߫€%€[€W9_W€X€€€kQ/€€7\P €€?€8€€.€€W
+̄χ€€wQu€€P]€gF€€€ €€€.n/€+€g H€€€% €FwÈ­+€r€r€;w€€€€+€€j€x€ꔳ€=€z€€É|€€€€€€€€€€€€X?€ €€€€D€9€qF5>€T€qI€Q€2€(€€\€pÇ„G9€€GY€€€€€S €€ €€€€€Y€€€A€€o€H€I€€ĵ€€o{€€Nڗ€kW€€v€€€jP~€e€€;Qr!&€o€-^\Ê€J€€d€€€(€ /D€€€p€w€€€€€€n€€_€€€y€€\€ n€\€€€€#€=€€ʎ=@uW€€€ €€r€k€8€^€€€Z€q_€jh€*['€€€€YOR€Y/ #€f€|€€m €k[;@0€€€€We%\å¬p€€€rv€s€
+ !@U\€€€iEhN€€ܷ.u€>€€€€€€€yY€RW€{1f€B€ծh€€€-€H€\€3k€wR€€#v€€D€€]X€€€€€6(<€€q€&Rހ"€€U€€€ €'€€};0€Uv€€w.€3C)€€Y€zv€€6sx€€€€€Ӏ€€€€p€€€€w€ I6€(f0_hL€q€d8€JG€€[€3e€€}'€€€€3€0k_p€"€€B53G€'€€$Z K$^/;€€€6€€7€€€!€9€}(MØŒp`[€€€€€€hO€S€m€€€+f#Y€€e€z€€€€/v€€<€_O€€n€€€PÙ¹#T€B€€€$€€hevY1€1€€€Ip:€€f€T€€€[€€=Y€€€
+[€€~€7€€8Y€o€~€Vo€8€€]€8€€-s)U€€€y2€€%€? ' ")Ke11€0€€€€€€€€JV&€€€Űs€J€€€R€€c, €€€€ €S,. €P,€W€>+-g.f'p0ï”1΀Ӌ€b€*€2Ivt|€_€qS€ €€ vC€€^€€6x€€€€€€€€x€€V€€€€G€Z€€y׽€€}€€3€*È»€€&l€€€€L€€+€€€€€€}€l€€;vÙ¨1€€€,e€yw€€€€YC֯€>[€'€J€€d€j€uX€@€€˽3€SI€mv߽€€f€R€d€Eguyx€4F€€۱=x€€€€0{€>€B€s€€€€€€/ €x€€d€n€€o€€€0)€<€2v€*v€€€€mj€ٞ8€%Ë€€q€M.€€:€€q€[_€€€6:c<Ù¡J€€4i€Rt@0€€Ћe€€€€ €o€]K €k€|€I_€€€€€!€C)€9^€1€ʬ€\y€M€€€a€$€=€€N€I€€a€€W€Tc7€€€9C€e'€a־Ո€€+C€x€ۨ€€€€€7€k€m€€(!nh%€€^€€w€d€€€€€€|€<^R€X€€qՈ€| €€€€€€Z€W€€€V+d€z€r€€0Z€€/€€?Ñ‚K€5€gi€C€ބu,€€迬_7€€€ €j€[€€€ˌ€€€Fsr€iyy&€€€ €€9€ €€€F9€j€a׳€I/}€*€|€€d?€€€h?zJ€+€E€۩j€€=P€€^€?€op€€€t€ӫ€€€'[€€€€.€ <O^€€@€l^*Ý…qÈ«b€7€Mb€w€€`€€€h€I?€€?€-€+f€Ä€€p€<€cV#OÖ]i?€=€^B 0M€€QC€2€€€€ €€€N€ע*;T€C€V€:״€€€e€T€€€*€€L;€€€w€€o€2€€b€v€€>A*U{W€#€Cѵ€~€3ԕ€€€ €€Us^€[€j€€7Ӥ€+c€€)a>€€'€€€&€€\Ut€C€€€€Y€,͹€&€[I€@€€€€€€€€€€€€Rݗ€&€€€€€R€Ex=€€€€z€€€Q€QJ€€€Ҥ{€€4€M€9H:€ɤ€€_{€€y|€}€^€€€€€a_?ÐbeqH€XY€y€€%l%mY€€<€€
+\€c€€a€€s'€€€€Cv€€QŅ'€2_€€€\€€€o|€€€€?€€-\€€P€ǵ€E€&€€€€€
+€!€€€%€X€€ €
+ €€Q,€겡*G`>t€G€[€€€w0\€€k€€I€€>€=€0{€€€€€€€ €=€€€T€}€IĔ€b€c$g:€_€€€€!€€R€.8€€Qֈ€3€€€&4ÍsU€k€€€€Knhk€H€€€€H-€=<1 €T€ٌ€A}|W€1€€€o€ >€!€/€€;€/QtcKÊ© €€€P€€'€€Ô€I€€€€&€€5€€hN€€€*g€!€€€5€€€ ܼ€€€€€HD€[€J.€ Ga€€[€?€€.3€€€W]€€3€Mdk=€E€€€ 2€w€~€€€o€€t€€€9€€€]€ €"€"tp€€#€pU€€€Q€€€,€€€њ€€€€€€-VU€t€€Ú€@G€5€€€€€Kv€a€j€€%~€vc."}D€n€€ߞ€€€Ӝ€€s€7€€(j€u€€€XV=€?€€C€,y€9€ס€€g€€W€€}€€€€'}€a€I€€eYA€€€€]#g€€€€€€z5€€4/cš1€€€€#€ €€€:€€€=éœÂ€:€7€u€€€v€o€;€€€€-€€€€€}y€O€€€,€€7ÚŸ~€€,€Y€G€€€€€}E;€}€€g€#€€r2€€1,~€€€€€u€€xÍ£z€p€€<€€;€€Z€€€.€z€._륛€Λ€€.€K€€€.9~1€z€>€K€'=D.Fk€€k€€N€€€€5€]-€z-€€
+t€€€€u€7€c€€€€Jev€€€~$€Z€€[6€u€€y €0€*€mJ€a€€Ǣ€€€Ε,€€€€6€€J€_v€€/]儲;€€Z€€a*€U€tE^€kk€nmè¹²+€€l{€k€I.€Q_o]€t€€€€uG€€rtJg/€€€€€€n€q€€€€xl€€€€D€o€fxs€SĜ€€€ʺ€e€€€€€q€€€€}'ܾ€R_z€€€e€_Ǟ€€'(€j5EU9€€€>w€€€O€€€€€|€s€m€€U`R€}R"€€€€€€€€€n€€€[%€)|sԊ€€ou€€Uu€-€€€~/€€€l€y€|€u*W€€ALa€j€€€€>€€]€€V̛€N€€m6€
+€L€Nk€"€€71?€O€swu€x€€~€v€T€ޡ€€0C€6€€A€€+X€=€*€2€j€)€€%€-€€au€:€€€€;e.r€€W€݀/8€5`W6€€€€郶€"eN€8€A뺪ʓyI€€€+_€+€<€€€;€€€0€€w€€b€o€#€€T€€€U~1s€€€o€€€€€4i€€&칆€7€€€O€€ڵ€€€€€€€€3€€b€~o€€"€Q_€€€*€€€ €€[:}%;€x€a€+€€Q€V€€li&€€€r€€M€.€€C€€€0€€€VA€R€€€€€`€€€|#€f€f€€€#€€:]ë’€€E€€€€ €V4€€€U}€€{߶;€€(w< €€ €?y€€S€b{€€€r€€€€`€?o €€l€€m€€€€T€€1€€eeh€€€€{€€€Z€€b9\z€€€[€€€g€a€F€#€€€,&p€
+€€€€€€€ǿ('q€u9€[€4€€9€E€G^€€c€[ے€€k€€*87o€€>€€Ft€€Dᴪ€€€€€€€B€€€'€5G€`D€€P>{€9߶€€€€J c€q€€ᙛ€ €€~qu€€NT€q€€!€€€ €€€€}€y|€ݸc€Xjv€%€x€a€€€jo"€J:-6€H€ €€€.K€€€€€Z€€€D€]€€0J€€i€€€*€€€€€ʹ9€€ѡ€€`€€€tM€.%€€`€€˛€€€€Ts+€z€€e€Ub.€€€€U€€€€€€€€€€H/)^€€m(€€€€€b[€€€G€eyÑTV€J€ ]W cU€D€3TU€xs€€€€K€AÐ¥n,€m€)#fvc€ԇ€€b6&$€€€€4w€€@rw€e€;{€M€€kZ€V€€ܩ€€ €€€y€({€)~€c/€€à±Â€€Ü€\F€Q€u#€€Vl€* r€B€|UA€€€€V€€€€U€u€U€€&{€€€Y$z#|}gWK€€€€ €€€U€€\€€k €€Æ€1€€A*y€€€€€€€€€"w€X€d€€€€€€hD€€€€Xw€€€€€s€
+-g€€€€€€s€€c€ יo€€€€€€M€,€ €w/€Gq€€Qo€0_€€€€9€#qZ4G€€p€[€€K*٭\€€€}ϫ€SC€€€€€ €€€:€=€€€tX€€xwO#€q€m€€;€€b€S€1€`0€€€&C€€€G
+0[€o€,€1ÖdMJD@€!€ k€ix€5b-&€€r:€7€c)6€l0Zb€ €1g€b€F€€€€7€M€€€ FS€€ T€€j6€€b6"€b€€€hA€1€€Ŋ1€€bM€)€MA€€b0Ù¨h$F€XcL€)€`€3€€€|P?g€f€M€JP€Ao€0€A€€cA@€d€€c€d`l€€€M@€^e €SF#*B^€€I2r*€€f Am0XP9€%€JK}3h1bc€C €x€@+ €B1€€€c,€a€€€ >3 g6S€jQ€s€i€€2€€G=Ä­c< 5Y€€p€,z#)!65€NC7€D&€5€€€7€€4€€S@ €€€€€€0€€ k€€€Ϙ €Ec€t€yz€€S€K€@€€€€1:}z
+s e5€ €z3€€€€€€z€€&R€ġ=,€d#€`€€O(O€€͈€O3€€€1€A€€€€>€0€.€S_€9*€€Ę€P€€(̈́€€;z3€m €€€3€€SϤ€I f€€f€€7€(#z֬€€€Q€f€Þ1Q€V3q&€ؒ€€D€€ €g€}€=ÿ€&€2€€0€[€ǘ€-F€Ùg€€(R~€#`F€€€`4€€€L€c8€ VJF€Ԕ€€i€€€€€€lL€z€Ã…BÑ·#€€€€f€1 Z€€XÖ˜`IA€ğ€€€€,4€€€b€€€€tDZ€K|€€Æ€€€߱€€€иDyDGxG€i(+€€L€1€i€L€`4)B€)€8€0€€MD€@=MS€6E&2€̌€F€WǑ€€!€g(€-<€l)h0€T~€g8€bz€€9!~€ 4E€d2€E€2€bbѤF=f ^€€D_S€€€_€€€(€Q€€€€€G7€€N€€4$€€€€id€€QQ €4€e€K€€€ zW€€j€€XbͶ€X€3[€bj€w€€€a2_K€S,€€€€X&€€
+€€N€ʨ%-€k\€€&€€\€€€€q€€>€€7K`,€D€Z-€€C€€ͥ€€22€*€0~€€€€c€6T€8=p€
+FY€€€€j
+€€1Պ€B`€€| €€όn$€| €R€G€i€€€&€€€T€4w[€ G[sL&5U€=G€,€ў€Vja+€35€A€p€Z€Sdo€€€Z€!gM€€s<€€S€iN€vW€tZ8€`€€A€z€l@€y€N€w €€m€gDk\~€€F g€*€€*z€€8 €12€U€1€B€z$k*€7}D€"=€=s%€8b€€€ht&7h€J€€€€€€P €S&i €C€Tn€€€ʓUkj#€f€€€I€Ѭ€K|€€Էp€€ s€"€]S€E€(€€ €€5Z€€€g €€€#€;€-€€ €€€€BI< [€Ҧ€0€hH€'€P €€€0 j€€d€€Bc& €,A€€j€ €€{€o%<€€€€_Ux€€€€{€€€€€€B€9&€3'IK€4_ӤLi€xNI€€!I
+€€€&q€€Q}€€t*€Z^4€Z4@Y€k€c€€}€%€€B€s€€€xir@€nn<€€€0€T€(L €@€€>0M 匟€o€y€2 W€^€€€€b€0€4!HEZ-Fi€€UA>g€C€€€€ZL€€b,q€b€)€!F€bL€€>GI€ǩ€|s<€Dz€5Æ–€k=ۚ€O€€)€€,€Z€Xg€F€€€Me=Ú‚:,€€X€€€ €s)€H€€€€!z€R$R€P1&€€.D€€詇€DЀ€€8z€€.N}€#AbhB5j<B€€€3€
+€3€€P€€=€.€jL$2äºÂ€x€€€)€€n€€Ф0瘬~CIM€f8H€€€€, Hǂ€€€A€@€f!€€€k€€tF€€€P€ €€€u€.€X€Ya €R€}€€€,j€€€€^a_`€€L€)47#<€€€€D€€5LHER€)H€W€€I@€€6 /R€0€)Ø¢ €€DP3#€e*€€ÒŸI€5€CE)€F}€)6+J<€ €Y€!€{€€€€J€X€€W`€€4g€M€€ €€6%€#67?€€3]€€洫€€ƞ€€€MËœe^t€€\d€1_hN4g€€€€€g€S€3€JOj€w€=;n€€c €o€)ś€€€€€€Ցd͈€H€€€.€€€€x˦€OK€€_g- €o€泦€ܹq€€€€'€L€€h€€d*<;Ʋ€l€€5€2€€ |i€]€IY€€%%%€€€̤€l€t{€,Czo€€€>€€€€3N€€ض€3€€1ϭ€T€€€€l€[€€-SA\*€€#61€2€€€^0Q€S20€O€Ȗ1%€l€B€x€ I(S€€H€G€€J€1€€€F€ €OÉ£J΀€R €S€€R€Ǖ€0€v€%6€LË”3l€:cJ€r€€L9€lXL%^ğ€S*€w€€%2n€w€W@Isԗ€u€€!€M€€€L€M*GV€€7€€?c€HF €€+@€€a€ €€C€y @€S
+a€!G€€Ä›c€€€12€ˢG€J€€€€€ bk@€€1h6€8|€hs4€B{€Sb€4i/€€€pxL$>fJ€P€#Ý =€N€ €€Rz€€ة€€Ā€r€€x€€L€€€'A€€€€€€H#xpk€SQw€€њM~N€<%€€.€JL€€€€L%€€d&€=€€€?€XSÖ”€N€LY€€€€#€kf€€̞€€€€_ €€€b€8€€״H€o€€€€X€€pv€€9U€&N€{€-fz€€€g€€0ś€€]l,€€€<#9[€€zz€€€͜€€€€dM€n=#)€€q€R딤€€yYV€%€r€)€$Δ`€fÛ¬eS€ZÎœkJ€>=€€€€€€ٶ€€€Y2R€€(N5€€€€€K€L€bN€Y<%€€1@Z2€€M€k€$.591))FB€É€jI€$€€>€€€n^€Îœ€€k€`€€€\P€U€1€,€cJlF"|€€+
+€SC€€É€€
+
+p€\€€€;€€"€€€€€€>5€€€€€€C€uw³Zc€}A€€€€€dA|AJ#€€*p€:z,€ €Q€|€-€V€^€€€€€€€€€€€€؆€%€%€+€ע€€.lv€B€契€:€€Ӳu€1€€€K€pg€K€€D_*€€-€€€-\€€_{$W€€t͵€€€€€€-€€HCe€^osW€€€€€€pe€€K+€rN€€€"€ɳ_1_FO\€€9€€€/-€赥€E €[Ñ«"s€€B€0Ѳs?v€g€€€€€Y{tT€€zE€% €€gKse€=€€Dz€~]€l€(€=_*|m€€n€€€}€€eԔ€o€€j€}^=BiP2€<€€c€€M€€HM€e€€€€€€€€€ۅ€€Oz€€€€€€€@€ꋪ+KW€€]T€€s€~€€S€8€~ t€€€K€€П€€€6€€l€?€䟌€€€€€€€€€€e€€€̚€}f€€ܳ€€͛€_Px€€s|hṋ€[|~€€€KJ€,€€l€c€€€€€U€T€Ԯ\ui€e€?\€€€\€M€-€nO[€k::€]€€€w€€€€r€U€€€€Ñ€-€ҋJ€Jj€J1SY€€€z€€€€U€€S€€€Ѫ€x3€€€€€r/=w€{[€€€.€€€€€e€T*€€vosGoKk€€€nk €€€F€€€€€€T.mk€€*€€JO[€€€€€€€€€(€uR€€TJ€€€ݸ€Ѷ€c€M€€.c€
+€߫€€'€_E€;:;€€€€€€€V€€€@€ͭ-€€€€VÜ€€€€€6]T:IK/€€Q-ܶ€DF€€€€€3€€€XJ€1€€l€iC7*€€4€€?€|=A€\€€%z<a€i_€€;€€€H€.€€k€i;c€R €l€^€€?z€€€LQ€€€_€€47€€€{€RZ€5€€€€€D€€€€RZ€[FI€6€(€~€_€€P€€i€9sfr€,€€€[€,€"€jn€€€€5ڨ€€f € €€€v€€n€€€€((Bd€€
+h€€€QF€g€€=€|€€H€€e€X#%ت€fI€I€€^I€hT€[€€z€€€€m€?+€vy€R ~UW€€€
+.E^€€g€Tĕ€&€€/< 5T5€[€u€€yJ0\€t€€5€€€u€P€oQ€G€€F€€€€ֶ5€€(€€€€€Câ§t^€€€€ €A+€€€g€&TJOgv€_€€4€€€d€€€€€€€€€€7€€m€€€€$€+=h!€€€^€0€€ò€dDs€G1o9€ €€€€Vpek€€€ Xw€
+€oוb|=€€4€F L$€€SG@€€u€€€ގ[€ψ€€€€xkg€€*€€LT€ &y€=€MD€€€€€}€€Rm€IÏ–. $a€€€t6€{z€z€i€r€€€orc E€€€€XI€€5(€€€~€€€€€€€€Y€9D€€-€K€€t€€€€1€€3w€€€€f€oÓnj€O€€€}ÛƒC/m=׉z9€5€Ы€8€€€€M.6.ޚ€8€65)9eZ€€€€€O€8cF€؀€€€4|€h€nxc€€€€€6€c€Y2w.€ǒU)€€Vo€ZH€€€4vb€€'O€n€R€€€€m€+g€w€9€€ €}€€:+!€€!9<em€L€{Ö€E€€€Ok€€(€€€€€ÖŒ
+€€€€€€€€{;zDKW/€ajK€m€EO;4:€[€€€=€€€€TLآ€€€€€€€L€€&€^€€Ӛ;€€E€€€q€€€Ñ€o€€c€Omw'wcPmnKj€J€€€os€i=W€€n€m€€€9€cZw[€€G€€jo€€7Z;€[{{€Z€€€€-€€=€€€I€^/€J`€Gc€€n_€€€^€€€€m€€€€Gx€z€€A €~/€€€$€€'€j{€-€P€
+&0€€*n€n€C€b€€0€€€€0/€€€€€€€€´€mFh€€ G+v€/0€uӸ€o€€€vA€ €g€€€I€€€€€A€]€€Ȱ€5€€€€€€€f$€sч€"et€-{ '€av€r€IL€€{€x€Rd€)V€€@€r€€€€<€€-
+€€€v€€6^LA€Ԃ[9h€€% €T€€€€M)J`€€loi!U€€€€d 5€6 .Vl€m€uh€€€€:€€€i€€]€j€€€oBy,€ ,€€( #€ €k"€#UJpF€#eB€U€€&€E€
+j€€S €E
+€{€'s€€€€€€ͻ€€y€EEs€b¸ 'gÆŋ€€€€€€lj€€€眩€YN€+ Xp3€€€€HIHL€ؔɂ€€Rɵ€s€A€ €@$kjU€€€mJ€*€t€€€€Z €€ej€[ख़€R?{€â«Â€€ €€Ļ[0E€€J€€ d€€€AScG#€JC'€€j€€€€̫€\€€€€€fBP €€€€€ €3 €€€€1€tv6€€€.€€A€-€€D€€|€/Ȁ€€€T$oim€€€͛€€ؼ€u€€J€&Ӡ€€€€€€€€€ ͳ€Nji€2:0€`€€ͧ€ h€ƎnY€Z4€ €4€Gi€€C€N€َ€Ҡ֓€[€P€€l-]2€ 8€€€€€K€E€M€kE€;€€mkml€€€'€>€€€€nLa>Ah€,€ap€6 XeQ€vk€J€€€n~€S_$Ñ„H€q€€z1.w€€&€W€€A1Yv€€€h€BKZ€M€Ҵ€€ډL€.ۢ€WT^Z!is9ڼ€€y€€€F€@z€€€`D€;€€€€€|"}>5m€H€ݎ€€€€%}b@;€e€€€X>€5€€€€l0&>B€|+€
+ߩhT€€€L'€€
+h€€)€€z€€€€g[u"€<€+€€{€€€€o€m€h€€Cԓ€p€€ 1€€>€€€Ӯ€€€P_A}€W4€€€ۺ״€€n€$€€€[{€E€5€€) €€€€€T€€f)€€b6c€c€6€€€3u €,€€Z€|Z€€"€€|Q_€TQyyJ€€e€€€€€Z€€€€r|€=€€€+€€tz}U€E€€€;}€W€ €€€€€/€€€~մ€€€€€Ըnj€€i€K€€€e(€©€W€€W^-€€€{€€i€a €€H€Q€€€€hN€1€€€€€€v€€€o{ l&Jr+€*i^BoP}kD}[S׺€S€€€€
+E}a€€€Ӷx€€€€( €€€€€€ €€4€,€€d€€€*€VK€_r5€]€(€€ €S€[€$tu€€€R€ €S€t:D)L€%€€€4`#€~€€€€ r€_€€€4]`€A€€ €U_€|W€oM€g€€€~€€/€€B€€3.€€€€CV€€Y€€€~€€€€d€€€€€~€ҫ€K€€W€€€€€r€_mk€€W€€H€€vy;€-€€[€P-LHA€€€€/€Z€€€#€a(#-J.F)/!̖?€]€!8€
+mC}KC€€ً4€䅳lsf*€€€0€€N€J€Z_f€€€€J€€}䘙7€<€€€ €9}€€:HBl(€<€€€uw]pY8€€4('RO€€̶@€€Z7M€H€$!Q€€€N€hȹ€w[€€€>€h*€€€)€$€Ѿ€ޤ€€\€n€U€T€DK€h'A€€8€~-€vԣ€€€̭€€€8€€0a€€u`K€€€ €€€€€€€€€)€€9Ez€A€iK€€€€[€€€~€-€€€€€ANa€€€w€(Xz€€€i{€O€€€€_€€€€€1X]€€€€$€€9€€€N€€3,€V€_z€€`p€ˢ暎€3jXzo€€)5€.€R€,€SU€€V€€€Lv€€ơ€€C€€]€Io€g€~SbY€e54€n€ݢ€MwG€€€%€2d€€€c€=ɺg€€!1€€tt€€&€€€€€€€€€€u€€€€€€€5S€€€!l€€ €4=<€€€R€€€k€€5€€€E@|1}€v€z€|€€€€€7€€DB^€lj×›7
+=ɒ€€B?€S€>ş€€Nߕ€€€€€~]€o€uq€€!€j€ γ€&//\€; 6€€€€UȽ[Z€/€€€€€,€gم€€€X€"xC€Ew€7€ €€€1€€"€€y€0€Mg!€€€€oY筯ײ€ޥ€€.,|Í„?€€€4e€€€€€€€€ۊ€z€;@€!€€€€€Ƭ6DÞœ/Jk€[€€6>c=m%€uk;c^€€@)€€€:))€,y€€6^u nuG€&€€€Hո€nW€[€€€\ε€€2a=€+€€€€J€L`R€€L€€€>a.€€€€BeD€€ €€\t€Gq€Gq1€€ .€c€€€:.€]€€€€l€Cp€€xUl€€[€Ƹ€€€€7€€€€€€ €€€b2€€4€€3€nS€‚/;5€pC€€u€l€i€€v€D6€€€|€€€%:pm^€€ €*u€€€€r€Q€:€€€€:€n€z€'€€f€rý\€€Vi€€n€€ڻ€{€b7ê…©i€€€s(€mD7€)€7€€׾€Ўz\€€€z€¨$€€I€'€€€€€€/€8?ٙ€t€)€€€€€€Ø´|€E8k€€€€0€\€k€€wQ5€q$€€€€€€-€S-f-€€€p€ €1/€€€€€J€€€€=€€Ҩr=nHB݅€€€€[C#U€:u€C€s€€*€6hJ€€:}€€€€€€774€€€€€€€J€€
+€€o€̎u€~€U€€kJs€?€TUzʲ:€€]d€;€W€€€c€€K!€€u11€€}€^€ |€t€€7€€€€b€€9€€o€€Pߊ€€€€i%€€€Qi€,€0€D€€€{G€Ts€[€€€!y€€=€€€nC2Pu€Qel1€€y€f3nÇŠ#.9€M€€[€€q€y€€C#€€€€}b€z€`C3 €+/Z×®n€.0o€€€€€`n>€€|Yҗ€]€€€آ€M€€u7}€€€€€;€€€€u/}~%}€€o€€€ €€€o€~_€€r€€€€}€.į€€7Ŧ€€$fz|.€€€]€€€€€S]€o4€V#f€€LW€F€€b€€€€€*€ht€n€qo€€#€Bä˜Â€Â€Â€Â€Â€9S]9\Y€p€@€€€€]€€MB€Ä3\q€5€[€1E1çƒÂ€g€o€l€U€€0Ú‘.p€E€€ˎ̸€8פ`Ždt€€€€€€€€€#
+€€Ovݖ€^€h\n湆6€o€€€€€€n*€V€/€g>€€+N)WL€€€*RL€€1€r€€+€e!\€€Փ€€g€'3x€|[€€€{€׿€sÑŸ?€җf€€€M€€€\p/USC€59j€OB€€a€€Bt€€ʃC€Ĵ€uf€-TG͖€A€€SkQ'€€7t€75,€€€m€]€ OU>C~€Y6€,€€€€€€ccog€1€}€€€€€€€€v€J€$€€-€€€€_€g€€€^€€€Ǜ€€€€€k€IZ€V€€€][€22׌"s€ h€o€?!l€€9EEÔ<€€L€€€5€€!bÑ‚|€€Ӏ€u:8€€E^€+€g€€V_*€3O€Voy~3€€͸€€ €g€€€€€C€€€w8d€<p[|€l\€€€€€}€Y€€ӹ€J2€}q€p€ €*1e€/€€ €*€€q/€€€€€€€mS+€q]0€€Y€€€€U1€;麛4ή€J€€. €€€+&#Ù¿{€/€€I€S€\€€8€€€<M€€€/k€c€oI]d yÓ€8€ f€f€31Jy€.€j€€€€>€€€€N€€€;T€€ SOjE€js0zWN€€€]P€€€€1o .\€€rq}€€€7aN€€'2x€€€L€mW~€€m¹iz$€c€€€+RJm€€¢€€€ >€€B€h€€}Ì™/€€€B€N^nA/}€h€€€€` €€€€€€€t€€€A€b€€B€:€€€€€€€€€=U€€€€qI€€€€=E€€€Y€ဧo€€{r€m>€ǵΈ€€=i€€€€&€@|€€€€ .8t€m€-w€€ҔB\€€€€Z€€€Z{J:€€€C.€€{zZz€€€€€€u
+€€krW€t!€=p€€€€x€ʨ€€€8€g]€€y€€f€z\€€€4y€
+(€½€^€z€JYySA€O€I€R`€Y€€U€€\€`€€-N8€€5€$€€8g
+f%€PJmku€€v€€&g€[€VЫ€c€€^9€€€P݊€wm+€-€+3€€€`€z€€"€€Ψ
+^€€(€\O€R€M€WjÂ…_C9€€€€€€Rè’€€;nl6€€H€€\s€€€c;€&x€€e€/IJ€E€n€-o€RE€€€aK€€}€€€€j€€m€€ey€€Ç
+L€ۃW€€€€L€€€n€€^5€]€p€€€]€^€)€^€>€€>#€F€€€^€€€:€Փ}Fmp€b€€€€€^€K€€U€KJql€/€A€€|€W€€?sqօ€€€€€€7€X€E€€€€€€€7€€>\j€€
+ E€€€€4€€€€)€€p€$e€€€€€V-€€€€Xfs€€€ •€'Ls€I€€€Ó¡w€€€€€ pd-€F€€Ĭp€k1€?f€Z€€€ؖ€€€s€Ib€h&B€€Q@€€v€€€€g€%QT€4Yf6S€ Ó‰փ€€;€€€€$Æ°m^€Ls(XMLs€F4]0
+2մ€|€€IF[€€€%€RLW.€€dGÚ¥€€9J.€€€€€ €€-5€€€y€€ ~€€ €ۄ€€€k€€€
+1€3?;€s€€€Zs€€ wÛ¾^€)[€€€€k€€€€€kZ^€S€)€[€-€ٙZUr€€€,h€Y€oX(€€3W€€€€€€6€:€€ A€^€^€.a€Y€E€€€€€'€9j€f&:€€€*€:v_]H€€8€U€!€€€J€€€€L€€€€L€ϹL€s€DÑ­9€€hB€ €€|74€€€J€€€€ €€LYD€€€€c€>€fF€€.:S€-i€€!m€]€[ykm€€€€}<B€l€V[€€b€€€€€€€€!Kpμ€€V€cG7€AE€€€€qf€2€€
+€a|€€€€7€€€|€j~)n€€.€€€€K€€Gh~
+€
+€€_(€G€5^w;€€€€i6€w€€r::/€#€t€€H€_€€€€€ΑSs#€€#€€€€x€€â«Â€Â€Â€v׀Ù€€=H€€€lFh€€d€€3Å‚r€*%Z€€a€€€€7€[€€€bp֓€€`€#€d޿€4€m€Vƀ€x?€ɾuSG€€~€l€€€€ᕢ€€€O€=€S€€€7<€€f€ǂ_+~mg€5€€\€€€€ۄoCp&t€:€€0nf€€€€€m4€^€3ݹ€i 0€€Rc€;m4€s€3€€€J€)(€€€8€i€€L€€€€€€j€s,&Þ«1€€K€€€lpg€€P{Q]€0€q"€b€b#_E€€€€€I?€7€cl€€€€€€€€[€€€€€ >€QX€€€O€1w€€€CU€ =a Q€:n4€€€r€V€€€GYz€u#yl€€€G|€€€:Ë€w€€8€[Q3]€€ €€l€€7\€€#,¢#)ٱ€€€€%E€€Y€Ϻjw€€€€[ŀ€m۬€€
+€€€€]€u€€ €€S€y7€ȷ€€uabFN€€.Ä–€€€€[j+€€€}€q1 €€€€J6€€€-€G€€e€€€*g€w€ʛ€녘DQ€j€€€€bqa€€ÌdP€/€€z€C€€$€p€m€€pd*€€b€€€I€ €€€%€€9<€y€€ehr€€€*l*€€}y€€qI&€€១€€€e€H€€V€>@€<QT€€g€^€€f€€€Ӈ; }`€€|g€€€B€
+L@€u€ €7/%3"€€€k€€€M€\€€.€¨€~w€€€F€€s4€+6O€[€uY7€\I €€ zW\(€p€f(€€2âŠe€€L/$€ʆ€€sb€ P€6{\€J`$'€@€€€7€€€dduj+T+/€1Y€4€n€€€€f W€s€€€€юv €€€€w€ri R€X€€€i€i€€=€j€B2€f€€,"€€zF.€Ơ€€e]€€\(v/En€%€H}.}€#o@€€Y*(€s@3*#€€^€€s€}ážÓ—o€B€w߃€}w€g€€€€H€€€€€€€r€€€€b€€€€€€-]^R^€€temme€€€%耤XJ€)€A9:€ €€ €R|ݮ€x€ "€g€Y.€]X€€]_€€(€€€ը€R€€QVPX€€c.€1€€L€€€s6<1€€d€€Е€€4Y€(L€5€mPj1€€€7€.€€€[€€€B€ujqט€ѷ^L€€J€}_,€B€ €€Q€RK€e€€€€€€€€짳€Vjqq€ €€TjQ€€€€9€€€rC€YDT;x €s€n€€U€€Cw{^€€Ǚ{€Y€dnS€€€€k€€€rÖ€€RT€€€€HÜ»h€€€Ow€€x€€€€:€:€€xT1€o€cB€€/€_.4 €€€€€€__Qb€€€€oD€/€€^€€€€€s€€€_€€Kd€h^€ €q€{>€Ӡē?€}€€€L€o€€€€=7€€€€€€1€|€€n€x€€€€l]€UE€€€t`€€^*W€a€€€€&Cw+€ o€€€€s
+F^€€~€€€Z€€€€€m€€ef+TÏ‘B€l€€€€t€€8O€5€&€Kt€€qɓ€€€€€€€€ßR1€̙o€€T€'€€€7€#€x€fE€1€€€€ €€€€€q~€d€9€€@J_€A€€;€ €€_VÝ€€€ €e€}€€€€€b€€€€ԭ€|€€€€€bKF€5P50e`€N:€2€Q€.€b=A€ €€€€€U€j€O@€[z^€C|€€wK€h€€UÇŸ3€ ~r€€:€P
+/$€l€J€=X€€€€Մ€€€|_€E€o-QM€€[€€Hs€€2i€/u€~˼€֌€€<€\€€€z€€ w€€! 71~Ę(€€rFm€
+k€€j€凸"€€€g€€€€€€xO€€ÄM€Ρ€|pK}€€€ݜ€€S€€JG4€€v€€€€€W€´€€LI€€ ʫ€7<E€W€_€E€\ E3€E€já›»(Þ±^€€€ǻ€#€€€I8.€D€€ €€d€84€€xh€€D€€€%€}ʺ€:>€€€º€€h9€È€T€€Trs€€€€]€€€e\,n€€€€]€Pk€>î€%j€'€€€y`)€L€B €/€A€xib€€€€€
+€E~€Ew<~€€ao€€U€€!;X€͋Ś€l€}€€Ȩ-€
+€E€€͛t'€€€槥
+FX€€€€:€€€H$€€ 3i.€€€]F*€€z€ճ€p˳€j€$Eo4€€p=n€3€€€€€\€a€€€ €€€_#€N:!z€W€€.€€p€€d€H-P
+€ v€߯€o€Ã€B€€€<t€€_q€€ €b€I{€(€€'€€€1 € ފ€3T€J€€|€€iO g€tL€€g(€5Bl€'€€>€V€€mh^K€S x^€J€o€€€y€€€€€€`ÊŠ^ހYd€ €m€€{hD€€€Y€€€O€?'€kɜ€€!€€-m€in€€€€T!<€3€7€'€€€ €c$€€<@€€€€*=@€a€€4 /C€€€€€€ZvCL€V€€7€➺€lA{)€T€W@€€I€ €c€€=€€€^€F€O€t€€€*q€E€€r€€I€€€ӳsU€€ '1€e€a€€€'8€€>€€ފ€nuq€€ k€€Vv/\€€a€ WE€EMzÔ”H€€€€T€G€Q€쿋€?€€pQ€7€p€€€@q€€€€€gWJ€q)yS7€€€€xh€€€ €€Z€€X€€€M€M€€€€€Jb€儒€*€€€€€€/&€4F€€€€€€€€ۋW€Mpß•|Oߤ€€-y€€(€€€€Z€%€g€|a€€u/G€^r€R€€ €z€_€€t€€f6€€jLO€ƅ€€I€;-€€у€€6€€o7t€€€3€1_€Ⓙ€€€€(€€L#€(-€€ €pN€€€€Nr€€m€.€€D€d$€]€€€€Y
+€€!\€k€€€€Q€€€€94€€€€A+€&€
++€€ Ó£(Ô¡#€€€€€€€€[€€A2€I€]€€w_€ €€u€€w 5Â€Ó Â€&€€€€€€#W€€tש€€€€€€€k$€\€dI€K€€>€44WEKvbuN€€€€O2€6e€0V€!e€!€€€€O€3€€MC€/4 €נo€€€€€€€€e €€pZ€wp€€Y€€i1€€€€\e€j€€€7:T~€b€€€€€j€€mt€7n€ |€6:V€?3QE€S*€:v€€WkKUk3€€Eg,€׌€O€1€€€t€!+e€€€`
+Â’u€€€Ը€$€=€€bf€€€€[€€K€€€: €8€H€€I?3O€qĪ€[€€v&EF€€€%€€ɹ6€+Y€8>€0]o€€€€:€€€
+O'9`€|`s€€g]€ €€€s€€Ԥ€€n"€€g€€[;€~€hV€€.9K€\W€€ҕU<>€ظ€€€q€.€>€€i€D€€€=ä–€Ns€`€ WӤ€€€€€€y%"€w1.€1€€:ON€€[€
+r?€4€V€|€4\€€€€5€y€c€€€o€€`>€
+€€€€€€€-€+5€p€U€€蔥€lrBU€߈€€#E€2nM+)4A€c€€V€€_€a€€€€ˉ|w9€} €€Nqm E.?€€1W€0#җ€_€€@€C€3 €i4€^C€s(€€€3€xz€s6(€€jв€pÒš€€9€€€Y€a€€vn€€€:€€Z/€€€K/P€Q €WQ8€o€€n€€€ls€€:€g€€q€!€€€cVC€ '€Il!a€y€|€ACb€€~]€l€€ F+€)€€€€€`€€Ds €+€€d€€ €€€€!€R€x€€S?:€€ϼ€€€€"€€€€٬€;j€€j€r€[€€€2{€m€A}€⼮€€ym€€7S€У€€€€.Q1f€@€̓چ€€€L€€€€A€Z€€€€W.€€@€"€€€€.€€9€€€ [L€%€ E€Tl€=€€mRp€€€€b€€uqx€A€€\Y€€€€€W€b€€& €€€O€€r€FR€n€€€€Û€€€ ;8€€j€€r€€€€[€ €=€Մ€€€!\%€€-€€`Q€€7€€€€€€€ҡ.€
+€7€€<]w€₭ij€€4>€€(i€N€C'€h€€Q€€€Ú¶T€:€€b€m€€€T/tDK€€€€€U€!€€`I€@€n €3€Y€€€U€7€€9€€k€€€bT'3€€€€€jVD€€j€&€-n€€€Y€m€mȪ€€桦€>€:py€€€€€:5€ j€€a€g€€ €k€€6€€€€€€€or€€€A=€&|€o€€€€zh 㲘€R€URLJ €€D5€I€M€€€€€΄/€€€€=m€€,€Oe€;wlj€$yM05c€€€€€?€ m^€€€€€hv€€-€7[€€€€€€Y€€1€€=€€ݸF9€i€€€€Θb|€+€€€o-€€€€€€€Å“si€€€€&q+€€€€É^]€€€€€R€€Z€#xY€€U€/€€/u€€xY€€ծ;qY€fw^€v8G€b€€pCdY€I˖€V€2€€sh€€8׌,€سI€}€€=€=€}€€€€ËŽu€€€€5€€۱€€1€€€€€{€€€k€€ (€ܩ
+sr€cI€w€z€Jϊ€V:Gw€€'€7€2€c€'_€epÖ¸R/؀€€@€€€k€€ Ʈ€{€ €€Jmxq3€€%€€H€969€€€€€]F€€/€ €Wn€€€4~€Ed€%€<€€€€€€€/į€=J_€{€€€r*Æ‹) €3€€u)Uq;€,x€€M€^_j€},€€€€€€F€€€:€@y€v€F;€
+€€€;€€€€€€Ek€€€㭨€ñ u\€#€Jo€ €€€㊎€€A€€€€p3€€€€€W2h€K€€D€€€€€A€S€€I€U€$€€<aR€^lE2€€ €м]€5€€:€!Jq€0€€\€€.S€€€ -p€b€€ D€O!€€€zQw€g€€ he€€€€Õ€u€b3€€€:€b€X€#j€s€#€€€x;€€€€€w€€xI€€\€3€€T6€8€€0)1K€~b€€€X0D€~€€€€€a%{€€€ €€€€zz€Ӫ€-€€ Y1Õ›z€?€€€D/.€€€7€|$/bJHϱ€€€€KM€bB=f€6€c&€€Q[€]€[€€:B<€€€€G€€p{€€9€}SZ€=X€€€€+`€^I€€€(€€€ϻ(X€€'€€5Ûƒ@€€€6€€€€j€bJW€Kty/€€_€€/€!€}€€m€2J€/€€w€t`€€€u€€€e€€€€€p€€€N€€"D€€€€€ڊ+{€€€S\€€>€€€€€C€cƪ€€F€€€H€^}€€@€P€€g€L4a€€€e€€v€€a€|€€v=€€ €€B€x€x€€/6€€N€€.wzA€€}m|8€€€€€}m€€h_€}=€€€ :€t€C€r€Bo€X€s^€€Po€&'0-8€€€€€€€€ô>€%€tP'#×–.Bf2€
+€€9}€'j€x€€Z€€€€Ƹ"?ƕ€V€€ €€'€€xRv€n3€ȸ€€2€€€€u€€M€€uAz€1sc'€/w€€€|€l€€2€€]€€k1€_€€*ƚ€€€€s,€€€€€Bm€€v€€€2Lj€@ m€c€ €.1€€€2€€€MMg€A€€J*€€ݨz€N-:3M-€[€€€€yb €W€€€€2Tٱ,W€€0€€€b€N€€IJ€€`p€u€€'ߡ2`\€€kt€€€i€a€€>Zve€~€€Q}€ۃv€T€€€€€F€,ޜ€€|€D€€w€{Hy€€}€€€€€€€€€€€€O€€Q€j€€ߵ€€/l€F@€P€-0r€€€c€€ʀ^1"€€s€€€€T\p€S€/€A>€*v€D€p]{\ 9̀M€€&€€€€I€
+&gH*)€2€"€€T\%€€€z }€j€€€€{{€^'w€p€[€€{:€z€€€€Y€=€gш€s€€€€€E€€€€ €c€€@€}€8V€€€Y€€€;a€€^~v€€€+€`€s€t*@€€CK+U€€}€€(€€-,,<K€€e€€€€u€ €"z€€78IwM€[€€€ÇŲ[€€g#,C€-€KVV€@pOoÄB€ټ€r€Ex€E€w€€6€€€߮€€~~€€=€o€€€€€B\€odICE€€€€€€'€€[€€J*€€€>€M€€€ €)"FÖ­Sa€€€€؊€;_€6€€€;€€€€€(€K€mH€€y€€€€€L€E€€n€€ZBq€€[_LO€s€€kjÇ¡8A€€F€qEc€€\SRqQ€€R€€%Z€m€€€€U€€€)Yz€*sM€€%€€€€€€? ctanglee.SYMM€€€,€€€€€€MPSTMPS €N€€€€4€Øfq~€€F€ ?€€+39€€€€g+39€4€€€€€n€€€€V€r€€s€]€€€f€€c=sY€2A€€e€|k€€M€€ '|aÛ„l€+O€r€y.l{€€€€€€p€ €n!_x.B€M€€l€€€f [8€!€fâºÂ€tyuv€k€&d $€3€'pN€€€€ !^{H€€€€o€€€€€€€€€€ €m€€͡€vȻ€€€€hn€€€[€€€zmeu €€*~p+€€€€€oG€W€€/€oi€lloj€;€€€?€?q€€™€`€€€€+f^}€€€omn€",h^€€€lk€m€[|Ù€€@gq€€€+€;€:C€€€€€Ζ€€€;€0€€€`€%Щ€wuvt€P€Zq!€0€=€€€€|7€€€M€€€€€[€€ €€€€€/€{'€[€€€€.|€€{7€۸€ z€%€)€ €%€iۮp€3^€`€b)1€P€€g€4€7€#€€װ€€yl€€€W €€€䑨L<@€'€€<.y€B€€€7€€,€/ €..€d€€€€€€€B€Ä€€cg€€€쉯€W €€€€€€€€€G€€kW^€}€€ㆂ€€Y€€€€€آ€€|y€u]€y€€€€€K<€€€y€€€>#€€€€€L/€;€€€€€€)€€€+€]Ljs€€€J[dkv€f߫€k€~€~M€ß€n€f€4;€€wj€€>€€€€֧hv€f€€€€f€ m€E€}€€€€€€j€k€€€€€N€€&h€€d͞€ٛ€€€€€€€€k€7h€q€~@€:€f€)mC€€€€I۬ŋPı_€€€€€€€€ì´mFi'€,€€€€€€f€vJ€f€5;€€[€€€€ٹ€€€€€0q7I[€U€F€f?€€oh€qi€%i€S€€~€€~i€€€ֿ&mà€-K€Z€€/H;!Y€W€G€€`€W&{€~}yW€€€Y€7 €g€€ζ€€€€€€R€€€h{€WJ€€€?€€!a/€€€~{€m%€C€€€%€€€€€€€€ Ýšz!ÞƒG€€%€Ú€€€w€d€푯€Ja۞€€€€€€€€pÒ•3€Z:€::€C€]A€€€€€&€?I€Z€/€€Ô^€"€€1€€€€€€€k€€XY€X߸€€€€€€€u}€@8!j€+k€o€n€€€ق€€1Ǩ€>€uK€g#&6€Bí¡ºÂ€Â€Â€Â€Â€f €z€Ы€ €€€0€?€€€€€€k€Ža[8€.€€€,+9~€~€€x€€:€*€€%€[€€€€€@"€g€BL+P€€€€?€€{€&€{\€€€1]€g€4€{ℤJ€b w€€1€T_€a=U0€€€€ҩna,hzTeG€€€*{€€/h €€Z[€€€€h"€€€'€€€9€圚€€UiF€6P7O€
+€€&€Pu€?o€ԕ€wW€€€~€€€€€€€% €€€ €€€€€ ×´tÖ´W€lnm€€€€xb[ €d €€v€€€ݖ€r€ Cßž!!|€]€ [€-€€€€€8)^€€€Í‘^€€€€:€€g/(:€€€€HR-€€€€t€€€Qi€NU€]€7€b\€€€€Ƕ€X€>€gN€^€~{€€€€€%€SÂla€O€€a€€€ €@€{^€%€Wv€k€€€ß±h$€?€lZ€€€$n€)€€i€€"ÅŸ<€Z€€oq€_9"RP€€J€€ÅŸ €g2Ѭ2o€€€€€€Z€ԡ€6€\€ռ€|€Ð€ߎ€€ _Ê¿^€€€z€€ޗ|€3G7ÃN7€€L'€€€S!B5€€€€I€Y€s€€€B€€€€uTp€Z|€J%z€a€OE€2€>gI€€]€€€j*€u-€E}€H€€€<€€€€1€%€,€; _€€p39€€u€MM€€P9<s€€€v€€+€€
+€€€݅V.q€€t€JuX€N€€_€`€pd€€€€€€Q€€€€&v UTJ€€Z'€€~€# O€€€2€ w5vr€€€W€ €€€€€€B€€K€-+€oQ*m€€€€€€U€Wt€YXbRL€€W€€€.€d€8*a€€€j€MFئy\€|€b€T€€€oʈT*~׿€G€Ч€z1|(€Y€€%!€€ €€R €€]€4€€g)€€l€€€€€€€Rde€€€€.€€ O€">!€`€K]wº↊€"€€<€k{€€W€€€u€€€€€[€D€N^€€€Wk€^€€dL1€b
+€Q1€€€I€€€^€z-R€€ €€S€|€SÛ…I€€€V€x'€O€K€y€Vx€€€€>x€€ €€€T€:€!€2AaO€[W%[€€\€€Hvr€€€Zo€€€wy€p€= Q-U#4€wRPl€f<v|€€FC€€€n/€x8ꔺ€S€«€€/€€¯€b€€€€€€R€€+€y€€_€€€K,T€€~€'_€I€L~€CE^€€"€M€€(€€,€€2f8€€u€€€|€Qg€€€€€€t€a€R€H€G2y€/U_V*€€Hۮ€€€€J]͖€€€€€€+€€€S€_A€Hs€m€u"ÓµR€€v€<€€€km7 z2y;v€€€€€5€!2€€d€3Õ•-&m€G€$€€|€H€$€a€18€€€ €י|8J€!€l.€{y€&€$€€I"€€€ry€ €€€T"J€WL€€w€€t€)hy€€5-;€c^€€?€e|P €€€€€:€a€€e€#€c6x€€<ᑨ€€K€€€N€€€-€€€RPd€€}jqq€€€€Vß‚mQv€Cs€€€<€€r€€€E k€V€aZ€T€4€€€€€€'aY€{]y€v€j€€€€€uÔ€J€,,[X€P€€7#€€€€€d€€€€X€\€€€€€{€€ڤ€6€€ܒ€n€ڔ../€€ٹb€y®€X€I€€€3|€€€€?€€€€8€€.;*€€u€€W€d€M`0#€€€€G€R€€€IJ€€}€QƗ€€,€€f€s€^{€€€<€€€€€€€wз%€rJ€;€"Z€€€€fy€0€€€€qs€j؛€€€F€[}€.L€€ܤ€}€Ɔ&غI€€€7€v€€€€€)T€F€€V<€€A€w€c€~ws
+€f€lkѯ€€€€5€€ؾ€<€€7(
+€€€€e)€]>€€€€€Έ)€ €€€Rqj€€€€€€<€͙€€O€9€€€€€€€€€1€€€MB€€ € A€W€wPXۚy€€€@€€:fr'}€€€R€u€€€>"
+€€€€€8€€}€~2€*€€NN€€€€€€€zQ€€w€ab€^g2€,€`n€9€€nLM€€;€׉ l:€A€€F€};f€€€U€€€€R€€€€lH€o€eh3V;e}€€€uÙ¹u€€€<€€o€a €€€;€(€R€€€€;€EY€€n€€€€€€€€:߉€_Pâ«6Ғ€€\E€€€€€€e€€€Ɋ€{€v€€€{At€€€€€€€U€€|€=€6g6J€€HG€€YEBM€ۑ€€€€€5\€K€A€ƙA-€€€€€€€w€€[€€€€C€€^€€€€ۆ€€3€Vx¾€€€€€€€€M]I€ €hlr€ւ€€ w€X€uɂ€€z€%€€€R€ڲ€5u€€€€€€i
+€y€€€i;y€€€V0€w€€€ީd€)6€ v,Ù²kÛ’-€€]d€€Iɶ€€a€€v€(€5€€€€€€€ €€s€"€€€€€xr€€€€€(€qr€€€€€Vt!#€€:€€€€€FFJ€€m3€€€€€€€:€€pA€E€€€€€€€€€€€€€M€U€€€€?€W€€€€]€<€Rv4€_}€€€€€€€1}^€€3€@€u\a€H}w€€2׷€tu€€Yg€R€:Z=€FV€Ӌ €ݔ_€€V€€z€*qk €€€J€ €€u€k;*l€€€So€V€€u€€€€
+€%€€€L1 €}dn€€rn0O 6e€&€E€€€ €€ €*@Y€2qN^€H€Bn€€€\€€€T€B€€€Vv €€OR€€A]?l€€5€T[ߵ€€€€€€&€€`€ M€<€~€€->€€€~o€φv€?o€€€€
+€G@€Î͞^_€ [€€€|;€€{Qe€lP€€JZPs€€€€€\kzM€€[€€ʠn€€䫨€#€7:€€=€~[~Au€>€€%?;€€€€=€E\€€€ur(€€€o€€€Ny€€| €€€€
+ym@€€€}'_€€€-€l€€€[Q€€€U0€ѓo|R€h€€€€&€€˓€€O€€€Y>€€€Z€€€BY'V€9̊€€!€€€g€€<€աsN€€€€b᱕"€€€U€€do`Ý´ (€Gʎ€€€€nﭫ€€€€€<€-z€g[€€E€ €|€O€€€€€-€€€j€€€̓€TlUa€€€€ݾCAD€ €p€€€€€€€Z€€qU1€)€€€ Q€€€o#€Y|D€€€z€€€JMy€ e€€€K€GQ€!h€N€'€€€€[>z?€€,€€€h€€|GW[Y€ €€Ԙt€[9€)€€€'€€.€j€€€€€2PB4€€€ €€d€€€€€€€€a€€K,€€fn€€b€€€1,€€_:Ë»<€S<=7€€€€kA€bX] €€€€€`A€€€3sA€€€€<€€€S€KwW€€€o]€€nT€@€v€0SP€˻€%€€€ €D€.€#€ €!€M=TҜ€€€€€€[€€€€€P€€9€'€fe€€@€u€€€€€CA€ €€Ӄ€€ c|h&E€€€ €€€€€g€€v€€€|€C€:€€€֦€^p€M€€€€€i€€€I€€€<€€€€€€_€€€€€rr}u^€€@€€€€D€G^€Q2€€€€2€€=€€4€€€2€€€€|ɵ€€€*jk€J*€5%
+P€€€#<€v˥€CX€FW€6€(€b]FP€€€J9€€€#€€?ÏŒI֓€A€€o€1S6f€X€€€€|€€€X€€€d€@O€€€€s€b6€€€€€R€]€~ €€€€)á’¥%€€J\e€ڑ€\€ד€0€€€€k€€€€7v€\~€€3€€YN€€%`€`€=[€/€D€€B€1€4{€€TOx#€z€€d9g€€k€€r€€%€€€fRYά€€Û³
+ €Ԙ€_€o€|€4IU€€€€€g€€€€R€€€€G€€3€€€P€23V€€.€€3€€€€€ۉ€S€€ €}€€€U€M€€ z€;N€u€.€WK|€Y€€ǯk€w€t €€€€?a€u€]€3€!€€ €€0€€:ū€€. €€€P€€N€F€}€€_Ûº€#€€€€S€€€ʟƴ€€€O++.€/€€P€ČZ€€ӭ€S€€A€_€€+p€€u€€US_PO€]Æ–dA€€€+d€€€±€€€z€<€zٛ€\Mv€€d€,H K€=€q€€͠€Ú€€€CP€€€l€€d€ €€P€ӻ€€€-€I€\€}€͈€€€€W€€?&€€M\€€€€U.€€€{m€E€䡠€c€€ɯWVx€w€€cxF€(F€€kÉ‚#€͂X!€%€€€€€m€s€€€€€€u4C€p€ 4O€u€8€€=L€!€€NL0€oR€€z`€K€€€€)€ԽiÇ‚"€€)
+€Iz>MQ€k€U}€€€€€z'€Fa€€€_€€=a€M€€€'\[€'€€€^d€€€€€€€ݸ€€€K€€Y€ €f€€ €Nuz€G€C€M€(€/YFx€€{€G€3źcsK €€Y€J€€b€€€ €av€€€x€€i€€€€€€€€€:€V`€vT€Մ€'ȱ€U{€Dxv€€`€vO.€€€€2€[-€€dCK€ €€.€¯iYF*X(+X[\C€€€€€l[€k9€P;OG€F"b€[€I€|v€€€7€€€€A%€€E€€Px€s€€ﺧ0€ €^€€€€M€€€m€u€+€€€)€7€5t€|$,€€€c€߱C€€:A€<;D€;;зY€€€€€€W€Y€|%€€a€H{<€€€!B€€€€;€€=€€€€D€€4€Ժ€€€ŧ~€€€i€€ܦ€h€*€€S€€€€€€€€e?[€>€t:7€Ü•9€€}Oo;4€€ ƺ] ˎ€€%€=€ch€]€O€€;€€€€€€€€R€€€ €$ټ€€ë¾I€€€€€{€9€͜߀€W€DÞ‰;€€€b€y€€€€€)€ũAb€^q€8€j€#€€€€5 €"€]€€ˣ\€€V€Rx'W€
+€€Uk€y€Z€uEM€yi€2/€€€Q€o@€L€ €€€€l€€ٱ#$€@c
+€€€€€P€€\€€;€\€}Ë•IoÕ”;|;z€"{€v€!d€ó€€€€å“!€€€Q5v€?€ոg€
+lD€@F€€€*9€€U{€Y€| /€€€€G"€ €€€"€/€€€€tT +€€€l€€nj€;$€€&3€€ӗ"#€€!B€€€k€€
+]€o€€€€;d€€!Ƴ;/€k€b€€€=c€mP€€€g€w€#€€€E€€ӈÅ¡(€gk€A€"D{€=}€€p#€VQv€cj€j€€&€€)k(t€c€€ڸ€€R!>€i€7€€ي €€€€€€€€€7Þž€€€€€+€€€̩՜×A+G€€€+€
+€ €"€€W€€3€€€€€:€€€€€nw€)€׶:€€U€€€)I€€€&m€6€Xm|OBr€€ y€€L€nlQ€:e€)Q€䲰]糦U€€€€!€€€€€!}€W€€€€€3G€{%€>w€€b`tg€€f€€€€€€€€€ €€9€€qۡ€€€€€4>€'€Ó€~l€`€==€x €.€1€S€2€Fpkfktc€€ €ԸZ{[€zΟT>€€l̤€€P€Q€€V€€€wB{€W€€€€€€€€€€€€€2€€T€€€E€€=€I€Q€€€€,€_B€ƞ€€&D€€€
+€[1IV€s/0"€礮^J,gx)O€€(€€2œ€e€€`*€X5O^€h€€_€ c€W€a|€€;L€7€C€€9$€€|<=€t€E€>€:€€€SU€4*€,T€€€€€d€e€P€€R€€€€€e€€€€€T€€M€;%€vu€€P€€`€H€€G€€€€€€đ艣€5n8€€€€)Ž€€€xƢ€€€€€€€€p€hȹE€€€q€€H€ €;+WV€€€z€ؤ€€KE€€€€*=M€c€€€S€€7Ö²z€€|€b*?€W€€$rD!WhY[€€€3€>€€y:€€I€€j€
+ €€le5y%€"
+4r€׬<MtS€>XG€j4K€€ԵH€€€*€€€€€€@€*€3€ބ€}O)€€q€€e€
+]€€€5€€€u€h€s€€€|b€€ff9€€;%€E€€"€€=È>sÌŸ&fQ€€k8€%€€€*cm€q€ı€€A€ԟ€€ه€€€F€v€€Q:f€+<€P€€€P€Y€€€:€€€#U€<€€9€€€€€J€'€€1€H€€SA`€ȑ€~iE€3€Ao€€o€€€€€NC€"-€€€€€f w€ƪ€€€#€Ps€!d€€€SW`€q€6 €R€€<€u€w€€€#€€]L€|€€€#TXI€߯!~Gc}€€>€€V]€€9mR€€HjPb€J€ϚU€€5€€€€܄€€€#€E€Vo€b€MNq€€€;€€€€€€€-)OT€}㥆ʀ9
+€2€@^€1€€6€?
+€8€}M€€5€€€€v€€€/3€u6€€€#:"Gߧ`W'€b€v+€t€€e`€W€€€€趘€€€v€€?€€€]AbnC€€€€HTm*v&€V5€-€Kտ€€€€W€f€€%}d€e€€B}SR7€)g+€€4յ€€€(Y€T"€nf€€€€$L€€€€s€=?€v€€€€$€NjŌ2hj€€9€j€?_€€N}€M€e€€*6€,€€€€€Ê.{€€€€]€€€N€9€€bL[€MT4€€mm€€BE€9€€€0€k€€€~T€4ٞ€z€ɄY€D€;€€K"€bt€IA€7U{5xm€U€e€€€€m€€J{z€b€ʞ€F9%€
+€€€€X€€N€}€K€€€qj~+€Cw€b€˰€€k€€-€cs€€ꣾAo€€€~€€-€YRWY€€€j"€€uzW€€€€€ €[v€€aw€i u€€;?€;€€€`€*€«D^€)€€/{€;€O€^€€J€€]€p%€G&€€€_€€5_ËšÔŠb€€&€ ə€#€€€€B €P€Iӱ€€s€#€Pf€€€Ѵ€€€€)c€€€#~i€€€x6Oc€€€€€€ €L€€A€€€
+M€€{€€M:€€: 1€W€€€€1֑€€€I€€€v€AZ€]T€€6€c&€€ €€#gQ€i€S€€€OW€€€€7F€€;€€€€gR€F0€7dz€€€€€€X€k~Qi€8€€€€€[€€1€T€L€€If"€q€€€g€R €€€\ǟʵ€€ €z€€€€k€k€€€€Y€€€C€XGj€g€€r€€€€iS€€#F€€KM€S€€tJ4€0€F€€鱗€e(ܓ€€~cÚ(€0€@$:€ €L€M€€€;€€8o€P€€{€€ €V€~&€€€TA€p_€ €€u€€€R€G€€l€i€€*€€U45}6{€Q€€Û‡m€€<)hÙše€b9EvД€ €€€ €€€€€#€nx€k€€d€4€`€r7i€Ӥ€r0€€:€$€Y€€€€Mì½Nd€Lr€€€.€~M{€*RJW^€NU€€$€€€€€€m€€y€CD9=€b€€t€€YQ€€{е€"€€x€XNá„¥sa €l5€:)J€€€:%€€€€€€€` €€:€€c€€€€€Td€€l€€@xaʼn€`€€€€V-{i€€غ€€€l]€V€ȳY€€*€€€€^€€€j€€$€€7€Q€€M€€7€€&€€€€u-€€cÃ’Q€€_EÖœ9€I€€UÓ„nh€;5€ n€LZ€€€€L;0€w2xe
+o€€€i1u€€H€7k€Md€€€€€E6+€€=IS€h€#g€€€DW€€€€'€RQ€€€#€;€ 5€€ S.€6S€k€{]1€€^M€€€€€€€€€€€D€1€€€~&vB<€€Yi€N{€Cq}€t`#
+Ôž7€€5€€Ik(e5€7€q~€€Rf€€^€H6|€€€{`€|tˀ € $2€P€w)€e€Tzqh€€€f€ €x€€€9€€&€€€i€€€mA€`€J+€G&€€3€€€GtT€p€€€€€€YSE €€€€yC€\'&€=€^lM€YA€*€€$€ €'€€U€z€€€>€^€h€6€y€iΨ€@€!€ €H€'€€€j=qT€1€ËšR€€€€:€€€€c€€€`{0€€] €€€F€€v€€€€€>€ {€€€€€R€/€€~€=Tބ€€ X€u€€z6€DZ€U€~€€C€{€:Rݘw€€€€o\€€T€€E€:€~
+7€ɷ€*O€€x€€bj LB_m K€Ȍ€mƢ€r€Z€€€-€>}€€ €?dEJ4€(O€€€sK"€€€3€€'€€ku€/€r€€€y€€g€s}€Z€€€€0€€€z0€UBÑž`€€€€ã€€€mJ€€f€l€B€€€€€€€€U€€€_͘€€€T\€€€€dq`3u€€@€€ǭ€€-€}w€€&€€X€€€€B€€€€€€€H€7€s€Ԛ€HP€€fנ€ €€Ա€€lG€̨€H€€_€€€þ€GH€c€€€H€ €€€x֢€€€€^P€€i€K€€€€gʹ€^€€€€€-€LV@€€h€f€p3€TO€€)€€€뚦€€€r€1€€€h6r=€€A€€€€€Q€W€C€€ZD€s€^€€€€/,€€7^€€€U€€€€mU€€€€s€0€2a€O€€€ȓy€€€G€`€€/€€€€@5€e€p€G€]r€F€G€€€€€k5i€€€˧0'>€€=8F€7€€€\€]>€2P€€€€lyuUhz€€2mz€|€€€h€€€€€3€8€€r€cs"€b€€.)€V€T€€€€~€m€6K€€€4€SÄŒ€€i€€ɿʀ€~p\€I€n€>Ƶt€€€l€R€|€x€€̯c€€€€€€€Iop/€€|€€€€€€€€€€€`€€*€xT€€є€€€€<€*€M€~€€€@€€ȑg€€€€YV]eP€!€€ l€iޡ€€$ֻ€€g€€M€Z,qbv€ W€^,Yz€€J€€5€€c|€ty€€P€€€€€8̃€h€B€I€€€<}Ze€€ܬ€.€䨦€4W€€5€A5€Sf\IS€P€d`€€€€€j€dz€€€€€€€A€€€R{€€l€€€€H€6 €o €€$?k€&U€kDx€\yY_2€€~€91€*€# €֭٨)o0y€E€€€€
+i*0€3C%€€?€4ô€O€€8Ҋ€€€€B€=€€€$^М€€T2€€p€xu€€z9G€€€€1n0ɷ€IR€qz€*o€€€€F€€em€€€€֨€€X€s.|€€x?€s€7P€€5€>€€s€Je€=€€<€€ €€:€’€€C€Eza€€€€3€od€<€€\€€ €€Sg]€?l€€€6€€€€€€€Q€v€€ €Í€€o€€€€€€XvS€>€u`€J€ؘ€€€ €f€€jw&Z€€D€ݴD€€%€€€!h€€€_€€€€<€k€z€,S€€ +€€lmg€€V€€ €€ [€€€ € €€쉰€€]€5€€€m€b?€mOr~€㗺€O€€€,ט€€€\€€K"€]€ن€€€€€€€d€|4#€e€€€v€i€շ€P€€O€2€€€€€€j€fWz€€e€kO!€e€€q€}€Rn€€€€w€=dTCÓ€€d€8€€€€€o€€€€€Q?€8€€k€~€€L€5[€€Z€€`€€hY€P€€€[€F[€€€€9€[€gg€€€€€€Yۓ5€€ V€€€|€6€€"€q€€8€€€!>€U9€€{€€!u€V€g€<€€€€€c€€\€a€€e;€=`€€€€€Ėu€€1€€€€€€€}€€€D€gQyCG-€x<€xb€gQ€€€€A€G€u€ ǧQ /G€~€€1g{"糨€F€€.€ €;€>1€€€ Ѩ€o6[€€EÍFup€b€\€FÕ¿€€€€€&@€ €gQ€€Q€€x€lU}€€hTÖ‰?€€€e€E€€F€€1.Ù·<y€€C€€€O€dk€€q€€;€P€€€ €x€>€€.€€Ѩ{€Յ€O€€€.€l€?€˲h€4M?€€€6}€€ml€€i€€D$Cq\͠€€5€€-€€€ €`€€€€Y€Ʋ€hY€€)€'Yb€€4€_Lcs€ъ€dvд€€mM€Ä€€€&e:€€R€€€iL€|.€~-€7D`k€€Wn~€€€pz€€€€€€B€€h €€€B[€&C/€i$N€X %€€€E€€€€€f€̣€)*A€@€Z€,F€B-€€Qٰ€p︱%XW€€€€€€>€-k.€€€$€€€€L€€€`€€+ /y€€€€€€€y€€€t€C€>€Gn€€P€s]d~€ €€€€€HŴ€€lDL€€,L*€][#yz€l&€DM€€€l€ €€;€€'€€ZVc€Q'€h€€€!%c€€€€ޠu€8 +€€€xw€€€€€"€€3€€=€€ Ba+€€€€€M<€€€€/Ӝ€€€€€€o€€€4€€@€€]€9Xhn€€1€G€€]€xHvM€€3[€f€Ԛ€?o֦€€€€%€€ۜ-€lU€p€€€€€€f€Oh€?T€€Y€€€€x€€€ɿ€윺 €V€€€/€*F€t*E[P€€€€€';Ofʮ€€)€Gs€€€?€€c#\€€€€c€gu€(g€€
+S-€SB€€1€€€u€€ˣ€€<l€€€<€j E€€6€ر/€l€y€E|€e9€€|€-€€€}€tYZ€D€jd€€f€Z€€€&€&3;€r€€€ ?/|€€€f€€€€€J€€€_r=€y€j €I€€€>€€€I€€€#O€€a€€B€€u€€ c€\€€L€;H€€n€8K€€[gP€]€€€€€I€€€€i€P$€k€€€€€€€€€€*]€€{f€€€`Q€€r;€€€€|4€€€€€eQ€*€x€lv€€€€Xm€€€€~`d€{$€€€€Z€€D㊲€€-x:€€€€*€8€€E€€€€z€V€}`€oÛ½H{4a3€j2€€ިK€N€€€1see%s9€€<€€QFw/s€€€|€CQ€€€Z€P €€_€/uo€€€q;€€€€U€€+€`€P ~€€€3€€€&€ß€)€Yg€mvs€yG€i€€€€€ɘ{.€€I)5€O€€€F4Z€ €€"€€€€ZE€Ô€€€_9:€€/N€&€€€zX€€X€A€€€€€ €RX€€€€€"€{~€€€L€€?:>€@><€{€5<r€䉲X€€P€<WD€€€€€€s€€O€r€'Y€€~€:Z€?a€€€€>@.ͧ€g€€€€&Xf€%€€<yRSw"€€€2€€e€€€€Q€FZ€lMؗ€e€`c€|€€€€)€€+€€€€[& €€€Șͬ€x€€-€€€€vI%€ulg€L€€dd€.A€€M€€m€€[€€€>xr€a[€#€€€g€€zLwb€€wV9q€gh€&€k€E|3€€`6€m}€l€On€ €€s€M€€€*eU3(€x€€€B€_€;6€€WL€€j~m€€W€*€R€^J€€g€€Kh{4€€€€€(€y'€X:Ú³16€Fߊq€?€€[13 Ö—Dy k€€E€€xeo €€Yƒ€ €W€Ϟ/€lcU€€€€€€F€C€p€L€€€€€\€tejv€€€€€.9€€Q{€$€€€m€€€a€€Χ€5€€„,€€Z=6€k(*ރ€T€(€rd^K#€€€€€|€€€€VǸ€R€A3€R€y€€69€€€€#<]2€ht€oS€€€€€w€=€ €€€=#€€ڜ€R€v€€€[_>€6€€?-€€h€-p.€ܱ~&€E€€<m€/€]€h€€€I^y&€€o€€&u€g€aw€x€\4V{€D€|.€€F€fÕ¢]€]v.€€qq&V€7€\€;+ի€€|€1y% €;4€€€g€8€ϴ€jI€€0&€€€ۘ* c€Ɖ_Ε€!g€€e€N€€€[€€y€€€'Grã­Â€Â€Â€Â€l9€w€s.'€g€€€X;€€z€{€€|%N€€ c'€
+c€€L€ћ€€:X€€F€€€€€€ €€e€?€€€s€€"K€€€h€7€Lgy'a€€€€
+€€w€U€€€€€€€€€€=x€€€€O€€€€.*w€€<€}€s}=Uv%&N€|€9€€€_b€S|€€Vmw€€€*O€€€ƚ€Þªr€€PQ\6€€}€ĥi^C€€€ €&Ӵ€€_€LU€€€L€€€€€€€x~L]€€r€O€:JF!€€€€€=€€=€w$7€f€€€y9€€€€€Hۦ€o€€€l€€€€F€gz{:€€€€€€9€€Ӭ€€2€€€€€€Fo€€€€€\€€ӣ€€€lb{€€Mlc€m^s8€€€7€€€€€€€€3ٱ€€€v€€€€t€Ôs€U v?€€€€€y€€€V€
+ɧ€€€€v͈€€U€€\€€N€€+€?€ €€b€[€ |)kâ½…k€€€X€3€oޚ€^€€>€;€9;V€P€€r€F€€<€€ޞÙ!€ȼ€€€|€€AÔ§G€€€€x€ٌ0W€q7€5RL?a|€vn͒ۘ€[q€mzA€FWuoġ€€€<O ǫ€€/€€j€{€€C€€z€€€€€+7€€ €?VY€€€;€Oy€€€€€+'€€€o؅€€H€€€€€'€€Ñ€s€7i€€z€€<€(€€zGzg€/zG€+€u_€€€ZSB€€{€ژ€€G€€€o€€€€y€€،€/€g€€€Z1€€€€€€€g€€}€€Dx€r€€!i4€g€€x€€m€ç·Â€Â€9€€~€€€€YK€z%7P€E€H><A€€G€CEK8+9€>h'€rD샤#€€^€€€€;€€€?Dsbm€j:€€~v€֕G€a€<A€zLn;€€€C€A€€%€ €€M€Ø€0€€€w€ޗi€€€A/€8€O[S€f€€Km€€7€€ݸƧ|€W€€4€€€dX€€€Ϟ€€y€€1€€q'€€€€€F6 Mä«|u€vo€i€€€€KÍ…=€Z€€€s€H><€C>3Ó‚p€€f€€^t€€€€g6€€€€C|€@€€€o=€€€€\y€v.W€€€5€@€`€'s4s€€€- €€€d€€z€€€€R/€κ€>€kjnli€€€.€#Y€€€o€#o €}O;€€D倱€iS€€€:€/€€h€€ߟ€D×—H€€DÒŽL€r€tKþd€/€}]€\€J€€€€€]'F_€b€' €€HZ€€wF€€€€x;€"€€€€˵ €€€‚€l€hg'8Y€Wmy €€"€l€.(!d€€€w+€̥€k€€~€€V)€v€€€j9€€Ҕ€€€€bx€€€.o€€€h€
+€k>€€*r4€M€€ê±i€€i€€t€€nj€€€3€[9+(€X€_€€e|€€G€€€x€€G€€€€p€€*€€7€€€€€€ €#€W€€_€u€€€ €€~?€1€€+3€€6€€/ €w€|€S€o€€3€€q€€_Dv€U€2D~;_b€€€€G€€OVÓƒS~ €€ع€ˣ€€€€€UY€w€€€€€c€6€/€€ݷ"€€4/P}€€€_€=€Ifj×侊m|€ €€€€€>€W€5#€yȕ€€x€€€ 3€€€jMW`€€g€w€€€d€€€€€2€~€€̸;ˆ€:Ø„<€g8€%€t1o€K€|€€€€€€=tE€y€€€€2ɹ€M€€€€Vmc€€€,€€€€€€.d€€€€€ €ߗ€€€yc€%€€j€pd+Z;€6€€€€`L3 q€€7⌖<€€٢ٶ€c€!ٖ€€C* €€€€o0€[LF€€€o€3Æ“o€€`€€Y €q€&€€F€€€K0€M0-€€€g€€ER5aZ€F€€P€€€€g€ €8€€€bC€8€€`€&€€4 €]€€€`€S€€€€Ƹ8S€€d5€܂€ €z€!>€2AJ€!݌€ €M8€I€Z&€Åo€€€q6~6€€*}€"€€€)€`L€€€€€)qTj€€€€U2\@a€o€8Z€€€x€P€1€<€
+p€€€€s€€,( €P+€P€€i€ԫ€K€€€€€t€b€Rq€/FN€-€0Մ€HN€OMAq/€%lB7蹥€€€3€Ԋe6\>)A €x€€p€€3*€€f@7Y€xEc|€ €q€€€M4€,€€€$€Ohb€O€ €€€NAI€€L=€€MK1€0M{€%&iO€€i€AiiN€)€€''€Y'D€€z€ /€+W/€`€_l€€YFc€€€€G€€ P"p€€f€?` Ђ=€€€€G€€ €A€€r-dL€€€&2€€f€€€g€€85ʖ€€_3ZR€€㸔$j€g€€€€€€€€€s{€E#€@%€€€D€€MgC€̓ €,€&& €€h€j0$€![€VgS<€ €€DR€&([€p€&@r2€€,€(€€5€1_ €€'€%€z#€€^0€
+@ €€€€x-&=
+B€G€€n%€ΖЀ€`3€€sw€€[me€I€€Ȅ€b€E€z€8ɕ€€ =@_€Y€Z€€€8€b€€€€&€€€8€€Bd€YhA€€€/Å /py€€(F€3!)€*€Pc €€H€€€$Y€€h€€€€€/ÅŒ€€€)yZ€8_b€€€&'€9€6€m€)16[€€€€€@{O€€€€2€38'€%€/€ƕv€/€€€€€T0[%€R€€€€+€Czi€A#€ZU€ €€€€Ӫ€J€o€Z€€%No4€€T€€p€€€|K\€9€l€€2k€€ķ€g€€\5€k€Ȝv€cB€U)€€€€€€€9€M€"s€y€9ɜ€gN4O€œb€|€€€€€€L€ €€€)=0€v€\s€€€<kFZ€bs€ds€ü€<€f€ `+S€€€_€€xQ€_€€€s€€€€€J€€€+S€€€.1[&€-M€€a€%|€€4K~x}€b€€€€€€t€&e^€€Rs€%€xÕ¥l&E€/5_n€1€€;€I)€€KȪN'+€|Q€y€9€Ƥ ͦ L€€.€P€d€xaF€e€K€Y€^l€€l€€B€€q€`€€€"yo0ߊ€ €€á—€ q%€ €$€y€€€oË»p€€€€€tK€o€€€€'€v€
+\ɊK#T€̬k€€*.€€UҺ2€ aqwZp €€Ô,w#€{~"<䶺€d ӥ€u JjJ€/€Af€j؈[!-€€:Lb€2u€q€€€€€€€€€:€c> <ff€€€{€€|€.€€€ €€€[|ǽp1#]clǵ€8€€n€€€€=Ԋeit€€*@€€€+ί€2€€€?€€o=7€€˞€€p€[ޅ€!3€^€ɗ€€€W€€€€D€,€€€€6€€€m€€€Vd€
+ٛ€€€UI€€z-€wnw>€€€#W€€€€~ 9%€€€€#€€€u€J€€Ο=3}€˰€€€€€i€€€~€€y€€<€;€qKm€€tY€€.[XU€ZRZ€€€€U€€€€S€€€/€€N€€€€}€€€€€߆€Os€€€€€O€€€€€Ü€€ €s6€ӿ)€€€Ӳ.˾<gz€€+f^9€€f_5€€€€€-€€,q€_€€t€{€皲k€+*€€€€Y€€€€€}~€V€y€€€}€€-€nlm €€8€€ٵ€€57€€€€d€bϼ~€€€€€-nS€€€€@{€Bg€(r߸€€€€€ɟ8_€8EYL€€)t€€€€ޮ€€€€€)Jy;€€ml€jj€Pp€M€M€MpP€ x€>g€r€€€P€€ҡ€DA€O€h €€€y€t,€€hB€z€9€€€>€nh€€€ €y3b€!€€_g3e€nk€€€S:€ۚ€vG€667Q€v€v€-€.c€d€€5Z€€.\€€W€€€€spX€X3€€w2"€€€#€R2>*€M-8€€€k€cí€u€€R€€€2E€€D€Z€[V€2€€€€Z€€H,€€K'€\:E€€€nV€€\Y{ €€€=€9Wi€€7€tÞ¬4€ilnF! €€€3t€€€€€€* W}€€G€+€֤€€€<eʔ€€S€i€€ҩ€Bvmo€I€!j€€€Í¿q€;0€€
+As€€€u€)b€€€€L*€R€˦u\€9€€PmZ€€;)€^u6J€€U€€fI€Â€í²’€MԌ€€€@S€€€€€ P€€ۻ€€f€)€€€€J+€R߀€€€]€*€CMh€€€\€E\€p-€aw€;€€€€ǯ€$S~ €kV€w")€ €€:€*m7+€P PaЋTG€€i€ €Ŵ€<€€4aZ€D€t6€€g€€€€I<€€€{x€e Õ¯P€D €G€€€€)€/(€€€%=W~3€pN@€/PQ€ nj€_€€X€q€€7€€€Rc4gI€}€€(Ղ€Յ€]€€€€O€€.} €€€n€F€€&3€c2€C€!q><€€v€o U{68 ճ€€$€S€€€€W{W1*€ä€€Ad€T€€\$€T€?€€w€€@€\€@Un€€?A€€!€R€;€ig \ €g€ €€€s€€€]€€€€€!€€ؠ€>:(\E€J0#|€+5%€€€*€€€@sS €€€€k€€€€€+€€€€€PW}H€€ꫯT
+
+
+€hV€€+€€€vFg€€`S€€@€€7
+p€€ €C1€€€ €H€< 1€€@€.€TVB€(T€K0MFe۩€€ €€0€Ãuwt€€ N€€€€€sтī; €:@
+q€q€$yb€€€€iM€n-€€€Ѵ€LL€:€н€Z€€€D€€!\€€Z€%€€J€€€€?€€dJS€€€_9V€€€^€€C<€€P€€€€0€€
+€5€€~€T>J1€€h€Cop€9€7M€;€cÆŒisaO!wL€4€xZGQѴ€€€aõ€,0€€€i€s€€-FVÉŠ €/F€€€€€\0€€€QA€€P€€€€€€4C€[LAr€Q€t€€€"€y€)?gB~€€ €$€€€€"g€€DC€"q€€:8Bk€€<€€1,€s+€€ €€€€V{͇€€r2€k€€€ȬG€Gr€I€€€€€€" €ris€Ä°M+€H€€uu=#Ĕ€€Z€€s€€(.*€>€ɹYY€€€€€€€€v€€€€€€^€"e€$)׶tt€Pm€y:€z>€€X€€E3€(€IT€(sI€€v€e-€S€ M"€€€9€€l€€}>€
+T4Ò+J*e€\ _0€€€€€€y€y2€€j8€r€O€vvaƅ€€?€€83€€L=€€-1€€€€+€6v€rm}c€]€€€€€N€€Qj€€ €€€v€€€€€C[WkgK€ce€€€ €d€€€%6€€&`€lm!}€€H€€ g€I€€€€€O€8€k€g5?]vٳ€ÖF#€hbBx€\n/€€܀a2€€CM€*€<€JH eB+W€€y€M€€€`F"€€€€4r€€€€$ Ò‡{IX. =w:E€~€€p"€[€[€€€a€€#€:€]T€oÍžVW€ €€X7€ 4€ՈS€€€`iO€€8€-'€s$€AW€V€Uu'€ €€€€0€€=I€€7T€€u[u€€€=<Q€w~E€ty^wPwH€€D€[R€8€q€ d;V}€n€.€.瓿€€n€€€€z*€€€L€~B€&€€€B=4J€€€€€.6€_€€)€€€'€€€o€s€€€€/€€iћ· €F€€$€€€I€5€€{€-x4S€lMÇ– #€€€3Xg €€m€MW€€3سq€ €&€€ͅ;Г€€s®V€€W€R€5M|9!€€(€g€€€n't€ €€€.€0]_(€€€A\€ /v€€Ng€€€[€i€](;€€A€8€n€€)ߧ€<R€\€9€€ q€€€€<€€€€€€<€€€€~lS€€€qostT)v'€€€€€€€ € €€€€d€€mвNɺ€€€d€x€€X€//€€q€%nI€€€Fu€€&€Ϥ€€€k€€6€€/€€E]RF€€[;V€x]€G~]€Gu1>€˺l€ €G€yA#€b€ %€6€U€€q ǧ;*€:€€ZuL€€€QLF\€€€€gB€h€€"€j€€€€€€€j€€9€S€.€€Mb€€A€€€F€V€€T€€2€€€€5€€€Q^(G9€€€tfo€€€€G37<€9jh€€qcK{cgtK€€€€€v€€ψn€)€q€€€€gH€€€€*N^GnT&zQ€€€€ €€€€€r€€ṻ-w޿€L€€f€€€æžÂ€Â€pc} 6€€€U݀€G€N€€€€€€€€€O€?m€€€€€r1G|_€€^€€€€€€z€6G]€>€€{€€€€Q€€T€[eN€€wmɢ€"€Y€€t}'€€R€€8Cښ€R€€Κ€{<7˾€€€€€€€€€€R€€uSd€3€2E€k€;O€€€€€€€€€vrHi€€€ m€€X<€U€€u1!H€€€->€}77S€€€€|€€€@€77€&koExKF䴒€€€"Ó£Sݸ(o€€€€Uz_€+€Q€€zL€p€'D84€iǣ€€b€€sE€&€'€€€̬€€€Ý€€۫~#€€€€€€€€.€P€⊅k"W€€€€ѭ€V€S݌€€€ԥk(€;€1Ú¡+6€€€tÅl=€փl}€€€€z€v€€€€€€€`U€[˯€ê€€€`€€Û€A€€:€M€l€M€׎JL€€€u)€U뒼€u€ކu€+֙€€€€t]€€j€€[€N€€€€€€€3z]€€€€€l€Bʀ3a筛€€Y€€€Z€€u€€€;€&€€ț
+€d€OZ7€k€€ €~€&€€3x+€2 VTC€€€P€€¤€-€€€qY$€d€€€€€}À%ZÓC@r€Yv]o]+€"Xnf^C[€€€€€i7l€€€€¼ lK€*e€i;v€€>YÓ—'€ݨ€5z€€I€A€$€€€P€€€€€9€R€€€}'k€_€€]€€€uP€o€]€[€€€€€€H0R€x2z€€-r€"]€MJ€3O€w4€ҫ{[€=€€€1€/€€膺€€r€7Ǯ€%€H€sN0€ €€ €€ ਕ€€€L# €€€^jx'€€ 8.€€M€€h €€€}€€€_€#í±—€C€€€€D€.*w(]€€€pO€wr€€€€€{€€@€U€>€€€€€€.€€\€€ol€€1z€€EtO€-<€€€Dn€75h€n>[0€€€€€€U€om+€€€6€!ÚšE€g€€€'€I€;€€€-+A_{€
+€€y컌t=€^€H~O!}€ET%€4€€J\5€€€€|€€€vx€{6€€Zfv€€8x€=€€l€[€€9€€0€€:€5€€€k€€€d€Qߦ€o€€€€€:€l€€€I\yb€€h€ßT€€B€ `19]y€€€8€ m€Cm€€ÏS€€€€€k'ß”}€1T€Bs€<أ͊€€€€٬h[€€g€€€€}n€€€+€€€>+€€-€€å›Â€;€lO€€M€€`qF€ޟ€R€€€葴[p€h@€€€Ø\€u?mޒ€€i€Ń{Q€€Ы€v€nE/=n 7AG€€6€uG€€€ z€€€l1€o"[€€/€!쯥7€€€J€q€€€.€_€o€€"€g€€€|€_€7€€€€g€6€c .|mfr<€?NH2€€€€C€€L€wX€J)€€€€€ €5w€€€€w,€€€]Dw_€€IÇ¥`€€k€€l€€Gi€€€ €1A€pUq€€j[€€€€€€]€€€€{L€4\€€€+€€€€˸͊€Þ”%[€€€ €€)€€€m€€€ Ϣ€ €Ћ€€1#6{s€O€€€nUBo,l\€€€€€€L€bU€€n€̴€€€<"Y€]uU€ €€€€€p]t€d6€W€*"€€€J€€lw€Qu-1%€]€€€€
+€!\€| ]=,o€%€€7€€€T€€€€<€W~€€€€MJ€€€W€€€U€€`[€D9E€J€O€€€"w€:€€€}€w€€@€20€€Vo€b€B7€hb€z€€naß³[ €
+€kq€€W€O€2€€€Q€t€-T€H€€3€€€€€€֨k€€wnuV€€z8€5t€q_I5:E €N}€€€€€q€€T€*'O€l€€€€€j€][€/u€q€€,l€,€wI€Få»Â€Â€Â€€€€ظ €i€W€W€⢖€€€y"€€J€Gn€7P€€E€w€€F€€€€Z͸€€71*€zb€€€A€€
+€€`€€€$k€^)LT€cc€€-€€€€ĥNY€€€V€€q€€€Te;€z`Rw€]€€€€€€͌4'€*B€m€iomj1€€Ѣ€D€€|€€€"€`W^€€dO€€/€C~€€€€€€Ø€X€€€€!Hn\ €_€sݸl€€#€݆€€Ą€€€€€€oY€€€€D€€€€U€d€€€V€^€€€W€ozOO€.€ €n€̈d%y€0€#K€g€€a€€׈€z€̂S€K۔@€N€t€€y€;€€€€D€€:€q€€$|€€€M€LvtX'&nK€€€ €€€€€ og€2|(+€"Þ‰D€€€gP~€E€€$€€( €'€N 唼?€€€QZc€€o€*€9€€ x€€V0€t€W1M€-9€€€€1{€n€€€p+]`€mT€y€fG€€
+€ lPrC\€31T€ DQsf\€€(€q| €(€:ӓោ€€C€€€€E>o€ӽ€[€[€i€€€€€-€<d5€€SOR€€y€o€b€€€d€}€€_a€€$q#€*€Ò]€€€wy€€€€€d€€r$€bl€€€€€z€"fS6X€9€€€€~J€€I`&€€@×£€€€€€ls€€bA€€€2€€€€€€۸7€^$€
+]€€'7€J4€e€oy€>;|€5€€j€€€€g€E€€Q€Sjx?P€F€€o/€+yA€`€€L€w.€€T݃-€=~€€K€€€€€$€z€&€€B0t€:€€€€€€€€€c€€eSM€PS€H=N€€€bx€ 0bL€€€€€2€€€"훓€[€q€5g€€,€€€€G"0€€y€|€€5 kk€€€€€AHRl€{€€sg€€'}€7€c€€m€€€;=:€€€€Ƃ€lrAjP€€€w€€Y€€fR]€T[ e€€€b€€ O € €c€>€€€o€Ic€و=L€€€r76M€€€YkC€t€ n€V*€@Õ€ €V€€€B€Z€&Ot€T€€€St_€쀿€:L€€2€g€€€€$€m€z.€€€L€fV9V k,L;€€€€€_€€€€01"'u€€|€Q€€€B€+;€~l€9}€uT€€'r€/€ €"€Cu€€2€l€€:L,Cߘ€/
+ €P€€̑Z€€€€€+€€€€€€€=5€
+€€"}0>v€/&€€€8(€€€€€h€€€€€ € ]€€ €3€i€€1€€F10€€€€!€€G0€1R€€2F c€_€U,€€7hAu3G€ €c€€>€PN€€€€7€Y€€Ճ:€€ €€€,RE"€€'nT€€)€6rs€$€To/€€€K€
+#€€&1{€€'€€€Z€€n€7€€€M€€{€€8O {6a€€h€!€€€Z€€€€<€P€€€PN€տÓ¡M~/y€F€€hL€€̂"€+€€U€ȭ@˼X€8i€Nc€€ d€e€<€Q€€€hg€&u€€6t€b) €€/€ph€€€€!m€€€€€D€€€!z€&ހf€CP€€€1€ba%I47]€F€€€€€€€㺀M€A€}Õ´b€H€€w€}ß·w}€€€€<€ v€€€Ñ€ €€g€i€€=€€?€€P€€W€lu/.[\€p€⒲€E€%55€2€w0€Ù€dP€z€€6lÃ¥€€\€Э€€Ux€6`€e€n^€€ς€€^€€€+O€€€€} i€€V'€€€€Mb3B-€ƺˠ€q€a>Ä·h€€8€€t€9)t€J €€A€ €)€€V€Y€y€φm<ש€€BF€Ķ^\€vp€€k€€€€9j€€€€€^:€€7/€€H€|=€u€ƕ-&€€€€ 3€`€€L€}€€€E€bj €pÞb€*5€€<€€€€j€È€vjh$2€6a€€€~:€Q€!KQ€ngq€xxΌ€€{€N€
+g€€€€v€€€€€€b€€C€Yq?Ë»€t8^€€€€€€€€"€€€S`€€;x9€€>€€€mf€€€€€€_ €€€€|Û®?ɪS€^&€d€'€€€ -€€€€€€€€€-€€€€€x'ԃ€?w,h€€€€fR}-€^n€¢€€"€v€k**^€€Jj€€y€NyE€€€ B6€€4%€'ToÒ„j€€€c€jt€€x€€5Ŧ€è¶Æ’W€€%'€8€%'€€j€€#€6€%8|€s€€€m€€€øu€€€ €€[€ €o€€€gd€MB€€7€€6M€b2€€€dF€€€€€€€:€0€y(B€G8€€€€€€€n€€ET€€€€€}#€`€€€€€Ko€9€€Gs€ĈM€€€I€
+d |B€:€€s€o€€nA;€o Q€lNQȃ€€jǪ€€€€€€€Y€€€+€€€€€D€F€€€GU€y~K€€̄iv 5b)€\B€ b€.€owSc3cL€€€€€€€€€€€€€ 7)aT€(7€ €Q€c€ \T;€€€~€€€äš€€w%€€ڔ€€€€،€€€Fn€€€D€2&e::C€€€€7€q]<€€`€6€{€€57Ƣ€€€€€"€€Wc€€€€€`s%€€€p;€€.€Ke1€$€€F@E0€€€J€k€O€€€3 €€C=€K€€Ƕ€::€€`=պ€€€JR4€3R€€HÍN~T€€€€/7€ST{ €€Π€€rO€€€€€€€€€€M€+€a€€B8(/M €€ᶺ€€€h€g%€€€€€"$"o€€#€€7:€€Bo€€C€€€G€Dz€€+€€u€€rKs'€€BDOK€€G€€€L~€"€€";€€4s€.€€e4€^€€€i€€0H€€€€€€€>r€-€, €my€€€€:€I€ €7],€€{RZ€€€€y€+t€c€€;=€€€€€€€F~SCK`e€€€€€$€€€1M€ M € €€€€J€2Oa€€€€B{€€€;k€s€6^.€€€^€€€€up€`€€€€€|],>€J݆€€€y€@&ƙ€`€€-Y=R_€€€2 €€Y€€e€Kl€€€q€v€€€€€€€}€€غ{X€€€€€€€€€€€€€M€€a€€|[A€€€€^€€
+ڀ€€€€€3€€5€-€€pi€ €F€€P|€Z€llԯ€(qKက€9:%€€€€€
+€޷€g€€€€f%€€€€€€€€8Ò€g+€R€!'€&€€€{€q߉f_€€!Ò qŅ€q|€\
+€X€w€€€€]€Ã€€t€€)T?€$€€P€wY€nR€jeϼ)€€€p€€€€ŴM€M0>€€€€Ne€ e>Ö£t;€€€€{S@KC€€e€€ũh€€+e_€€P€M€Y%€#n`€€'k€€C€€€€€€A€,€k€Iv€€ZqX€G€OY€€€35e€€€€p€q+€?€€€€€ €€lSP€Ó€%_avX€Az€€9€€%N€;€n4€ޕ٦€€€€v<€c)e€€€€€€€pe€€{c3€g€ l€g;Q€%€€RW€€5;€0€€$€€.€V4€€>€€ʖR]€N0€€€Z€€tms€ț€€€€€€in vb€y~€WlzJ€€€€ €0€(€
+;€2€€€ NE€v€€gZÞ²6€€€=d€/€€€/€€€u#€~(Ô†p€Q€€€L€K€%CӶ€€€xÒ€x€€K€h3b€€E€j€€ohtvL€n€€€E€y€͊eL€ɑ€˞€€b€̓€€€€€€ €€)}=@kÖ€A€;QG€:€€XWg€€:o€€ĕF€€€€det.€€h€d`€90€€g`:V€S5€2n€€€€d\:w€€N€,€€[ i€:T€€E€€€
+€€€€}€U€€€9€€€1-€I€ز&pG €€5€€Ĉ€M€€€€€Ӗ€Dj€sx€€€ tvz€:€€€I€€€Hq€€N9€€€t€€V€~€g€E€€×q€H€S €€€~.€€€t€U€€>0€H?mDZ`Z€€/ €€µW€€€€:€|€Q)ÊšS€l€€€õ€€€>M59aɷ€€5€6€€€€€€€Wi/,€3€€€g A€€€$€€€€€
+\[ O€#q€€€€:€€€D€€n€;€€€ c"€i€?WIen€€j€€€tu7€-€ۇ€%€€€ɬi€]€€
+€€N'ߌ€€€€€€€€T€XL€€€€N€€`€€€€4m€€€MJ€\€€€D남X€<€th€6G0€€(:€€'€€(4H€ €Ճ€€(С#€€€]€€$€OhaGI€W=_CuiR€ox=#€€ D(€€-€€€X@9€€F€€EO€ZR€o"€€h€€FY[€W€$.€€w€)f€€€_e'.€
+WÂ€í¹›Â€nWn€%€_€€v€€,I€s€/€G*€€€7€o€€n€€ €Y€uS€@€€€€Md&€€d\€D€ I€dEC.\`€€€͆€€m4€€;€€j€
+&€ Q €U^€€U€<€|€€€V_€-U€̈́€€\€€M€€€H€7€t{€€€"ى€TK€խ€d€€Iֲ€##Kz€€€€F€€s€€
+h€=€€€€<€€K€ci€6϶€€€
+#€$€€€q€4€€_€6€€€
+€u€Pc€€€€C€€;€€€€6€~€5€€€0O€ 5€€{h€€mNF϶Vc(€H€n€\€€€
+Oo€J€€€n€€€sk€K€€€€€5€€€€€€€€€I€ͭÛ‰eC€€S€€Gb€w^]"€y?€€$8^€€$+€€Ҥ€*€€ǚ€€F€Oo€M!l€€q€o€slP€€V €€M€€g€€€€{c€p3€qs3€Q€€q6€P5€7b"C{€$*€o€hi€2€€€& €eO.€€x€€w€€€ €/D6€€€€€€=€qe€€C€€_€€@€€€5€€aÌŸ^€€9€d€ɚ?€€9€€€j€D€6€'€€€€€?€M€ >/|U€M@=0@G7H€€z')_€%€p€€€€[€Y€€:€6€€€€€ț€€€€pi€5Z]Ô­&€K€Z€€b€€#V<€€€`€€€€€€€z!€}l€€€€`&€3€€6€zԅ€;?€I13?€€€i€S€€J€€€qd€p8€g€€€€€axE€€€!$W€€v€ѡoS<€==€k:€€€€€€pp€€r€lC€ €€€IØœC3€€€;y€€ذ€Y0aGP€€m€€€Oؤe€€S €Q€€i€€€€>€b$€€€åŒÂ€Û¤Â€Â€Â€` Þªq€€4€€:,€@'€€w€€€€0=p;€€€3€€+&€€yZ€€C€€€€~€€€€n€€V€V€ߋ)€€0€€€>€€€€€th€€€€€i=a€ |€&.€D€€€.€€#S€€h'Zщ&€b€€͛TMuA €€U€€fA]ؾ€€|€€vK€€€ J€€€€€v€%€j€€€€|F1k€t"€I€€HÞ†llY€€k€ €€]€5\€g=€\"€€€IF*,u€€€}J€;3€€z€€€sI€?+E€<€j€룪€€ €A€€€nY€€8€€Xn€u€€+X€C€€,t}_€7%X€€^€W삾€€€€€€N€€R€H€€SL€/i€€€$.€€M€€€m€€€€€+€[-€Ys€i€|7€€€€€€€€€|߿€€€J G|i€]€u€:M€3€K€Ϙ€€€€#r€€€€M>\D€4€€XiS1€5€€j-€5€€W€€€R€Yׇ€€€d]€€€€ã‰Â€UU€€} /5x€€>€€€xY€}
+/€x€€€€€2€,€>€€€6€rkwC€ €€RRK[I€]€€6€€F€€tq€€NƄ€€P€€€ѭ€‡6€ z3J€Ò: €€n
+€€WCMp€€€2e€q€€]€€ד€F€€€€€t$€€kq€€#n<S€2>€€e€€r€ €X€€ €€€&\€k€€€€Ɩ€€€€rTvy$€€€€€PD6`[€€.;^|\€r|I€€1€€}€€€δ€H€€€€€qtI€€L€wܸjJ€€ǿ€_€€€,f€+t€2<L€€€T>€€€€€u\OY<? ^p[i\ hE€+€%€€vR€€vz€ll3€€€<€a€}€€Wyg€€S€VG€ €tS€oC.€|C€*€‚Wz€0qV€€€ Z€€@€U€€€€€M€€Z2h>B€€$€/€6€A€k€&Z€,€€c€3L€=€Mc&€/+T€ €€;€ܘW'`ߊ˛I€QV€€9€
+6\T`€J/€€L€SE|€€€€;6Ȼֿ4؎j9€ €Z\€€€݅mw€€€€B€X€€€y€€>4€€)j€€l€€€€€€s€e&ג*€I/€€€&%nA€'€€ €U€I€€ךL€€AO€VrD}€Q5€x€€€€€5€h€nG\UO€€€{€M€€€K€€€U[€,aR€€S€€€d€t€!€c€ €=f
+iulWp1€T q0X€€€€€P€\B€0€€€j€€€{%€€€Ľ€D€€^€I͛€P-Dž€1€?€ޭ€€€€€5€€`U€€
+€€€€€€€b€Gu€pY€€|€Sn€€^€<€;LعÄ€P€€Cȣ€€€€j̈E .c5€Bx5Ǽ€€€€.€'<€€€z€€q€Bc€B€€c-€€€€;€€3Df
+€€STƨ€ €€kLÄ°F€€0Vo8€€C€bA€€ €€gTO\€+.€€L€€€:]€v€€€€~€€€g€€€€€x_€;€€€€e_€€.i€Nny€€€Ý€€>^€€l X€€i;€€€€1€€ U€€8€ZLRN€R'#Vo€ !#€P€\2€PF€€€=€OcE^€7{€€€€ן€€€€€h€&t€q€€k€€€€ 7C€nl€€€3;€€D€€˒€€'€¦€vS€٫€€€€€€á€€WZ€€€€)€Z€€€€j€€€€€9€€€€k€€]Z€z%EXÓ¥+1͸€j€$€€0€Q€"€Y€T€ZP[lƣ€_A€ 50€€v v"€֣@9€€{4v€5€z€€& €Uu€€6m'€1e€.€5€€6€€ƥ€€Y€€€g€€€i€€€ݪS€€€€€4i#6€7€€€€6P€л€C4y(€I€€€€z€u€6/g€{€€€pF€`€€R€Ú€Ci€€ȓ€€€€SL€€^€k€7€€e?6*€/€AA€€€€€€@€p퇼€9€$B<€Qv€p€dRÚ“2$€&€җ<8€T\€$€€s€ €|€€-€€€#€€€;€07g€f€€€€€€€"€€€€€w€>€€W€€+€ €u€|€€€€N`€H'€ €S€€€Nw޻€€:O€€}€tN€JÌ¥C€€€1]€€%€ٸ €r!€€€€Zȃ!-€y$€7€€€Iu€€€CB€|u+m=v€z€€€€z€€€I€€TUCĘ5€b€Ba€9 €g€€€€G€K€€a€€€€€ß~€€ۻ€ƺ?€,~€€o€€€€߾€oX€e Ķ€m€7:lJ€[€€~~€€€€€€€€Í€ow€I%€€"€€€l=€7켧€~+€€>~€€ow€€€€ wS€€€€v7€I€€6~{\_UaZ€O€€Ë›ZSMP€€€ozl€ay1€€j>€oF€€€/€€€8€])€€c~3€+€€}€f€S€3€€d€r挆€€€€ e}€xm}K€\]R€€l€€<€€€c€€iqy€€€€q€% .5W€,€€8Ø‹+€ cweavee.SYMMM]>6€€_€€€€MPSTMPS €N€€€€4€€€€Ir€€ €€km€ir€i'€€€&€€€€€6€(€|íº¼Â€Â€Â€r€€~€n€€6€€€3€€/37€+€€y€A€ €Np'€ €.€ €~B€]€€€€p€€m€€€r€l€8€€€€\8€w€p€c€m€]€yf
+€€€€}€y€€Xg€<߬]€€@€6#8z€o~/€?€B€€x€D€€-/kU€-S€:UW€Rh€€€€€ €˿€ә€€jm\€€€^qiUM-~!€€C€€€€cQÑ¿{*€9€€ €€`€;E€€€€€€G€€€/j˺D€RY€W€eW€+€€!€J€0€€tQ[pH,.\€€r€€ÂLU€[=€, €€{€€B UT, €bhϲJG€€Wl€€|U€€ €€+€€€{v€€x€€|/pX4€E€m€nGN€m€€e€€€€ls€€€M€m€L€€€?3€Q€-/V€€€€O€€€€€€€:.CW€€e€V€_^€<€€+f€€€€€<€@€€
+€ц:€C€ =€?ױ€€Rԑ€:tDL€Rǥ€€€€εT€€€_€€sy"_€n€€F€~€€€€:€n€€f€€QB€€n1€€€o€€€€XX€E?€€€€7€m€€€€:€€€€€}€€#€€€€€€€[7U€.S€€€€€€€€{€€=$€€€€w€€=_€€߻€€€€~€€€€w€>€m€€€€W€ūq€d€{€€€I~'€u'€&€*€€€8€}€€€€€€m€[o€߆r€€B~€€|€w€€ˑ€q+€w€^€€€o€Q~'<-€S*€€€€€ €;5Y€v€€€€6€€€€~€R€€€€W€T<€w€€€%€€-€€&€€N€{€€€€0€€€€#€€€€€g€€a@~[€€€qu€€n€€€~_€€€€€€€`€€€€W€Í€;€OX€k€7wo€€?\€€(*޺€€€nO&t€€€/|€€[€m€~€€]€€€€€€€A€€i€uD€(€€\€0vn€6€€€€zк5KY+€€Dw€€€€€44€€4t€4€{z}e€€ x€€€M€'C9_€/}€€€"@€€€}€€€€€€€nkhnlnk%Jm€€,€€€?€€€6€w5€Դz€㬾€€€p`(.€€-€v͘€€€w€€€-€~f€€€>€a>%€€€ €x%€b€€{€pv€€^<|€(€W€€€p€€€ ×€€€u€*€€7€nm€€€w€€~{€€€\!€C( €€ j<€€€x€€= v€€~]:€€p7€.J)€€/n€€€!€€€€]F|=\€€I€€€€€X€.€@垢€{€T-u}5Oj€€€::|€=h"€€€€€€€€€rM-€)NiF€€€€z€G€)\,k€€V€i(o€€6€q\v€€€2na[c€W€€o€uT€€€xM{OmWM[kG€€€€ktSd€€€€€€w€*€7
+Ö€B€€€€€d)vÊ·€€€€€3€€€]€€:€€m€€€c€"L€ȕZT(2Qڀ*€e€ €Ku€Q΢s€€€siqb€€v (€mqÎУ€ڲ€է€\@n€T€Fk{€!€€|€€€
+€y€€€ji€€€P&€'€€j€€€< €m€€t€6€€I€v€H/€d;€€W€€6€!Û‚xœ€x€m2€€€[&r9€€€"T€€`n€z€€€€€7; zx€'€€r€€€]&z_€€€€€€t€A8g&€.8€'VS€:Ĝԟ€?0L€T€(€€3€€צT€G€€€€S€€€n€&€g€}3QHow€0€Ɔ9€€€€€`€€l€€€0o64€€€[€A<`€€r€€€€€E5€O_w/0€Z€€€€<v€€€€TQ^p€=€€F;€€€€€6€0€/€R€ ֪€C`€€€€]€€xU€JZ€*kU0€4 €€Wt€€ |4€b€€€z€(#€#€€2q~k€X€€€€_€Kß… €$=!€`XK]v0€€+* € €€Ľ[€€ǹ€€*DQGyл€؆€bw€€€Z€r€]>€€0€p€€€€€=€ì€ȳ€EY€3V€й€€w €H'€€€$€qME€Þ€€€t€5€€zߤ{€€/K64w€€€€ [€'ne€% Ì€€d€$7Z€-€€?€€緺^€€>[:€Z€[;€€{(€nJ€€€ؤ€€€€L€ €;ݠ€d7( [€V€€~€€€€zv€59€(˩€€p€K€€ €*€ Þ±B€X€€v€€P=€€2y€w€l[€]V€zO€KWq€Ͳ€€€€€?€€€>2nչ€w€JT€€€€d€€X|Z€<€+,"}€€B€€€€Ri€€€€€€€€€U_€€€(^A€H€€
+€€€DNY€€U€M8u€Zk€Ù“):{€ȫ€2€P€€*Dq"€€L+€[c€-€€€€ɑ€9€2W€€5€€€€€€€€€€"ã·¦S$0€€€€ €"€€€€:
+€.B6e€B€W€Ju€€I€t€€g€€€2€,€€F€b9*v$€x€@v1€€€€ ",#€€€€€"€:€€€€€€*4€Fw_Xv€€|€'€D€€`II€|€€_·E€€p€H-(€€.€,€ٱ€€€€€€pk€7]HU|€X€€€€|YAp+W€I€€€€€G€G€]\~q€€2€€r6€€*+(€€€"€€€,€€G€€€6i€f€Z[bE€€€€€€€+eu€W bV€€€5.~€¡'J€€9Z€€€€€9€€€€,€€|€€\?\yM€rÕ€G€€€€€€€/Ǔ€€€`~€s€€€WT€€eÙˆz€€€€€€d€ €€€€€[€(€K€€:€"[€k€€V6€\€€€€€€}u€j|€€€]€€€€€€%]q€€€(€€wUS €u€=€€]€€I€€c'}€u€€€5€€ӹ6f€€o€€€€Pv€€v€jaq€€.€m€€€€.t€D€|€
+€,€☯+D€:€€€€ͷ€;>€3W€<o€G3€&8€€€tO€€~Q€dž€€€DD€€@€€Qu€.€€€€€ֺ梠€fo€ts€€€€€€€€['€€€6!€p€€]€€CO€€맢€Ҳ€€(€€€€[€T€ €ACJ€^g2c,€Pn€€€[W€%€€€€€$€zТ€€€/Ù®€z]ag!k€€{€€2tk€€!€0.€n.€u€€€y⮸.~Ú¶[€,dY€@€€€E€€€ۙ€€€IÉ»l:€€€w+€5v+9€€.FQm€l€€€€€
+€d€l.€ €€e€€e6€<€u€,+M€"€€#{7€€4Ê aI92Q€}n€&€l€€€'€€-J€m€]€dk€€S€]^€€€Î€€€$~€(€T€ԗ€€;J=u€€€€€€W€€T\W€ €s
+g<€€'€€D€€€m€
+€€€€ZWT<tƽZ€{֢ƞF€€€€€€€Ѿ€€€€˫€€;Z[€€€€€€€€€o€yn+|G€€€۔€€
+€€€e€€{Dz[
+€€€]€€€€€;J€/dw&€€€o€€D€€€]&|€€Z€;€€>€€cWv€mE€7€ճ€€€v€<Tt€€€€c€=8€€7€op€€€€"€p€*@UJB€€/€Qq;EW'€呀w€€1€€€C€€€€€w_€€sqcC€B€€€@€€€1ž€€O€€%Æ·j]€k€.5€€C€€ €€s3€۩>€*€€~B€€2€C€€€H€|y€€z€€€€€TWYÕ€€€*)€tx€7€O1_€€o€€€7€H 7U€&T€€€€(€€G€€€€€€€€/(鹨€€€g€c€]B€[A+Û…~ۮ4€,€n€€€€Ò¬[.€Zr€;€€€X€€€r€€U€€g_€€€€A€€€€€O-<k€€€o€€€E`}v€s€;€€[P€€€?€A€€€€€r€€€۔€€5€€€€$€|€€€€€R€V7:ppG€€ZXLT]€Swg]e€€f#Þ£\€€€D€AEËŠW€€€ȫiPy€4€g€!€€€Z€€€€u€u€€;€€e
+E€Ң€€€€`€W€€€€€€€ԙ€€L7€€€x}€f€m€z€:&۬€€€]€Uf€€€C€d.€Q€€x€€€€pUo~h€€ݴ€'€G€€e€€€n€€P]€€O €;€-z€m€Z€€K€€€D!€€€€€v
+€[^€K_]€Lu(€€€€Rw€€v€€€€€A€pL€V/€\U]c*q€cT€€T€^ۊ€5€€J €t€€€€€€cTj+€\QN1_~€u€Q0€€9€€€€€|€€€M€€€U€€-R€€€€*€€€€4w €Uv!վ€k€€€€2€€2€€€€€€R€€€€€^d0"€z4n€:x€€o€€^j€k €
+€O€2GÏsX€€€€+z€€U€€ €€\bqE€€ €.€W€€€€€Z€(€€€€(€€z€s€€Q€,ugf€€RG€'n€_8€h€€a|g€ €+z€% sE€ί€€€~€J€Sښ€L€7;>€€€€€€)€| €ľܬ€Y€€A€€€€ O€€€€€P%]€X€€€€7ح€€?ݖ€€€6€+}€€P€^€2€€€z3€€&€€€/€i€€C€pkÉa€€€€€ihq€:€€€€€€€m€,LtT€<€€ާ€>€d€€}€€€uL€3€€*€€€€b٥€?(/€€€€.€€QU€(:€A€ tY€€€ €2€€.heE€g`AQ€€+€€€5D€€ s€€"3€€€2€|€&w€1S5€`€(€ €€цNc \€d€BO€`€~_E€J€-ßµHL€€Z€€€VM€./]Z^ZV€€€€€€
+€/2@€c€l€€€€{€ex€Y€€\{€€e€P€€P€w€€JO€€î…Žsđ€>€<€€Fb€kɵ€Û€D9\€€€ª€B€ €iU€kϭ€€ҕ[d€I€y€€€[€€2-\V]sQʽ[s€s€€€€€e€€€€€Ò€€Ҫ/Yn€€€€€€€p€f€m€€€}€<'€€=€€€€€€€#€ϔ€€s€\€€\֥€1€W&€ٿ€€¤m€U€€€* EY€]^c€€G<€Y€€z€Y€QR€€C€€€€XJ_O;€t€€W|n€(€OWU€€€P|B1€2€8€^€€Ӷ€|€83€2ʻ€€P€po€tx7פ€W6"€ €/€€!3d€€k2€€(€€6€€€€€€€O€u_€/€€€€€€A77€€€w!o~€ €€_€"t€€-€€!€€@€q_€€<€€€v^€,U€€€}€€1€k€€€!€z9€n€€!€ᬻ}€ѻ€^€>WU€ZÄ™vqS€€T€DZ€E€€ G€ UHo€ €€' €€€€€qcsWgg€€€<$M[&€€`€€.✓€=€€~€cv€ €€ċԯ€€€€€€]€€:€€€€>€Sv€€€$#€JY€7ͭ€€y{€€a€IY%€€$€Wm6g€eU{}€3PWY |€€QaŽ€€€e€€€{€€€€€9v#:€p€€~€€{€€€€QFw€€€e€€f €v€€€€€€f€4€ €€)€ €€'€1€€€€_€€B€€2€€LNu€p€€)€€€56=cK€q~€€€I€€€€€0Jj€€€€€o)}c€l€Vt€v~M€ܨRC€ €`]€o €{
+|W€w€o-€€€hFo€€€o€;H€m€o~(€\€€jÏ“J€€€€)[€€€€€i€€R€€€€€€€€WaG€w}€€€ֆ€€ֆfÌ”yZ€z€n,€€€c€€I€€zA€€S@€ۓ€€O€{€MB_€€j€J€€)€€H€9iÖŠ €€1?€€B~?€лH3sz€€l€vq€;€€€E€€%€s[€C€€€ݛ€€s"Yׅ€€O€€€g€€€€€€€€€̗€€vn€€€€h€€€€.€dG€€€€€€€0[€{W€€€€hQ€€€ڳ€€€€9IV€b'€€tgp€€€j€ޫ€€€€>g €9Q€€N€€€€€"pB€1€€c&€€xÄ‘R€.q€{€€݄€€€U*€€€&€€€a-C}+{)€€*€J€€€€O€€€ҔW€-€€€ G€€€W€Q柊€97K€€€Gs€€€M~1 3€`_€}i€€€
+Ê—<€t€€+.€Vr|漯€€1L€€€€€7b s€K9€u€+Ù²3d]€tB€€€~F㙇€€& €€+€R6:€z"€€€W€"N€W€€€\€P=€o€€{4€€€g|€€€€€€€€_€T€_D€Seh=dha€€€FE€€ €_€OÓ¿J|~€:€S€€V€€>f€B€€y€Tz]m€JϢ€€(€w€b€<U;('!Ô“€>€€C€€
+€€Rmk€€€€!тޔ
+€€0.+wru€€€€{s€€
+86€€€[,ޞV߲€€€p€€dF€€€€9€€€r€€8€€ €W€€6(€€/€€€5€<8€k
+€rG€€€l€€€€€€€€€€€€€)M€D€I€`c c€~€!€X!w€€Ú-
+€SÞž9€€Jgl<€;}_p0€ *€q O€q€€€k€€€€€€€E€€$€>w|]10€€€L €v€{C€€}q€€€ € €€y€0€€€€*€{@ @€C€€€P€C0ێ€ZT€€€5€2€€W€-_^ȋ€€=€€U€€€€€€<€OS>€€<xR€-T€€€'€€€€€€€^€l€€€€:€媪€0€€€I€7P€€wr€€2b€oj€&€ԗ€x€H€R"€q]e €€€*€€€<8"€mGW€€€#€€NU:r€V€s€€!S€cՂʑ€k€€€;€€*€€€mh€p €6(f€H€€qnpe€:(€€)€€z€€8€€_R€"H€€vH€%f€€€€€z -€€€4€€€: r€6€n€€÷€[€^€|€"x€€€€€ €€H€€€€€6€Jj€€+Y€€€€c€E€!m€€Ír89€€ €€€H€yG3€€w8€D€€W€€€€i*\/'Ò°4€€€W€q €€>€€€V€€€€€[€(€€b€€€dq"C€€€€串€€€ߋB€S€€€ ~''e€w€h€€€ €}SOQT|€`F.€€[€N]€o€5Юu€%€lq€€€€€€€+Ù¿_æ ¯*€l€7€{ù€€€€”U€€€€€€;€ €€€3L€€€€€5€€ڕx€;E€€Zh~As€€€€>g$€€€€€K8€€W €€-€٬e)#€€€€_€ۑ€€€€€"€_X€CE€€,€t.€[€€€€ €€€,wC€€#€€€xL €SNI€€€H€Ο€€€€ș€€€t€€€3€a€h€dž€Bx€:€-€€ €Z€VÊ›;€€A€6UG2CsLC€:€€€9n€W€ €\Å’=A€W€G(€€€€€Nt1€€@wq€€€T€€R€€€€€€€€`V]€€9=€@€€4(€e%€€[€€€K€)€€Y€_€4i/€oue*€€€ɩ€ €€€€€n6M|7R€€€Q]€'O5€€€Y€`V&€€2€u`€€€€€F €€€€€€€€€j€|[€€s€x€&€€dG€€€€€€€€C€€v€Ôn€& j€pov3wQ€€€LKw€€€A€€€ €€Lm€Y}€€€+6€UE€rK€€€€\€€€M€€ €€€€8K€_€€
+M7€(€€€€[:€€VIU"'€inf€€€ϗ3Hp€€€ g [a*€&`€€}€€%bv9fj€€9q5vO2~-.€€+_W€bu€e<€€f€U€€€€€€-7€z€(4€VB€€€UGE€T€€€+ T€€R6€€€€t€>€€b€*€€[L€€R<€R€;€"0€se€€€4€€€€R€9-€{77\€€D{z€;Õʞ€€r€€
+€€`€o€Ou€d€nUS€€€q€€L3€€€e€€ €€€u€Uy€€T€€f€€€c>P€€Βs€€-€€V€Mܯח-€@€€€!€€G@€ވ€€M˨€€€€i€€6€S€€\€J€u€€.€€€€€€€t€€€*€€€€€zI€Q€ €€€€báš»}M€€B\`!€KO€Շ€€1 -€€>;€c?x€K=7€j5U€€8(€ܚWl€€_€€€€€€€€€j€€€wn€€€y€?x€5'€A!€?€€&w€hp€-€€€)'€<G€'%€€€€ €€€€€hG€€€I€t€̹€0m@x€r€(ʬ8$€2€€J-.€Û€z€P€/F€€€_"}€O€€€-€o€€€€€3€"H|* i€€'€~€€m€z<y4€€€€€€€€€1€€5Ò¯e}€€€ք€f€"€E)8<€€€€4€€€€}€€€€"Wf€*ET€^€€€S-€S€j€ʵ€z€€€€€€0Ë°`Ǭ`€cL Ƴߤe€9€;R€S€/qe€€€3€:n€B_€€€JK€€€€€h*€Q€€N,€€€€a9€G€€€k €€€T€€*€€€€€M߇€;P€€€€{€t€_€€*'€€€€q€€iA€m(€J€€ €€€€
+€r#€H_F€€G€€€kÛ³u€€€€€gG^€y}b$€c4#[674€:fR€"€€b€K€€€b6€€ZLÇ—^\€€A€€€Z€uX,€/7€€€€€€€_€€€_€D-€€k€€€×€€€b|€€€€€€J|}J€€€I€_&
+€€C1 _€:|€H€€ 1_o€ €€€—U€€W€€€€!1€€€寢3;€]€€€/L€*€ࡹ€€窹<Ï°3s€€€^€i€!&€€N€t=€ €€!s=€T€€iR€HU€€?׀€J€€&€ƾ€€€4%l€:€D4Þª*€Ρ€€€€€s€€.€q€€b€€€€EbÖ¨1€€€&b€Ԙ€#1€€"fQ$€€€€€€ cq€D=<I3€n€h=O€€€€8€[€Y€yj€€g&j€9\€,€ļ€€,€€€|€(€O€€€G4€€z5 €B1€€€z~€€ƔFbR€€€Ì€y€
+1€Dbr'j€€€h€p€D€5€€;Óh€<C€€U€k€ G€R€@€€4m€€€w€D!€€jqW€€€€bweꖾ€€&"2€+f€€€AN€#€͖>€&€€€€;€b€
+€€€€€헚9€X€€€L€1<€߽SU€€€0€€ًk/S€z`€.€€€€v8α€€}€5€TL\€[€^€|)<€€=V€9G€.€€€*€€€€€SnI€f€M`X€€+p g m€j€*py€€€€aR5S€€m€€€#€€%€€9€uR€ױʮ€€€y
+€S]€q#€€/€€€`gE€x0€€2€`€€€6€€€*€} €]€SÛƒ€€€€€€Y€S€€€*€,€€]"€€€ Oh€r€€€€€5p€"€ 9y€ ,U+!€&w€€€€Ƌ4€)€€€t€Z€y€e?Ü;€W€/€i€h~$O`?€V€€€€€n€r&#€3€Ì€€€€]l€ņ€-€b*€€6mjD€€€€^ͱ€€€€€%R=C€L€ €1@€€€s€j€€cȘռֳ€y€€4€€\€€%€€€D€E€€H€€X2 €d8€€€J€x4€€I€U€€ēF1€€h[€€,=^e*o€R'€€r€޶[€€@XwC'-€€nT€€^1IXιdxV-€h€|€B+€€ €p9M€9€€9€€;Cy€€ €€53O€ܬ€NNr%€z×Ά€€J;/R€8YC€€€s€€€€€€Rto€€€€{U€€€M€€ "€"€@€;€\€?D&4€I€hߎ"€1€€€€€€j€€=€€€€p€c€j[€B€€E€ oc€€0nز€€^€w€€ug€©€€€C€/€p€W€€"€U69€M2o€:€Úž`S€5€݄56€%€8 D€g€nj}€€€4u€€A€0B-€ujH€%€€J€€€€€7>€
+€€€s€€Cy€5K€€T€€€i€;O€€d€€ -j&€ ?€€W€=y f€F:a,€€€€O€xR€€V€?W€N€€KX_€t€€#€€€€€-<€[€€X|QG €O€"€€€€X6€€ Ւ€€w€€€€R€€€]€3Í¡n€€ €€&€B€3€˨'€€€3€{(Κ}€Ygx,€ €N €€€J€€€€€€€€Է;0€€€€ €€€€Bۗ€*€#٠€c€€0g,€€€P4€fy&€€€€€€;€€#€€€€Z€€€€1{€w€€€cՔ€€]€€€M€€€x€€Ywo€€<w€q6€€c€#vx€f <T€ԣ€€ٵR€€z7€€0€€ €2€€XT€f€X€€D0.T€€m€€C€€€€€€€Y(€€€7b7€€€U8{z€D€€T€€€l Fz€%b_R€€€€Y9€€€~€€ۖ€€€/cz/€#b€]€W€|€€< €€€€K<+€€€o^€{€)€ag,€€€0m;o0O€€€w€8Ò¶@S€ӿN€€#€€€€e€(r€b€x€€@[X€€[€€T€€€_€€0Gս͒CÔ­*a€€€ €=€€€ē?R€>€UÚ°[Õ²>€@g~€%#j€"€T€€d€G€?jL€n€€Ur€B€#€j€NUcJÜ–Z€€ք€:€€5€€x^€pqUW€c€€€€€€ €D`€̷€€a€€붭W+€164€,P:€*€#s€€s€€€€~$g)€€€Pa€€€'O€€J€u~>€t ts€u€Qϙ€GEM€J€'€ €h+€\M€$€€rZ€t€€C€€€€>P€q€IBo%€€E€€€€y~D€H€€€V€€0€€€€F`a*€8€c€€"€aEH€'€a€/€€f€€ Ú¾U€€€€€€{€€P€€h€G0€€€ӯ€@€€€+€€€€€)€€v€€B€€{óC*BC€€3€€[
+€€…€€€y5€n>€T€€}€€+]+€€=€O_ʱK€͒i'€8I[/B€€h€€(O€+#m€€)€DŽ€Ob€2€}€pH €€€i!€€ k[€m€+€€R€€€€^€ٗ€BI\€8€ү€.W€!€€f4€€u
+€€J€w"€€ڵ€Bo€ݷ€D€€%€N@_dž€&€€G€=€|€'€€€€D€]È·~"{€€€/€€€€[€&€€€€o€D>€€€€€€€&€€€€€=:€€€€L€€€€<€O€€€YC€€€€ʉlr€€h€G]E€€9€€€€Ko3c€€`€€€€!o€€€€`€T€=€€€€7xO€W€€€€\puZ5G€€€iF€€ϳ΃€€fB€׈€€*€Yް€€€€T€C€€€y^*€Z;€€€R€€€€(€*-€€T€€
+€€f€)nv€€;B^€€\Wh€€€€æºF[€€€€€|€€€j€€ke€Zn€;€Px€?3T€nR€c€€€/€€€'€]€x+*€-€€€€(€H€€R€€Aw€X€€B_€)€€€€€~€€€^m8€n€€€
+x€€€S€KuC€€€€€€€ZQOJV[dD€J€€+€y€p€€g€n€€ޗl€t€`€€V€€€P€€ t€m€€>€l_1€=k€€€€x€#O€€€J€€€r w€;€€€O"€TB€€k€M7QT$"#€;€€€€aNs€€<€5/€ _1ȓ€€,€€€̅%€
+€€ €c€>€̠mϹ€€€€€€€Ek€ԩx €€€]€"€n-€€€T€€<€g€[€
+€~€ʹ€€x€€M€€[<€v€x €€Vc~)€€"-€€*4€€F2c€.ª€€€€^€€'€€€€l€a€€€€N€(Q>€ѯ€€^lB€€€7O€€€€€€22€€€€€$mзa€€Q€€€€0#~€-€€ €€l€W%€q€€€Eo€r`gttÊg€€i€€ٶv8€€J";€JF6Xig€{€€p€€I€@3h줾€nK{ε€'N€€r€^€€3€<-€[s€Y€€€€d*6qE€€€i€B€/€:C€-Ll"T€€€€€€€€9L€9€I€€€,€€€€€Q€€€BÞ“€$l?O€€€€x:u€;€>€€m€€€i€€kk~5€7€@_€€T G€€Iâ”±5[€[M€€€3€€€€q5B2€€_u3o€€f€€€alG+€€Õ€€€€€€!€t?z_ØŸb€€€9€€€{f _(@q€f€k€€€)nË€r€p€€$XÒ–OH€€P_€€P€F€8€€?K€€€€=€€R0+€€€€k€G€€€€l€€$n€M€`€€QN)€€r€Q#€€€3€3€4€€/€€€€€€}P#€_gd€-u<€€€€€e€0bO1k€€€€YK€Ì4({€€€€€]y€f)P€#TL€Q€€€€€€€€[€€€€€€r€€Ep€S="€>B8Gxk€€M€€€U €€€€)ڥ€€`A€36K€€€€-?€/€€€l€€kf9v€€Z€'€€
+=€60€€€G€ə€
+W€ €߷€€kpq€€€€€Ö¸B郌€Ͽ€c€9$c€,€lL€\€€€€`€€A€€r€0€Ѐ€€€;_€€€€J€]€/€€€€O7€€€7jwh€2€h3€{€|€9€€€€A.€4€eb€€]€r€€&B€G€-PBȭ€ڬMٌ€€x€H€€€y&4€@€.€OLOC]€Oo€.æx AO€€,Ö‚_€€€€€4€€€v€€#W6€€€3€w€c#€€Ov€ €]€€Gæ±µm:me€€€2€€ay€;<€€3€c€{d€€mV€/€Í€€ _€n€€" "s€€2€€<v€€€€6€ €€78€O€€vt€ۆ€€€K€€€n€€€€€'€€-oq€€ €€I€€€€!ֶ€€€€€€f€RHű€-€1€€/€^D|€Ωf€€q€O)€€€΀w7]t€€€7ӆ€X€€€iB€€\I€€.€?:]€€€
+c8€96_.Ğ€€€€s€€€€€€3fG€€€&Ǒ#€t€8 o€;€&€€€ ͼ€€_h€€€€€€D€6Sq€S€€&€1€*v€€r€€8€€€€3€꼀Z)€Cf€€=€€Z€€M€@€
+q€€s
+€€@€ޭ€H1V!\ܬI€€z:R€(s€'€€€€ >€€€€>€€?€^?€€€x€€€€€€'€€€%Zi€-s€ ^6|€€€€€€bO€€ l€T€€€V€ո€ €~€€€/€€u&]€._W€€й0€v€€s€m€€€€t/€€€€€T}€~€ީ€€{€€m€€€€w€€׿€2€ ن€€ņ:€J€:€͆€€ €€5€5 €€€|€€€Ⱦ€_€g$7N€€€1a€]k€€€Ԉ8€€H{8€€€€€\=€€€€P€€€€€G|€"Þ€[2€€€ €R€€sDxo/€k€9€$#hC€€r€HF€€7€äŒÂ€Ý­Â€o€€€2"€#€€€€€€€;€"€€sDx+€€€€€7€€€€€€[€€u€'G€€€"€!w€€€€€;€o€T#Vs€€S#hO€€€€W€€€ު€F€9B€փ#h€€€€q€€€€7€}€€€€€€€€€j€€8€€R€x€#€€D<€€t=G€€u€#€€€W#n€€[€€ro€R#€(€M€]P#xϛ€.$€€€€7#€€€ hoF€C€€€o€€W#X€)g€8B r€€3BF€€€Ո€8€€f€Úž=€€:€€_€€€€€d€€€H€€s €€o€C€t}€€€€€;€€~su€€€€€0€€€{€G€€€€ €€M׃o€[€€M׃o€֧w9€C€€q4€€€[:€€€̣z€€Þ€€€€€=€B€€p€l€€G]DS€}€€€€-M€i€j€#€sh \€€i€bh€JT€€€Y湊Cyy€€%€w"€€2O~€€o€€g>€€€z۳€;o6€9vmF€w0b_5v€VÕ2€€€€EC€]€€+Q€Q'€湜€€Ok€€€€€:€rË/€wl€€€€€€€Ю0€€€{i€Ux€ƚXL€€D"⟨ €ZÌ»ÖÞ’È®u€€€€€€€€€&5d6}7Ðmk€€~E €b€k(€EfW\m€W€€0€€€[.€M_€v?€pl€€€2 o€€€X n€€€€p€f€kxƇ'€0€€€€C2v~1/€/€€<€€€€€€€̱€d€€[x€€_€޹€>€€&€PF]€m€ۿh€Z&Ɏ€€€€€€€Fe€[:W€6€z[Z€4z€N~€+W€€Jm€€€€€d1€i€6Ϡ€€JRYB€€€€€€€€7€V€€7>€€)€v€i€€€O€6€&€-€€€VV%€€€W€€Ys€€€€g€€€€€ =€w)€€7€€€0€^\ €h"€zܶ]€€€ʰi€€€€€€€€ (2 €*€€#€€€€ƶc€€u € W9€€mÞ³A€€€rK€€P€€€€]€鷟T€€€U€CWI}9M€T-n€€pN€v€€ €€€Ŏ'€MZ€B€€A€€h€8€+G€€€€~d€7€€€`k€<\€€As€€[U K€0U€€
+t?€r€€€€9€€€€U€ε€€€€€€
+?€€!€t€*€€雉€H€SE3G€€I€€;f€fGP€=€€:€€€€c*€p€€7€HaES€o€v€€i€€G €1€€1O8€X€T€ €gU€'€]€€€€^€M€֖€€€$€H3€€Qe/€€€€€L$€€}€€A€+z€€€€€:€9|wPE€<€€{CG7k€€€€€Þ®AS€€>€I€$€Vu/'€€f€9€M€€€€€€€-n^€€€W€A€€€&L€€€ b€+f€€€€€8K€€€€€€KUZDZ€€н€Yy14€€,€€<S€>€€€6€€/M€o{Z€h{€€€€ €>€€j€m€€L€€€4€q7€€a€z%M€€0$"€€ƹ€€͹€C€€TV3
+x)€€€%;€4߀€zu€€n€-€@!€€A\€H€b#~€ȑYY[_€/€r€€^€:€€€€y~€€Mt€ꋤ€€€€Q€€p€·+~\€/Z€z€p€€€ҽh€€€H€€€€A€׻€€}n€€€ {FBx€m/L€}b€8^€€€C€S€}€O€€€q€€€`'€ O€€X=€€€€€ZP€€9èѾ€a€b€4€N/€:€€'€€"€€€€€€€j€9?€€v€€S€0SP€€€€€N€€ S`€€=€€€s'€q€#C€x€Q<Q;€€C€€e€>€3€H€زqE€h€a€€ÙG^€s€tP2€ €€€€~Q#€#(€FP€€wP€KÔ…YJ€€w€9n€€ #€LɎ€
+€€8Ȼz5֌0K€IfA€€?;R}€€|€€€l€ԥ€€€€(€<z€}€h€€€€€€a4g€€€€€€€7F;€r€€6€ٴ€lDA€iok€O|€€r€€hUˣ€€t€€V€€V€YU€'€€€€sy€{€€€€€f€}_3$€€#€€€ Ͱlp€€,€€€*g€WN€Jq€Wxd€W€€€1I€H€€̖E€o€€q€K€€QV€€€€'€#€d€`ƓPG€€ڈư€q{K€€r€ڇƑ€€@€€Q€(€€7+
+B€€€€VS0€€"€€M&!|CZ#€€€€H€€{L}€D€€G€{€€€€W€€€(€€Sʲ€.€y€0€Jd€€€ >ã©¥ m€rÒµ€;€€Rfo€o€R€€'€V€€€€€΄><€̪€€€3€NЙg€Ȥ€€3/ +j€Ę€WbijU€-'€€e€#U%€€K€.€-ha€{€€€F'€X€€€A踿T€,'€9-B€€€#€G€wtE:]{c€€{€]€8][e€B€€€€€SpY€€€>€*TM€ +T€t€€~€Py.R€<+p€€€PpgEz€€€€B€c€€€€€€€ €aK€€€€t€€:€qæ‚*€<€ €Ո€HdF€€~L€^€8€:€l{€ €{E€€€>€<€€€ €€<A7USg€v€€:€€Ah€q€€v€15€+S"€gy€W€€€%a|€€€z€€S€N€!€1$O€€=€[.>bÈ©€z€!€t{€€€>€cR|Ș|€€€<'€/€€€€㌹€€€u€i€:€C€€j€€€%€`PL€z€8€:€€;'€o€Sx€€€€C€[€€u[€€kf€1€j€3€€€€€.€€ţ€€€€|kހ€>€€€€5€N€}€S#Dܣ€ €T}€8 €€€€#{€ _€o€€1€*€Ԭ€€€€s€€J€o<€€U4€€€€€€8:uQ4>A€~€䞚Z€8€N€?c€€€|q€€#€€€&€b€)€€8€€3€F€€€€€y€€A€€€-4x€€Q48€€€ˆ€€P€C.ۢ€€€1€v?€%€M5€€I€€€€€€€,x€€€€hLL€€€ €B€wfhf€€"f€€C€
+€€€ €.(W5Ú©Y㼑€€Â€€T€€c€7fE€8€ €€€ͽ€`€%€€€€]€€€€I€€€;€7€uFٚ€Έ€D€&yx€€€€c€€€€G;€o€P;€w霚ݙ€€8/€€€€€Ҩ€=€€翅+€tQq€ܿ€Z€€
+€€€€ݧ-€€co€€€"€€€€€€€k€€X0€t׋€6€0€€€€€7€€ܓ€€zQT€€€€€A€€€:€(€€_€€O*b€€IŒ€€B€€NLO€\€G€€q€{\€€€€T€K€€r€€€€€€q!€€Am€S€_€~,R€qza€€S€u€€)€€€€€.€€€?Z€€qM=€€QV^#n€€7€|€$€`€b€€q€a€I€€ܼ€t€€e€?€|€Z9€€€€-€*€y€€€O€€ €€ϼ€̶€€€g€ €€€Ėc€€€€2€RD€€€.€@€o€€]S €€ny€ Oy1€'}
+€€€€K€€€K€5€€€j€%€Pe x|'€€F€?€4€w€€€€f€€4
+v€3j€:pB€€O€€ €€€5€E€*€w€€h€€€€€€€׎€€ €€oM€€z€oT#€€K€€€€OW€€q€€€€麶€€€€€G€€€€O€€€d€€€€€h€s:֧€€€g€yQ€{€[N€>݈w€€€E€€Q€?€-€€aP€ o€€€29b €0'X€cQ€w€€€7]€€€€€Xx€€€l€{&€€=tq€I€€X€€€X€€€€+€€€t€€€F€€€`a9 p?_€G€`€[| €?€€€=ð€€€€c€j܃€€F€€Ǧx€€€ €€"F€€5€€uT€y€ j€€2€o|€€€z€Qç•Â€Â€Â€Â€z'€€t€€€€€9t€€p€c€͜€€۔€|€€€|<€n€€€174i€ €€€ €4€s€€€s€€y€€~€€€€€€)€z€ܨ€€€€7€k€€€€€I€U€?
+€Wyr€€€(€€ €1€O€Ș€7€&@€k=Tu€g€€€€€€p
+Ϻ€3€9<€I€Eg€>€€€K~9€€€8€z€o€€€6€€€€€N€/)€€€€y<€€+€€43€}€^€E€j€6€€€#€€#€Ì¥D€?P7€€a€_€€b€7€|4€]s€ۡDgG€?€{€€]€D0€+=€er€6€€'€ge€u€i-v€€u€3€.€€ Lj/€€€€I€€0€c€€€€z€+€2€€QSt€€{=€€€€€[€~€€_~€€€
+€€€€€!p€/€€€€*€|+€€p€€€.8΀€N €€€€b€7€€€€€€V€qsU€W€s€€0j€v€€€a€A€€G{%€€)€2w€€€>€€GZ€€=€€€c;€&X劓€ €€€c€S€{€)#€€v€.€PaV o(€}€€€€ O(€5]€€^€€x€{x€?€L€€~€<+N€€€.qvt€€€)<€N? w€€Oá½Â€~€€€€,€ υ€€€€EP€€€€€D€€cO~€c€Ez€€€ py€€"=€€€€OD€€M€]W€€_ﺣ€€€~€Q€€>\€;|€%
+kF€€€€n€;=€n€€+N'€€U]RO€€€€€€g€ff€f€€ib€€€f€€€[:€a€€€ư€|€€>z1€G|W€€ €?€Y€<€>€FӢ€€€Y€-€€t€p€i€5oB€]€€o {G€€€€€n€€u€€6€%E€6€ €t  €WF€€€€uY€€€9€€|'€n€€5>2kb€Gn€8: €pr!Y€€€G€=6et€^שz€€€€{€€€rj<5u45€G€=6€~煉€€Q€€€F€€r€€;€t€€€S;€€€'€€€€€€ŷ€€<3€€*€€=v€€Vu€2€€€€€€€֯€€€Y€€€€}€rB:€€€.z€Y€€)4€#A€0€]€?€€€€€€€€€ €ΊοN€€€€6€€€€Ĝ€YtQ[€€€€S€€oM€€€€7€hbʶ]€[€N€bFt€€€€Xg€€z€:щS€€€€€€g€9FV~t€€t€)€US€O€€€€Q€€€€8"€+o€€&$!€E$h]{r€€S€ {€€8€^.€ң€€€
+ϡ€€zt€€€!3U€m€W€<€€
+€€€€o€€€€&€€€€h€€Ӭ€E€€€?#€€;€€€€T€€ި€€€€'Vb€t€€?€€w׫h€]I€€€€T€€?€-%€I€3€€€Q€€O€€wN€€3€€ÌŸP sN#€€€€S €€( €1€@7€€€@5€R€UCj€8R€IR€s6€ €w€T€m'6€€€~€'€9€R€@€€€€€=€€€ €€;€s€€Û¹S0€;€48€V€€ I€IH€€€[€€€€€€€€]uR1`€=)zuF€o\€5€€€F6€€<\€Y€F#€€o€€p€€€€€qUd€€߅€€5Z{€^€F€€€€€€€€5€€€€G+€'€€€€€L€€€9€4\€€S\€€0€0€6€+%€€€€€\€€+€i€€**€^x—M€€€8€€l€€H€€{2!€€€€€=D|A€|€€€;€{V€M~€€10Mp@€S.€€€1€sp€5:€8€€€1C€€ʌ€UB€€€T€€€;€3€֋Ί€€?€8]€ €€w+€€Ggw2>€€€€€€ܩ€€o€;€á€€|€€] €;€€€€€7€#W €t€b7€€Zì£w€€Ö8T€€]€€€€€€4€b€D_€€€€,€}]o€€€€€s€y?€€€€>€€7€€)BH€€v€ €€q€€€w€€€w€€z€W!€z?€€€!€€ĕ[€L|€h€€9€[%}€]NҦ€€€s€t€€€€€€€€€Fs€.T€€€€1€€€€O€S€€ {€2b€€/9€w€€$u€Q8€€€€'€€!€€€€€€€€<af€(€=[€Η€r€-€4n9{€[0€l €@!€q€€€€^q€[€xN[€€€ègD€€€ӎ€€[Cxßj€€Ñ€J€€hH€N€€€u€€*O€ €€€€€;€€€€F€8€3€m2=cW€y€TV€€€ʺ€€Ά€€G€I€€€;B€€A}T€€€߷€€€€He€€€€€׃׃€€ H|.€€q=€€€€€qo<E€q€€c€€ؚ€g.€Ý€p€atQ€?€ͷ€€{€€€€yF€€x€€€"€jd€€'T_€€€€\€9?€G^j€Փ€€k€F€€€M€€/€€'zs€€€u€#€޻€€~€o|a€K|I€€,€€€*€€T/€€ã®Â€g€€o;v+€`Df_WzHÞ K€€€€&z[€€€€/Q€N€€€ €€sD&€P}€
+Z€€9z€a_€€€€E€€lz7n€& €€/P€Vw€e€v7€€€rK€€€1G€€Gd~€Ï#N€€€€€€€€€K €€FH€€€€€7€€€7z€;{€n€r€€€n€€€€€Mtg1€ߢ€ߔ*k€,b€z€€N€Y"/€€r€€?^x(tY€€€€#€€€2€ €p€€GL€€7€€6€QT€^€2€€€€\@o€g€€xG€€€€d€ҧq€3€€€€eE€M€€*g€€€bj€€€}Y€€%€>z5€€€€€=DNA€v€€"G؇y€9r W€ W9€€ V€R€U€€/€j€J€+€€€€״€q€€_w€W"㓾€€€€t?*€€€SL~€bΨ篻€+€€€€€m€€}M€€€4€€m€>€€v€jVr€€€€b€/€5€€?€€L€n|€€W€
+€U€€l[ €€l0€ͣ€€€me€€€€=t€[(~€Rß¼|€€t€€u€€3~€m_ |H€€d€€€@#€€€;€1€€WRo€mϜ€€ը€€€€u€€€q€wT€€€€€:Hn#€€€€棺€€}]|5€!€€€ߢ€—SR€=€€c€P͵a.7=€W€Sf1J€€€€Z€€€€A)€€€>€n€€-%€€ć€€€€€€&€€€2€F€?€€LA€$€€Ї€€€€æžÂ€Â€Â€Â€Â€Â€$€€€€O€€€€$€1u€€o€€=€€I€€ܶb4€€€€`€€Ý€Ey_€}HÝ‚x€j€n€C€€€TS€ը€€~€։€€Pw€€V}'€€ը[XF€€€€,>]€bL€w€€N€€€€Z~€€ €€P:€W(Y€j€C€€€€Z€€5JÖ»>B)€€Qr2J€m#~€ €€€€€€W5€€vÀժS€/"€O€€€OP€€€S$€./
+€EWͻ €€€=€€€n>4K^€=€€€u7€€€L6|Q€St€€̂ә€€€*€€€ɀWJ€0€É€8€cA€€FL8€€€a€€€€€Ю€ !€€€2€嵊€€€
+?5€{1€€€8€h~€of4€€€€s|€г€0€€/€€€~2€^€&d€3€€+€߭€i \u€€o€8Σ(€€€€€€zq/€€Y€<Go€L{€€݂€€&;zC€€€€%€zp~€€i€€€€€€€h€F*F€)€€€U€€U€€€€€€mӖ€}T{€:€€:€€€€€€€W€€€_€(*€|€n€6€€6€€€€4€ߠk€€€€€€>€€€€€}€?€n;€Ag€€€n€n€€n€€ʧ€]Ӝ€jW€€€7€€€€€g€€€€€>€=r+€€z+€h€€拿€€€:!r€€€z€€h€€~]€€Ñj€\9€^9Z{€?€^€Q€€€€€Gk€€€€ Op5|€")uD|€#€€xV€<u9€€€€€T€€~@k€€€z}€h- €€L€€€sק^€v€€€s5€i€€€2€€-€€v7€€€€€W€2^Q€Ó }€V€€€€€ֲ€ķ€v€€€Zԛ€€T€iÞŸ{€W€c€€€f€g€€)€ռm^€€;XW€€y€xl€W!€€€€Q€€€3€€6€€ݡ€T€.€ėS€€e€Ú€_€r€N€ €€%€€€)€€]€>€€€€kP€M€\9#~|€€€B€N€9€)F5><€{€†€€€€!€{t€w€€€€€9ܼ€s€r67:€{€€€€€€€>€€€€y€W€€€€Aq€€$€'€€€€€€€€€€?ϮĿ7€ͺՠ€l^;€€D€Q€€P€^87{Ep€i4€€€S€Nut€€€€€€€€׹߻z{Z€cl€H€7€y++€F€=€z€d.€6€Gs€€€-|€€}#€]€€€}#aT€/€€ϥ€€ÜŸS5|€€Z€Z€€€€€6€€=€5a€z€€t€€€€€€€uuk€zw€€€o€J€€€€€€€€€€<+`€x€^a!€€€}]>€m€|)€€€€€dUV€€€€€yM€RW€{ 4C€€j€ 4€€€€],D€€5€€ҹ€€#v€€€€€?€,€€g <€€€?Pt€n1^€€M€€€E€b€€_€)D+€n€€&€€/€€\"X€N€2€7€3€€v€m氶€€€€Ӏ€€€€p€€gw€ J6\/€2_hL€q€d8€JG€€[€1e€€€€€c€`€€F€€ RD€7€f€€€€X€D€a€€€5€+Y€5b€-o€ɮ€p€p€?€.lF8€€€€€€€E€4 /g€€€€I€€€Y€ €€_€€/9U€<€€~€€€€€€,.T€q€€4o€€<Ch{€[€]€€C€B€€ 8}l3B얷€€Wg€€€'l[n€€ €y€€€*Ö¹x€€{€€x€€€,€A€€Pp,€̥T€(€€€€-.1€yLl €€T€ €€H€j0€]€€ܖ€Ö*Q€€E€g.\|€€دX\~y]€]\-€>€r€A;€€yӀq€^€€+V €I€€€k[€€1€>€3€€€7€*€€€€€€€=}€€mx?€p€€€€€QES>€Z€€€€>€€€€fW€>X€€ [€1€}5€K€7€€z{p_&9€€Ǝ{€€€U€,b€y€€€€س֯€€ۖ€1m€€€d€
+€u8_€€€€n€עֶ€€€€lP)€s2€Juuy:x€,F)€۱=x€€€€p€€`!€G€€~€{€€€€€(ݫ€€€€ZX€&€€U+#a'(€b€;+ئf€€€S_€ݩ€€1€€€:€€€€€e1€n€3Æ“€€€€Jɓ€*E€€_€€€€€€€ €kɃA€b€€/€€|€€/€C€A€=€€Z4f%€€€+5€<€ s%q€aÚ@€€:9€v€oᕱo€€€€X€Y€剷€€}€€€ W€€€€Q1WoV_o€ך͚€€(!nh%€€^€4€v€
+€* €€€€€xU€c€Z€U#€€U€€€u€-Ե€€Õ?€VȮ€D€€G!Z€€€€€on€fl€a-€{o?PX€r،€+€€F2€DX€€€€€rJt€9€MY$/k€€|*S .?€x!€Z€€€ €€€]Oz€s€Uq€
+€€€€€p€Y€€€eo€€1€€€eR{ à[€€!€€n€ <€-w|€€€i€O[ƹ€m€x€€|C€€ټLN€y€A€€_€7€ _g6€Ϳ€€€€€x€G€€~a€€%€€v$€ߩ€€€€F€€;€޼3€^B
+€€d0D€P€€G€-b€*n€€)-€€€9€g箳qUk€ȑ^€Mu€€Ѫ♠3€€€€€€€7€€-z€€€5€Tm $€€"€€Þ€QW€€a€s€€€€n€€ (v_>Ԥ€+c€€U€~€€€€€趮€<_€y€€€45€€Ҝ€€€€{€€€€€€€€€€[€€eWJw_z€€[€€Q€Y4€€€€€€€€7(€^€€€>"ݳ€€Ho€€€€€н€or€€^€z _q€€€€H_3:<€t€X€Y:vY€q<€€Q€C޲€€:€€nF€Ǚy€€;€-7@v€€f€GV€€€6/mV€€€x€€€€€)€o€€€Z€€€€€€zPM6€%84߯€H] €€9v€>€';€BEBFF€v€Ѻl€€€€1€A€€E˸€1€€€€ׇ€€€Is€€b€>€h€Q€€€€"€€M"f1;€~F€)€€#€€3r€c€€g€€€q&€€Qֈ€3€€G€=€€rU€€*€E€€€€€"'/Gj€€a€4€€r€€€€€€€€€€~o€€t€G8€aJD€€€;€€(€€NW€€ԓ€€Y?€B€€Y€€€€9n€€ޚT€)€p€€Y€6d7€k\€€€€N€€G"j€€Wr_€€>zw€€€€6e€€€L€€€^€6€€€€€g€€€€€€€€Yw€y€-7€Y€?!5€ް€€A€A€W€€g€€,\k€CY*ßX€?€5€€ €€wYU€҅jw2á§Â€@€€€€C€5U€€/€€€€he$v€I€€{Oo€Is€['t€7€€(j<1€€ٓY€X|$€Lϋ€€,y€O€3€€a€.€€j€€€9h€3€+€+$[jYvP€€~t€€g€€€m€€€€€€+€Y
+€d€€?%4}0<€s€gy€€€€€€€€€€_]%G€€€M€€€lڜ€€€€€€€^€硞o€€€y?€Yw€iyκ=Ò€4€€+€A€€=€A€€3€€€€a€{€€€€€3€c5€€ C€"€€€€€;€W€_֣€€€/ €_)€I€|{€€I€%in€)€&€€P€;9€֤€€{€€M€V€€k€0€B/€€5€€€j]V€3€€f>X~€| €€€€Jevƹ€€X€uE _€`_€€€€
+€0€*€+€6€€i!€EQ'r€;Oe€€€§€TI6€k€€€€€€]N8€€/€{Ä€€€Z€T€€€€€€ֆ€€€€3€m€rM€t1%42€[W)'{€PmoO€€€€N9Ù‹yT€€€€€€€€w€
+d€€€€€€"€€7 |3€€xKb>€€€Ǿ€€€€€€€€€€€€€€%€€2j€/{€€:€In{€€€VPT€3<€€€n€€c€S€ʹ͒€e€-€€*0)ß²):5uWdv€b€n€€€€J€SXӔ€Ь8x€C€€€€l€0€9և€€€€€€€€\€€1m€E€€{4€€B€ ~OU€€N€€K€Bb2€;!€e€€€€€€€€>wWW€€€€€€NO"€ >€€h€€€€L€€€ժε€€€c€}€€€€€!€J€€€4"€x€f€€&e€4Ý€/L"€€߮€ >€€€o€{€=-2Ñ€ Z€UU€̛€v^€€€"€q€-€€aw€€b€Z€z€X€i€€€.U€€€/€m€r1Ì›<€€c/)€€€€€€7€€Ôƒ€€.€u€#&.€€€Mm23€%|€€}€W€G=|€/⫤€_ |+vl€L€€€€€€ €_€€P€j€€€€%Mb_}€€{7|€t€€€€p€i€վ€ €%€p€€}`€€/€F3€€7C/W+U]€ Sy;€€ ͙€^€wZ9e€€X€o€~o€€v€€€€€€_€€'€Ct€*€=€!€dA€|€W€B€€UW€€€€€€€2ASz€€c€€yI€€~€€K€€X€€~~€Y€!€€€wÖŽCr€€€€Ó€P€€+h€€mr€ǿ*€€n€€€€is€€Q=%gq€O€€ږT€]€-`€€J€x/€6€|j€g
+)€€UUg€OFu €ӆK€€€€€€(€€g_Mn€w€€$€€€W€€€€O€€€=~ý_R€€Uh\€qH€€€ €*G€S€€;€€c€€E€€€}€€j+€€€*€€؈#uS€c€)€€1Γ€E €j€:k€|(y€€~€€U J€€€€4€€€€`€V€€8Jg€Í‚E#8/o€€€€S€Q€x€€R€€r€*€€€€l€€€S€€o €€HI€€€~€KJ€€€€M€[€ms}€€QyY€#]€孒€h.-€€`ˊ€J€<€€€!€oN€[ÞA>J€%o v€6€€€Óº!#€€(€€€d3ט€€\ $w_c€€€m€m^€*€"€t€€€fÌž*€%€€€
+€S€x€€€€c!_)€r':€€€€€€€€€ V€=QD€V€€€#.H€€V€
+;€€ €€€ v€d/WU=€Do€€€€€ji€€۽€)B€uU€€)B€€Bl€`€xbF€t€ЗC9M[€€3€€+G€$€\3€0€È\€€€€%g€p/Z€&€€I€w€€{€1O€€|'~€ս€€€n
+dYcx€{€?J€€€ €€=€€8€€€#€€€€9b€p€cͥ€k*Ù­\€[€^RQ €€&\ Xi€€ k%̬€€€€S€ €Z€€€i€2€խ~wG€UBl~€`0€ €|€€d€1Z€€Hf€€m€n0€€€ɉ€7€!€€`€9/€C€€d4X΢€€c,€ƚ FKL€!6f€!€k4€T_€€l§€o0€b€SP€V€وO€وx@€IA>€U€ o+Ä $€5YL€ 6 €#€€d€€€€c€11€€)€dBr €A€€€ Cl2U€€ zC€€ €M€ €Z&€€'cc€€l€*c€€2Q€"(€`L€€Ix€€i1€€`A€H€ €(-€€X€€h€€E%€)€€ €.Ȉ€€+€0€€2€€L€€E€€QgΉ€€c€€€€L€d1Z€€M€€€€شT€{€€€$2€€k€|@€€Ô q?€€&€|T€€€Ç­gH€€X€€d|€dR€c&Ì“€€€_€"€k€€€Y€S€>(€Ña0$Л €c4€€l€n-&6€#aA€ €€€|ByzlF€€ € Mo€cL`4€lx a1€€ 3j€8s|ɦ€€h€G€€€'3€0€€ތ€@€€b€L€€€(jZ€€f€Y€€ &ʈF5€€?€'€N€€1&€k&€D[
+È”T~*s€€_t €€€@€€ìm€€€7Y-F€Ùg€€(Q~@ C€€€`4€€LLc8€ "JAҴ€€€3€€S€٘€u€#R €€o€e$€€€P1€V€€€՘`IE€€OA€fRj€€bc€%€V€€h€€€€€€w,~€-6€-€€€w&€J€(€D$~€!€€E €€@9€؇ж€;€€Zl"€€`€K€€€I2€€€€€x€€Uw€€S 9,€ PXzl€h+C€'€€?€(€jN€O€€V€€€€L€s6Cf\L,ZӨ€h €"€}M€/€€_ԙ€F€O€€C€&yD€@̚€LZI€3~€u€)A€€€V5€€€x€%€l€€€?€% j € €€x€MR€€ű€€€`€€XNa2Q8€€ڬ€Xd€ €€R€eJ€3CA"!^€€o€€€TM€€(€ˆ$&€€C€(Y€€€€€c€U}f€"€€c(€€<€ Û”d€€]|ã‹U€ghM [€D€eӨ€c€#€0€ €oh€€(€/€j€€€€€K€Z€ַ€$€j€€€hf€€€nJY€kN€;Z€€9o\€€^€r€ ΀)9€K$@G€0€ʱ€k8€€€€L€€€p@(c$d<€Zc$€V€pV€€€€>"O€'€C{€&J5€€a€€h?€0€)€€f€€€P €S&k €ClR2'€.=V€€€6-€A€€a€@€€U€€€€€€ €0sO1BK€҉F€ 3€p%&€|€ń03€͉q€Ip€؅b€!€€ €€$5€̒€€Tz€€€€6&CBQi€eN€ak$>Y€€€P€ k4X€E€,€DÖ¹'€€€w€€YQ€X€/Q<B4&70€ &€€;R€€&€]€M€Ø,€3€€C€€€G€ f€o€€€€k€d€v€€€5T€€€H?€f€ €k^!tt€n€4€€€02X€€ €€€€D@oJ
+匟€o2>€vWK€^'€)€j€(€|€)Z-F€€€U€Of€@€€#€ZL€€b,q`[€)€€B€~bLi€wG€4€€$s€9E"€€cK€ͳ€kM匈€€€T€ €€€J€3€A€Y€Mc€‚:,p€€݃'p>€€H€\€K€=J€€b€€€a
+{ )`€a€4`' €^€€€€€S€€ȡ€Q€G€€б€€挧€€€$€€€Wz€€€€€€n€1ޤ€€€I €€7€(€€€€o(€)€ €€€€ €€G*X€z€€€9R;j?S€€錆)€€ߑU€€€€f'€J(€0aPi€€>Z€€€€€€€€W€€€€€€V€7e€H€nI$€€YÄ$p€€xy€V€€TX€€<7€€Ev€€€v&€`€€!jf€€$!?€!o€€PS<,B€€f€ǘb€€S3 2€€r€'€Yⱪ!€€P}€€€,s€ٔ€>w€€€b;b€
+R?~€€<Ùœ~uvR€€Scݵ€Y€€€7€€€€€E€Dsf€9€\€q€9€<€€€€&|'€s€f[=€€€€J-€ =€€€1[€€̸O€€€€€€oÙ}f€e€ki€€x€€€Miy'0€?91f€€DË…&Sѹ1€€f€€€I€€€O€k€€t€'gۦ€€€€€€߳€€r €€€€ €€ig~2eÒ™9YSΜ€€€b€d€g€Y€€j€g€%%€2i>€€" 6€NÊ´$€}6€ €€€€.€eN€4[€€€€<v=&€a€.€€€ O&€€1sR€€€u6"€€n)€€€;€R~€NZ(€.U€.€€
+€m€%ζLJ€€€Y€€&MLJiRJ"3Q:">>i>A;€€€>€6€/€`€€€€€€€€x/€€€€N
+'€ €ձ€)€Rh€€TJ€!€j€o<H€b€:d€E*€€wÌ{@€€ €€€ԇ€IM€K8:&€€€4€€€L€Q€%€€C}€1€ p(
+€_€4O€յ€<€0€$&FM€3€'As€€€€^€.€€€ N€€€Hk3€9fʤ€€0aB€K€€€bմg€€€€l€€
+ۊ€€ €€53€€̘€i|€€fF7}€€tM€€m€S>€€c€ojW€€€6Gь€Wr€>€8i€ն€€sgvL€M1Å›f€q€€dzJ€Ԕ匴€€WT}l€€€€شdk€d€€€ ߲€Y'%€L€€m5[€-g€K€L 6k€ͺ8)€r€LS€€€YgM€€1ϰ€€s€%3€€̒4€!?Õ–n^€€`€€sfÌ‚I€QgÉš43y€Ჸ€€€€€T(€€€!-Í’jI€4€€Y`&h€€iÌ’L€l€![X€]iz€€1)63ÃB€€€€г€q€€?€jtt +€3.*€€€€€^€?€M͟€^~€+€>€t@€€s€5v€€t€ɽ€w€)€/Lm€€X€€€(€o€€ug €|/L@€€€ €€€€€ €6,*€-]Z€€€ewa€x€€€.V€0É€€ӗ€b€8€]€€€[\€=€€2€€mAÄœ€€€€€€€钟€€€=P€€€€€€€€€€m€€€€[€€€€€w`€&q€W€Y€0y€€+ƣ€€€€k€^€h|€k +zm€€V€€€€y€H€L€€Û}€€€&€fn€U豮̵€€/€l€€L€€€L€7€€e€€"€€€€€€€€€€[k6€€GM€€֎€f€€€€€J€€€€€ɛ€>€€€€€j€8=[€|€ǔ€X€€€€. .}€c€€V€€V\\]Y€l€⋫€]cnU€€T!€o€€@@€hy€z €9lÑ¿kCj€€€M€€€€€€€€€h6-{€oZ€€€€sgä“?s€€€¢s€€7€c€>>€€_Xr€€€lᢋ/q,u^R~iEe€e€5€˖_^wÅŠO€€€WcSsK€€€־rUG€€€€;€€€€€W€€z€5€>€^€€\~qYUi€C\€€;6z€€B€€€z€€Sq€w€*S€ >+a€€€K€€€V€€€K€€€zl9Ӕ€.€€€€€€€ڭ4v`V€€Js[€€€€€m€€)€€€€[€€n€€€U€l€ink€z€€€€€p*€€ۂ€€nl€G€€€XtS€€ €دF€€€€q€WS€€€΂€€€€€U€rs€isk € €€w#€h€2€MAE€ C€ҋ)e€Ҩn€€u#€€€€€€Xl,%€€W€€€€€Ú€€C€€ _*€€€€€€€€€n€€€€6TY$W€W€5€€M€€Ԃ:€W+€€@"b€S€t€€W€R€}€€€=W+€k€[[€e€€{€W+-€- €$€[€V€€˯tB€4zZ€M€€€0]9€;€€x€r1€v57€€€€mTGw3€€{z;QU€BI€\!€€'@%'(€€€€)€€€€g\€€€€݂€h'%ت€fI'27K€€C€2€€€UԌ€€^oK€9 €+€€€€z€€V€)€€F?C€B€46a€€€sPCU€€m€€:Ki€K€€ݻ
+€ݾ€€<".€€(W€A€Tߢ€ڶ€€y€4vHf)€W+n;XiЋ€#€€€€ €€€€€W€6%€Ý€€€€5€\|€€€N>€€€ݶ€€i€2€o€҃B€€€€OPA€T>!;KF4€}€€€pM`€O(jW€6€€€€5ǫ€€€v]€€iG€€95n`& l9}T€ZW/€€€谕€€9€€€€€vv€€?€D€Me€€3€€€€D €€€}@€ݧ(Õ–MBx€tA€€€|€R€€€€€€€€&E€n_€€€ƪ€d€u7aoB€~׀€^€€€€k€€€€^Ų€ €F€€/€€Ó>€€€@€g€ €€€€Ͷߦ€{?ÃZ€Pp€€<d€N€K9ÖŒN€€Z€`B 6.ޚ€8ɖ€€€zF€€€33€ʜ25kT€€€€ķ€v€OxX€€*j€ €€€€€t€€J€€€€€€Ò¢(€@€ظ€€€€9€@Y€€€€m€+€€€yJQт€€]0€\06€€<=€€)€֞^€w2
+o€€€-]€h€€€€€€.oO€€€5 2Y€z€€=€֖3i€F€€€q€€€z€!€€I€€€nh€€€T€K€€f€LI€€€€6€L€€ڇ6w€ߠ€:€€n€€€€€]€-€€FCkGwkcoOW€€€€€^/€E`QDc€€n_€€€> t€OWOW
+€€"€€€x€o <€p)€€€€z€!€€€ HLA€㋹jV€€€€€€=L1€mFhNX Eiu_  €€I €[€€€$€€!€€€s€€€€HQ€€2R€ €Z€€€€€yt_€05€€€)€l9€8 €€i€P{P€3z€x€Rl€-Q€€€QR€€€l€€€W½E€€€ގ€3ÇŠ)€O*̷€€€{€r€x€€н,€€֤i€€€€€B€Ý€€d 5€€€(i"€@€+PF_€F€€€:€1€j€€]l?€€€7€N€8N|€a€€€€€p€€€€0V€€~€)€[€M€€N€H €€€T*€€ /,I€€/€€€€͞}á…³K€€g΄€07wݺ€€€!|{;€Z€€€g€P[%€€€€
+€€_€€1€v*€7^€€€€T€M€(€+€)€<[g`Ë¢ 6 €€V€€O<€€€6IG€€€€€-I€€€EÓ”E€,{€íªÂ€>u€ĜÜ€€5
+€$€d€R!€€ €€ m€€€4€€€2€z$Ìš;As€K8€€u€ €vt€z`k€€€€|P€>W€p{€€€Q4wt€€hÕ¶api~€L-€€€ҥ756€€€9€m€€€WeB€yZ[€{:{€€€€g€b而€€͡€ h€Ǝn &€֫€Oŀ€}~€8€Y€`XSݩ€€(-€€€€€酵€€€l€RA€€Z€€€€ӗ֋қڡ7E€;€€mkml€€€'€€wUF7t€O€2KD€ejJ€
+Y#ÝšLe€€[€n€p€€€z"€€€€iH €€vRS€)+WQ`=€";€,Y€D€€ €€&HIv€v"€€€6Y€%€€WH~\€€€€`g?€€€n€€€ੵ€€€
+
+€€Hjj~€€€Z€€€%c\€€ݲ`
+zB-pb€€]g€€ €)€é£Â€L€€€^(€€Y€b€>€㱣€׈O€€€€€€L?€zZ€t€m bN€=M€€€3€€€hí©¯Â€Â€Â€É€O€k>esP`}[€€v߹€€€€€B€WW€b€€€€€d€€6K3€€€€R€ZS>€€LEe]€Rn€€€€g€_z€€U€€€I€€€€<€€€%€€€€I€?{r}y€.€€F€€UI€€€\_U€€€€7€€€ӗrM>€€€X€€€€€€뗟Q_€Tԣ€€$€OO€_€€.J€€€6€€€Q_€€ €€fPe €Z€#€€€€€"€€ €€€€-€€€€€€:aB"€€DB€@uu€€mM]k€IU˚€\$€€R4Ĝ€Ó”K€€€€ €L€Ǝ€&€?€€J1€3€M€€^€€ €!?€E€-€o€,€6K€*€4IN€}L€C5&€(Ч€R€€&€€gR€ȵ€dh€u€Då—¬zj=€8€z€^€€€€€€j€?€~€€€\E}€€€€€p€€€€€€#N=€o€€I€)$€ €€~€€k€€€€W€5€€€€J€_mk€€€€H€€vy;hT$,€[€P- r€€€€_€W$€/€€€€€€€€€€A#$€€€@€€g€€r€UB۰€€T:{€€摼p€-€r1 !€9($€I.€€€T€€€l€4€€€5€h\d€l€d€€€€ €€rX€J0[€€{€]^H€ €Y€㩓꯰͕€€€€K€€B €$$j€'' 9€n[|ͧrN4€Jcc€€€qt€€€7iT€Ի€E}€*_€€R€€€a€€?€~5€vԣ€€€€€a€&€€6L€ €w €€R€€~]}}€€€€€€€€O€€D€€z€c€"€t€薎€€_` |€]€€€11/€€Jl%€€[€7€€€J€Dž€w}v} v €€o`€`€€€ؤX€€€E€+€€=€d08€€€€ؑwvC €€ 0
+€€€€7,€€€>Uu€€n€w€€€€n€€8€€`p€€€7€€€,€oH\\sE €@€ €€t_€ݕ€€oae€ ٩{L€€nO€€y$€EH€€U€€€€€tstوPt€€€€€€?€<8€19 €€0€€€€!€L€m€€G6€>€€Ռ €€€€€€€€€O€r€ӹyճ€]o
+€(€€€I€f€$|OJ€€%€R€€€]€€ȸ<uVU€G€;€€€<€ m€g€q3€€; €€€€€€jYQ€H€€€€a€€O€c€B€cM€€ €^l|€i^W h€€€TV€€6€€€€6€€XL€y 6o弖=€€€s€va€€k€i€€f€)€€Uvv€V€€€Ep€Uh€€qcv"o-e€€€€G€€[=m€€€a;c^€€@)€w€:iթ,€
+€m€€€€9o€Zur€j€^€€€-s€r€€€w€ba=€+€€€€J€€cR€€L€i€€€
+\v€]€€€€C€€ €€a\tkGp€Gq1€€1.€c€~€뮂(€~€bH.€\€€ €'k€€p~!€HtķUtL@€T+&#ns€<s0€l
+a€JX€€€€Zy€€$€kZ€ī] €M€€6_pËa€€.^€€r€:`pIv€Ϩ|€f}€€€n€z€'€€f€r€}\€€V€€€€€€ڻ€{€€2ê…¤t€€€€9€€6€€€f€€€ᩴCW€€^O€0€r€€€€~1€V€€ç·w(€€€J€w€€€w€€7,€oN€C€€Q7€B€<;g€€€€€€€\g€'}€k8€j1k€€܅€€^€€€€x€€r[€€€€tp€€(€k€€€N€€q€€.¾€€€€€ԩ€2€6Ó€€Bl€€€V<€€€€Z8޽€}sCf€€VV€Ìd€B€€(€c€n U€*€̴€;T€*=€€;€]d€;€W€€€ci€K!€€u11€€}€^€|€q€ .€€€€b€€|ڬ€7ަ€o€xKF€€€€€€€4y€C€@€€R€€#€€€y€-@€€p<€ žF€~€ڂA;€J€£€€b€€g€€M€€)€€€06IWo~ds€€€z€è—€€€]€%z €€€€V^€€]€L\h^/€€€€€`n€€€|€€€€.€€~l€€e€€€_7€€€€u=€_€€€W€€€=€v݀€*€€€€€U€/_€W9~€!€€E€€€7S€€€T€ڀ€4€€€]€€Z€>€€^€€jZ€€€r€ɵ1€€g€€€€\€€.€€X€€€FW€€W€z€kr€C€9€.X€€€_€€€]€€€^?€5€2€Ov€!6€€Ou€!Ö„o€€T€\6€€€€€€€WY_>€€Z€J€€ €€z9q€I€€=[t'€Ρ€€N€€€#
+€€Ov€€€^v€5.7€€€ €€v`€_qK€€€€€ €€M]qJ€bÚª(VW€b€€€َ€€s€^€€€G€D€<<€€€S€[€€€R€€€€F€€€€K_€€'O5 €:€€€^€€€€li€€€e> €'Ea€€d#$f€]€€€€€t[€€€€€ݧ֢*€€6t€75,€€€m€]Ò€€€€€!?€,|€ ~€€Ƒ"€€€€€ۙ`€5_~€€Ղb;6=€Ҡ€S€€€€_+€H}€~ €€l_~€€R€€_€L
+€RnR(€ص€.€rM-6w€€€€€_€l€€ TD€€€€5€€€€nl€€E €eLN€€|tp€€׋Y1€4€ WX}i€Ϭ,€€€€&€€M€€€€€€€K€€:€€A\€S€; €c €n~)W€>€€€,a€€\z%€€€:€€ €€Y€€Å€€€€r€€qϣ€€€€€€mS+€q]€€€€€€€qު€€N€€%€€€€R`€€€€bz€
+e$€wo€e€€€€ڭ`"€q€yR€€€€i€Cꀷ€/2€€€Ft€€€€€ba€R^€E] €€€€€€€€€€€€€C€€€€€t€+€C€€€Y\€€^€zaM€€2op€€U€@€q€€€>0€=€n€N€5€Y€zWI€϶€ € ݞ€ܰ=€€€:€€e6WzQq@€€€€j4E€>€,€H€Ыӆ€€€K_1Z€>{€€}?<€€!€Ao€tз€€зN奔"੣7€€*€q€€€,€Y€o€b€g€€€D€S€7€Л€<|€€q€0b€fO:j<€?€O4€=€€p€pk€€,€B€^+€yIkOiG{c€R€€ZON€(€€1€€€,tM޲[.€€€Z€k+€€-€€€€K€<q€%€€€€Xdv€Ņn€N€'€€r(€€€€€@ €€€e€€€tY€€)€V€u€€€,€€H€€€mq€€}€|ԓ€z✩€J^€€€V€€€㴹M€T€~€€W€gϽR€€€P€
+€€€€t €€ €€;€€€€€€€)U€€€€€€kI)€€d}e€5L7€[^}€K_}€-€.€€€iÇ€&ß‚)€€j.€€€ylSj€W)€€€-€ɩ€€€ €€,E€(€Z€€y}€oA€Ȏ€€€€v€^€€€€y€€€€€=x€€.€6€€€€€ xu€va€Eq~wz-€~%€,#€€e€>C€kx€g€€€DVOΔ€€€:€ €s€€F€€€€Z€€€ذ€€€€€V€W€€]€Y€€€€€€€€Z`€y€V㗺€޸ €pI+€€#]s€€€€ݩ€S€/€jD€€>€A€€Z|€)/€€€€/€€+UO€:>€€z€€€€€w€B€€?€8€€y#€cbVX €Z€€-[ €€€€€€9O€$€6a"€€€€m€o€o/!1€.€€€Z eE€€L€&€1€'%rw€€€5€I€a€€€€€`€€€€€h€:0€€T€J€€€€B€ B€EPW.€€tG€€€€9J/€€€€€u€€-5R€X:€€€_€v€f<=€ڬ€€A$u€€~Y€R\k.€€€hÛ·j6€€€€P€Q€€€€€€€€€rM€]€€n€€Ҫ€:{€og €€tßP€=Fg
+€€!€]€€€€ A€V€^€/a%-€"]G[M€€€€\5k 3€ F€€-€c€€E€€€%Y€"€€€e€PU€E€€eR€זdQ}€%€΅E€€!€N
+€k€€݋K€€{€e€+€€€k@€C€Xk€O€€€,3€:g €%€3Z€Ƽ5€e€€€€ڋߗ€€c€͆l€€+ԠԆ€.€€€€€F€`€€K€V€cG7€€€/=\€€Y€€€€€F€=€Q€K€uOo>X 7€ 7M€+@UCe€#€€€€‚€€ €€€!€€€%N€Ga€€i#|€;$€€€€€2(€"%~€€*vʗ€€€€€€€€€%€€€€€c€€€n€%p€#jm€€s€€€"€€€k€x€DPnT€D+€r€"s€€€{€€%€€'€;=€,=€M€€€€N€ۆ€!€a €Ù€#€€ Q7uT€€`>€€€€^€^^€W€Ú‹>€€€L€o€€€ئ€  ~€€€Mk€p%€[€o€ €3€€€€€?C€€u€€`!€H€}€3€y€i 0€€?c€;}$€s}?3FRm%€€P€É´s~€{€€€k€€€,€ €€€j 0€*€€8€ٳ€€^\W;v€€€€€€Wkl€€€O€€{:€€_€€€€=p
+€€€X€M-*v€€€€€€#8€P€€EO€”€€€A€>€A€€J€€€( €Ͽ€c€€u€€1_◲€q€&€h=εV€LW€t€€€:€€A€ €€ €€€HNql€.u|M€}ij6€€/€€'39€€8w€m€>Q]€rIbs€€W€€pp;՚€pS€|€^&f€d€€",X€F@€V[€Ĕ€€€?€[€€€€J€Q€[r€,eKd 5U€*€€e€€׋€DQ€
+€€€€bAQ1€€̉dP€/€^ €€!€€iL€m€€pD€}€p€€€€ €€€€r8H€€`\fw€€€a<h€W€€PaSI8€[€€\€K€€€o€€ }€~83F€l€b€*f€E}P€c?€€€,@7g€^€>€I€ €€€€Z€.2+€€€€€€ €$€ˆh€€-V)|٫ɛ€€5C€€€ ~w€€x*€€€€'€€]€u:W€:€+q€€€€0€€€€€CF\€ĕ;€€E€P€€ј€€ܡME€€€I1€,(€ `€bY]€ڊ€€KdL62€ن€€€€€
+X€? 6€€v€kpE€mw€k€€€ €€€€€€€€€܃€€+$€l€[€&B€€b€"o ^€ ]>€€€ra€P€€Y€€ϥO€O4€ ؤ€€E€€€€€^€€€€}€€€җo€"€€€€۾m€€€€€8€€o;8€€€€Ri€€€€€ͱ€|i€ŋ€€€W.)[V[[Y!k|> y€€}*4€AG€PQa€€AW€€;u€€€!"€|Vp€€"€Eź€€€B}€pT€€)€€€€
+
+k€€€€ o€o€€l€€€€€7€€{€
+€4Mv€Ϛ€€)€€>€€M€€ j€€~€€}€ZÜe€€€€-€€] €€€KD|€€k€€€€Zr/€€}€€H€y.€9€€M€€,€€)J-&'rP[^€6€€€3€C€x€€€€€Ԃ€
+໽€b€€€=ȬD2€€%€S4€R€€P9€zTb).€m+)€͟}€€€€€€€><€ €€€€;€P€[6€€€t€ €€׊L€€p€€w€G€7€€-€€4oD€€€€*^€€€l€€B€l€€b€Kd€H€€€€€€€B뽟€mP€i>€€
+r
+€€=€Yj€7/€|ýQ€€€uC€ >I€sӢ€*€€€€k€€€r€€€€!k€€n€€4E€K€|€,,€€ €۪€€V€€€€06€€2-€€É¡Z€ohY €B€k€€€€€€%€;F€€€€Cp€€€€r€€ϩ€l€€7€p€ €T€€€u€;€€m€m€€€d€%b€€€€€€1z€d€E€€LN_€A€^<€ €€^S€;iVW€ €€€c<€8€€]€€€€€€€€€€€`L€€R€q\ € €A€€€€E€€B%€€€r€o€FS€€倀 |€€y€nQ€oIQu€9M€€'€€€€W €€>€€ƫÚ€€ا€€G€F腥€€€Zd€€€€ɻ€4".€~]€€2'€€̻iaϘ€€c€€|€w€g€n€€`€€M€L€€C €Q€€€€.n€o€€€€<€€m^€€€M€6D€T€€€€€ҟh€9€suÊœTé°‡€€€̕€€€q5'€€€€€jy€*€j€€\€€j8€€.€W€€€E€€€:€=€E9Y €€3€"€€ @.€Рk€€€€uO€€qA€h€€€%€}κ€:s€I€€€uQ1€€*€h€ x€€€€h€€€€n€:/-€bq€2eÂ€íª…[k€vU€(U€?€€€€€€R€ix€&_, €€;74t_b€€8b€€€X€€€€€)"V}k€€`€7/vJ€€I€€€l"€6#*€€€O€&k€€xO&€yZ€`€%8€-€3yL€€Db€€2€€B] €e€€/€€€€3k€€€€ά€ZL€€7y€p-n=3€6cH€€€€€€€.€:€j ;:€€€8;8x!€d€C€€€}"€P)T.Rx
+€€€,@*D€.€CW€N€X€€)€€€,€3€`€€€€€€B]8?€€€€€:Uu€*1Ρ€€€€ €n€S€€€
+€!€l.€6,_ѧX€€ҵ Í«i€€€3/a'€€o€1€€ w_€€€€€€E€€h€&T€€[€€a€€2g;€s€€?€€9a_K椙€S€€€8€muÔ;*+z1#8m€€$ϸvb€1€QG3@€o€ €U€€ƴҲt€ €€€
+€€k€ 1€Z€z€€€{€N€€€€€€€:a€[*€+ €€~€1€wѫ߈7€)Rw;€Ǩw€Qd*&@€9i€5€€<€*sZ€€ܲj<gA€c€G€€9€€ފMnuq€€ {€4€잷€€Cv€.€€€€€)€€€€Q€€zݒ€"€€€€Cŭ€vb:€€€U €€€<€€2€€XB7=j€€q€€€€C€<,P6`\€gi€Wc€>(7mh7€or€;p€z€€€JV€p辺J€€}€0Ù§1€€ €€€€^t€€m€€€€€€&u:€2k€€d€€Z€€D€€€h€€8€l€€(.d€€?€t€:H3€+€€€ €q€€l€S€€€€1у€€×€o7|€€KSy€b€|Å¥u-͹ڛQ4€€€F€(-€€ €pN€€€€Nv€€m€.€€~D€2€€€€:=c€J~d€J€䙋€(4€€€94€€€€@+€&€ +€€€Q€€R€€&€€p€€6t€€{€€G@€T€Ρ€€€_'€€€{€H€=€€j€Y€ÞJ=}d€?HwwjNO€€€€€Jb€€J€Թ$>€S€€€*Z€€s5€;og€m€*a€€#€nC.€€€€€ݙ@Ц!€€€€€з€]€0€€€\€e €蘴h€€&€ Ѥ€T€€Fs€*€TKD€e€qϡ€€R€€€՘€€€eָ€^$€€и€€ X €€€*€ĀP€€؅xI€-M€̈́€€OY€Y3€?€€€H€€€€€€) U'€S€€+€€€€€$€€€QM63K€€ǘے!€]€9^€€ÇŠd€€€€AW€€€€€€€€€Q€Qy"€€€4€6€+FG9>€0]׆ɑjut€€V'€`€`s€€€\€ €€€:Icj€D€6€S€€3F€F?X4;€€@€€R€€U:7we€€€06n4€yظP€€€€€€5$?€hy२jn#€N€€€r€@˵€~~€H€]F€€ah€P€IU€€€UU€€)€€İ€€€€p€;.WE€&:€z'e€€a€>€
+€€€€€€͑+"€p€€€€€€R5€T€*€€€€v€HV€-€a'€D;uj€gi€+6€K€o€T€€€+y€€€[0)€ma€€E৙;f
+4"}Y€UO Dsȳ €o€€€P|>€€8~€O€z€€€_ Z€<€€ѓ€€$Ï¢Ow€sXE€€U€z€€NSz€€€X8€€€*€€-€€ i€€v€€€€€€|€€€€nL€€€f2€€€€<$v>Е€c;N1Z €€€/€n€M€€W€)€€ €€€€€€\-V~R€€€x€€wB€5`]d3x8€]#€€€:€€€\€€)€V€|vGPߦ:€k€p^€€€€j|BU €€€cv |ÏY€Û€€5€€-€€ExZ€q€a\.€€j€H€€€€^€O€€c€-9M€(:€c€€€€n€€€€€€3խ€€€ r€͕€|€€€RS€u5€3 € r] €a$G€€€€€€lTL€€a.P€€€c}€€€€€€1€&€$_€€U~q€sX,€€纋€€E€t€K€B€M€"€€€r\€5M€€€€%=Ô‰q€Di1€€J€!\€€ms€#^P/€€€8€ê…h€sÔ•cbb9Ï€~€dv€f€€€Ŭn€€*€€€Þ€m€ƚ먻€`€{€v€'T7+€€h€h€k€[+FN€€,€€}€j€€٨)€€€\H3ƃ€J Q€€€ j€€a€&ΰ€A"€€€€mĿ€€</߲€€€€€€x5€€h€€ͽ€€€€1. €)€]%%€€€€FTC€D€$yi1€٘K|€*€€FO€w€K0€€Ù7€€o€Y€fhj9€R€€€/€€5É~€€;€€+_€€€€L€Ϝ€ €€€6€€€<€€É€4vS€hgL €הm€€€€€€c€€€Å“{y€3 {M€€<6€€€€`€€]O€€/€€€€€/€]€€/u€€xY€€€€q€€&€€€€€€€nÀ€;h€t€"€€€X€C€€>皚€{6(€€^€'€g€€€€€€€€€c€;€7yM€€wl€x€€|€€ݸ6€Z€e
+6w€€B~v,i€€[+\€1€J€u'€|}S/c€€=€€€€€€d€+€€u€Pd€€l€VI€@€rLo5a€€€2^ÜŒt~iB€s$€_€€€€=F€€/€ Û—m€€€t~€Ed€e<€€€€혻€€_€{€€ €ї€U€T>€S6ާ€7€r€€N€Y€€€€_€€8€~%6€X€;Q€_€€Þ€u€€
+'0ì²t€J׼€;€€€€€`€€€kG€[QK€c€X€#€Jo€ €€€ceGj€€€H]FXɌ€€5€T{€J€{)ҕ€€€€|4`~€ޡD€P)yl>`€I€8€€e€€€
+€y-€€€\€€x€€(€M€€€r%T]T€€€€,€(
+€P'€$D€€"€€€zQw€g€€ he€€€€Õ€u€a3€€€:€€X€5×¹
+€݋€M€€P€y€€;€c€,€N.sKB*€^€€u€€€E€€€-€L,€ !N€€d€€€ €€J€€X€/€€~.€€9ϩ€n€€ˎ€€Г€€ ]&zq€€Hp]h€€{P €v€:`€€€€€P€€€€€€ɯr€M€.€-€F!€€U€€c€L{€_€€)€€,SJm€0q€$R€p€€̾8X€€,N(€€j€+€DEm8€T€:l7€JWÌ‹t-€€|@€€/€€!€}€€€€2J_ €/w.s`€€€u€X€e€€€€€pq€€N€€bD€€€0€u€€€#>#Lq}€ژ€c€ 2€€€€w"€S8€€_DC€_€€KO€€€6€\€G€€0b>€€k€€€€€€!X€O€R€u?€~€Ko€;€0æ½¾6>€k€€Ѿ6~€h_€}=€*€€ >€€H€€€؅€^€'€Z€€€k€ަMN`ZpV58€'€7€€ t€€&€đ€d€€€eC€LF_f€扚€€€€€€€€Q€(€q€€€€}€€€::€€€ۄ.2€5€L€ €Z€/xӟ€€u]€€~˜y1€€€;Wvn€x[a€Lyf€€€Z€€k€V€X€=x€Ex^€€^€u^€N|uX€€Pb€€|€€€C+€,^€€j€€7€&€P€€€Fe€€vjѹ€T€Z€-€xQ€€€€€€B]€€e€€cX€̵n8w€%€€z€€€€€€€€€:U/N€€e€\e€kD€€€€€vo€O€W€]€€€€€7€€h{€.'€€€€€i#5€7€€€€6z€]€r*p€0€€€€€€€€€€€y€€`iT€€.-€w€;€€€€€o€9€€€1€€g@€U¹€\9€.
+.l€)€€A> lU€܇€€€#\A€€<€G€ }Ԅ€€7€€€i2$€€EK\A.i€ €€D€E€"€€"€€€€\€€;a8Q€€€€{:€~€€€'-€€€3€€9€€€m€€€`dX€u w€h€€w€j€€}+w€€x'€v€k/€t€x€€€tN€€
+€€€€€€€i€-*J+€€€€€bi€bQT€€€5€ €"€Y€€€'€€:L4€ €€€ €€ €€€€€s€€€€€˪k`€g4€8€lZX€€b€€&rv€€6€€€€6€€~€ €=€o<€€{€€€€€h$ €n€€?€v€€€€ B€€€io€€€€0@€*bd€:€€€}€€€V,€9€€€€€sdMF€€€€€o1b€€€€€7€8Oѵ^€ofq€€€<HO€€€€nj€8c€€>ã¥Â€^sMi€€€K€€g€~l)€њ€V€^\€<€€t€€€€5€€"8€K+€€2\/
+spider.webMPW_SpiderWEB_21Mar93.sitSISITDSIT!€€P€1?F€%\/ weave.webq%\/WebMakefile.unix}%\/webtail+€2!9€2Setg
+€€!€< \ No newline at end of file
diff --git a/web/spiderweb/ms-dos/whereis b/web/spiderweb/ms-dos/whereis
new file mode 100644
index 0000000000..137bc53d0d
--- /dev/null
+++ b/web/spiderweb/ms-dos/whereis
@@ -0,0 +1,325 @@
+From @pucc.PRINCETON.EDU:HHBODE@DOSUNI1.BITNET Wed Dec 4 10:27:13 1991
+Received: from Princeton.EDU (Princeton.EDU.) by fs.Princeton.EDU (4.0/1.105)
+ id AA15150; Wed, 4 Dec 91 10:27:12 EST
+Received: from pucc.Princeton.EDU by Princeton.EDU (5.65b/2.84/princeton)
+ id AA22962; Wed, 4 Dec 91 10:27:00 -0500
+Message-Id: <9112041527.AA22962@Princeton.EDU>
+Received: from PUCC.PRINCETON.EDU by pucc.PRINCETON.EDU (IBM VM SMTP V2R1)
+ with BSMTP id 7652; Wed, 04 Dec 91 10:26:37 EST
+Received: from DOSUNI1.BITNET by PUCC.PRINCETON.EDU (Mailer R2.08 R208007) with
+ BSMTP id 4355; Wed, 04 Dec 91 10:26:36 EST
+Received: from DOSUNI1 (HHBODE) by DOSUNI1.BITNET (Mailer R2.08) with BSMTP id
+ 0546; Wed, 04 Dec 91 16:25:55 MEZ
+Date: Wed, 04 Dec 91 16:24:12 MEZ
+From: Hans-Hermann Bode <HHBODE@DOSUNI1.BITNET>
+Subject: PC implementation of Spidery WEB
+To: Norman Ramsey <nr@Princeton.EDU>
+Status: RO
+
+Hello,
+
+I like to let you know about a PC version of your Spidery WEB system that I
+implemented. In fact, it is an ANSI-C version also, as appropriate changes
+are provided and the PC-related stuff is conditional. The implementation is
+available as an archive file spiderpc.zip by anonymous ftp from
+dione.rz.uni-osnabrueck.de (in the directory /pub/msdos/tex/web) or from
+rusinfo.rus.uni-stuttgart.de (in the directory /soft/tex/web/spiderweb); it
+contains the original files (none of it was edited directly, but a few had
+to be renamed) and changefiles and makefiles for the PC version. For your
+information I append the file readme.pc from spiderpc.zip.
+
+Hans-Hermann Bode
+Arbeitsgruppe Systemforschung, Universit\"at Osnabr\"uck
+Tel.: (49)-541-9692545
+e-mail: HHBODE@DOSUNI1.BITNET
+
+------------------------------------------------README.PC-from-SPIDERPC.ZIP---
+ -*-Text-*-
+This is the PC implementation of Norman Ramsey's Spidery WEB system,
+compiled and provided with changefiles and makefiles for PC-/MS-DOS by
+Hans-Hermann Bode <HHBODE@DOSUNI1.BITNET>. The changes are appropriate for
+ANSI-C compilers as well as for Turbo C++, where the latter are made
+conditional (they will become effective only if the symbol __TURBOC__ is
+defined, which automatically is the case when compiled with Turbo C++), so
+users of other systems with ANSI-C compilers might be interested also.
+
+Note that---though the Spider programs itself now should be suitable for
+ANSI-C compilers---there is no Spidery ANSI-C WEB yet, i.e., a weave
+processor capable to typeset ANSI-C programs is missing (the provided
+ceeweave is intended for traditional C only---the tangle processor, on the
+other hand, causes no problem, so the make procedure is not affected by
+this). You could use the C++ version (ccweave) instead, but this will not
+recognize traditional comments (the /*...*/ form). A quick solution might be
+to take the C++ Spider source (./cc/cc.spi, see below) and to change the
+comment rule appropriately. Possibly, this will be the first exercise for
+you in generating a new Spidery WEB.
+
+To install the system unpack the archive and reproduce the following
+directory structure:
+
+.
+./ada
+./ada/make
+./ada/ada.spi
+./ada/stacks.web
+./ada/new.spi
+./ada/old.spi
+./ada/pcmake.sh *
+./ada/pcmake.bat *
+./ada/adatangl.exe +
+./ada/adaweave.exe +
+./ada/adaweb.tex +
+./awk
+./awk/awk.spi
+./awk/make
+./awk/tangle.c
+./awk/nawk.spi
+./awk/pcmake.sh *
+./awk/pcmake.bat *
+./awk/awktangl.exe +
+./awk/awkweave.exe +
+./awk/awkweb.tex +
+./awk/awktangl.c +
+./c
+./c/local.gui
+./c/make
+./c/c.spi
+./c/tangle.c
+./c/pcmake.sh *
+./c/pcmake.bat *
+./c/ceetangl.exe +
+./c/ceeweave.exe +
+./c/cweb.tex +
+./c/ceetangl.c +
+./cc
+./cc/make
+./cc/cc.spi
+./cc/pcmake.sh *
+./cc/pcmake.bat *
+./cc/cctangle.exe +
+./cc/ccweave.exe +
+./cc/ccweb.tex +
+./dijkstra
+./dijkstra/binary.web
+./dijkstra/make
+./dijkstra/d.spi
+./dijkstra/sp.web
+./dijkstra/readme
+./dijkstra/pcmake.sh *
+./dijkstra/pcmake.bat *
+./dijkstra/dtangle.exe +
+./dijkstra/dweave.exe +
+./dijkstra/dijkstra.tex +
+./larch
+./larch/make
+./larch/l.spi
+./larch/lists.web
+./larch/pcmake.sh *
+./larch/pcmake.bat *
+./larch/ltangle.exe +
+./larch/lweave.exe +
+./larch/larchweb.tex +
+./penelope
+./penelope/make
+./penelope/spiderma
+./penelope/a.spi
+./penelope/nesting.spi
+./penelope/stacks.web
+./penelope/proc-a.spi
+./penelope/scan_ann.awk
+./penelope/spimkfil.pc *
+./penelope/pcmake.sh *
+./penelope/pcmake.bat *
+./ssl
+./ssl/make
+./ssl/s.spi
+./ssl/pcmake.sh *
+./ssl/pcmake.bat *
+./ssl/stangle.exe +
+./ssl/sweave.exe +
+./ssl/sslweb.tex +
+./doc
+./doc/spiderma.aux
+./doc/spiderwe.toc
+./doc/makefile
+./doc/cacm.aux
+./doc/cacm.tex
+./doc/abstract.tex
+./doc/spiderma.tex
+./doc/overview.aux
+./doc/overview.tex
+./doc/spiderwe.tex
+./doc/descript
+./master
+./master/cycle.awk
+./master/nodups.awk
+./master/transche.awk
+./master/pathopen.h_0
+./master/multitan.ch
+./master/common.web
+./master/cycle.web
+./master/webhead
+./master/spider.awk
+./master/webtail
+./master/common.h_0
+./master/newdefs.awk
+./master/transche.lis
+./master/pretty.awk
+./master/pathopen.web
+./master/make.pre
+./master/webmakef
+./master/common.c_0
+./master/pathopen.c_0
+./master/makefile
+./master/spider.web
+./master/junk.lis
+./master/weave.web
+./master/tangle.web
+./master/makefile.pc *
+./master/pathopen.ch *
+./master/common.ch *
+./master/common.hch *
+./master/common.h o
+./master/tangle.ch *
+./master/weave.ch *
+./master/pathopen.h +
+./master/pathopen.c +
+./master/common.c +
+./master/common.obj +
+./master/pathopen.obj +
+./gawk210
+./gawk210/gawk.exe
+./gawk210/gawk.1
+./gawk210/gawk.dvi
+./gawk210/gawk.tex
+./gawk210/texinfo.tex
+./gawk210/problems
+./gawk210/readme
+./gawk210/copying
+./readme
+./copyrigh
+./bugs
+./webkerne.tex
+./makefile
+./readme.pc *
+
+The files marked with `*' are specific and essential for the PC
+implementation, those marked with `+' are the results of pcmake runs (see
+below) and are reproducible. The file marked with `o' will not be generated
+by pcmake but might be reproduced from masterfile ./master/common.h_0 and
+changefile ./master/common.hch by means of a tool like WMERGE or TIE (or by
+hand). All files with names ending in `_0' are renamed from the original
+distribution, because they are replaced by new ones. The file
+./awk/nawk.spi, a Spider source for the new Awk language, is contributed by
+Erich Neuwirth. The directory ./gawk210 contains the GNU implementation of
+the Awk programming language, Version 2.10; the interpreter, gawk.exe, is
+used in the pcmake process. All other files come from the original
+distribution of Spidery WEB.
+
+For more information on the Spider system see the file ./readme and the
+documentation in the directory ./doc. For the copyright policy on Spidery
+WEB consider the file ./copyrigh. For the same subject on GAWK pay attention
+to the file ./gawk210/copying. Unfortunately, I can't tell you where to get
+the source files of the PC implementation of GAWK 2.10, since I got the
+system myself exactly as it is in ./gawk210 (look in ./gawk210/readme for
+contact persons, if required).
+
+Using Spidery WEB on a PC
+-------------------------
+
+For your convenience, precompiled executables are provided with this
+distribution. So, all you have to do is the following:
+
+ - Copy the file ./webkernel.tex to a directory where TeX looks for input
+files.
+
+ - Pick up one or more of the directories ./ada, ./awk, ./c, ./cc,
+./dijkstra, ./larch, and ./ssl that correspond to the languages you like to
+use (cc is actually c++ in the original distribution). Copy the TeX files
+(*web.tex) to your TeX-inputs directory, too, and copy the exe files
+(*tangle.exe and *weave.exe) to your binaries directory, i.e., a directory
+that is in the DOS PATH.
+
+ - That's all!
+
+Note that there are no executables in the ./penelope directory. This is due
+to the fact that GAWK hung up while processing ./penelope/proc-a.spi. I
+didn't fix this problem up to now.
+
+Setting up new Spiders on a PC
+------------------------------
+
+If you want to build new Spidery WEBs or like to change existing ones,
+you'll need the following resources:
+
+ - An Awk interpreter. As GAWK, Version 2.10, is included in this archive,
+you don't have to worry about. Notice that GAWK, Version 2.11, will not
+work. Other MS-DOS Awk interpreters have not been tested, but probably won't
+work also.
+
+ - A C compiler. The executables and object files supplied herein were
+compiled with and the changefiles as well as ./master/makefile.pc are
+intended for Turbo C++, Version 1.01. Other MS-DOS C compilers may also
+work, but you might run into delicate problems with Microsoft C, Version
+6.00.
+
+ - A make utility (if you don't prefer to do the job by hand, which would
+be a hard one). The file ./master/makefile.pc is intended for Turbo Make,
+Version 3.0.
+
+ - A lot of memory. The most storage-consuming process is the interpreting
+of the Spider source (*.spi) by GAWK. This will need about 550 to 575 KByte
+of memory available on your system, so remove all memory-resident programs
+that aren't really necessary.
+
+The file ./master/makefile.pc provides a full automatic creation of a
+Spidery WEB for a certain language from a Spider source file (don't use the
+other makefiles in this distribution, they are not intended for PC-/MS-DOS).
+For flexibility, several macros have to be defined from the command line;
+read the comment at the beginning of the makefile for more information.
+Incidentally, a symbol CMD may be defined, in which case the
+makefile---besides the interpreter and compiler mentioned above---will use
+standard DOS file utilities only; default is to use Unix-like utilities like
+cp, sort, and rm.
+
+Each of the language-specific directories contains a script file, pcmake,
+that calls ./master/makefile.pc appropriate for the major Spider source of
+the language in question (sometimes, alternative sources are provided;
+again, don't use the other make scripts, they won't call the right
+makefile). Actually, two versions of pcmake reside in each of these
+directories: pcmake.bat is a batch file for use with command.com, pcmake.sh
+is a shell script for use with a bourne shell like ms_sh. Because both
+command processors will run the corresponding script automatically, simply
+type `pcmake' if you use either of these.
+
+It is assumed that bourne-shell users have the Unix-like file utilities
+mentioned above available, thus pcmake.sh will run the makefile without
+defining CMD, while pcmake.bat defines it. Besides, in both cases the make
+utility will be called under the name `tmake'. If one of these facts doesn't
+fit your needs, you have to edit pcmake.sh or pcmake.bat first.
+
+The make procedure implies a call to both the tangle processors of the Awk
+and the C language (awktangle.exe and ceetangle.exe). Hence you must install
+those in your binaries directory before doing anything else. If for some
+reason you can't use the binaries provided, you have to recompile
+./c/ceetangle.c, ./awk/awktangle.c, ./master/common.c, and
+./master/pathopen.c (don't forget to define the symbol MSDOS from the
+command line) and link the resulting ceetangle.obj and awktangle.obj with
+the resulting object files of the ./master sources, respectively.
+
+When you ever change ./master/pathopen.web or ./master/pathopen.ch, the make
+process will generate a new pathopen.h in the current directory. You should
+move this file to the ./master directory, so it will not be produced once
+more in subsequent runs until it is outdated again.
+
+By taking all these suggestions into account, after editing one of the
+Spider sources you should delete the exe files from the directory in
+question and, from that directory, just say `pcmake'. If everything works
+alright, after a while you will get new executables *tangle.exe and
+*weave.exe and a new macro package *web.tex besides some intermediate files.
+You can remove the latter by saying `pcmake clean' (this will not affect the
+exe and tex files). If you ceate a Spidery WEB for a new language, you
+should take one of the pcmake files as a model to proceed with a similar
+procedure.
+ -H2B-
+
diff --git a/web/spiderweb/os2/os2.changes b/web/spiderweb/os2/os2.changes
new file mode 100644
index 0000000000..0d34a86b0b
--- /dev/null
+++ b/web/spiderweb/os2/os2.changes
@@ -0,0 +1,688 @@
+From bdubbs@cs.tamu.edu Mon Feb 15 18:25:17 1993
+Received: from flash.bellcore.com by mailee.bellcore.com (5.61/1.34)
+ id AA24579; Mon, 15 Feb 93 18:25:13 -0500
+Received: from NEURON.TAMU.EDU by flash.bellcore.com (5.61/1.34)
+ id AA06361; Mon, 15 Feb 93 18:25:09 -0500
+Received: by neuron.cs.tamu.edu (AA01812); Mon, 15 Feb 93 17:24:16 CST
+Date: Mon, 15 Feb 93 17:24:16 CST
+From: bdubbs@cs.tamu.edu (Bruce Dubbs)
+Message-Id: <9302152324.AA01812@neuron.cs.tamu.edu>
+To: norman@bellcore.com
+Subject: Re: Spider Web port to OS/2
+Cc: bart@cs.tamu.edu
+Status: RO
+
+Attached are the final changes I made to the Spider WEB system for
+porting to OS/2. Also is the readme.os2 and makefile.emx that I
+included in the package. The file, spider.zip, is now at
+ftp-os2.nmsu.edu in the /pub/uploads directory, but it should be moved
+to the /pub/os2/2.0/programming directory in a week or two.
+
+I made the bug fixes in common.ch because I did not want to change
+your distribution code until you made the changes public. I also made
+a slight change to weave.web (weave.ch) because ceeweave was giving
+an error at a single @ inside a /* ... */ comment.
+
+ -- Bruce Dubbs
+
+---readme.os2----------------------------------------------------------
+This is the OS/2 2.0 port of Norman Ramsey's Spider WEB.
+
+Briefly, WEB is a system that allows the creation of computer source
+code and typeset documentation from a single source file. The file is
+processed by tangle for input to the target compiler and the same
+source is processed be weave for input to TeX for typeset
+documentation.
+
+This port includes the entire source for Ramsey's system that allows
+the creation of custom tangle and weave processors for arbitrary
+computer languages. Included in the main directory of this port is a
+set of OS/2 specific files:
+
+README.OS2 -- This file
+ceeweave.exe -- C Weave executable
+ceetangle.exe -- C Tangle executable
+awkweave.exe -- AWK Weave executable
+awktangle.exe -- AWK Tangle executable
+cweb.tex -- include file for Woven C tex files
+awkweb.tex -- include file for Woven AWK tex files
+makefile.emx -- make for C and AWK executatables and dvi
+ documentation
+common.ch -- change file for common.web
+weave.ch -- change file for weave.web
+emxlibc.dll -- emx C dynamic link library
+
+The only change I have made to the original files is to rename
+common.c to common.c.old in order to force the makefile to create a
+new common.c from the combination of common.web and common.ch.
+
+INSTALLATION:
+
+Copy the executables above to a directoru on your PATH.
+Copy cweb.tex, awkweb.tex, and webkernel.tex to the directory that TeX
+normally looks for inputs.
+Copy the emxlibc.dll file to a directory on your LIBPATH.
+
+>From this point, you should be able to run the appropriate version of
+tangle and weave from any location.
+
+That it.
+
+NOTES:
+
+1. I have assumed the files here are on an HPFS directory. This means
+that the capability for long filenames is assumed.
+
+2. The TeX include file webkernel.tex appears to be too long for
+tex386, but internally tex386 processes the \input command properly
+and will find webkernel.tex properly if it is in the current directory
+or the proper TEXINPUT directory. However, tex386 will not recognize
+a file on the command line linger tahn the 8.3 format.
+
+MAKING IT YOURSELF:
+
+The makefile "makefile.emx" will create the executables and dvi files
+of the sources and documentation. The primary commands are:
+
+ make -f makefile.emx exe (default - makes executables)
+ make -f makefile.emx docs (makes dvi files of documentation)
+ make -f makefile.emx dvi (makes dvi files from Spider sources)
+ make -f makefile.emx all (all of the above)
+ make -f makefile.emx clean (removes all non-essential files)
+
+It takes about 13 minutes to to a `make all' on my 386/33 + 387 + 16Mb RAM.
+
+The makefile assumes a lot about utilities that are available. I used
+the emx 0.8f gcc compiler, gawk, sort, rm, cat, and sort. It also
+uses tex386 from the emTeX package using both plain and LaTeX styles.
+All of these are available from ftp-os2.nms.edu.
+
+If you want to develop one of the other Spider WEB languages, take a
+look at the makefile closely. You may even want to develop a Spider
+Web for a new language.
+
+ -- Bruce Dubbs
+ bdubbs@neuron.tamu.edu or
+ bdubsb@hal.kelly.af.mil (after August 1993)
+
+REFERENCES:
+[1] Wayne Sewell, Weaving a Program: Literate Programming in WEB.
+Van Nostrand Reinhold, New York, 1988
+
+[2] Donald Knuth, Literate Programming. Center for the Study of
+Language and Information, Leland Stanford Junior University, CA, 1992.
+--------common.ch------------------------------------------------
+% Change file to common.web for Spider Web generation for OS2
+% Not to be sold, but may be used freely for any purpose
+% For more information, see file COPYRIGHT in the parent directory
+
+% This file is part of Spidery WEB
+
+% This program by Norman Ramsey is based on programs Silvio Levy
+% and D. E. Knuth. Silvio Levy wrote most of the code.
+% It is distributed WITHOUT ANY WARRANTY, express or implied.
+% Dec 1987
+
+% Change file by Bruce Dubbs, Texas A&M University, bdubbs@neuron.tamu.edu
+
+
+@x Module 7 Sun Feb 14 01:12:22 1993
+@ The \.{WEAVE} and \.{TANGLE} processors convert between ASCII code and
+the user's external character set by means of arrays |xord| and |xchr|
+that are analogous to PASCAL's |ord| and |chr| functions.
+
+@<Definitions...@>=
+ASCII xord[last_text_char]; /* specifies conversion of input characters */
+outer_char xchr[@'200]; /* specifies conversion of output characters */
+@y Module 7 Sun Feb 14 01:12:22 1993
+@ The \.{WEAVE} and \.{TANGLE} processors convert between ASCII code and
+the user's external character set by means of arrays |xord| and |xchr|
+that are analogous to PASCAL's |ord| and |chr| functions.
+
+We have to change the size of xord to |last_text_char|+1 to cover the
+entire 128 byte ASCII array.
+
+@<Definitions...@>=
+ASCII xord[last_text_char+1]; /* specifies conversion of input characters */
+outer_char xchr[@'200]; /* specifies conversion of output characters */
+@z Module 7 Sun Feb 14 01:12:22 1993
+
+@x Module 8 Sun Feb 14 01:16:14 1993
+@ Every system supporting \cee\ must be able to read and write the 95
+visible characters of standard ASCII above (although not necessarily using the
+ASCII codes to represent them). Conversely, these characters, plus
+the newline, are sufficient to write any \cee\ program. Other
+characters are desirable mainly in strings, and they can be referred
+to by means of escape sequences like \.{'\t'}.
+
+The basic implementation of \.{WEB}, then, only has to assign an
+|xord| to these 95 characters (newlines are swallowed by the reading
+routines). The easiest way to do this is to assign the characters to
+their positions in |xchr| and then invert the correspondence:
+
+@<Functions...@>=
+common_init()
+{
+ strcpy(xchr," !\"#$%&'()*+,-./0123456789\
+:;<=>?@@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ");
+ @<System-dependent parts of character set@>;
+ @<Invert |xchr| to get |xord|@>;
+ @<Initialize pointers@>;
+ setting_up=1;
+ @<Scan arguments and open output files@>;
+ setting_up=0;
+}
+@y Module 8 Sun Feb 14 01:16:14 1993
+@ Every system supporting \cee\ must be able to read and write the 95
+visible characters of standard ASCII above (although not necessarily using the
+ASCII codes to represent them). Conversely, these characters, plus
+the newline, are sufficient to write any \cee\ program. Other
+characters are desirable mainly in strings, and they can be referred
+to by means of escape sequences like \.{'\t'}.
+
+The basic implementation of \.{WEB}, then, only has to assign an
+|xord| to these 95 characters (newlines are swallowed by the reading
+routines). The easiest way to do this is to assign the characters to
+their positions in |xchr| and then invert the correspondence:
+
+We make a change here so the string copy does not add a null to the |xchr|
+array.
+
+@<Functions...@>=
+common_init()
+{
+ strncpy(xchr," !\"#$%&'()*+,-./0123456789\
+:;<=>?@@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ",128);
+ @<System-dependent parts of character set@>;
+ @<Invert |xchr| to get |xord|@>;
+ @<Initialize pointers@>;
+ setting_up=1;
+ @<Scan arguments and open output files@>;
+ setting_up=0;
+}
+@z Module 8 Sun Feb 14 01:16:14 1993
+
+@x Module 28 Sun Feb 14 01:17:40 1993
+@ When a \.{@@i} line is found in the |cur_file|, we must temporarily
+stop reading it and start reading from the named include file. The
+\.{@@i} line should give a complete file name with or without \.{"..."};
+\.{WEB} will look for include files in standard directories using
+the |pathopen| module.
+That is set up at the beginning using the {\tt -I} arguments
+and the {\tt WEBPATH} environment variable.
+@<Add environment variable |"WEBPATH"| to search path@>=
+ pathaddpath(getenv("WEBPATH"),':');
+@y Module 28 Sun Feb 14 01:17:40 1993
+@ When a \.{@@i} line is found in the |cur_file|, we must temporarily
+stop reading it and start reading from the named include file. The
+\.{@@i} line should give a complete file name with or without \.{"..."};
+\.{WEB} will look for include files in standard directories using
+the |pathopen| module.
+That is set up at the beginning using the {\tt -I} arguments
+and the {\tt WEBPATH} environment variable.
+
+We change the path delimeter to a semi-colon for OS/2.
+
+@<Add environment variable |"WEBPATH"| to search path@>=
+ pathaddpath(getenv("WEBPATH"),';');
+@z Module 28 Sun Feb 14 01:17:40 1993
+
+@x Module 70 Sun Feb 14 01:19:06 1993
+@ @<Set up null...@>=
+#ifdef MSDOS
+strcpy(change_file_name,"NUL");
+#else
+strcpy(change_file_name,"/dev/null");
+#endif
+@y Module 70 Sun Feb 14 01:19:06 1993
+@ OS/2 uses {\tt /dev/nul} instead of {\tt /dev/null}.
+
+@<Set up null...@>=
+strcpy(change_file_name,"/dev/nul");
+@z Module 70 Sun Feb 14 01:19:06 1993
+-----------weave.ch---------------------------------------------
+% Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+% Not to be sold, but may be used freely for any purpose
+% For more information, see file COPYRIGHT in the parent directory
+
+% This file is part of Spidery WEB
+% This program by Norman Ramsey is based on programs Silvio Levy
+% and D. E. Knuth. Silvio Levy wrote most of the code.
+% It is distributed WITHOUT ANY WARRANTY, express or implied.
+% Dec 1987
+
+% Change made to overcome a small error. There is a comment that
+% only use a single at-sign. We change it here to at-at.
+
+@x
+@ Control codes in \.{WEB}, which begin with `\.{@@}', are converted
+into a numeric code designed to simplify \.{CWEAVE}'s logic; for example,
+larger numbers are given to the control codes that denote more significant
+milestones, and the code of |new_module| should be the largest of
+all. Some of these numeric control codes take the place of ASCII
+control codes that will not otherwise appear in the output of the
+scanning routines.
+@^ASCII code@>
+
+@d ignore = 0 /* control code of no interest to \.{CWEAVE} */
+@d verbatim = @'2 /* extended ASCII alpha will not appear */
+ /* extended ASCII beta will not appear */
+@d begin_comment = @'10 /* ASCII tab mark will not appear */
+@d octal = @'14 /* ASCII carriage return will not appear */
+@d hex = @'15 /* ASCII form feed will not appear */
+@d switch_math_flag = @'175 /* this code will be intercepted without confusion */
+@d underline = @'176 /* this code will be intercepted without confusion */
+@d param = @'177 /* ASCII delete will not appear */
+/* identifier =200 or octal @'310 */
+@#/* following three must be conseccutive for indexing to work */
+@d xref_roman = (identifier+roman) /* control code for `\.{@@\^}' */
+@d xref_wildcard = (identifier+wildcard) /* control code for `\.{@@:}' */
+@d xref_typewriter = (identifier+typewriter) /* control code for `\.{@@.}' */
+@d TeX_string = @'356 /* control code for `\.{@@t}' */
+@d ascii_constant = @'357 /* control code for `\.{@@`}' */
+@d join = @'360 /* control code for `\.{@@\&}' */
+@d thin_space = @'361 /* control code for `\.{@@,}' */
+@d math_break = @'362 /* control code for `\.{@@\char'174}' */
+@d line_force = @'363 /* control code for `\.{@@/}' */
+@d line_break = @'364 /* control code for `\.{@@-}' */
+@d big_line_break = @'365 /* control code for `\.{@@\#}' */
+@d no_line_break = @'366 /* control code for `\.{@@+}' */
+@d pseudo_semi = @'367 /* control code for `\.{@@;}' */
+@d vertical_bar = @'370 /* The `\v' used to mark Ada text */
+@d trace = @'371 /* control code for `\.{@@0}', `\.{@@1}' and `\.{@@2}' */
+@d format = @'373 /* control code for `\.{@@f}' */
+@d definition = @'374 /* control code for `\.{@@d}' */
+@d begin_unnamed = @'375 /* control code for `\.{@@u}' */
+@d module_name = @'376 /* control code for `\.{@@<}' */
+@d new_module = @'377 /* control code for `\.{@@\ }' and `\.{@@*}' */
+@y
+@ Control codes in \.{WEB}, which begin with `\.{@@}', are converted
+into a numeric code designed to simplify \.{CWEAVE}'s logic; for example,
+larger numbers are given to the control codes that denote more significant
+milestones, and the code of |new_module| should be the largest of
+all. Some of these numeric control codes take the place of ASCII
+control codes that will not otherwise appear in the output of the
+scanning routines.
+@^ASCII code@>
+
+@d ignore = 0 /* control code of no interest to \.{CWEAVE} */
+@d verbatim = @'2 /* extended ASCII alpha will not appear */
+ /* extended ASCII beta will not appear */
+@d begin_comment = @'10 /* ASCII tab mark will not appear */
+@d octal = @'14 /* ASCII carriage return will not appear */
+@d hex = @'15 /* ASCII form feed will not appear */
+@d switch_math_flag = @'175 /* this code will be intercepted without confusion */
+@d underline = @'176 /* this code will be intercepted without confusion */
+@d param = @'177 /* ASCII delete will not appear */
+
+% This is where the change is
+
+/* identifier =200 or octal @@'310 */
+
+@#/* following three must be conseccutive for indexing to work */
+@d xref_roman = (identifier+roman) /* control code for `\.{@@\^}' */
+@d xref_wildcard = (identifier+wildcard) /* control code for `\.{@@:}' */
+@d xref_typewriter = (identifier+typewriter) /* control code for `\.{@@.}' */
+@d TeX_string = @'356 /* control code for `\.{@@t}' */
+@d ascii_constant = @'357 /* control code for `\.{@@`}' */
+@d join = @'360 /* control code for `\.{@@\&}' */
+@d thin_space = @'361 /* control code for `\.{@@,}' */
+@d math_break = @'362 /* control code for `\.{@@\char'174}' */
+@d line_force = @'363 /* control code for `\.{@@/}' */
+@d line_break = @'364 /* control code for `\.{@@-}' */
+@d big_line_break = @'365 /* control code for `\.{@@\#}' */
+@d no_line_break = @'366 /* control code for `\.{@@+}' */
+@d pseudo_semi = @'367 /* control code for `\.{@@;}' */
+@d vertical_bar = @'370 /* The `\v' used to mark Ada text */
+@d trace = @'371 /* control code for `\.{@@0}', `\.{@@1}' and `\.{@@2}' */
+@d format = @'373 /* control code for `\.{@@f}' */
+@d definition = @'374 /* control code for `\.{@@d}' */
+@d begin_unnamed = @'375 /* control code for `\.{@@u}' */
+@d module_name = @'376 /* control code for `\.{@@<}' */
+@d new_module = @'377 /* control code for `\.{@@\ }' and `\.{@@*}' */
+@z
+----------------makefile.emx--------------------------------------
+# Makefile for awkweb and ceeweb of OS/2 2.0 with emx/gcc
+# Run the file from a directory containing the master\ and awk\
+# subdirectories. Edit this file to make the ROOT variable the
+# same as your main spider directory.
+
+# That is, the directory structure should look like:
+# spider\
+# spider\master\
+# spider\awk\
+# spider\c\
+
+
+# make -f makefile.emx [argument]
+
+CC = gcc -Zomf -Zmt -O
+O = .obj
+A = .lib
+
+LIBS =
+CFLAGS =
+
+# Basic directory definitions
+
+ROOT = \spider
+
+C = $(ROOT)\c
+AWK = $(ROOT)\awk
+MASTER = $(ROOT)\master
+DOC = $(ROOT)\doc
+OS2 = $(ROOT)
+
+# Executables used
+
+CTANGLE = $(ROOT)\ceetangle.exe
+CWEAVE = $(ROOT)\ceeweave.exe
+AWKTANGLE = $(ROOT)\awktangle.exe
+AWKWEAVE = $(ROOT)\awkweave.exe
+TEX = tex386
+LATEX = $(TEX) `&lplain`
+
+# Files to make
+# Note that we need ceetangle to make a new ceetangle if we do not
+# have the C version of tangle.c--its recursive.
+
+# Also, if we lose spider.awk, it can be remade from spider.web but
+# we need awktangle to do it.
+
+
+CEE_EXE = $(CTANGLE) $(CWEAVE)
+AWK_EXE = $(AWKTANGLE) $(AWKWEAVE)
+
+CEE_DVI = $(OS2)\ceeweave.dvi $(OS2)\ctangle.dvi
+A_DVI = $(OS2)\awkweave.dvi $(OS2)\atangle.dvi
+AWK_DVI = $(OS2)\spider.dvi $(OS2)\cycle.dvi
+
+COMMON_DVI = $(OS2)\common.dvi
+PATHOPEN_DVI = $(OS2)\pathopen.dvi
+
+CACM = $(OS2)\cacm.dvi
+S_WEBMAN = $(OS2)\s_webman.dvi
+S_MAN = $(OS2)\s_man.dvi
+OVERVIEW = $(OS2)\overview.dvi
+
+
+EXE = $(CEE_EXE) $(AWK_EXE)
+DVI = $(COMMON_DVI) $(PATHOPEN_DVI) $(AWK_DVI) $(A_DVI) $(CEE_DVI)
+
+DOCS = $(CACM) $(S_WEBMAN) $(S_MAN) $(OVERVIEW)
+
+# What we want to make
+# The default is the AWK and C versions of tangle and weave
+
+exe: $(EXE)
+
+dvi: $(DVI)
+
+docs: $(DOCS)
+
+all: $(EXE) $(DVI) $(DOCS)
+
+# This is how we make ceeweave and ceetangle
+
+$(CTANGLE): $(C)\tangle$(O) $(MASTER)\common$(O) $(MASTER)\pathopen$(O)
+ $(CC) $(CFLAGS) -o $(CTANGLE) $(C)\tangle$(O) $(MASTER)\common$(O) \
+ $(MASTER)\pathopen$(O)
+
+$(C)\tangle$(O): $(C)\tangle.c
+ cd $(C)
+ $(CC) $(CFLAGS) -c tangle.c
+ cd $(OS2)
+
+$(C)\tangle.c: $(MASTER)\common.h $(C)\outtoks.web $(MASTER)\tangle.web
+ copy $(MASTER)\tangle.web $(C)
+ copy $(MASTER)\common.h $(C)
+ cd $(C)
+ $(CTANGLE) tangle.web
+ cd $(OS2)
+
+$(CWEAVE): $(C)\weave$(O) $(MASTER)\common$(O) $(MASTER)\pathopen$(O)
+ $(CC) $(CFLAGS) -o $(CWEAVE) $(C)\weave$(O) $(MASTER)\common$(O) \
+ $(MASTER)\pathopen$(O)
+
+$(C)\weave$(O): $(C)\weave.c
+ cd $(C)
+ $(CC) $(CFLAGS) -c weave.c
+ cd $(OS2)
+
+$(C)\weave.c: $(MASTER)\weave.web $(MASTER)\common.h $(C)\grammar.web
+ copy $(MASTER)\common.h $(C)
+ copy $(MASTER)\weave.web $(C)
+ cd $(C)
+ $(CTANGLE) weave $(OS2)\weave.ch
+ rm common.h weave.web
+ cd $(OS2)
+
+$(C)\grammar.web $(C)\outtoks.web $(OS2)\cweb.tex: \
+ $(MASTER)\cycle.awk $(MASTER)\spider.awk $(C)\c.spider
+ cd $(C)
+ gawk -f $(MASTER)\spider.awk c.spider
+ cat $(MASTER)\transcheck.list trans_keys.unsorted | \
+ gawk -f $(MASTER)\transcheck.awk
+ gawk -f $(MASTER)\cycle.awk < cycle.test
+ cat *.unsorted | sort | gawk -f $(MASTER)\nodups.awk
+ copy cweb.tex $(OS2)
+ cd $(OS2)
+
+# This is how we make awkweave and awktangle
+
+$(AWKTANGLE): $(AWK)\tangle$(O) $(MASTER)\common$(O) $(MASTER)\pathopen$(O)
+ cd $(AWK)
+ $(CC) $(CFLAGS) -o $(AWKTANGLE) $(AWK)\tangle$(O) $(MASTER)\common$(O)\
+ $(MASTER)\pathopen$(O)
+ cd $(OS2)
+
+$(AWK)\tangle$(O): $(C)\tangle.c
+ cd $(AWK)
+ $(CC) $(CFLAGS) -c tangle.c
+ cd $(OS2)
+
+$(AWK)\tangle.c: $(MASTER)\common.h $(AWK)\outtoks.web $(MASTER)\tangle.web
+ copy $(MASTER)\tangle.web $(AWK)
+ copy $(MASTER)\common.h $(AWK)
+ cd $(AWK)
+ $(CTANGLE) tangle.web
+ rm $(AWK)\tangle.web $(AWK)\common.h
+ cd $(OS2)
+
+$(AWKWEAVE): $(AWK)\weave$(O) $(MASTER)\common$(O) $(MASTER)\pathopen$(O)
+ $(CC) $(CFLAGS) -o $(AWKWEAVE) $(AWK)\weave$(O) $(MASTER)\common$(O) \
+ $(MASTER)\pathopen$(O)
+
+$(AWK)\weave$(O): $(AWK)\weave.c
+ cd $(AWK)
+ $(CC) $(CFLAGS) -c weave.c
+ cd $(OS2)
+
+$(AWK)\weave.c: $(MASTER)\weave.web $(MASTER)\common.h $(AWK)\grammar.web
+ copy $(MASTER)\weave.web $(AWK)
+ copy $(MASTER)\common.h $(AWK)
+ cd $(AWK)
+ $(CTANGLE) weave $(OS2)\weave.ch
+ cd $(OS2)
+
+$(AWK)\grammar.web $(AWK)\outtoks.web $(OS2)\awkweb.tex: \
+ $(MASTER)\cycle.awk $(MASTER)\spider.awk $(AWK)\awk.spider
+ cd $(AWK)
+ gawk -f $(MASTER)\spider.awk awk.spider
+ cat $(MASTER)\transcheck.list trans_keys.unsorted | \
+ gawk -f $(MASTER)\transcheck.awk
+ gawk -f $(MASTER)\cycle.awk < cycle.test
+ cat *.unsorted | sort | gawk -f $(MASTER)\nodups.awk
+ copy awkweb.tex $(OS2)
+ cd $(OS2)
+
+$(MASTER)\spider.awk: $(MASTER)\spider.web
+ cd $(MASTER)
+ $(AWKTANGLE) $(MASTER)\spider.web
+ cd $(OS2)
+
+
+# This is how we make the files needed for all executables
+
+$(MASTER)\pathopen$(O): $(MASTER)\pathopen.c
+ cd $(MASTER)
+ $(CC) $(CFLAGS) -c pathopen.c
+ cd $(OS2)
+
+$(MASTER)\pathopen.c $(MASTER)\pathopen.h: $(MASTER)\pathopen.web
+ cd $(MASTER)
+ $(CTANGLE) pathopen.web
+ cd $(OS2)
+
+# Note the OS2 change file here
+
+$(MASTER)\common.c: $(MASTER)\common.web $(OS2)\common.ch
+ cd $(MASTER)
+ $(CTANGLE) common.web $(OS2)\common.ch
+ cd $(OS2)
+
+$(MASTER)\common$(O): $(MASTER)\common.c
+ cd $(MASTER)
+ $(CC) $(CFLAGS) -c common.c
+ cd $(OS2)
+
+$(OS2)\common.dvi: $(MASTER)\common.tex $(OS2)\cweb.tex
+ copy $(MASTER)\common.tex $(OS2)
+ -$(TEX) common.tex
+ rm $(OS2)\common.tex
+
+$(MASTER)\common.tex: $(MASTER)\common.web $(MASTER)\pathopen.h $(CWEAVE)
+ cd $(MASTER)
+ $(CWEAVE) common.web
+ cd $(OS2)
+
+$(OS2)\pathopen.dvi: $(MASTER)\pathopen.tex $(OS2)\cweb.tex
+ copy $(MASTER)\pathopen.tex $(OS2)
+ -$(TEX) pathopen.tex
+ rm $(OS2)\pathopen.tex
+
+$(MASTER)\pathopen.tex: $(MASTER)\pathopen.web $(CWEAVE)
+ cd $(MASTER)
+ $(CWEAVE) pathopen.web
+ cd $(OS2)
+
+$(OS2)\cycle.dvi: $(MASTER)\cycle.tex $(OS2)\awkweb.tex
+ copy $(MASTER)\cycle.tex $(OS2)
+ -$(TEX) cycle.tex
+ rm $(OS2)\cycle.tex
+
+$(MASTER)\cycle.tex: $(MASTER)\cycle.web $(AWKWEAVE)
+ cd $(MASTER)
+ $(AWKWEAVE) cycle.web
+ cd $(OS2)
+
+$(OS2)\spider.dvi: $(MASTER)\spider.tex $(OS2)\awkweb.tex
+ copy $(MASTER)\spider.tex $(OS2)
+ -$(TEX) spider.tex
+ rm $(OS2)\spider.tex
+
+$(MASTER)\spider.tex: $(MASTER)\spider.web $(AWkWEAVE)
+ cd $(MASTER)
+ $(AWKWEAVE) spider.web
+ cd $(OS2)
+
+$(OS2)\atangle.dvi: $(AWK)\atangle.tex $(OS2)\cweb.tex
+ copy $(AWK)\atangle.tex $(OS2)
+ -$(TEX) atangle.tex
+ rm $(OS2)\atangle.tex
+
+$(AWK)\atangle.tex: $(MASTER)\tangle.web $(AWK)\outtoks.web
+ cd $(AWK)
+ copy $(MASTER)\common.h $(AWK)
+ copy $(MASTER)\tangle.web $(AWK)
+ $(CWEAVE) tangle.web
+ rename tangle.tex atangle.tex
+ cd $(OS2)
+
+$(OS2)\awkweave.dvi: $(AWK)\awkweave.tex $(OS2)\cweb.tex
+ copy $(AWK)\awkweave.tex $(OS2)
+ -$(TEX) awkweave.tex
+ rm $(OS2)\awkweave.tex
+
+$(AWK)\awkweave.tex: $(MASTER)\weave.web $(AWK)\grammar.web $(OS2)\weave.ch
+ cd $(AWK)
+ copy $(MASTER)\common.h $(AWK)
+ copy $(MASTER)\weave.web $(AWK)
+ $(CWEAVE) weave.web $(OS2)\weave.ch
+ rename weave.tex awkweave.tex
+ cd $(OS2)
+
+$(OS2)\ceeweave.dvi: $(C)\ceeweave.tex $(OS2)\cweb.tex
+ copy $(C)\ceeweave.tex $(OS2)
+ -$(TEX) ceeweave.tex
+ rm $(OS2)\ceeweave.tex
+
+$(C)\ceeweave.tex: $(MASTER)\weave.web $(C)\grammar.web $(OS2)\weave.ch
+ cd $(C)
+ copy $(MASTER)\common.h $(C)
+ copy $(MASTER)\weave.web $(C)
+ $(CWEAVE) weave.web $(OS2)\weave.ch
+ rename weave.tex ceeweave.tex
+ cd $(OS2)
+
+# I wanted to call this ceetangle.dvi, but tex386 only understands
+# the 8.3 filenames right now so ceetangle was one character too long.
+
+$(OS2)\ctangle.dvi: $(C)\ctangle.tex $(OS2)\cweb.tex
+ copy $(C)\ctangle.tex $(OS2)
+ -$(TEX) ctangle.tex
+ rm $(OS2)\ctangle.tex
+
+$(C)\ctangle.tex: $(MASTER)\tangle.web $(C)\outtoks.web
+ cd $(C)
+ copy $(MASTER)\common.h $(C)
+ copy $(MASTER)\tangle.web $(C)
+ $(CWEAVE) tangle.web
+ rename tangle.tex ctangle.tex
+ cd $(OS2)
+
+# This cleanup applies to the root directoru, master\, c\, and awk\.
+
+clean:
+ cd $(AWK)
+ -rm -f tangle.* weave.* common.*
+ -rm -f *.unsorted *.list grammar.web outtoks.web scraps.web
+ -rm -f cycle.test spider.slog *.obj
+ -rm -f *.c *.o *.tex *.toc *.dvi *.log *.makelog *~ *.wlog *.printlog
+ cd $(C)
+ -rm -f tangle.* weave.* common.*
+ -rm -f *.unsorted *.list grammar.web outtoks.web scraps.web
+ -rm -f cycle.test spider.slog *.obj
+ -rm -f *.c *.o *.tex *.toc *.dvi *.log *.makelog *~ *.wlog *.printlog
+ cd $(MASTER)
+ -rm -f *.tex *.obj common.c
+ cd $(OS2)
+ -rm -f *.dvi *.log *.toc
+
+$(CACM): $(DOC)\cacm.tex
+ copy $(DOC)\cacm.* $(OS2)
+ -$(LATEX) cacm
+ -rm -f cacm.tex cacm.aux cacm.log
+
+$(S_WEBMAN): $(DOC)\spiderwebman.tex
+ copy $(DOC)\spiderwebman.tex $(OS2)\s_webman.tex
+ -$(TEX) s_webman.tex
+ -rm -f *.log *.aux s_webman.tex
+
+$(S_MAN): $(DOC)\spiderman.tex
+ copy $(DOC)\spiderman.tex $(OS2)\s_man.tex
+ -$(LATEX) s_man.tex
+ -$(LATEX) s_man.tex
+ -rm -f *.log *.aux s_man.tex
+
+$(OVERVIEW): $(DOC)\overview.tex
+ copy $(DOC)\overview.tex $(OS2)
+ -$(LATEX) overview.tex
+ -$(LATEX) overview.tex
+ -rm -f *.log *.aux overview.tex
+
+
+
+
+
+
diff --git a/web/spiderweb/patches/001 b/web/spiderweb/patches/001
new file mode 100644
index 0000000000..02a21aedd8
--- /dev/null
+++ b/web/spiderweb/patches/001
@@ -0,0 +1,32 @@
+*** WebMakefile~ Thu Apr 6 19:53:39 1989
+--- WebMakefile Sat Apr 8 12:32:06 1989
+***************
+*** 134,139 ****
+--- 134,140 ----
+ boot:
+ cd ../master; rm -f *.o; for i in $(COMMONC); do \
+ cc $(CFLAGS) -c $$i; \
++ mv *.o $(OBDIR) ; \
+ done; cd ../c
+ cc $(CFLAGS) -c $(TANGLESRC).c; \
+ cc $(CFLAGS) -o $(DEST)/$(THETANGLE) $(COMMONOBJS) $(TANGLESRC).o
+*** spider.web~ Thu Apr 6 13:57:13 1989
+--- spider.web Sat Apr 8 12:49:58 1989
+***************
+*** 1133,1139 ****
+ if (tempfile==ttokfile) { ## output to \.{TANGLE}
+ #<If |t| is |"string"|, |"constant"|, or |"identifier"|,
+ just |continue|#> ## already defined in \.{TANGLE}
+! temp = temp + #'37 - highesttoken ## hackety hack!
+ }
+ printf "@d %s = %s\n", tokenname[t], temp > tempfile
+ }
+--- 1133,1140 ----
+ if (tempfile==ttokfile) { ## output to \.{TANGLE}
+ #<If |t| is |"string"|, |"constant"|, or |"identifier"|,
+ just |continue|#> ## already defined in \.{TANGLE}
+! temp = temp + #'37 + 3 - highesttoken ## hackety hack!
+! ## +3 because three highest are already defined!
+ }
+ printf "@d %s = %s\n", tokenname[t], temp > tempfile
+ }
diff --git a/web/spiderweb/patches/002 b/web/spiderweb/patches/002
new file mode 100644
index 0000000000..c120280709
--- /dev/null
+++ b/web/spiderweb/patches/002
@@ -0,0 +1,95 @@
+*** README.old Sat Apr 8 12:55:24 1989
+--- README Mon Apr 10 12:16:25 1989
+***************
+*** 33,38 ****
+--- 33,44 ----
+
+ 6) Go into WEBROOT and type `make boot'
+
++ Once this is successful you will have executable versions of tangle for
++ C and Awk, which is the minumum needed to make other things. After you've
++ done this, you can afford to `make clean', which will remove the .c and
++ .awk source you used to bootstrap yourself. You can always make them over
++ again using the executable versions (`make source').
++
+ 7) Move webkernel.tex into a place where TeX can find it
+
+
+*** Makefile.old Mon Apr 10 12:10:11 1989
+--- Makefile Mon Apr 10 12:14:16 1989
+***************
+*** 2,11 ****
+ # Not to be sold, but may be used freely for any purpose
+ # For more information, see file COPYRIGHT in the parent directory
+
+! # This is a SUN OS 4 Makefile. Sorry.
+
+ MAKE=make $(MFLAGS)
+ DIRECTORIES=ada awk c dijkstra larch penelope ssl doc master
+ clean:
+ @for i in $(DIRECTORIES); do \
+ cd $$i; \
+--- 2,16 ----
+ # Not to be sold, but may be used freely for any purpose
+ # For more information, see file COPYRIGHT in the parent directory
+
+! # This is a SUN OS 4 Makefile. Sorry. Makefiles in subdirectories
+! # should work under any reasonable Make.
+
+ MAKE=make $(MFLAGS)
+ DIRECTORIES=ada awk c dijkstra larch penelope ssl doc master
++
++ # Removes excess junk from the world, except it doesn't remove
++ # common object files from ./master
++ # This destroys the sources, so don't make clean until you've made boot.
+ clean:
+ @for i in $(DIRECTORIES); do \
+ cd $$i; \
+***************
+*** 16,34 ****
+ rm -f *~
+ @echo "All done."
+
+ source:
+ cd c ; $(MAKE) source ; cd ..
+ cd awk ; $(MAKE) source ; cd ..
+
+ distribution:
+ # $(MAKE) clean
+ # $(MAKE) source
+! tar cvhf spiderweb.tar README COPYRIGHT BUGS webkernel.tex Makefile $(DIRECTORIES)
+
+ boot:
+ cd c; $(MAKE) boot; cd ..
+ cd awk; $(MAKE) boot; cd ..
+
+ all:
+ @for i in $(DIRECTORIES); do \
+ cd $$i; \
+--- 21,46 ----
+ rm -f *~
+ @echo "All done."
+
++ # This creates the minimum sources in preparation for `make distribution'
+ source:
+ cd c ; $(MAKE) source ; cd ..
+ cd awk ; $(MAKE) source ; cd ..
+
++ # Put everything into a tar file. Must `make source' first, and should clean
+ distribution:
+ # $(MAKE) clean
++ cd master ; make superclean ; cd .. # remove common .o from master
+ # $(MAKE) source
+! tar cvhf spiderweb.tar README COPYRIGHT BUGS webkernel.tex \
+! Makefile $(DIRECTORIES)
+
++ # Used to bring up the system when first installing it. Requires sources,
++ # either from the distribution tarfile or from `make source'
+ boot:
+ cd c; $(MAKE) boot; cd ..
+ cd awk; $(MAKE) boot; cd ..
+
++ # Make all known webs. For lunatics only.
+ all:
+ @for i in $(DIRECTORIES); do \
+ cd $$i; \
diff --git a/web/spiderweb/patches/003 b/web/spiderweb/patches/003
new file mode 100644
index 0000000000..e5d5931076
--- /dev/null
+++ b/web/spiderweb/patches/003
@@ -0,0 +1,179 @@
+*** doc/cacm.tex.old Thu Apr 6 14:01:25 1989
+--- doc/cacm.tex Mon Apr 10 14:47:13 1989
+***************
+*** 182,188 ****
+ \put(125,30){\line(-1,-1){10}}
+ \put(115,20){\vector(-1,0){25}}
+
+! \put(104,21.5){\makebox(0,0)[b]{\scriptsize\sl CWEAVE}}
+
+ \put(60,15){\framebox(30,10){xtangle.c}}
+ \put(60,-25){\framebox(30,10){xweave.c}}
+--- 182,188 ----
+ \put(125,30){\line(-1,-1){10}}
+ \put(115,20){\vector(-1,0){25}}
+
+! \put(104,21.5){\makebox(0,0)[b]{\scriptsize\sl CTANGLE}}
+
+ \put(60,15){\framebox(30,10){xtangle.c}}
+ \put(60,-25){\framebox(30,10){xweave.c}}
+*** Makefile.old Mon Apr 10 11:14:16 1989
+--- Makefile Tue Apr 11 11:51:42 1989
+***************
+*** 29,35 ****
+ # Put everything into a tar file. Must `make source' first, and should clean
+ distribution:
+ # $(MAKE) clean
+- cd master ; make superclean ; cd .. # remove common .o from master
+ # $(MAKE) source
+ tar cvhf spiderweb.tar README COPYRIGHT BUGS webkernel.tex \
+ Makefile $(DIRECTORIES)
+--- 29,34 ----
+*** master/Makefile.old Thu Apr 6 19:37:11 1989
+--- master/Makefile Tue Apr 11 11:55:29 1989
+***************
+*** 2,12 ****
+ # Not to be sold, but may be used freely for any purpose
+ # For more information, see file COPYRIGHT in the parent directory
+
+ clean:
+ -rm -f *.tex *.dvi *.log *.wlog *~ *.toc
+
+ superclean:
+! -rm -f *.c *.o
+ -rm -f *.tex *.dvi *.log *~ *.toc
+- -rm -f sun3/*.o vax/*.o
+
+--- 2,18 ----
+ # Not to be sold, but may be used freely for any purpose
+ # For more information, see file COPYRIGHT in the parent directory
+
++ OBJECTDIRS=sun3 vax
++
+ clean:
+ -rm -f *.tex *.dvi *.log *.wlog *~ *.toc
++ @-for i in $(OBJECTDIRS); do \
++ rm -f $$i/*.o; \
++ done
++ -rm -f *.o
+
+ superclean:
+! -rm -f sun3/*.o vax/*.o *.o
+! -rm -f *.c
+ -rm -f *.tex *.dvi *.log *~ *.toc
+
+*** master/spider.web.old Tue Apr 11 13:19:58 1989
+--- master/spider.web Tue Apr 11 14:02:06 1989
+***************
+*** 1939,1945 ****
+ if (n%5==0)
+ print "@ @<Test for all of the productions@>=" \
+ > grammarfile ## avoids overflowing \.{WEAVE} of \.{WEAVE}
+! #<Remove \vert\ from |inputline[n]| and put results in |this_string|#>
+ #<Make |this_string| no more than 60 characters wide#>
+ printf "if (%s) {\n\t/* %d: {\\tt %s} */\n%s",\
+ prodtest[n],n,this_string,prodtrans[n] > grammarfile
+--- 1939,1945 ----
+ if (n%5==0)
+ print "@ @<Test for all of the productions@>=" \
+ > grammarfile ## avoids overflowing \.{WEAVE} of \.{WEAVE}
+! #<Change \vert,\_, and {\tt \##} in |inputline[n]|; put results in |this_string|#>
+ #<Make |this_string| no more than 60 characters wide#>
+ printf "if (%s) {\n\t/* %d: {\\tt %s} */\n%s",\
+ prodtest[n],n,this_string,prodtrans[n] > grammarfile
+***************
+*** 1991,2005 ****
+ # It's desirable to put the production in a comment, but we have to
+ get rid of the confusing \vert, or \.{WEAVE} will think it introduces
+ code.
+! #<Remove \vert\ from |inputline[n]| and put results in |this_string|#>=
+! this_string = inputline[n]
+ tempi = index(this_string,"|")
+! while (tempi != 0) {
+! tempa = substr(this_string,1,tempi-1)
+! tempb = substr(this_string,tempi+1)
+! this_string = tempa "\\vert " tempb
+! tempi = index(this_string,"|")
+! }
+
+
+ # We have to keep these productions from making an input line too long.
+--- 1991,2025 ----
+ # It's desirable to put the production in a comment, but we have to
+ get rid of the confusing \vert, or \.{WEAVE} will think it introduces
+ code.
+! We also have to escape underscores and sharp signs, otherwise \TeX\ will
+! think we want math mode.
+! #<Change \vert,\_, and {\tt \##} in |inputline[n]|; put results in |this_string|#>=
+! this_string = inputline[n]
+! tempi = index(this_string,"|")
+! while (tempi != 0) {
+! tempa = substr(this_string,1,tempi-1)
+! tempb = substr(this_string,tempi+1)
+! this_string = tempa "\\vert " tempb
+ tempi = index(this_string,"|")
+! }
+! templ = ""; tempr = this_string
+! tempi = index(tempr,"_")
+! while (tempi != 0) {
+! tempa = substr(tempr,1,tempi-1)
+! tempr = substr(tempr,tempi+1)
+! templ = templ tempa "\\_"
+! tempi = index(tempr,"_")
+! }
+! this_string = templ tempr
+! templ = ""; tempr = this_string
+! tempi = index(tempr,"##")
+! while (tempi != 0) {
+! tempa = substr(tempr,1,tempi-1)
+! tempr = substr(tempr,tempi+1)
+! templ = templ tempa "\\##"
+! tempi = index(tempr,"##")
+! }
+! this_string = templ tempr
+
+
+ # We have to keep these productions from making an input line too long.
+*** doc/spiderwebman.tex.old Thu Apr 6 14:01:32 1989
+--- doc/spiderwebman.tex Tue Apr 11 14:24:39 1989
+***************
+*** 579,599 ****
+ can define two kinds of macros to make the programs shorter and more
+ readable.
+
+! \yskip\hang`\.{@d} \\{identifier} \PASCAL\ text' defines a {\sl
+ simple\/} macro, where the identifier will be replaced by the \PASCAL\ text
+ when \.{TANGLE} produces its output.
+
+! \yskip\hang`\.{@d} \\{identifier}\.{(\\{ actual identifiers})} \PASCAL\ text' defines a
+ {\sl parametric\/} macro, where the identifier will be replaced by the \PASCAL\
+ text and where occurrences of the \\{identifiers} in that \PASCAL\ text will be
+ replaced by arguments.
+
+! C programmers will recognize the C macro processor.
+! The implementation relies on the C preprocessor to expand the macros.
+! The author of \.{Spider} \.{WEB} intends to correct this unfortunate
+! historical accident at the earliest opportunity, by restoring
+! \.{WEB}'s built-in macro processor.
+!
+
+
+
+--- 579,595 ----
+ can define two kinds of macros to make the programs shorter and more
+ readable.
+
+! \yskip\hang`\.{@d} \\{identifier} = \PASCAL\ text' defines a {\sl
+ simple\/} macro, where the identifier will be replaced by the \PASCAL\ text
+ when \.{TANGLE} produces its output.
+
+! \yskip\hang`\.{@d} \\{identifier}\.{(\\{ actual identifiers})} = \PASCAL\ text' defines a
+ {\sl parametric\/} macro, where the identifier will be replaced by the \PASCAL\
+ text and where occurrences of the \\{identifiers} in that \PASCAL\ text will be
+ replaced by arguments.
+
+! For C programmers, this is similar to the C macro processor.
+! \endnewstuff
+
+
+
diff --git a/web/spiderweb/patches/004 b/web/spiderweb/patches/004
new file mode 100644
index 0000000000..72dee88b34
--- /dev/null
+++ b/web/spiderweb/patches/004
@@ -0,0 +1,70 @@
+*** master/weave.web.old Fri Apr 14 12:31:34 1989
+--- master/weave.web Fri Apr 14 12:33:28 1989
+***************
+*** 353,359 ****
+
+ @d ignore = 0 /* control code of no interest to \.{CWEAVE} */
+ @d verbatim = @'2 /* extended ASCII alpha will not appear */
+! @d tangle_force_line = @'3 /* extended ASCII beta will not appear */
+ @d begin_comment = @'10 /* ASCII tab mark will not appear */
+ @d octal = @'14 /* ASCII carriage return will not appear */
+ @d hex = @'15 /* ASCII form feed will not appear */
+--- 353,359 ----
+
+ @d ignore = 0 /* control code of no interest to \.{CWEAVE} */
+ @d verbatim = @'2 /* extended ASCII alpha will not appear */
+! /* extended ASCII beta will not appear */
+ @d begin_comment = @'10 /* ASCII tab mark will not appear */
+ @d octal = @'14 /* ASCII carriage return will not appear */
+ @d hex = @'15 /* ASCII form feed will not appear */
+***************
+*** 395,401 ****
+ ccode['-']=line_break;
+ ccode['#']=big_line_break;
+ ccode['=']=verbatim;
+- ccode['\\']=tangle_force_line;
+ ccode['d']=ccode['D']=definition;
+ ccode['f']=ccode['F']=format;
+ ccode['c']=ccode['C']=begin_unnamed;
+--- 395,400 ----
+***************
+*** 2026,2032 ****
+ break;
+ case xref_roman: case xref_wildcard: case xref_typewriter:
+ break;
+- case tangle_force_line: app_str("\\]"); app_scrap(SP_ignore_scrap,yes_math); break;
+ case thin_space: app_str("\\,"); app_scrap(SP_ignore_scrap,yes_math); break;
+ case math_break:
+ small_app(opt); app_str("0"); app_scrap(SP_ignore_scrap,yes_math); break;
+--- 2025,2030 ----
+*** doc/spiderwebman.tex.old Fri Apr 14 12:32:11 1989
+--- doc/spiderwebman.tex Fri Apr 14 12:39:57 1989
+***************
+*** 952,958 ****
+ \@= [\PAS] The ``control text'' that follows, up to the next `\.{@>}', will
+ be passed verbatim to the \PASCAL\ program.
+
+! \@\\ [\PAS] Force end-of-line here in the \PASCAL\ program file.
+
+ \@! [\PAS,T] The module number in an index entry will be underlined if `\.{@!}'
+ immediately precedes the identifier or control text being indexed.
+--- 952,958 ----
+ \@= [\PAS] The ``control text'' that follows, up to the next `\.{@>}', will
+ be passed verbatim to the \PASCAL\ program.
+
+! %%% \@\\ [\PAS] Force end-of-line here in the \PASCAL\ program file.
+
+ \@! [\PAS,T] The module number in an index entry will be underlined if `\.{@!}'
+ immediately precedes the identifier or control text being indexed.
+***************
+*** 982,987 ****
+--- 982,990 ----
+ \@?
+ [\PAS,T] This cancels an implicit (or explicit) `\.{@!}', so that the next
+ index entry will not be underlined.
++
++ \newstuff This is not implemented in the current version of Spidery \.{WEB}.
++ \endnewstuff
+
+ \@, [\PAS] This control code inserts a thin space in \.{WEAVE}'s output; it is
+ ignored by \.{TANGLE}.
diff --git a/web/spiderweb/patches/005 b/web/spiderweb/patches/005
new file mode 100644
index 0000000000..52f9a47999
--- /dev/null
+++ b/web/spiderweb/patches/005
@@ -0,0 +1,74 @@
+*** master/spider.web~ Tue Apr 11 14:02:06 1989
+--- master/spider.web Mon Jul 3 12:46:05 1989
+***************
+*** 772,778 ****
+ } else if (length($2)>1) {
+ #<Handle multicharacter tokens#>
+ } else {
+! temp = sprintf "'%s'", $2
+ tokenname[$2] = temp
+ tokenlength[$2]=1
+ }
+--- 772,778 ----
+ } else if (length($2)>1) {
+ #<Handle multicharacter tokens#>
+ } else {
+! temp = sprintf("'%s'", $2)
+ tokenname[$2] = temp
+ tokenlength[$2]=1
+ }
+***************
+*** 791,797 ****
+ tokennumbers[$2]=tokennumber
+ tokennumber--
+ ## figure out how to recognize the token
+! temp = sprintf "strncmp(\"%s\",loc-1,%d)==0", $2, length($2)
+ tokentest[$2]=temp
+ tokenlength[$2]=length($2)
+
+--- 791,797 ----
+ tokennumbers[$2]=tokennumber
+ tokennumber--
+ ## figure out how to recognize the token
+! temp = sprintf( "strncmp(\"%s\",loc-1,%d)==0", $2, length($2))
+ tokentest[$2]=temp
+ tokenlength[$2]=length($2)
+
+***************
+*** 1738,1744 ****
+ $i = substr($i,2) ## peel off the \##
+ #<Make sure |1 <= $i < arrowpos|#>
+ targetcategory[prodnum]="Unnamed category"
+! temp = sprintf "(pp+%d)->cat", $i-1
+ unnamed_cat[prodnum]=temp
+ } else if ($i ~ #=/[a-z][a-z_]*/#>) { ## a category
+ targetcategory[prodnum]=$i
+--- 1738,1744 ----
+ $i = substr($i,2) ## peel off the \##
+ #<Make sure |1 <= $i < arrowpos|#>
+ targetcategory[prodnum]="Unnamed category"
+! temp = sprintf("(pp+%d)->cat", $i-1)
+ unnamed_cat[prodnum]=temp
+ } else if ($i ~ #=/[a-z][a-z_]*/#>) { ## a category
+ targetcategory[prodnum]=$i
+*** webkernel.tex.old Mon Jun 26 12:32:33 1989
+--- webkernel.tex Mon Jun 26 12:35:38 1989
+***************
+*** 218,224 ****
+ \global\output{\normaloutput\page\lheader\rheader\lfooter\rfooter}}
+ \setpage
+ \vbox to \vsize{} % the first \topmark won't be null
+! \eject
+ \write\cont{\string\catcode`\string\@=11}% a hack to make contents
+ % take stuff in \.{---}
+
+--- 218,226 ----
+ \global\output{\normaloutput\page\lheader\rheader\lfooter\rfooter}}
+ \setpage
+ \vbox to \vsize{} % the first \topmark won't be null
+! % Delete as per bug report from kademan@stat.wisc.edu
+! % Causes headings on first page to be missing
+! % \eject
+ \write\cont{\string\catcode`\string\@=11}% a hack to make contents
+ % take stuff in \.{---}
+
diff --git a/web/spiderweb/patches/006 b/web/spiderweb/patches/006
new file mode 100644
index 0000000000..361103571a
--- /dev/null
+++ b/web/spiderweb/patches/006
@@ -0,0 +1,92 @@
+*** master/spider.web.old Mon Jul 3 12:46:05 1989
+--- master/spider.web Thu Jul 20 19:00:04 1989
+***************
+*** 1532,1537 ****
+--- 1532,1541 ----
+ each scrap is true, the whole production will fire.
+ If we're called upon to make a scrap underlined or reserved, we'll add
+ to |trans[pos]|.
++
++ If a category is negated we add an extra clause to make
++ sure nothing matches the zero category, since {\tt WEAVE} assumes
++ no production ever matches a scrap with category zero.
+ #<Process a single category#>=
+ field[pos]=$i ## save this field to compare RHS
+ #<Set |negation|, and remove leading |"!"| from |$i| if necessary#>
+***************
+*** 1540,1548 ****
+ cat = $i
+ categories[cat]=1 ## remember |cat| is a category
+ if (negation==0) {
+! test[pos]=sprintf("(pp+%d)->cat==SP_%s",pos-1,cat)
+ } else {
+! test[pos]=sprintf("(pp+%d)->cat!=SP_%s",pos-1,cat)
+ }
+ #<Update the record of the rightmost occurrence of category |cat|#>
+ #<Advance |pos|, making the new |trans[pos]| empty#>
+--- 1544,1553 ----
+ cat = $i
+ categories[cat]=1 ## remember |cat| is a category
+ if (negation==0) {
+! test[pos]=sprintf("(pp+%d)->cat==SP_%s",pos-1,cat)
+ } else {
+! test[pos]=sprintf("((pp+%d)->cat!=SP_%s && (pp+%d)->cat != 0)",\
+! pos-1,cat,pos-1)
+ }
+ #<Update the record of the rightmost occurrence of category |cat|#>
+ #<Advance |pos|, making the new |trans[pos]| empty#>
+***************
+*** 1551,1556 ****
+--- 1556,1565 ----
+ categories are separated by vertical bars.
+ We have to make the test for these things a disjunction, but
+ processing is more or less like the processing for a single category.
++
++ If a list of alternatives is negated we add an extra clause to make
++ sure nothing matches the zero category, since {\tt WEAVE} assumes
++ no production ever matches a scrap with category zero.
+ #<Process a list of alternative categories#>=
+ field[pos]=$i ## save this field to compare RHS
+ #<Set |negation|, and remove leading |"!"| from |$i| if necessary#>
+***************
+*** 1557,1563 ****
+ if (negation==0) {
+ test[pos]="(" ## open for a list of good alternatives
+ } else {
+! test[pos]="!(" ## open for a list of bad alternatives
+ }
+ #<Strip stars from |$i| (if any) and add appropriate
+ translations to |trans[pos]|#>
+--- 1566,1573 ----
+ if (negation==0) {
+ test[pos]="(" ## open for a list of good alternatives
+ } else {
+! temp=sprintf("(pp+%d)->cat==0",pos-1)
+! test[pos]="!(" temp "||" ## open for a list of bad alternatives
+ }
+ #<Strip stars from |$i| (if any) and add appropriate
+ translations to |trans[pos]|#>
+***************
+*** 1635,1644 ****
+ #<Forget this production#>
+ }
+
+! # Wild cards are easy to process
+ #<Process a category wild card#>=
+ field[pos]=$i ## save this field to compare RHS
+! test[pos]="(1)" ## anything matches
+ highwildcard=pos ## we don't really need this?
+ #<Advance |pos|, making the new |trans[pos]| empty#>
+
+--- 1645,1655 ----
+ #<Forget this production#>
+ }
+
+! # Wild cards are easy to process, but we do have to remember that
+! not even a wild card matches a scrap of category zero.
+ #<Process a category wild card#>=
+ field[pos]=$i ## save this field to compare RHS
+! test[pos]=sprintf("(pp+%d)->cat!=0",pos-1) ## anything nonzero matches
+ highwildcard=pos ## we don't really need this?
+ #<Advance |pos|, making the new |trans[pos]| empty#>
+
diff --git a/web/spiderweb/patches/007 b/web/spiderweb/patches/007
new file mode 100644
index 0000000000..0dc52bbdad
--- /dev/null
+++ b/web/spiderweb/patches/007
@@ -0,0 +1,188 @@
+*** master/spider.web.old Wed Aug 23 14:08:45 1989
+--- master/spider.web Wed Aug 23 14:03:12 1989
+***************
+*** 314,322 ****
+
+ # If the macro facility worked right,
+ we would use the following patterns to recognize items as they occur:
+! #d cat_pattern = #=/[a-z][a-z_]*/#>
+! #d trans_pattern = #=/<(([0-9]|[a-z][a-z_]*|"([^"]*\\")*[^"]*"|\*)-)*#>#&
+! #=([0-9]|[a-z][a-z_]*|"([^"]*\\")*[^"]*"|\*)>/#>
+
+ # Here's where we swallow a translation and spit out the \.{WEAVE} code
+ to handle that translation.
+--- 314,322 ----
+
+ # If the macro facility worked right,
+ we would use the following patterns to recognize items as they occur:
+! #d cat_pattern = #=/[a-zA-Z][a-zA-Z_]*/#>
+! #d trans_pattern = #=/<(([0-9]|[a-zA-Z][a-zA-Z_]*|"([^"]*\\")*[^"]*"|\*)-)*#>#&
+! #=([0-9]|[a-zA-Z][a-zA-Z_]*|"([^"]*\\")*[^"]*"|\*)>/#>
+
+ # Here's where we swallow a translation and spit out the \.{WEAVE} code
+ to handle that translation.
+***************
+*** 341,347 ****
+ if (alternate ~ #=/^[0-9]$/#>) { ## digit
+ temp = sprintf("\tapp_str(\"%s\");\n",alternate)
+ outstring=outstring temp
+! } else if (alternate ~ #=/^[a-z_]+$/#>) { ## key word
+ translation_keywords[alternate]=1 ## remember
+ temp = sprintf("\t%s(%s);\n",append_keyword,alternate)
+ ##Call |app| or |small_app| depending whether we're reducing or creating scraps
+--- 341,347 ----
+ if (alternate ~ #=/^[0-9]$/#>) { ## digit
+ temp = sprintf("\tapp_str(\"%s\");\n",alternate)
+ outstring=outstring temp
+! } else if (alternate ~ #=/^[a-zA-Z_]+$/#>) { ## key word
+ translation_keywords[alternate]=1 ## remember
+ temp = sprintf("\t%s(%s);\n",append_keyword,alternate)
+ ##Call |app| or |small_app| depending whether we're reducing or creating scraps
+***************
+*** 394,400 ****
+ if (alternate ~ #=/^[0-9]$/#>) { ## digit
+ print "Digit not allowed in restricted translation", wherestring
+ exitcode = -1
+! } else if (alternate ~ #=/^[a-z_]+$/#>) { ## key word
+ print "Key word not allowed in restricted translation", wherestring
+ exitcode = -1
+ } else if (alternate ~ #=/^\"([^"]*\\\")*[^"]*\"$/#>) { ## string
+--- 394,400 ----
+ if (alternate ~ #=/^[0-9]$/#>) { ## digit
+ print "Digit not allowed in restricted translation", wherestring
+ exitcode = -1
+! } else if (alternate ~ #=/^[a-zA-Z_]+$/#>) { ## key word
+ print "Key word not allowed in restricted translation", wherestring
+ exitcode = -1
+ } else if (alternate ~ #=/^\"([^"]*\\\")*[^"]*\"$/#>) { ## string
+***************
+*** 576,582 ****
+ #<Process newline token description#>
+ } else if ($2=="pseudo_semi") {
+ #<Process |pseudo_semi| token description#>
+! } else if ($2 ~ #=/[a-zA-Z0-9]+/#>) {
+ ## we recognize no other names
+ print "Error: unknown token species:", $2
+ #<Punt this command#>
+--- 576,582 ----
+ #<Process newline token description#>
+ } else if ($2=="pseudo_semi") {
+ #<Process |pseudo_semi| token description#>
+! } else if ($2 ~ #=/[a-zA-ZA-Z0-9]+/#>) {
+ ## we recognize no other names
+ print "Error: unknown token species:", $2
+ #<Punt this command#>
+***************
+*** 1200,1206 ****
+ that an item of ilk |fish_like| will get category |fish|.
+
+ #<If no category is specified, invent a default if you can#>=
+! if ($2 ~ #=/^[a-z_]+_like$/#> && $0 !~ #=/ category /#>) {
+ ## give default category
+ this_category = substr($2,1,length($2)-5)
+ categories[this_category]=1
+--- 1200,1206 ----
+ that an item of ilk |fish_like| will get category |fish|.
+
+ #<If no category is specified, invent a default if you can#>=
+! if ($2 ~ #=/^[a-zA-Z_]+_like$/#> && $0 !~ #=/ category /#>) {
+ ## give default category
+ this_category = substr($2,1,length($2)-5)
+ categories[this_category]=1
+***************
+*** 1490,1498 ****
+ for (i=1; i<=NF; i++) {
+ if ($i ~ #=/<.*>/#>) { ## should be |trans_pattern|
+ #<Process a translation in |$i|#>
+! } else if ($i ~ #=/^!?[a-z_]+(\*\*?)?$/#>) { ## |cat_pattern|
+ #<Process a single category#>
+! } else if ($i ~ #=/^!?\(([a-z_]+\|)*[a-z_]+\)(\*\*?)?$/#>){
+ #<Process a list of alternative categories#>
+ } else if ($i == "?") {
+ #<Process a category wild card#>
+--- 1490,1498 ----
+ for (i=1; i<=NF; i++) {
+ if ($i ~ #=/<.*>/#>) { ## should be |trans_pattern|
+ #<Process a translation in |$i|#>
+! } else if ($i ~ #=/^!?[a-zA-Z_]+(\*\*?)?$/#>) { ## |cat_pattern|
+ #<Process a single category#>
+! } else if ($i ~ #=/^!?\(([a-zA-Z_]+\|)*[a-zA-Z_]+\)(\*\*?)?$/#>){
+ #<Process a list of alternative categories#>
+ } else if ($i == "?") {
+ #<Process a category wild card#>
+***************
+*** 1632,1642 ****
+
+ #<Strip stars from |$i| (if any) and add appropriate
+ translations to |trans[pos]|#>=
+! if ($i ~ #=/^([a-z_]+|\(([a-z_]+\|)*[a-z_]+\))\*\*$/#>) { ## it's double-starred
+ temp = sprintf("\tmake_underlined(pp+%d);\n",pos-1)
+ trans[pos] = trans[pos] temp
+ $i = substr($i,1,length($i)-2)
+! } else if ($i ~ #=/^([a-z_]+|\(([a-z_]+\|)*[a-z_]+\))\*$/#>) { ## it's starred
+ temp = sprintf("\tmake_underlined(pp+%d);\n",pos-1)
+ trans[pos] = trans[pos] temp
+ $i = substr($i,1,length($i)-1)
+--- 1632,1642 ----
+
+ #<Strip stars from |$i| (if any) and add appropriate
+ translations to |trans[pos]|#>=
+! if ($i ~ #=/^([a-zA-Z_]+|\(([a-zA-Z_]+\|)*[a-zA-Z_]+\))\*\*$/#>) { ## it's double-starred
+ temp = sprintf("\tmake_underlined(pp+%d);\n",pos-1)
+ trans[pos] = trans[pos] temp
+ $i = substr($i,1,length($i)-2)
+! } else if ($i ~ #=/^([a-zA-Z_]+|\(([a-zA-Z_]+\|)*[a-zA-Z_]+\))\*$/#>) { ## it's starred
+ temp = sprintf("\tmake_underlined(pp+%d);\n",pos-1)
+ trans[pos] = trans[pos] temp
+ $i = substr($i,1,length($i)-1)
+***************
+*** 1751,1757 ****
+ targetcategory[prodnum]="Unnamed category"
+ temp = sprintf("(pp+%d)->cat", $i-1)
+ unnamed_cat[prodnum]=temp
+! } else if ($i ~ #=/[a-z][a-z_]*/#>) { ## a category
+ targetcategory[prodnum]=$i
+ categories[$i]=1 ## remember this is a category
+ } else {
+--- 1751,1757 ----
+ targetcategory[prodnum]="Unnamed category"
+ temp = sprintf("(pp+%d)->cat", $i-1)
+ unnamed_cat[prodnum]=temp
+! } else if ($i ~ #=/[a-zA-Z][a-zA-Z_]*/#>) { ## a category
+ targetcategory[prodnum]=$i
+ categories[$i]=1 ## remember this is a category
+ } else {
+***************
+*** 1827,1833 ****
+ temp = field[pos]
+ tempa = substr(temp,1,1)
+ if (tempa != "!") {
+! if (temp ~ #=/^\(([a-z_]+\|)*[a-z_]+\)(\*\*?)?$/#>) {
+ ## list of alternatives
+ #<Remove trailing stars from |temp|#>
+ temp = substr(temp,2,length(temp)-2)
+--- 1827,1833 ----
+ temp = field[pos]
+ tempa = substr(temp,1,1)
+ if (tempa != "!") {
+! if (temp ~ #=/^\(([a-zA-Z_]+\|)*[a-zA-Z_]+\)(\*\*?)?$/#>) {
+ ## list of alternatives
+ #<Remove trailing stars from |temp|#>
+ temp = substr(temp,2,length(temp)-2)
+***************
+*** 1836,1842 ****
+ alternate = tok[j]
+ reduced[alternate]=1
+ }
+! } else if (temp ~ #=/^[a-z_]+(\*\*?)?$/#>) {
+ #<Remove trailing stars from |temp|#>
+ reduced[temp]=1
+ } else if (temp != "?") {
+--- 1836,1842 ----
+ alternate = tok[j]
+ reduced[alternate]=1
+ }
+! } else if (temp ~ #=/^[a-zA-Z_]+(\*\*?)?$/#>) {
+ #<Remove trailing stars from |temp|#>
+ reduced[temp]=1
+ } else if (temp != "?") {
diff --git a/web/spiderweb/patches/008 b/web/spiderweb/patches/008
new file mode 100644
index 0000000000..d0e0615e3a
--- /dev/null
+++ b/web/spiderweb/patches/008
@@ -0,0 +1,29 @@
+*** c/c.spider.old Wed Nov 29 22:48:59 1989
+--- c/c.spider Wed Nov 29 21:55:48 1989
+***************
+*** 18,28 ****
+
+ token + category unorbinop
+ token - category unorbinop
+! token * category unorbinop translation <"{*}">
+ token / category dot
+ token < category less translation <>
+ token > category greater translation <>
+ token = category equals translation <"\\leftarrow"> tangleto <"="-space>
+ token . category dot
+ token ~ category unop translation <"\\TI">
+ token & category unorbinop translation <"\\amp">
+--- 18,30 ----
+
+ token + category unorbinop
+ token - category unorbinop
+! token * category unorbinop translation <"{*}"> tangleto <space-"*">
+! # avoid inadvertant /*
+ token / category dot
+ token < category less translation <>
+ token > category greater translation <>
+ token = category equals translation <"\\leftarrow"> tangleto <"="-space>
++ # avoid inadvertant =-
+ token . category dot
+ token ~ category unop translation <"\\TI">
+ token & category unorbinop translation <"\\amp">
diff --git a/web/spiderweb/patches/009 b/web/spiderweb/patches/009
new file mode 100644
index 0000000000..ce36467111
--- /dev/null
+++ b/web/spiderweb/patches/009
@@ -0,0 +1,44 @@
+*** master/WebMakefile.old Mon Jan 22 13:26:49 1990
+--- master/WebMakefile Mon Jan 22 13:32:40 1990
+***************
+*** 70,76 ****
+ $(MASTER)/common.c: $(MASTER)/common.web # no change file
+ $(CTANGLE) $(MASTER)/common
+
+! $(OBDIR)/common.o: $(MASTER)/common.c
+ $(CC) $(CFLAGS) -c $(MASTER)/common.c
+ mv common.o $(OBDIR)
+
+--- 70,76 ----
+ $(MASTER)/common.c: $(MASTER)/common.web # no change file
+ $(CTANGLE) $(MASTER)/common
+
+! $(OBDIR)/common.o: $(MASTER)/common.c $(OBDIR)
+ $(CC) $(CFLAGS) -c $(MASTER)/common.c
+ mv common.o $(OBDIR)
+
+***************
+*** 79,88 ****
+ $(CTANGLE) $(MASTER)/pathopen
+ mv pathopen.h $(MASTER)
+
+! $(OBDIR)/pathopen.o: $(MASTER)/pathopen.c
+ $(CC) $(CFLAGS) -c $(MASTER)/pathopen.c
+ mv pathopen.o $(OBDIR)
+
+
+ ## Now we make the tangle and weave source locally
+
+--- 79,90 ----
+ $(CTANGLE) $(MASTER)/pathopen
+ mv pathopen.h $(MASTER)
+
+! $(OBDIR)/pathopen.o: $(MASTER)/pathopen.c $(OBDIR)
+ $(CC) $(CFLAGS) -c $(MASTER)/pathopen.c
+ mv pathopen.o $(OBDIR)
+
++ $(OBDIR):
++ if /bin/test ! -d $(OBDIR) ; then mkdir $(OBDIR) ; fi
+
+ ## Now we make the tangle and weave source locally
+
diff --git a/web/spiderweb/patches/010 b/web/spiderweb/patches/010
new file mode 100644
index 0000000000..fca8083e4c
--- /dev/null
+++ b/web/spiderweb/patches/010
@@ -0,0 +1,36 @@
+*** master/weave.web.old Thu Feb 8 12:55:12 1990
+--- master/weave.web Thu Feb 8 12:55:50 1990
+***************
+*** 254,260 ****
+ (mod_xref_switch==file_flag && q->num < file_flag)) {
+ printf("\n! You can't use <"); print_id(p);
+ printf("> both as a file and as a named module"); mark_harmless;
+! @.{You can't use <section name> both as a file...@>
+
+ }
+ }
+--- 254,260 ----
+ (mod_xref_switch==file_flag && q->num < file_flag)) {
+ printf("\n! You can't use <"); print_id(p);
+ printf("> both as a file and as a named module"); mark_harmless;
+! @.You can't use <section name> both as a file...@>
+
+ }
+ }
+***************
+*** 968,974 ****
+ if ((cur_xref->num)/def_flag != level) {
+ printf("\n! You can't use <"); print_id(p);
+ printf("> both as a file and as a named module"); mark_harmless;
+! @.{You can't use <section name> both as a file...@>
+ }
+ cur_xref=cur_xref->xlink;
+ }
+--- 968,974 ----
+ if ((cur_xref->num)/def_flag != level) {
+ printf("\n! You can't use <"); print_id(p);
+ printf("> both as a file and as a named module"); mark_harmless;
+! @.You can't use <section name> both as a file...@>
+ }
+ cur_xref=cur_xref->xlink;
+ }
diff --git a/web/spiderweb/src/68k/68k.spider b/web/spiderweb/src/68k/68k.spider
new file mode 100644
index 0000000000..b3f7a8943a
--- /dev/null
+++ b/web/spiderweb/src/68k/68k.spider
@@ -0,0 +1,569 @@
+# 68k.spider
+# Copyright (C) 1991,1992 by Izumi Watanabe, FUJI PHOTO FILM co., ltd.
+# email address nabe@miya.fujifilm.co.jp
+# This source is trial to generate an assembler-WEB.
+#
+# For Assembler weave, I use simple idea;
+# label, opecode and operands are in a TeX's \hbox.
+
+language asm-68K extension 68k
+at_sign @
+
+comment begin <";"> end newline
+line begin <";"-space-"line"> end <"">
+
+default translation <*> mathness yes
+
+token identifier category sym mathness yes
+token number category math mathness yes
+token newline category ignore_scrap mathness no translation <>
+token pseudo_semi category ignore_scrap mathness maybe translation <>
+
+module definition stmt use pure_stmt
+
+macros begin
+\def\opsize{6em}
+\def\opbox#1{\hbox to\opsize{#1\hfill}} % Use in code
+\def\popbox#1{#1\quad} % Use in comments
+\def\OPbox#1{{\let\&=\. \opbox{#1}}}
+#\def\REGbox#1{\let\&=\. \hbox{#1}}
+\def\REGbox#1{#1}
+\def\Lbox{\hbox to 1em{}}
+\def\C#1{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % redefine: comments
+ \XX\hfil\penalty-1\hfilneg\quad
+ $\commentbegin\,${\let\opbox=\popbox #1}$\,\commentend$\XX}
+macros end
+
+default translation <*> mathness yes
+token . category dot
+token + category unorbinop tangleto <space-"+">
+token - category unorbinop tangleto <space-dash>
+token * category binop
+token / category binop
+token , category camma translation <",\\;">
+token ( category open tangleto <space-"(">
+token [ category open tangleto <space-"[">
+token { translation <"\\{"> category open tangleto <space-"{">
+token ) category close
+token ] category close
+token } translation <"\\}"> category close
+token : category colon tangleto <":"-space>
+token # category unop translation <"\\#"> tangleto <space-"#">
+#token ` category unop translation <"'"> mathness yes
+#token ; category semi
+token < category open tangleto <space-"<">
+token > category close
+#token = category binop
+#token ! category unop translation <"\\lnot">
+#token & category binop translation <"\\land">
+#token || category binop translation <"\\lor">
+#token | category unop
+#token != name not_eq translation <"\\I"> category binop
+#token <= name lt_eq translation <"\\L"> category binop
+#token >= name gt_eq translation <"\\G"> category binop
+#token == name eq_eq translation <"\\S"> category binop
+#token >> translation <"\\rangle"> category close
+#token << translation <"\\langle"> category open
+
+
+#macros begin
+#\def\LRA{\Longrightarrow}
+#\def\IFF{\Longleftrightarrow}
+#\def\FF{\Longleftarrow}
+#\def\DEF{\buildrel\triangle\over=}
+#\def\CE{\mathrel{{:}{=}}}
+#\def\CC{\mathrel{{:}{:}}}
+#\let\RA\rightarrow
+#\let\openbraces=\{
+#\let\closebraces=\}
+#\def\{{\ifmmode\openbraces\else$\openbraces$\fi}
+#\def\}{\ifmmode\closebraces\else$\closebraces$\fi}
+#macros end
+
+
+
+
+
+## definition of reserved
+##############################################
+## Pseudo Instructions ##
+## (should be changed for your assembler) ##
+##############################################
+
+ilk equ_like category equ mathness yes
+ilk dw_like category dw mathness yes
+reserved equ ilk equ_like
+reserved set ilk equ_like
+reserved EQU ilk equ_like
+reserved SET ilk equ_like
+reserved dc ilk dw_like
+reserved db ilk dw_like
+reserved dw ilk dw_like
+reserved ds ilk dw_like
+reserved dd ilk dw_like
+reserved float ilk dw_like
+reserved dfloat ilk dw_like
+reserved DC ilk dw_like
+reserved DB ilk dw_like
+reserved DW ilk dw_like
+reserved DS ilk dw_like
+reserved DD ilk dw_like
+reserved FLOAT ilk dw_like
+reserved DFLOAT ilk dw_like
+
+ilk pseudo_like category pseudo mathness yes
+reserved name ilk pseudo_like
+reserved include ilk pseudo_like
+reserved end ilk pseudo_like
+reserved org ilk pseudo_like
+reserved aorg ilk pseudo_like
+reserved bnd ilk pseudo_like
+reserved sect ilk pseudo_like
+reserved NAME ilk pseudo_like
+reserved INCLUDE ilk pseudo_like
+reserved END ilk pseudo_like
+reserved ORG ilk pseudo_like
+reserved AORG ilk pseudo_like
+reserved BND ilk pseudo_like
+reserved SECT ilk pseudo_like
+
+ilk glo_like category glo mathness yes
+reserved global ilk glo_like
+reserved GLOBAL ilk glo_like
+
+ilk ext_like category ext mathness yes
+reserved extnal ilk ext_like
+reserved EXTNAL ilk ext_like
+
+default translation <*-"\\"-space> tangleto <*-space>
+ilk if_like category if
+ilk else_like category else
+ilk endif_like category endif
+reserved if ilk if_like
+reserved ifdef ilk if_like
+reserved ifndef ilk if_like
+reserved else ilk else_like
+reserved endif ilk endif_like
+reserved IF ilk if_like
+reserved IFDEF ilk if_like
+reserved IFNDEF ilk if_like
+reserved ELSE ilk else_like
+reserved ENDIF ilk endif_like
+
+########################
+## All 68000 postfix ##
+########################
+default mathness maybe
+ilk post_b_like category post translation <*> tangleto <*-space>
+ilk post_w_like category post translation <*> tangleto <*-space>
+ilk post_l_like category post translation <*> tangleto <*-space>
+ilk post_x_like category post translation <*> tangleto <*-space>
+reserved b ilk post_b_like
+reserved B ilk post_b_like
+reserved w ilk post_w_like
+reserved W ilk post_w_like
+reserved l ilk post_l_like
+reserved L ilk post_l_like
+reserved x ilk post_x_like
+reserved X ilk post_x_like
+
+##########################
+## All 68000 registers ##
+##########################
+ilk reg_like category reg mathness yes
+reserved a0 ilk reg_like
+reserved a1 ilk reg_like
+reserved a2 ilk reg_like
+reserved a3 ilk reg_like
+reserved a4 ilk reg_like
+reserved a5 ilk reg_like
+reserved a6 ilk reg_like
+reserved a7 ilk reg_like
+reserved d0 ilk reg_like
+reserved d1 ilk reg_like
+reserved d2 ilk reg_like
+reserved d3 ilk reg_like
+reserved d4 ilk reg_like
+reserved d5 ilk reg_like
+reserved d6 ilk reg_like
+reserved d7 ilk reg_like
+reserved pc ilk reg_like
+reserved sr ilk reg_like
+reserved ccr ilk reg_like
+reserved ssp ilk reg_like
+reserved usp ilk reg_like
+reserved A0 ilk reg_like
+reserved A1 ilk reg_like
+reserved A2 ilk reg_like
+reserved A3 ilk reg_like
+reserved A4 ilk reg_like
+reserved A5 ilk reg_like
+reserved A6 ilk reg_like
+reserved A7 ilk reg_like
+reserved D0 ilk reg_like
+reserved D1 ilk reg_like
+reserved D2 ilk reg_like
+reserved D3 ilk reg_like
+reserved D4 ilk reg_like
+reserved D5 ilk reg_like
+reserved D6 ilk reg_like
+reserved D7 ilk reg_like
+reserved PC ilk reg_like
+reserved SR ilk reg_like
+reserved CCR ilk reg_like
+reserved SSP ilk reg_like
+reserved USP ilk reg_like
+
+##############################
+## All 68000 Instructions ##
+##############################
+default translation <*> mathness yes
+ilk opcode_like category opcode tangleto <space-*-space> mathness yes
+reserved ABCD ilk opcode_like
+reserved ADD ilk opcode_like
+reserved ADDA ilk opcode_like
+reserved ADDI ilk opcode_like
+reserved ADDQ ilk opcode_like
+reserved ADDX ilk opcode_like
+reserved AND ilk opcode_like
+reserved ANDI ilk opcode_like
+reserved ASL ilk opcode_like
+reserved ASR ilk opcode_like
+reserved BCC ilk opcode_like
+reserved BCS ilk opcode_like
+reserved BEQ ilk opcode_like
+reserved BGE ilk opcode_like
+reserved BGT ilk opcode_like
+reserved BHI ilk opcode_like
+reserved BLE ilk opcode_like
+reserved BLS ilk opcode_like
+reserved BLT ilk opcode_like
+reserved BMI ilk opcode_like
+reserved BNE ilk opcode_like
+reserved BPL ilk opcode_like
+reserved BVC ilk opcode_like
+reserved BVS ilk opcode_like
+reserved BCHG ilk opcode_like
+reserved BCLR ilk opcode_like
+reserved BKPT ilk opcode_like
+reserved BRA ilk opcode_like
+reserved BSET ilk opcode_like
+reserved BSR ilk opcode_like
+reserved BTST ilk opcode_like
+reserved CHK ilk opcode_like
+reserved CLR ilk opcode_like
+reserved CMP ilk opcode_like
+reserved CMPA ilk opcode_like
+reserved CMPI ilk opcode_like
+reserved CMPM ilk opcode_like
+reserved DBCC ilk opcode_like
+reserved DBCS ilk opcode_like
+reserved DBEQ ilk opcode_like
+reserved DBF ilk opcode_like
+reserved DBGE ilk opcode_like
+reserved DBGE ilk opcode_like
+reserved DBGT ilk opcode_like
+reserved DBHI ilk opcode_like
+reserved DBLE ilk opcode_like
+reserved DBLS ilk opcode_like
+reserved DBLT ilk opcode_like
+reserved DBMI ilk opcode_like
+reserved DBMI ilk opcode_like
+reserved DBNE ilk opcode_like
+reserved DBPL ilk opcode_like
+reserved DBT ilk opcode_like
+reserved DBVC ilk opcode_like
+reserved DBVS ilk opcode_like
+reserved DIVS ilk opcode_like
+reserved DIVU ilk opcode_like
+reserved EOR ilk opcode_like
+reserved EORI ilk opcode_like
+reserved EXG ilk opcode_like
+reserved EXT ilk opcode_like
+reserved ILLEGAL ilk opcode_like
+reserved JMP ilk opcode_like
+reserved JSR ilk opcode_like
+reserved LEA ilk opcode_like
+reserved LINK ilk opcode_like
+reserved LSL ilk opcode_like
+reserved LSR ilk opcode_like
+reserved MOVE ilk opcode_like
+reserved MOVEA ilk opcode_like
+reserved MOVEC ilk opcode_like
+reserved MOVEM ilk opcode_like
+reserved MOVEP ilk opcode_like
+reserved MOVEQ ilk opcode_like
+reserved MOVES ilk opcode_like
+reserved MULS ilk opcode_like
+reserved MULU ilk opcode_like
+reserved NBCD ilk opcode_like
+reserved NEG ilk opcode_like
+reserved NEGX ilk opcode_like
+reserved NOP ilk opcode_like
+reserved NOT ilk opcode_like
+reserved OR ilk opcode_like
+reserved ORI ilk opcode_like
+reserved PEA ilk opcode_like
+reserved RESET ilk opcode_like
+reserved ROL ilk opcode_like
+reserved ROR ilk opcode_like
+reserved ROXL ilk opcode_like
+reserved ROXR ilk opcode_like
+reserved RTD ilk opcode_like
+reserved RTE ilk opcode_like
+reserved RTR ilk opcode_like
+reserved RTS ilk opcode_like
+reserved SBCD ilk opcode_like
+reserved SCC ilk opcode_like
+reserved SCS ilk opcode_like
+reserved SEQ ilk opcode_like
+reserved SF ilk opcode_like
+reserved SGE ilk opcode_like
+reserved SGT ilk opcode_like
+reserved SHI ilk opcode_like
+reserved SLE ilk opcode_like
+reserved SLS ilk opcode_like
+reserved SLT ilk opcode_like
+reserved SMI ilk opcode_like
+reserved SNE ilk opcode_like
+reserved SPL ilk opcode_like
+reserved ST ilk opcode_like
+reserved SVC ilk opcode_like
+reserved SVS ilk opcode_like
+reserved STOP ilk opcode_like
+reserved SUB ilk opcode_like
+reserved SUBA ilk opcode_like
+reserved SUBI ilk opcode_like
+reserved SUBQ ilk opcode_like
+reserved SUBX ilk opcode_like
+reserved SWAP ilk opcode_like
+reserved TAS ilk opcode_like
+reserved TRAP ilk opcode_like
+reserved TRAPV ilk opcode_like
+reserved TST ilk opcode_like
+reserved UNLK ilk opcode_like
+reserved abcd ilk opcode_like
+reserved add ilk opcode_like
+reserved adda ilk opcode_like
+reserved addi ilk opcode_like
+reserved addq ilk opcode_like
+reserved addx ilk opcode_like
+reserved and ilk opcode_like
+reserved andi ilk opcode_like
+reserved asl ilk opcode_like
+reserved asr ilk opcode_like
+reserved bcc ilk opcode_like
+reserved bcs ilk opcode_like
+reserved beq ilk opcode_like
+reserved bge ilk opcode_like
+reserved bgt ilk opcode_like
+reserved bhi ilk opcode_like
+reserved ble ilk opcode_like
+reserved bls ilk opcode_like
+reserved blt ilk opcode_like
+reserved bmi ilk opcode_like
+reserved bne ilk opcode_like
+reserved bpl ilk opcode_like
+reserved bvc ilk opcode_like
+reserved bvs ilk opcode_like
+reserved bchg ilk opcode_like
+reserved bclr ilk opcode_like
+reserved bkpt ilk opcode_like
+reserved bra ilk opcode_like
+reserved bset ilk opcode_like
+reserved bsr ilk opcode_like
+reserved btst ilk opcode_like
+reserved chk ilk opcode_like
+reserved clr ilk opcode_like
+reserved cmp ilk opcode_like
+reserved cmpa ilk opcode_like
+reserved cmpi ilk opcode_like
+reserved cmpm ilk opcode_like
+reserved dbcc ilk opcode_like
+reserved dbcs ilk opcode_like
+reserved dbeq ilk opcode_like
+reserved dbf ilk opcode_like
+reserved dbge ilk opcode_like
+reserved dbge ilk opcode_like
+reserved dbgt ilk opcode_like
+reserved dbhi ilk opcode_like
+reserved dble ilk opcode_like
+reserved dbls ilk opcode_like
+reserved dblt ilk opcode_like
+reserved dbmi ilk opcode_like
+reserved dbmi ilk opcode_like
+reserved dbne ilk opcode_like
+reserved dbpl ilk opcode_like
+reserved dbt ilk opcode_like
+reserved dbvc ilk opcode_like
+reserved dbvs ilk opcode_like
+reserved divs ilk opcode_like
+reserved divu ilk opcode_like
+reserved eor ilk opcode_like
+reserved eori ilk opcode_like
+reserved exg ilk opcode_like
+reserved ext ilk opcode_like
+reserved illegal ilk opcode_like
+reserved jmp ilk opcode_like
+reserved jsr ilk opcode_like
+reserved lea ilk opcode_like
+reserved link ilk opcode_like
+reserved lsl ilk opcode_like
+reserved lsr ilk opcode_like
+reserved move ilk opcode_like
+reserved movea ilk opcode_like
+reserved movec ilk opcode_like
+reserved movem ilk opcode_like
+reserved movep ilk opcode_like
+reserved moveq ilk opcode_like
+reserved moves ilk opcode_like
+reserved muls ilk opcode_like
+reserved mulu ilk opcode_like
+reserved nbcd ilk opcode_like
+reserved neg ilk opcode_like
+reserved negx ilk opcode_like
+reserved nop ilk opcode_like
+reserved not ilk opcode_like
+reserved or ilk opcode_like
+reserved ori ilk opcode_like
+reserved pea ilk opcode_like
+reserved reset ilk opcode_like
+reserved rol ilk opcode_like
+reserved ror ilk opcode_like
+reserved roxl ilk opcode_like
+reserved roxr ilk opcode_like
+reserved rtd ilk opcode_like
+reserved rte ilk opcode_like
+reserved rtr ilk opcode_like
+reserved rts ilk opcode_like
+reserved sbcd ilk opcode_like
+reserved scc ilk opcode_like
+reserved scs ilk opcode_like
+reserved seq ilk opcode_like
+reserved sf ilk opcode_like
+reserved sge ilk opcode_like
+reserved sgt ilk opcode_like
+reserved shi ilk opcode_like
+reserved sle ilk opcode_like
+reserved sls ilk opcode_like
+reserved slt ilk opcode_like
+reserved smi ilk opcode_like
+reserved sne ilk opcode_like
+reserved spl ilk opcode_like
+reserved st ilk opcode_like
+reserved svc ilk opcode_like
+reserved svs ilk opcode_like
+reserved stop ilk opcode_like
+reserved sub ilk opcode_like
+reserved suba ilk opcode_like
+reserved subi ilk opcode_like
+reserved subq ilk opcode_like
+reserved subx ilk opcode_like
+reserved swap ilk opcode_like
+reserved tas ilk opcode_like
+reserved trap ilk opcode_like
+reserved trapv ilk opcode_like
+reserved tst ilk opcode_like
+reserved unlk ilk opcode_like
+
+################################
+## Production roles for weave ##
+################################
+
+# For register
+#
+#[ <"\\REGbox{"> reg <"}"> ] --> math
+<"\\REGbox{"> reg dot post <"}"> --> math
+[ <"\\REGbox{"> reg <"}"> ] open --> math open
+[ <"\\REGbox{"> reg <"}"> ] close --> math close
+[ <"\\REGbox{"> reg <"}"> ] binop --> math binop
+[ <"\\REGbox{"> reg <"}"> ] camma --> math camma
+[ <"\\REGbox{"> reg <"}"> ] unorbinop --> math unorbinop
+[ <"\\REGbox{"> reg <"}"> ] ignore_scrap --> math ignore_scrap
+
+<"\\REGbox{"> reg <"}"> (math|sym) --> math
+
+# For math
+#
+(sym|math) (binop|unorbinop|camma) (sym|math) --> math
+(unop|unorbinop) (sym|math) --> math
+(sym|math) (unop|unorbinop) --> math
+open (sym|math) close --> math
+(sym|math) <space> (sym|math) --> math
+
+#open close --> math
+#math semi <force> --> unop
+#math <force> lbrace --> lbrace
+#lbrace math close --> math
+#lbrace math close <force> --> unop
+
+# There are rules for if-pseudo-instructions
+#
+<force> if (sym|math) --> ifmath
+ifmath math ignore_scrap --> ifmath
+ifmath <indent> stmt ignore_scrap --> ifstmt
+ifstmt stmt --> ifstmt
+ifstmt <outdent-force> else if --> if
+ifstmt <outdent-force> endif --> stmt
+
+ifmath <force> else --> ifels
+ifstmt <outdent-force> else ignore_scrap --> ifels
+ifels <indent> stmt --> ifelstmt
+ifelstmt stmt --> ifelstmt
+ifelstmt <outdent-force> endif --> stmt
+ifels <force> endif --> stmt
+
+# For instructions
+#
+#-- pseudo instructions
+(dw|pseudo) <"\\"-space> --> inst
+<force> sym* <"\\"-space> (equ|dw) <"\\"-space> (sym|math) ignore_scrap --> stmt
+#<force> dw <"\\"-space> (sym|math) ignore_scrap --> stmt
+#-- CPU instructions
+<"\\OPbox{"> opcode dot post <"}"-space> --> inst
+<"\\OPbox{"> opcode <"}"-space> --> inst
+
+#-- ext instructions
+#
+<force> ext <"\\"-space> sym* --> extsym
+extsym camma <break_space> sym* --> extsym
+extsym ignore_scrap --> stmt
+
+<force> glo <"\\"-space> sym --> glosym
+glosym camma <break_space> sym --> glosym
+glosym ignore_scrap --> stmt
+
+#sym* camma sym* --> symlist
+#symlist camma sym* --> symlist
+#<indent-force> (ext|glo) <"\\"-space> symlist <outdent> ignore_scrap --> stmt
+
+#-- instructions
+#
+[ inst (sym|math) ] ignore_scrap --> pure_stmt ignore_scrap
+[ inst ] ignore_scrap --> pure_stmt ignore_scrap
+#[ inst math (unop|unorbinop) ] ignore_scrap --> pure_stmt ignore_scrap
+
+# reducing label
+#
+<"\\hbox{"> sym* colon <"}"> --> label
+<big_force> label <force> label --> sub_label
+<big_force> sub_label <force> label --> sub_label
+
+# Statements
+#
+sub_label <force-"\\Lbox"-space> pure_stmt --> stmt
+<big_force> label <force-"\\Lbox"-space> pure_stmt --> stmt
+<force-"\\Lbox"-space> pure_stmt --> stmt
+#stmt <force-"\\Lbox"-space> pure_stmt --> stmt
+
+stmt stmt --> stmt
+
+#labeled_stmt <force> pure_stmt --> stmt
+#stmt labeled_stmt --> stmt
+#<force> pure_stmt labeled_stmt --> stmt
+
+? ignore_scrap --> #1
+
+# end of file
+
+
diff --git a/web/spiderweb/src/68k/make b/web/spiderweb/src/68k/make
new file mode 100644
index 0000000000..d5de3d22b3
--- /dev/null
+++ b/web/spiderweb/src/68k/make
@@ -0,0 +1,3 @@
+#!/bin/sh
+/bin/make -f ../master/WebMakefile CPUTYPE=`cputype`\
+ THETANGLE=68ktangle THEWEAVE=68kweave SPIDER=68k.spider "$@"
diff --git a/web/spiderweb/src/BUGS b/web/spiderweb/src/BUGS
new file mode 100644
index 0000000000..5045ea5576
--- /dev/null
+++ b/web/spiderweb/src/BUGS
@@ -0,0 +1,84 @@
+ 8 Apr 89 Forgot to move object files to $(OBDIR) when making `boot'
+ 8 Apr 89 TANGLE token numbers were too low by 3. This caused a
+ duplicate case in switch when there were too many tokens,
+ because some token was getting decimal 10 (#'13). The
+ fix was to add 3 to the appropriate place in spider.web
+
+===> Bundled 8 Apr 89; all bugs into patches/001
+
+10 Apr 89 Confusion about Makefile targets; updated Makefile & README
+
+===> Bundled 10 Apr 89; all bugs into patches/002
+
+10 Apr 89 Bad figure in cacm.tex
+11 Apr 89 Make clean and distribution removed important source
+ from master directory.
+11 Apr 89 WEAVE itself doesn't WEAVE properly because of foul
+ comments in grammar.web. Changed spider.web to escape
+ _ and # as well as |.
+11 Apr 89 spiderwebman.tex had a missing \endnewstuff. While
+ putting it in I found some inaccuracies about macros.
+ The whole spiderwebman is pretty grim, and should be
+ rewritten, or at least checked for accuracy.
+
+===> Bundled 11 Apr 89; all bugs into patches/003
+
+14 Apr 89 Removed @\ from WEAVE; it was already gone from TANGLE
+ and is obsolete in Spidery WEB.
+ Marked documentation to show @? isn't supported.
+
+
+===> Bundled 18 Apr 89; all bugs into patches/004
+
+26 Jun 89 Removed \eject from webkernel.tex line 221 (before first page)
+ It was causing the headings on page 1 to come out missing.
+ 3 Jul 89 Added parentheses to 3 offending sprintf calls in spider.web
+
+===> Bundled 3 Jul 89; all bugs into patches/005
+
+20 Jul 89 WEAVE was erroneously matching scraps with category zero.
+ This was tickled in ceeweave by the name @<Oink |#include|s@>.
+ Grabbing the scrap with category zero caused WEAVE to drop
+ the text associated with the whole sequence. I don't know
+ why it didn't go off the trolley entirely.
+ Fix was to put in a zero check for negations (single and
+ lists) and wild cards.
+
+===> Bundled 8 Aug 89; all bugs into patches/006
+
+23 Aug 89 Spider wouldn't accept capital letters in category and field
+ names.
+
+===> Bundled 14 Sep 89; all bugs into patches/007
+
+29 Nov 89 Ceetangle rewrote `a = b / *p' as `a= b/*p', a phony comment.
+ Fixed by `token * tangleto <space-"*">' (changing / mucks up
+ #include files)
+
+29 Nov 89 Updated README file to mention . in front of path, clear
+ up some misconceptions, and fix my telephone number.
+ Added Wayne Sewell's book to bibliographies.
+
+===> Bundled 29 Nov 89; all bugs into patches/008
+
+22 Jan 90 WebMakefile bombed if $(OBDIR) directory didn't exist.
+23 Jan 90 Got a letter from David Ness, indicating some changes for
+ MS-DOS version (also some bug fixes to spider.web).
+ I integrated his changes by introducing longs where
+ appropriate and adding a couple of `#ifdef MSDOS' lines.
+
+===> Bundled 02 Feb 90; all bugs into patches/009
+
+13 Feb 90 David Ness reports some \& should be \amp in macro definitions
+16 Apr 90 larch spider specification had old-style comment defns
+16 Apr 90 \write\cont{\string\catcode`\string\@=11} misplaced
+ in webkernel.tex
+16 Apr 90 Give ** operator a translation in ada.spider
+11 Sep 90 Various bug fixes in webkernel.tex (from G. Alexander)
+
+
+===> Bundled 26 Sep 90; no patches for most bugs, some in patches/010
+
+19 Feb 91 Sequence @i wasn't in the manual.
+
+===> Bundled 19 Feb 91; no patches. \ No newline at end of file
diff --git a/web/spiderweb/src/COPYRIGHT b/web/spiderweb/src/COPYRIGHT
new file mode 100644
index 0000000000..193fdea8b4
--- /dev/null
+++ b/web/spiderweb/src/COPYRIGHT
@@ -0,0 +1,11 @@
+Spider and Spidery WEB are copyright 1989-1992 by Norman Ramsey,
+Odyssey Research Associates (ORA Corp), 301A Dates Drive, Ithaca, New
+York 14850.
+
+You may use and distribute Spider and Spidery WEB for any purpose, for
+free. You may modify Spider and Spidery WEB and create derived works,
+provided you retain the copyright notice, but the result may not be
+called Spider or Spidery WEB without written permission from ORA Corp.
+You may not sell Spider or Spidery WEB themselves, but you may do
+anything you like with programs created with Spider and Spidery WEB.
+
diff --git a/web/spiderweb/src/Makefile b/web/spiderweb/src/Makefile
new file mode 100644
index 0000000000..0b1510b6af
--- /dev/null
+++ b/web/spiderweb/src/Makefile
@@ -0,0 +1,44 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+
+# This is a SUN OS 4 Makefile. Sorry. Makefiles in subdirectories
+# should work under any reasonable Make.
+
+MAKE=make $(MFLAGS)
+DIRECTORIES=68k ada awk c c++ dijkstra kelem larch nawk \
+ penelope postscript reduce sml ssl turing turing+
+
+# Removes excess junk from the world, except it doesn't remove
+# common object files from ./master
+# This destroys the sources, so don't make clean until you've made boot.
+clean:
+ @for i in $(DIRECTORIES); do \
+ cd $$i; \
+ echo making $$i clean...; \
+ $(MAKE) clean ; \
+ cd ..; \
+ done
+ rm -f *~
+ @echo "All done."
+
+# This creates the minimum sources in preparation for `make distribution'
+source:
+ cd c ; $(MAKE) source ; cd ..
+ cd awk ; $(MAKE) source ; cd ..
+
+# Used to bring up the system when first installing it. Requires sources,
+# either from the distribution tarfile or from `make source'
+boot:
+ cd c; $(MAKE) boot; cd ..
+ cd awk; $(MAKE) boot; cd ..
+
+# Make all known webs. For lunatics only.
+all:
+ @for i in $(DIRECTORIES); do \
+ cd $$i; \
+ $(MAKE) web ; \
+ cd ..; \
+ done
+ @echo "All done."
+
diff --git a/web/spiderweb/src/README b/web/spiderweb/src/README
new file mode 100644
index 0000000000..d7750508f9
--- /dev/null
+++ b/web/spiderweb/src/README
@@ -0,0 +1,104 @@
+This file says how to install Spidery WEB. If you want more information
+about what it is, look in the doc subdirectory, especially doc/DESCRIPTION.
+Spidery WEB is not in the public domain, but you are welcome to use it for
+any purpose. For more details, see the file COPYRIGHT.
+
+
+How to install Spidery WEB:
+
+1) Pick a directory to install the WEB source in. Call it WEBROOT.
+
+2) untar the distribution in WEBROOT (cd WEBROOT; tar xvf spiderweb.tar)
+
+3) change to the master subdirectory and edit WebMakefile.
+ -- Set WEBROOT to the WEBROOT directory
+ -- Set DEST to the name of a directory to hold the executables
+ -- Set MACROS to the name of directory to hold TeX macros
+ Example:
+ WEBROOT=/usr/src/local/spiderweb
+ DEST=/usr/local
+ MACROS=/usr/lib/tex/macros
+
+ Make sure there are no spaces following the names.
+
+4) If your installation doesn't have a cputype program, make one (a shell
+ script is fine) following the instructions in WebMakefile. Put it
+ somewhere on your path.
+
+5) As defaults, the names of C tangle and weave are ceetangle and ceeweave
+ (to avoid confusion with Silvio Levy's ctangle and cweave). Awk tangle
+ is called awktangle. If you want to change these names, you must change
+ them in WEBROOT/master/WebMakefile, and also on WEBROOT/c/make and
+ WEBROOT/awk/make
+
+6) Make sure . is at the front of your path. For example, csh users could
+ type `set path = (. $path)' or sh users type `path=.:$path'. (I haven't
+ checked these since . is at the front of my path by default.) If you
+ don't like this security hole, you will have to change `make' to `./make'
+ at the appropriate places (found by you).
+
+ With your path set, go into WEBROOT and type `make boot'
+
+ Once this is successful you will have executable versions of tangle for
+ C and Awk, which is the minumum needed to make other things. After you've
+ done this, you can afford to `make clean', which will remove the .c and
+ .awk source you used to bootstrap yourself. You can always make them over
+ again using the executable versions (`make source').
+
+ In case it isn't clear, once you `make boot' you will never need to do
+ it again.
+
+7) Move webkernel.tex into a place where TeX can find it. Until you do
+ this you won't be able to TeX WEAVE output (or doc/spiderwebman.tex).
+
+
+
+Spidery WEB comes with the following languages:
+
+Directory Description
+
+68k 68000 assembly language, courtesy Izumi Watanabe
+ada Ada
+awk old-style AWK, a string processing language
+c Kernighan and Ritchie C
+c++ C++, courtesy of Ed Kademan
+dijkstra Edsger Dijkstra's language of guarded commands (flaky)
+kelem Algol-like C, courtesy Steve Kelem
+larch The Larch Shared Language, used for specifying
+ equational theories.
+nawk new-style AWK
+penelope Ada, extended with formal comments for verification
+postscript PostScript, courtesy David Love
+reduce A Pascal-like lisp, courtesy Marcel Roelofs
+sml A couple of attempts at Standard ML
+ssl The language of the Cornell Synthesizer Generator
+turing,turing+ Two versions of the Turing language, courtesty Kostas N. Oikonomou
+
+
+Each of these directories has a file called 'make'. The settings in
+that file determine the name that the executable versions of WEAVE and
+TANGLE have for that particular language. The names of the Spider
+files are also given. See ../doc/spiderman.tex for details on using
+Spider. Izumi Watanabe's Japanese translation is in ../doc/spdjman.tex.
+
+To make weave or tangle, change to the directory for the chosen language,
+and type `make weave' or `make tangle'. `make web' will make both weave
+and tangle.
+
+The `latex' subdirectory contains change files and other information
+to support use of WEB with latex. They may not be up to date with the
+current version of web.
+
+Spidery WEB is available by anonymous ftp from the literate-
+programming archive at niord.shsu.edu. Spidery WEB is no longer
+supported; it has been replaced by `noweb', which is available by
+anonymous ftp from csservices.princeton.edu:pub/noweb.shar.Z. ORA
+Corp makes some effort to keep Spidery WEB working, and bug reports,
+fixes, and new language descriptions can be sent to
+spider-bugs@oracorp.com.
+
+Norman Ramsey
+ORA Corporation
+301A Harris B. Dates Drive
+Ithaca, New York 14850
+Internet: spider-bugs@oracorp.com
diff --git a/web/spiderweb/src/README.DOS b/web/spiderweb/src/README.DOS
new file mode 100644
index 0000000000..596e6c5081
--- /dev/null
+++ b/web/spiderweb/src/README.DOS
@@ -0,0 +1,56 @@
+How to bring up Spider on MS-DOS (adapted from instructions kindly
+provided by David Ness). Assumes Microsoft C 5.1 and MS overlay
+linker V 3.65.
+
+1. Get \MASTER\PATHOPEN.* COMMON.*
+
+2. Get TANGLE.C from C.ZIP
+
+3. Compile with 'CL /AH TANGLE.C COMMON.C PATHOPEN.C'. (If your
+ compiler does not define the symbol MSDOS automatically, you should
+ use 'CL /DMSDOS' or whatever the appropriate incantation is.) This will
+ produce lots of warnings because the code has labels after '#endif'.
+ This produces your official C tangle, so perhaps
+ 'REN TANGLE.EXE CTANGLE.EXE' is in order.
+
+4. Get TANGLE.C from AWK.ZIP, and
+ 'CL /AH TANGLE.C COMMON.OBJ PATHOPEN.OBJ' followed by
+ 'REN TANGLE.EXE ATANGLE.EXE' should give you an Awk tangle.
+
+5. Not that the copies of C TANGLE and Awk TANGLE have been produced
+ from the bootstrap TANGLE.C, not from TANGLE.WEB. Our next task
+ is to produce good TANGLEs from the WEB. This will require SPIDER,
+ and SPIDER REQUIRES Awk.
+
+6. First we can regenerate PATHOPEN.C and PATHOPEN.H from PATHOPEN.WEB
+ with 'CTANGLE PATHOPEN'. This is done just for consistency.
+
+7. Now begin by creating SPIDER.AWK from SPIDER.WEB: 'ATANGLE SPIDER'.
+
+8. Run Awk on SPIDER, giving it C.SPI: 'AWK -F SPIDER.AWK C.SPI'.
+ This produces OUTTOKS.WEB needed for TANGLE.WEB and GRAMMAR.WEB and
+ SCRAPS.WEB needed for WEAVE.
+
+9. However, there is one problem. As is, the function `translate()'
+ generates a code segment too big to handle. By wild good luck, if
+ the appropriate calls to the `reduce()' function are replaced with
+ calls on `squash()', then it just fits. (SPIDER doesn't generate
+ calls on `squash()', although `squash()' is still defined in
+ WEAVE.)
+
+ DNN.WEB will generate an Awk script that does this reduction.
+ For MKS Awk this is done with
+ ATANGLE DNN.WEB
+ AWK -F DNN GRAMMAR.WEB
+ COPY OUT.TMP GRAMMAR.WEB
+
+10.Then 'CTANGLE WEAVE' to produce WEAVE.C
+
+11.And finally 'CL /AH WEAVE.C COMMON.OBJ PATHOPEN.OBJ'
+ and 'REN WEAVE.EXE CWEAVE.EXE'.
+
+12.We can generate AWEAVE (for Awk) by starting again at step 8 and
+ substituting `A' for `C' where appropriate.
+
+
+
diff --git a/web/spiderweb/src/ada/ada.spider b/web/spiderweb/src/ada/ada.spider
new file mode 100644
index 0000000000..6a76f95436
--- /dev/null
+++ b/web/spiderweb/src/ada/ada.spider
@@ -0,0 +1,278 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+
+# Modified by Sylvester Fernandez
+
+language Ada extension ada
+
+at_sign @
+
+module definition stmt use stmt
+
+comment begin <dash-dash> end newline
+macros begin
+\def\commentbegin{{\tt -- }}
+macros end
+
+line begin <dash-dash-"line"> end <"">
+
+default translation <*> mathness yes
+
+token identifier category math mathness maybe
+token number category math mathness yes
+token newline category ignore_scrap translation <> mathness maybe
+token pseudo_semi translation <> category semi mathness maybe
+
+macros begin
+\let\R\relax
+macros end
+
+# Delimiters
+token & category binop translation <"\\amp">
+token ( category open
+token ) category close
+token * category binop
+token + category unorbinop
+token , category binop translation <",\\,"-opt-3>
+token - category unorbinop
+token . category binop
+token / category binop
+token : category binop
+token ; category semi translation <";"-space-opt-2>
+token < category binop
+token = category binop
+token > category binop
+token | category binop translation <"\\mid">
+
+# Compound delimiters
+
+token => category arrow translation <"\\AR">
+token .. category binop translation <"\\.{..}\\>">
+token ** category binop translation <"\\mathbin{**}">
+token := category binop translation <"\\mathbin{:=}">
+token /= translation <"\\I"> category binop
+token >= translation <"\\G"> category binop
+token <= translation <"\\L"> category binop
+token << translation <"\\LL"> category openlabel
+token >> translation <"\\GG"> category closelabel
+token <> translation <"\\LG"> category math
+
+# Hacks no ', and this becomes a binary op
+token ' category binop mathness no
+
+token # category math translation <"\\#">
+
+
+
+
+default mathness maybe translation <*>
+
+reserved abort ilk math_like
+reserved abs ilk unop_like
+reserved accept ilk proc_like
+reserved access ilk math_like
+reserved all ilk math_like
+reserved and ilk and_like
+reserved array ilk math_like
+reserved at ilk at_like
+reserved begin ilk begin_like
+reserved body ilk math_like
+reserved case ilk case_like
+reserved constant ilk math_like
+reserved declare ilk decl_like
+reserved delay ilk math_like
+reserved delta ilk math_like
+reserved digits ilk math_like
+reserved do ilk do_like
+reserved else ilk else_like
+reserved elsif ilk elsif_like
+reserved end ilk end_like
+reserved entry ilk proc_like
+reserved exception ilk ex_like
+reserved exit ilk math_like
+reserved for ilk math_like
+reserved function ilk proc_like
+reserved generic ilk gen_like
+reserved goto ilk math_like
+reserved if ilk if_like
+reserved in ilk unorbinop_like
+reserved is ilk is_like
+reserved limited ilk math_like
+reserved loop ilk loop_like
+reserved mod ilk binop_like
+reserved new ilk unop_like
+reserved not ilk unop_like
+reserved null ilk math_like
+reserved of ilk math_like
+reserved or ilk or_like
+reserved others ilk math_like
+reserved out ilk math_like
+reserved package ilk proc_like
+reserved pragma ilk math_like
+reserved private ilk private_like
+reserved procedure ilk proc_like
+reserved raise ilk math_like
+reserved range ilk math_like
+reserved record ilk record_like
+reserved rem ilk binop_like
+reserved renames ilk math_like
+reserved return ilk math_like
+reserved reverse ilk math_like
+reserved select ilk select_like
+reserved separate ilk separate_like
+reserved subtype ilk math_like
+reserved task ilk proc_like
+reserved terminate ilk math_like
+reserved then ilk then_like
+reserved type ilk math_like
+reserved use ilk math_like
+reserved when ilk when_like
+reserved while ilk math_like
+reserved with ilk with_like
+reserved xor ilk binop_like
+
+ilk and_like translation <*> category and
+ilk at_like translation <*> category at
+ilk begin_like translation <*-indent> category beginning
+ilk binop_like translation <"\\"-space-*-"\\"-space> category binop
+ilk case_like translation <*> category case
+ilk decl_like translation <*-indent> category declaration
+ilk do_like translation <*> category do
+ilk else_like translation <*> category else
+ilk elsif_like translation <*> category elsif
+ilk end_like translation <*> category close
+ilk ex_like translation <*> category exception
+ilk gen_like translation <*-indent> category generic
+ilk if_like translation <*> category if
+ilk is_like translation <*> category is
+ilk loop_like translation <*> category loop
+ilk math_like translation <*> category math
+ilk or_like translation <*> category or
+ilk private_like translation <*> category private
+ilk proc_like translation <force-*> category proc
+ilk record_like translation <*> category record
+ilk select_like translation <*> category select
+ilk separate_like translation <*> category separate
+ilk then_like translation <*> category then
+ilk unop_like translation <*-"\\"-space> category unop
+ilk unorbinop_like translation <"\\"-space-*-"\\"-space> category resunorbinop
+ilk when_like translation <*> category when
+ilk with_like translation <*> category with
+
+
+# \MC means ``math close'' and sets \MS to ``math set''
+macros begin
+\def\MC{\ifmmode\global\let\MS$\else\global\let\MS\relax\fi\relax\MS}
+\def\LG{\mathord{<}\mathord{>}}
+\let\IG=\ignorespaces
+macros end
+
+
+
+beginning <outdent-force> continuation <outdent-force> ending --> stmt
+beginning <outdent-force> ending --> stmt
+# beginning <force> (stmt|ignore_scrap) --> beginning
+beginning <force> stmt --> beginning
+
+case <"\\"-space> math <"\\"-space> is <indent-force> --> beginning
+
+close semi --> ending
+close <"\\"-space> ? semi --> ending
+close <"\\"-space> ? <"\\"-space> ? semi --> ending
+
+continuation <force> stmt --> continuation
+continuation <outdent-force> continuation --> continuation
+
+
+declaration <outdent-force> beginning <outdent-force> continuation <outdent-force> ending --> stmt
+declaration <outdent-force> beginning <outdent-force> ending --> stmt
+declaration <outdent-force> ending --> stmt
+declaration <force> (declaration|stmt) --> declaration
+
+else <indent-force> --> continuation
+elsif <"\\"-space> math <"\\"-space> then <indent-force> --> continuation
+
+exception <indent-force> --> continuation
+
+generic <outdent-force> declaration --> declaration
+generic <force> stmt --> generic
+
+if <"\\"-space> math <"\\"-space> then --> ifthen
+ifthen <indent-force> stmt --> beginning
+ifthen <indent-force> <"\\"-space> math <"\\"-space> <outdent-force> else --> ifthen
+ifthen <indent-force> <"\\"-space> math <"\\"-space> <outdent-force> close <"\\"-space> if --> math
+ifthen <indent-force> <"\\"-space> math <"\\"-space> <outdent-force> elsif --> if
+
+
+is --> math
+
+loop <indent-force> --> beginning
+
+math [ <"\\"-space> and <"\\"-space> then <"\\"-space> ] --> math binop
+math [ <"\\"-space> and <"\\"-space> ] --> math binop
+
+math (binop|unorbinop) math --> math
+math <"\\"-space> resunorbinop <"\\"-space> math --> math
+(unorbinop|unop) math --> math
+resunorbinop <"\\"-space> math --> math
+# This doesn't apply in Ada: math unop --> math
+
+math arrow --> math
+math <"\\"-space> at --> math
+math binop <"\\"-space> exception --> math
+math <"\\"-space> is --> math
+math <"\\"-space> loop --> loop
+math <"\\"-space> math --> math
+math [ <"\\"-space> or <"\\"-space> else <"\\"-space> ] --> math binop
+math [ <"\\"-space> or <"\\"-space> ] --> math binop
+math <"\\"-space> private --> math
+math <"\\"-space> separate --> math
+math <indent-force> stmt <outdent-force> --> stmt
+math terminator --> stmt
+
+open close --> math
+open math close --> math
+open [ math semi ] --> open math
+
+<force-backup> openlabel math closelabel <force> --> math
+
+or <indent-force> --> continuation
+
+private <indent-force> --> beginning
+
+proc <"\\"-space> math <"\\"-space> is <"\\"-space> unop --> math
+proc <"\\"-space> math <"\\"-space> is <"\\"-space> separate --> math
+proc <"\\"-space> math <"\\"-space> is <indent-force> --> declaration
+proc <"\\"-space> math <"\\"-space> do <indent-force> --> beginning
+proc <"\\"-space> math terminator <force> --> declaration
+
+#record <"\\"-space> at <"\\"-space> math terminator <indent-force> --> beginning
+record <indent-force> --> beginning
+
+select <indent-force> --> beginning
+
+semi --> terminator
+
+separate math --> stmt
+
+stmt <force> declaration --> declaration
+
+stmt <force> stmt --> stmt
+
+stmt <outdent-force> ending --> stmt
+
+when <"\\"-space> math arrow <indent-force> --> whengroup
+[ when <"\\"-space> math ] terminator --> math terminator
+whengroup stmt <outdent-force> ending --> ending
+whengroup stmt <outdent-force> continuation --> continuation
+whengroup stmt <outdent-force> whengroup --> whengroup
+
+with <"\\"-space> math --> math
+with <"\\"-space> proc <"\\"-space> math --> math
+
+? ignore_scrap --> #1
+
+macros begin
+\let\AR=\Longrightarrow
+macros end
diff --git a/web/spiderweb/src/ada/make b/web/spiderweb/src/ada/make
new file mode 100644
index 0000000000..cbb39a896a
--- /dev/null
+++ b/web/spiderweb/src/ada/make
@@ -0,0 +1,3 @@
+#!/bin/csh -f
+/bin/make -f ../master/WebMakefile CPUTYPE=`cputype`\
+ THETANGLE=adatangle THEWEAVE=adaweave SPIDER=ada.spider $*
diff --git a/web/spiderweb/src/ada/new.spider b/web/spiderweb/src/ada/new.spider
new file mode 100644
index 0000000000..31f142b23e
--- /dev/null
+++ b/web/spiderweb/src/ada/new.spider
@@ -0,0 +1,315 @@
+From ngcr@planet8.planet8.sp.unisys.com Thu Jan 10 16:23:26 1991
+Received: from cs.Princeton.EDU (cs.Princeton.EDU) by fs.Princeton.EDU (4.0/1.105)
+ id AA12318; Thu, 10 Jan 91 16:23:23 EST
+Received: from fs.Princeton.EDU by cs.Princeton.EDU (5.57/1.105)
+ id AA09028; Thu, 10 Jan 91 16:23:19 EST
+Received: from Princeton.EDU (Princeton.EDU.) by fs.Princeton.EDU (4.0/1.105)
+ id AA12315; Thu, 10 Jan 91 16:23:15 EST
+Received: from [129.218.60.4] by Princeton.EDU (5.61++/2.62/princeton)
+ id AA16288; Thu, 10 Jan 91 16:23:09 -0500
+Received: by email.sp.unisys.com (5.57/Ultrix3.0-C)
+ id AA15274; Thu, 10 Jan 91 15:22:05 -0600
+Received: from pablo.sp.unisys.com. by planet8.planet8.sp.unisys.com. (4.0/SMI-4.0)
+ id AA12500; Thu, 10 Jan 91 15:22:39 CST
+Date: Thu, 10 Jan 91 15:22:39 CST
+From: ngcr<@fs>@Princeton.EDU (Sylvester Fernandez)
+Message-Id: <9101102122.AA12500@planet8.planet8.sp.unisys.com.>
+To: nr@Princeton.EDU
+Subject: Re: Ada Web
+Status: R
+
+
+All the bugs I found were in the grammar. Here is the modified
+version we are using now:
+
+-----------
+ada.spider
+-----------
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+
+# Modified by Sylvester Fernandez
+
+language Ada extension ada
+
+at_sign @
+
+module definition stmt use stmt
+
+comment begin <dash-dash> end newline
+macros begin
+\def\commentbegin{{\tt -- }}
+macros end
+
+line begin <dash-dash-"line"> end <"">
+
+default translation <*> mathness yes
+
+token identifier category math mathness maybe
+token number category math mathness yes
+token newline category ignore_scrap translation <> mathness maybe
+token pseudo_semi translation <> category semi mathness maybe
+
+macros begin
+\let\R\relax
+macros end
+
+# Delimiters
+token & category binop translation <"\\amp">
+token ( category open
+token ) category close
+token * category binop
+token + category unorbinop
+token , category binop translation <",\\,"-opt-3>
+token - category unorbinop
+token . category binop
+token / category binop
+token : category binop
+token ; category semi translation <";"-space-opt-2>
+token < category binop
+token = category binop
+token > category binop
+token | category binop translation <"\\mid">
+
+# Compound delimiters
+
+token => category arrow translation <"\\AR">
+token .. category binop translation <"\\.{..}\\>">
+token ** category binop translation <"\\mathbin{**}">
+token := category binop translation <"\\mathbin{:=}">
+token /= translation <"\\I"> category binop
+token >= translation <"\\G"> category binop
+token <= translation <"\\L"> category binop
+token << translation <"\\LL"> category openlabel
+token >> translation <"\\GG"> category closelabel
+token <> translation <"\\LG"> category math
+
+# Hacks no ', and this becomes a binary op
+token ' category binop mathness no
+
+token # category math translation <"\\#">
+
+
+
+
+default mathness maybe translation <*>
+
+reserved abort ilk math_like
+reserved abs ilk unop_like
+reserved accept ilk proc_like
+reserved access ilk math_like
+reserved all ilk math_like
+reserved and ilk and_like
+reserved array ilk math_like
+reserved at ilk at_like
+reserved begin ilk begin_like
+reserved body ilk math_like
+reserved case ilk case_like
+reserved constant ilk math_like
+reserved declare ilk decl_like
+reserved delay ilk math_like
+reserved delta ilk math_like
+reserved digits ilk math_like
+reserved do ilk do_like
+reserved else ilk else_like
+reserved elsif ilk elsif_like
+reserved end ilk end_like
+reserved entry ilk proc_like
+reserved exception ilk ex_like
+reserved exit ilk math_like
+reserved for ilk math_like
+reserved function ilk proc_like
+reserved generic ilk gen_like
+reserved goto ilk math_like
+reserved if ilk if_like
+reserved in ilk unorbinop_like
+reserved is ilk is_like
+reserved limited ilk math_like
+reserved loop ilk loop_like
+reserved mod ilk binop_like
+reserved new ilk unop_like
+reserved not ilk unop_like
+reserved null ilk math_like
+reserved of ilk math_like
+reserved or ilk or_like
+reserved others ilk math_like
+reserved out ilk math_like
+reserved package ilk proc_like
+reserved pragma ilk math_like
+reserved private ilk private_like
+reserved procedure ilk proc_like
+reserved raise ilk math_like
+reserved range ilk math_like
+reserved record ilk record_like
+reserved rem ilk binop_like
+reserved renames ilk math_like
+reserved return ilk math_like
+reserved reverse ilk math_like
+reserved select ilk select_like
+reserved separate ilk separate_like
+reserved subtype ilk math_like
+reserved task ilk proc_like
+reserved terminate ilk math_like
+reserved then ilk then_like
+reserved type ilk math_like
+reserved use ilk math_like
+reserved when ilk when_like
+reserved while ilk math_like
+reserved with ilk with_like
+reserved xor ilk binop_like
+
+ilk and_like translation <*> category and
+ilk at_like translation <*> category at
+ilk begin_like translation <*-indent> category beginning
+ilk binop_like translation <"\\"-space-*-"\\"-space> category binop
+ilk case_like translation <*> category case
+ilk decl_like translation <*-indent> category declaration
+ilk do_like translation <*> category do
+ilk else_like translation <*> category else
+ilk elsif_like translation <*> category elsif
+ilk end_like translation <*> category close
+ilk ex_like translation <*> category exception
+ilk gen_like translation <*-indent> category generic
+ilk if_like translation <*> category if
+ilk is_like translation <*> category is
+ilk loop_like translation <*> category loop
+ilk math_like translation <*> category math
+ilk or_like translation <*> category or
+ilk private_like translation <*> category private
+ilk proc_like translation <force-*> category proc
+ilk record_like translation <*> category record
+ilk select_like translation <*> category select
+ilk separate_like translation <*> category separate
+ilk then_like translation <*> category then
+ilk unop_like translation <*-"\\"-space> category unop
+ilk unorbinop_like translation <"\\"-space-*-"\\"-space> category resunorbinop
+ilk when_like translation <*> category when
+ilk with_like translation <*> category with
+
+
+# \MC means ``math close'' and sets \MS to ``math set''
+macros begin
+\def\MC{\ifmmode\global\let\MS$\else\global\let\MS\relax\fi\relax\MS}
+\def\LG{\mathord{<}\mathord{>}}
+\let\IG=\ignorespaces
+macros end
+
+
+
+beginning <outdent-force> continuation <outdent-force> ending --> stmt
+beginning <outdent-force> ending --> stmt
+# beginning <force> (stmt|ignore_scrap) --> beginning
+beginning <force> stmt --> beginning
+
+case <"\\"-space> math <"\\"-space> is <indent-force> --> beginning
+
+close semi --> ending
+close <"\\"-space> ? semi --> ending
+close <"\\"-space> ? <"\\"-space> ? semi --> ending
+
+continuation <force> stmt --> continuation
+continuation <outdent-force> continuation --> continuation
+
+
+declaration <outdent-force> beginning <outdent-force> continuation <outdent-force> ending --> stmt
+declaration <outdent-force> beginning <outdent-force> ending --> stmt
+declaration <outdent-force> ending --> stmt
+declaration <force> (declaration|stmt) --> declaration
+
+else <indent-force> --> continuation
+elsif <"\\"-space> math <"\\"-space> then <indent-force> --> continuation
+
+exception <indent-force> --> continuation
+
+generic <outdent-force> declaration --> declaration
+generic <force> stmt --> generic
+
+if <"\\"-space> math <"\\"-space> then --> ifthen
+ifthen <indent-force> stmt --> beginning
+ifthen <indent-force> <"\\"-space> math <"\\"-space> <outdent-force> else --> ifthen
+ifthen <indent-force> <"\\"-space> math <"\\"-space> <outdent-force> close <"\\"-space> if --> math
+ifthen <indent-force> <"\\"-space> math <"\\"-space> <outdent-force> elsif --> if
+
+
+is --> math
+
+loop <indent-force> --> beginning
+
+math [ <"\\"-space> and <"\\"-space> then <"\\"-space> ] --> math binop
+math [ <"\\"-space> and <"\\"-space> ] --> math binop
+
+math (binop|unorbinop) math --> math
+math <"\\"-space> resunorbinop <"\\"-space> math --> math
+(unorbinop|unop) math --> math
+resunorbinop <"\\"-space> math --> math
+# This doesn't apply in Ada: math unop --> math
+
+math arrow --> math
+math <"\\"-space> at --> math
+math binop <"\\"-space> exception --> math
+math <"\\"-space> is --> math
+math <"\\"-space> loop --> loop
+math <"\\"-space> math --> math
+math [ <"\\"-space> or <"\\"-space> else <"\\"-space> ] --> math binop
+math [ <"\\"-space> or <"\\"-space> ] --> math binop
+math <"\\"-space> private --> math
+math <"\\"-space> separate --> math
+math <indent-force> stmt <outdent-force> --> stmt
+math terminator --> stmt
+
+open close --> math
+open math close --> math
+open [ math semi ] --> open math
+
+<force-backup> openlabel math closelabel <force> --> math
+
+or <indent-force> --> continuation
+
+private <indent-force> --> beginning
+
+proc <"\\"-space> math <"\\"-space> is <"\\"-space> unop --> math
+proc <"\\"-space> math <"\\"-space> is <"\\"-space> separate --> math
+proc <"\\"-space> math <"\\"-space> is <indent-force> --> declaration
+proc <"\\"-space> math <"\\"-space> do <indent-force> --> beginning
+proc <"\\"-space> math terminator <force> --> declaration
+
+#record <"\\"-space> at <"\\"-space> math terminator <indent-force> --> beginning
+record <indent-force> --> beginning
+
+select <indent-force> --> beginning
+
+semi --> terminator
+
+separate math --> stmt
+
+stmt <force> declaration --> declaration
+
+stmt <force> stmt --> stmt
+
+stmt <outdent-force> ending --> stmt
+
+when <"\\"-space> math arrow <indent-force> --> whengroup
+[ when <"\\"-space> math ] terminator --> math terminator
+whengroup stmt <outdent-force> ending --> ending
+whengroup stmt <outdent-force> continuation --> continuation
+whengroup stmt <outdent-force> whengroup --> whengroup
+
+with <"\\"-space> math --> math
+with <"\\"-space> proc <"\\"-space> math --> math
+
+? ignore_scrap --> #1
+
+macros begin
+\let\AR=\Longrightarrow
+macros end
+------------------
+End of ada.spider
+------------------
+
+I'll let you know about the change you suggested. Until the problem
+has been fixed, I have asked users here not use bases larger than ten
+when specifying numeric constants.
+
+ Sylvester Fernandez
+
diff --git a/web/spiderweb/src/ada/old.spider b/web/spiderweb/src/ada/old.spider
new file mode 100644
index 0000000000..ce2b566a7d
--- /dev/null
+++ b/web/spiderweb/src/ada/old.spider
@@ -0,0 +1,261 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+language Ada extension ada
+
+at_sign @
+
+module definition stmt use math
+
+comment begin <dash-dash> end newline
+macros begin
+\def\commentbegin{{\tt -- }}
+macros end
+
+line begin <dash-dash-"line"> end <"">
+
+default translation <*> mathness yes
+
+token identifier category math mathness maybe
+token number category math mathness yes
+token newline category ignore_scrap translation <> mathness maybe
+token pseudo_semi translation <> category semi mathness maybe
+
+macros begin
+\let\R\relax
+macros end
+
+# Delimiters
+token & category binop translation <"\\amp">
+token ( category open
+token ) category close
+token * category binop
+token + category unorbinop
+token , category binop translation <",\\,"-opt-3>
+token - category unorbinop
+token . category binop
+token / category binop
+token : category binop
+token ; category semi translation <";"-space-opt-2>
+token < category binop
+token = category binop
+token > category binop
+token | category binop translation <"\\mid">
+
+# Compound delimiters
+
+token => category arrow translation <"\\AR">
+token .. category binop translation <"\\.{..}">
+token ** category binop translation <"\\mathbin{**}">
+token := category binop translation <"\\mathbin{:=}">
+token /= translation <"\\I"> category binop
+token >= translation <"\\G"> category binop
+token <= translation <"\\L"> category binop
+token << translation <"\\LL"> category openlabel
+token >> translation <"\\GG"> category closelabel
+token <> translation <"\\LG"> category math
+
+# Hacks no ', and this becomes a binary op
+token ' category binop mathness no
+
+token # category math translation <"\\#">
+
+
+
+
+default mathness maybe translation <*>
+
+reserved abort ilk math_like
+reserved abs ilk unop_like
+reserved accept ilk proc_like
+reserved access ilk math_like
+reserved all ilk math_like
+reserved and ilk and_like
+reserved array ilk math_like
+reserved at ilk at_like
+reserved begin ilk begin_like
+reserved body ilk math_like
+reserved case ilk case_like
+reserved constant ilk math_like
+reserved declare ilk decl_like
+reserved delay ilk math_like
+reserved delta ilk math_like
+reserved digits ilk math_like
+reserved do ilk is_like
+reserved else ilk else_like
+reserved elsif ilk elsif_like
+reserved end ilk end_like
+reserved entry ilk proc_like
+reserved exception ilk ex_like
+reserved exit ilk math_like
+reserved for ilk math_like
+reserved function ilk proc_like
+reserved generic ilk gen_like
+reserved goto ilk math_like
+reserved if ilk if_like
+reserved in ilk unorbinop_like
+reserved is ilk is_like
+reserved limited ilk math_like
+reserved loop ilk loop_like
+reserved mod ilk binop_like
+reserved new ilk separate_like
+reserved not ilk unop_like
+reserved null ilk math_like
+reserved of ilk math_like
+reserved or ilk or_like
+reserved others ilk math_like
+reserved out ilk math_like
+reserved package ilk proc_like
+reserved pragma ilk math_like
+reserved private ilk private_like
+reserved procedure ilk proc_like
+reserved raise ilk math_like
+reserved range ilk math_like
+reserved record ilk record_like
+reserved rem ilk binop_like
+reserved renames ilk math_like
+reserved return ilk math_like
+reserved reverse ilk math_like
+reserved select ilk begin_like
+reserved separate ilk separate_like
+reserved subtype ilk math_like
+reserved task ilk proc_like
+reserved terminate ilk math_like
+reserved then ilk then_like
+reserved type ilk math_like
+reserved use ilk math_like
+reserved when ilk when_like
+reserved while ilk math_like
+reserved with ilk with_like
+reserved xor ilk binop_like
+
+ilk and_like translation <*> category and
+ilk at_like translation <*> category at
+ilk begin_like translation <*-indent> category beginning
+ilk binop_like translation <"\\"-space-*-"\\"-space> category binop
+ilk case_like translation <*> category case
+ilk decl_like translation <*-indent> category declaration
+ilk else_like translation <*> category else
+ilk elsif_like translation <*> category elsif
+ilk end_like translation <*> category close
+ilk ex_like translation <*> category exception
+ilk gen_like translation <*-indent> category generic
+ilk if_like translation <*> category if
+ilk is_like translation <*> category is
+ilk loop_like translation <*> category loop
+ilk math_like translation <*> category math
+ilk or_like translation <*> category or
+ilk private_like translation <*> category private
+ilk proc_like translation <*> category proc
+ilk record_like translation <*> category record
+ilk separate_like translation <*> category separate
+ilk then_like translation <*> category then
+ilk unop_like translation <*-"\\"-space> category unop
+ilk unorbinop_like translation <"\\"-space-*-"\\"-space> category resunorbinop
+ilk when_like translation <*> category when
+ilk with_like translation <*> category with
+
+
+# \MC means ``math close'' and sets \MS to ``math set''
+macros begin
+\def\MC{\ifmmode\global\let\MS$\else\global\let\MS\relax\fi\relax\MS}
+\def\LG{\mathord{<}\mathord{>}}
+\let\IG=\ignorespaces
+macros end
+
+
+
+beginning <outdent-force> continuation <outdent-force> ending --> stmt
+beginning <outdent-force> ending --> stmt
+# beginning <force> (stmt|ignore_scrap) --> beginning
+beginning <force> stmt --> beginning
+
+case <"\\"-space> math <"\\"-space> is <indent-force> --> beginning
+
+close semi --> ending
+close <"\\"-space> ? semi --> ending
+close <"\\"-space> ? <"\\"-space> ? semi --> ending
+
+continuation <force> stmt --> continuation
+continuation <outdent-force> continuation --> continuation
+
+
+declaration <outdent-force> beginning <outdent-force> continuation <outdent-force> ending --> stmt
+declaration <outdent-force> beginning <outdent-force> ending --> stmt
+declaration <outdent-force> ending --> stmt
+declaration <force> stmt --> declaration
+
+else <indent-force> --> continuation
+elsif <"\\"-space> math <"\\"-space> then <indent-force> --> continuation
+
+exception <indent-force> --> continuation
+
+generic <outdent-force> declaration --> declaration
+generic <force> stmt --> generic
+
+if <"\\"-space> math <"\\"-space> then --> ifthen
+ifthen <indent-force> stmt --> beginning
+ifthen <indent-force> <"\\"-space> math <"\\"-space> <outdent-force> else --> ifthen
+ifthen <indent-force> <"\\"-space> math <"\\"-space> <outdent-force> close <"\\"-space> if --> math
+ifthen <indent-force> <"\\"-space> math <"\\"-space> <outdent-force> elsif --> if
+
+
+is --> math
+
+loop <indent-force> --> beginning
+
+math [ <"\\"-space> and <"\\"-space> then <"\\"-space> ] --> math binop
+math [ <"\\"-space> and <"\\"-space> ] --> math binop
+
+math (binop|unorbinop) math --> math
+math <"\\"-space> resunorbinop <"\\"-space> math --> math
+(unorbinop|unop) math --> math
+resunorbinop <"\\"-space> math --> math
+# This doesn't apply in Ada: math unop --> math
+
+math arrow --> math
+math binop <"\\"-space> exception --> math
+math <"\\"-space> is --> math
+math <"\\"-space> loop --> loop
+math <"\\"-space> math --> math
+math [ <"\\"-space> or <"\\"-space> else <"\\"-space> ] --> math binop
+math [ <"\\"-space> or <"\\"-space> ] --> math binop
+math <"\\"-space> private --> math
+math <"\\"-space> separate --> math
+math <indent-force> stmt <outdent-force> --> stmt
+math terminator --> stmt
+
+open close --> math
+open math close --> math
+open [ math semi ] --> open math
+
+<force-backup> openlabel math closelabel <force> --> math
+
+or <indent-force> --> continuation
+
+private <indent-force> --> beginning
+
+proc <"\\"-space> math <"\\"-space> is <"\\"-space> separate --> math
+proc <"\\"-space> math <"\\"-space> is <indent-force> --> declaration
+proc <"\\"-space> math terminator --> stmt
+
+record <"\\"-space> at <"\\"-space> math terminator <indent-force> --> beginning
+record <indent-force> --> beginning
+
+semi --> terminator
+
+stmt <force> stmt --> stmt
+
+when <"\\"-space> math arrow <indent-force> --> whengroup
+[ when <"\\"-space> math ] terminator --> math terminator
+whengroup stmt <outdent-force> ending --> ending
+whengroup stmt <outdent-force> whengroup --> whengroup
+
+with <"\\"-space> math --> math
+with <"\\"-space> proc <"\\"-space> math --> math
+
+? ignore_scrap --> #1
+
+macros begin
+\let\AR=\Longrightarrow
+macros end
diff --git a/web/spiderweb/src/ada/stacks.web b/web/spiderweb/src/ada/stacks.web
new file mode 100644
index 0000000000..8e05ee0f31
--- /dev/null
+++ b/web/spiderweb/src/ada/stacks.web
@@ -0,0 +1,443 @@
+\message{OK, entering \string\batchmode...}
+\batchmode
+\overfullrule0pt
+\input enumerate
+\def\VC#1#2{{\enumerate\item #1\endenumerate\par}{$>\!\!>$\ #2\par}}
+%\parindent=0pt\parskip=0.5\baselineskip
+\let\maps\rightarrow
+\def\title{A Generic Stack Package}
+
+@*Stacks.
+The idea is to implement, and to prove part of, a simple stack package.
+We write a Larch trait for the stacks,
+we use terms of that trait to specify our package.
+ In the package body we write down an explicit
+representation invariant |invar| and an explicit abstraction function
+|abstraction|, and we use them to prove the package \`a la Hoare.
+The package specification refers only to the abstract trait,
+and our software will automatically perform the translation required
+to introduce explicit invariants and abstraction functions in the
+package body.
+
+@*Theory of stacks.
+We use the following theory:
+%\input stacktrait.pretty
+
+
+@*Specification.
+We now use the |Stack_theory| trait to specify a package.
+The phrase
+|with trait Stack_theory|
+makes the |Stack_theory| trait visible and
+the phrase
+|based on stack|
+makes the sort |stack| from |Stack_theory| the abstract sort |stack'ABSTRACT|.
+We also use the |element| sort to represent the private type |element|.
+% ACK! What proof obligations does this give?
+
+In the package {\it specification}, all terms of type |stack| are
+specified with terms of type |Stacks_theory.stack|.
+In the package {\it body}, we will specify terms of type |stack| with
+terms of a sort corresponding to the private type of stack (in this
+instance, a record type).
+We will provide an abstraction function from terms of the record trait
+to terms of the stack trait, and an invariant function from terms of
+the record trait to |boolean|.
+@c@0
+generic
+ type element is private;
+ length: natural := 100;
+package stacks is
+
+ type stack is private;
+@/
+ overflow, underflow: exception;
+@#
+ function empty_stack return stack;
+
+
+@#
+ function pushit(s:stack; e:element) return stack;
+
+
+
+
+@#
+ function popit(s:stack) return stack;
+
+
+
+
+@#
+ function topit(s:stack) return element;
+
+
+
+
+@#
+ function isEmpty(s:stack) return boolean;
+
+
+
+
+private
+ subtype stack_range is natural range 0.. length - 1;
+ type stack_array is array(stack_range) of element;
+ type stack is
+ record
+ l: natural; -- length
+ a: stack_array; --stack
+ end record;
+
+end stacks;
+@*Implementation.
+We break the implementation into pieces so we can discuss them one at
+a time.
+
+Within the hidden part of the package, |stack| will stand for the
+concrete type (or sort), |stack'CONCRETE|.
+Outside, in the specification, |stack| will stand for the abstract
+type (or sort), |stack'ABSTRACT|.
+We use types in actual Ada code, and sorts in annotations and virtual
+functions.
+
+@c
+generic
+ type element is private;
+ length: natural := 100;
+package body stacks is
+@<Abstraction and invariants@>@;
+@<Implementation of |empty_stack|@>@;
+@<Implementation of |pushit|@>@;
+@<Implementation of |popit|@>@;
+@<Implementation of |topit|@>@;
+@<Implementation of |isEmpty|@>@;
+end stacks;
+@ Here we make explicit the representation invariant |invar| and the
+abstraction function |abstraction|.
+These are virtual functions, and templates for them will be generated
+automatically from the package specification.
+These functions will appear in the annotations for the operations of
+the package, which will also have been translated from the package
+specification.
+
+The invariant requires only that the length be within sensible bounds.
+(I have ignored the problem of definedness throughout the example.)
+The abstraction function works by peeling off the top element, and
+pushing it onto the abstraction of what's left.
+This works all the way down to |s.l=0|, for which the abstraction is
+|new_stack|.
+
+The templates for |invar| and |abstraction| are generated
+automatically.
+
+@<Abstraction...@>=
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+@ To implement |empty_stack| we return a stack of length zero.
+
+@<Implementation of |empty_stack|@>=
+function empty_stack return stack
+
+
+
+
+
+is
+ empty: stack;
+begin
+ empty.l := 0;
+ return empty;
+end empty_stack;
+
+@*Proof of |empty_stack|.
+Here and elsewhere we will use the notation |@@return| to denote the return
+value.
+Predicate transformation of the postcondition leaves the following verification
+condition:
+\VC{|true|}{|invar(empty) and abstraction(empty)=new_stack|}
+
+We split and get
+\VC{|true|}{|invar(empty)|}
+and, expanding
+\VC{|true|}{|0<=empty.l and empty.l <= length|}
+and substituting for |empty.l| (on what basis?)
+\VC{|true|}{|0<=0 and 0 <= length|}
+from which
+\VC{|true|}{|true|}
+because of the property |0<=n| for any natural number |n|.
+
+The second verification condition is
+\VC{|true|}{|abstraction(empty)=new_stack|}
+We expand |abstraction|, spawning the new VC
+\VC{|true|}{|invar(empty)|}
+for which we can refer to the earlier proof.
+We are left with
+\VC{|true|}{|if empty.l=0 then new_stack else
+ push(abstraction(empty[l=>l-1]),empty.a(empty.l));
+ end if = new_stack;|}
+Which rewrites to
+\VC{|true|}{|new_stack=new_stack|}
+
+
+@ Here we have to check for overflow, but there are really no surprises.
+@<Implementation of |pushit|@>=
+function pushit(s:stack; e:element) return stack
+
+
+
+
+
+
+is
+ t: stack;
+begin
+ if s.l=length then raise overflow; end if;
+ t.l := s.l+1;
+ t.a := s.a;
+ t.a(t.l) := e;
+ return t;
+end empty_stack;
+
+@*Predicate transformation of |pushit|.
+Here we have ignored the possibility of abnormal termination.
+
+I've written intermediate conditions in between the statements to
+which they apply.
+The predicate transformation rules I've used are completely
+informal.
+
+
+@c
+function pushit(s:stack; e:element) return stack
+
+
+
+
+
+
+
+is
+ t: stack;
+begin
+
+
+
+ if s.l=length then raise overflow; end if;
+
+
+ t.l := s.l+1;
+
+
+ t.a := s.a;
+
+
+ t.a(t.l) := e;
+
+
+ return t;
+
+
+end empty_stack;
+
+@*Proof of |pushit|.
+We're going to make heavy use of a (nonexistent) theory of records.
+Record states are as in Anna;
+informally they behave just as you would think.
+
+We first rewrite the term involving |t| into a simpler and more useful
+form:
+$$\vbox{\noindent
+|t[l=>s.l+1;a=>s.a;a(l)=>e]| rewrites to
+|s[l=>l+1;a(l)=>e]|.
+}$$
+
+
+After this simplification we have this verification condition:
+\VC{|
+invar(s)|\item
+|not (size(abstraction(s)) = length)|}
+{|
+s.l /= length and
+invar(s[l=>l+1;a(l)=>e]) and
+abstraction(s[l=>l+1;a(l)=>e])=push(abstraction(s),e)
+|}
+We'll tackle one conjunct at a time.
+
+@ {\it First conjunct.}
+We begin by proving a lemma about |size|:
+\VC{|invar(s)|}
+{|size(abstraction(s))|$\simeq$|s.l|}
+The proof is by type induction on the predefined type |natural|.
+We omit it here.
+
+Once we have the |size| lemma we rewrite the VC for the first conjunct as:
+\VC{|
+invar(s)|\item
+|not (s.l = length)|}
+{|s.l /= length|}
+The proof is by the laws (not stated) for |=| and |/=|.
+
+@ {\it Second Conjunct.}
+Again we apply the |size| lemma.
+\VC{|
+invar(s)|\item
+|not (s.l = length)|}
+{|
+invar(s[l=>l+1;a(l)=>e])|}
+Expanding the definition of |invar| in the hypothesis and the conclusion yields
+\VC{|
+0<=s.l and s.l <= length|\item
+|not (s.l = length)|}
+{|
+0<=s[l=>l+1;a(l)=>e].l and
+s[l=>l+1;a(l)=>e].l<=length
+|}
+and we again exploit the theory of records to rewrite as
+\VC{|
+0<=s.l and s.l <= length|\item
+|not (s.l = length)|}
+{|
+0<=s.l+1 and
+s.l+1<=length
+|}
+And the proof follows by |and|-splitting hypotheses and conclusion and by
+applying the laws of arithmetic.
+
+@ {\it Third conjunct.}
+This is the interesting part.
+We expand the definition of |abstraction| on the left hand side of the
+conclusion.
+This spawns a VC showing that the argument to |abstraction| satisfies
+|invariant|, but we did that earlier.
+
+\VC{|
+invar(s)|\item
+|not (size(abstraction(s)) = length)|}
+{|
+if s[l=>l+1;a(l)=>e].l=0 then new_stack else
+push(abstraction(s[l=>l+1;a(l)=>e;l=>l-1]),
+s[l=>l+1;a(l)=>e].a(s[l=>l+1;a(l)=>e].l)) end if
+ =push(abstraction(s),e)
+|}
+and, rewriting according to the theory of records
+(especially
+|s[l=>l+1;a(l)=>e].a(s[l=>l+1;a(l)=>e].l)|
+rewrites to
+|s[l=>l+1;a(s.l+1)=>e].a(s.l+1)|
+which rewrites to |e|):
+\VC{|
+invar(s)|\item
+|not (size(abstraction(s)) = length)|}
+{|
+if s.l+1=0 then new_stack else
+push(abstraction(s[a(l+1)=>e]),e) end if
+ =push(abstraction(s),e)
+|}
+Applying the laws of natural numbers we have
+\VC{|
+invar(s)|\item
+|not (size(abstraction(s)) = length)|}
+{|
+push(abstraction(s[a(l+1)=>e]),e) = push(abstraction(s),e)
+|}
+
+
+And now we show by a lemma that
+\VC{|invar(s)|\item |s.l/=length|}
+{
+|abstraction(s[a(l+1)=>e])|$\simeq$|abstraction(s)|
+}
+which is sufficient.
+The proof of the lemma is by induction over |l| (type induction of the
+predefined type |natural|).
+
+
+
+
+@ @<Implementation of |popit|@>=
+function popit(s:stack) return stack
+
+
+
+
+
+
+is
+ t: stack;
+begin
+ if s.l=0 then raise underflow; end if;
+ t := s;
+ t.l := t.l-1;
+ return t;
+end popit;
+
+@ @<Implementation of |topit|@>=
+function topit (s:stack) return element
+
+
+
+
+is
+begin
+ if s.l=0 then raise underflow; end if;
+ return s.a(s.l);
+end topit;
+
+@ @<Implementation of |isEmpty|@>=
+ function isEmpty(s:stack) return boolean
+
+
+
+
+ is
+ begin
+ return s.l=0;
+ end isEmpty;
+@ Predicate transformation of isEmpty.
+@c
+ function isEmpty(s:stack) return boolean
+
+
+
+
+ is
+ begin
+
+ return s.l=0;
+
+ end isEmpty;
+
+@ Proof of isEmpty.
+\VC{|invariant(s)|}{|s.l=0 =is_empty(abstraction(s))|}
+Expanding |abstraction(s)|,
+\VC{|invariant(s)|}{|s.l=0 =is_empty(if s.l=0 then nil
+ else cons(abstraction(s[l=>l-1]),l.a(s.l-1)))|}
+Simplifying,
+\VC{|invariant(s)|}{|(s.l=0)=if s.l=0 then is_empty(nil)
+ else is_empty(cons(abstraction(s[l=>l-1]),l.a(s.l-1)))|}
+which we can rewrite as
+\VC{|invariant(s)|}{|(s.l=0)=if s.l=0 then true
+ else is_empty(cons(abstraction(s[l=>l-1]),l.a(s.l-1)))|}
+Simplifying,
+\VC{|invariant(s)|}{|true|}
+
+
+@*Index.
+This is an index of all the identifiers used in the program.
+The numbers are section numbers, not page numbers. \ No newline at end of file
diff --git a/web/spiderweb/src/awk/awk.spider b/web/spiderweb/src/awk/awk.spider
new file mode 100644
index 0000000000..0ecc98c8c4
--- /dev/null
+++ b/web/spiderweb/src/awk/awk.spider
@@ -0,0 +1,168 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+language AWK extension awk
+
+at_sign #
+
+module definition stmt use stmt
+# use as stmt is unavoidable since tangle introduces line breaks
+
+comment begin <"##"> end newline
+macros begin
+\def\commentbegin{\#} % we don't want \#\#
+macros end
+
+line begin <"#line"> end <"">
+
+default translation <*> mathness yes
+
+token identifier category math mathness yes
+token number category math mathness yes
+token newline category newline translation <> mathness maybe
+token pseudo_semi category ignore_scrap mathness no translation <opt-0>
+
+token \ category backslash translation <> mathness maybe
+token + category unorbinop
+token - category unorbinop
+token * category binop
+token / category binop
+token < category binop
+token > category binop
+token >> category binop translation <"\\GG">
+token = category equals translation <"\\K">
+token ~ category binop translation <"\\TI">
+token !~ category binop translation <"\\not\\TI">
+token & category binop translation <"\\amp">
+token % translation <"\\%"> category binop
+token ( category open
+token [ category lsquare
+token ) category close
+token ] category close
+token { translation <"\\;\\{"-indent> category lbrace
+token } translation <"\\}\\"-space> category close
+token , category binop translation <",\\,"-opt-3>
+
+token ; category semi translation <";"-space-opt-2> mathness no
+# stuff with semi can be empty in for statements
+open semi --> open
+semi semi --> semi
+semi close --> close
+semi --> binop
+
+# token : category colon
+# token | category bar
+token != name not_eq translation <"\\I"> category binop
+token <= name lt_eq translation <"\\L"> category binop
+token >= name gt_eq translation <"\\G"> category binop
+token == name eq_eq translation <"\\S"> category binop
+token && name and_and translation <"\\W"> category binop
+token || name or_or translation <"\\V"> category binop
+# token -> name minus_gt translation <"\\MG"> category binop
+token ++ name gt_gt category unop translation <"\\uparrow">
+token -- name lt_lt category unop translation <"\\downarrow">
+# preunop is for unary operators that are prefix only
+token $ category preunop translation <"\\DO"> mathness yes
+
+default mathness yes translation <*>
+
+ilk pattern_like category math
+reserved BEGIN ilk pattern_like
+reserved END ilk pattern_like
+
+ilk if_like category if
+reserved if
+ilk else_like category else
+reserved else
+
+ilk print_like category math
+# math forces space between this and other math...
+reserved print ilk print_like
+reserved printf ilk print_like
+reserved sprintf ilk print_like
+
+
+ilk functions category unop mathness yes
+reserved length ilk functions
+reserved substr ilk functions
+reserved index ilk functions
+reserved split ilk functions
+reserved sqrt ilk functions
+reserved log ilk functions
+reserved exp ilk functions
+reserved int ilk functions
+
+ilk variables category math mathness yes
+reserved NR ilk variables
+reserved NF ilk variables
+reserved FS ilk variables
+reserved RS ilk variables
+reserved OFS ilk variables
+reserved ORS ilk variables
+
+ilk for_like category for
+reserved for ilk for_like
+reserved while ilk for_like
+
+ilk in_like category binop translation <math_bin-*-"}"> mathness yes
+# translation <"\\"-space-*-"\\"-space>
+reserved in ilk in_like
+
+ilk stmt_like category math
+reserved break ilk stmt_like
+reserved continue ilk stmt_like
+reserved next ilk stmt_like
+reserved exit ilk stmt_like
+
+
+backslash newline --> math
+# The following line must be changed to make a backslash
+backslash <"\\backslash"> --> math
+
+math (binop|unorbinop) math --> math
+<"\\buildrel"> (binop|unorbinop) <"\\over{"> equals <"}"> --> binop
+equals --> binop
+(unop|preunop|unorbinop) math --> math
+# unorbinop can only act like unary op as *prefix*, not postfix
+math unop --> math
+math <"\\"-space> math --> math
+# concatenation
+
+math newline --> stmt
+newline --> ignore_scrap
+
+stmt <force> stmt --> stmt
+
+(open|lsquare) math close --> math
+
+math lbrace --> lbrace
+lbrace <force> stmt --> lbrace
+lbrace <outdent-force> close --> stmt
+
+if <"\\"-space> math --> ifmath
+ifmath lbrace --> ifbrace
+ifmath newline --> ifline
+ifbrace <force> stmt --> ifbrace
+ifbrace <outdent-force> close else <"\\"-space> if --> if
+ifbrace <outdent-force> close else lbrace --> ifbrace
+ifbrace <outdent-force> close else newline --> ifline
+ifbrace <outdent-force> close --> stmt
+(ifline|ifmath) <indent-force> stmt <outdent-force> else <"\\"-space> if --> if
+(ifline|ifmath) <indent-force> stmt <outdent-force> else lbrace --> ifbrace
+(ifline|ifmath) <indent-force> stmt <outdent-force> else newline --> ifline
+(ifline|ifmath) <indent-force> stmt <outdent-force> else --> ifmath
+(ifline|ifmath) <indent-force> stmt <outdent> --> stmt
+
+for <"\\"-space> math --> formath
+formath lbrace --> forbrace
+formath newline --> forline
+forbrace <force> stmt --> forbrace
+forbrace <outdent-force> close --> stmt
+(forline|formath) <indent-force> stmt <outdent> --> stmt
+
+
+
+? ignore_scrap --> #1
+
+
+
diff --git a/web/spiderweb/src/awk/make b/web/spiderweb/src/awk/make
new file mode 100644
index 0000000000..5eda54b414
--- /dev/null
+++ b/web/spiderweb/src/awk/make
@@ -0,0 +1,2 @@
+/bin/make -f ../master/WebMakefile CPUTYPE=`cputype`\
+ THETANGLE=awktangle THEWEAVE=awkweave SPIDER=awk.spider $*
diff --git a/web/spiderweb/src/awk/tangle.c b/web/spiderweb/src/awk/tangle.c
new file mode 100644
index 0000000000..7cc7250d5d
--- /dev/null
+++ b/web/spiderweb/src/awk/tangle.c
@@ -0,0 +1,2172 @@
+/*1:*/
+#line 44 "tangle.web"
+
+/*4:*/
+#line 15 "common.h"
+
+#line 16 "common.h"
+#include<stdio.h>
+
+/*:4*//*94:*/
+#line 1046 "tangle.web"
+
+#line 1047 "tangle.web"
+#include"ctype.h"
+
+/*:94*/
+#line 45 "tangle.web"
+
+/*3:*/
+#line 9 "common.h"
+
+typedef short boolean;
+typedef char unsigned eight_bits;
+extern boolean program;
+extern int phase;
+
+/*:3*//*5:*/
+#line 24 "common.h"
+
+typedef char ASCII;
+typedef char outer_char;
+extern ASCII xord[];
+extern outer_char xchr[];
+ASCII mod_text[400+1];
+ASCII *mod_text_end= mod_text+400;
+ASCII *id_first;
+ASCII *id_loc;
+
+/*:5*//*6:*/
+#line 37 "common.h"
+
+#line 38 "common.h"
+extern ASCII buffer[];
+extern ASCII *buffer_end;
+extern ASCII *loc;
+extern ASCII *limit;
+
+/*:6*//*7:*/
+#line 55 "common.h"
+
+typedef struct name_info{
+ASCII *byte_start;
+struct name_info *link;
+union{
+struct name_info *Rlink;
+
+eight_bits Ilk;
+
+}dummy;
+ASCII *equiv_or_xref;
+}name_info;
+typedef name_info *name_pointer;
+typedef name_pointer *hash_pointer;
+extern ASCII byte_mem[];
+extern ASCII *byte_mem_end;
+extern name_info name_dir[];
+extern name_pointer name_dir_end;
+extern name_pointer name_ptr;
+extern ASCII *byte_ptr;
+extern name_pointer hash[];
+extern hash_pointer hash_end;
+extern hash_pointer h;
+extern name_pointer id_lookup();
+extern name_pointer mod_lookup();
+extern name_pointer prefix_lookup();
+
+/*:7*//*8:*/
+#line 98 "common.h"
+
+extern history;
+
+/*:8*//*9:*/
+#line 109 "common.h"
+
+extern include_depth;
+extern FILE *file[];
+extern FILE *change_file;
+extern char C_file_name[];
+extern char tex_file_name[];
+extern char file_name[][60];
+
+extern char change_file_name[];
+extern line[];
+extern change_line;
+extern boolean input_has_ended;
+extern boolean changing;
+
+/*:9*//*10:*/
+#line 124 "common.h"
+
+#line 125 "common.h"
+typedef unsigned short sixteen_bits;
+extern sixteen_bits module_count;
+extern boolean changed_module[];
+extern boolean print_where;
+
+/*:10*//*11:*/
+#line 131 "common.h"
+
+#line 132 "common.h"
+extern int argc;
+extern char * *argv;
+extern no_xref;
+
+/*:11*//*12:*/
+#line 144 "common.h"
+
+FILE *C_file;
+FILE *tex_file;
+#line 81 "tangle.web"
+
+/*:12*/
+#line 46 "tangle.web"
+
+/*14:*/
+#line 107 "tangle.web"
+
+#line 108 "tangle.web"
+typedef struct{
+eight_bits *tok_start;
+sixteen_bits text_link;
+}text;
+typedef text *text_pointer;
+
+/*:14*//*25:*/
+#line 254 "tangle.web"
+
+typedef struct{
+eight_bits *end_field;
+eight_bits *byte_field;
+name_pointer name_field;
+text_pointer repl_field;
+sixteen_bits mod_field;
+}output_state;
+typedef output_state *stack_pointer;
+
+/*:25*/
+#line 47 "tangle.web"
+
+/*15:*/
+#line 114 "tangle.web"
+
+#line 115 "tangle.web"
+text text_info[2000];
+text_pointer text_info_end= text_info+2000-1;
+text_pointer text_ptr;
+eight_bits tok_mem[150000];
+eight_bits *tok_mem_end= tok_mem+150000-1;
+eight_bits *tok_ptr;
+
+/*:15*//*21:*/
+#line 185 "tangle.web"
+
+text_pointer last_unnamed;
+
+/*:21*//*26:*/
+#line 270 "tangle.web"
+
+output_state cur_state;
+
+output_state stack[50+1];
+stack_pointer stack_ptr;
+stack_pointer stack_end= stack+50;
+
+/*:26*//*37:*/
+#line 413 "tangle.web"
+
+int cur_val;
+
+
+/*:37*//*46:*/
+#line 520 "tangle.web"
+
+#line 521 "tangle.web"
+short balances[128];
+/*:46*//*50:*/
+#line 583 "tangle.web"
+
+#line 584 "tangle.web"
+name_pointer parm_ptr;
+
+/*:50*//*62:*/
+#line 706 "tangle.web"
+
+eight_bits out_state;
+boolean protect;
+
+/*:62*//*64:*/
+#line 735 "tangle.web"
+
+name_pointer output_files[256];
+name_pointer *cur_out_file, *end_output_files, *an_output_file;
+char cur_module_char;
+char output_file_name[400];
+
+/*:64*//*78:*/
+#line 101 "outtoks.web"
+char C_file_extension[]= "awk";
+/*:78*//*80:*/
+#line 106 "outtoks.web"
+char the_at_sign= 35;
+
+/*:80*//*86:*/
+#line 943 "tangle.web"
+
+eight_bits ccode[128];
+
+/*:86*//*88:*/
+#line 975 "tangle.web"
+short tracing;
+#line 976 "tangle.web"
+/*:88*//*91:*/
+#line 1009 "tangle.web"
+
+#line 1010 "tangle.web"
+boolean comment_continues= 0;
+
+/*:91*//*93:*/
+#line 1043 "tangle.web"
+
+name_pointer cur_module;
+
+/*:93*//*108:*/
+#line 1310 "tangle.web"
+
+text_pointer cur_text;
+eight_bits next_control;
+
+/*:108*//*111:*/
+#line 1373 "tangle.web"
+
+ASCII param_name_texts[256];
+ASCII *param_name_texts_end= param_name_texts+256;
+ASCII *param_names[32];
+short next_param_name;
+ASCII *next_param_name_text;
+
+/*:111*//*132:*/
+#line 1693 "tangle.web"
+
+#line 1694 "tangle.web"
+extern sixteen_bits module_count;
+
+/*:132*/
+#line 48 "tangle.web"
+
+
+main(ac,av)
+char * *av;
+{
+argc= ac;argv= av;
+program= 0;
+/*16:*/
+#line 122 "tangle.web"
+
+#line 123 "tangle.web"
+text_info->tok_start= tok_ptr= tok_mem;
+text_ptr= text_info+1;text_ptr->tok_start= tok_mem;
+
+
+/*:16*//*18:*/
+#line 132 "tangle.web"
+
+name_dir->equiv_or_xref= (ASCII *)text_info;
+
+/*:18*//*22:*/
+#line 188 "tangle.web"
+last_unnamed= text_info;text_info->text_link= 0;
+#line 189 "tangle.web"
+
+/*:22*//*47:*/
+#line 522 "tangle.web"
+
+#line 523 "tangle.web"
+{int i;
+for(i= 0;i<128;i++)balances[i]= 0;
+/*48:*/
+#line 529 "tangle.web"
+
+#line 530 "tangle.web"
+balances[40]= 1;
+balances[41]= -1;
+balances[91]= 1;
+balances[93]= -1;
+balances[123]= 1;
+balances[125]= -1;
+
+/*:48*/
+#line 525 "tangle.web"
+;
+}
+/*:47*//*65:*/
+#line 745 "tangle.web"
+
+#line 746 "tangle.web"
+cur_out_file= end_output_files= output_files+256;
+
+/*:65*//*87:*/
+#line 946 "tangle.web"
+{
+#line 947 "tangle.web"
+int c;
+for(c= 0;c<=127;c++)ccode[c]= 0;
+ccode[' ']= ccode[011]= ccode['*']= 255;
+ccode['@']= '@';
+ccode['=']= 2;
+ccode['d']= ccode['D']= 252;
+ccode['f']= ccode['F']= 251;
+ccode['c']= ccode['C']= 253;
+ccode['u']= ccode['U']= 253;
+ccode['^']= ccode[':']= ccode['.']= ccode['t']= ccode['T']= 250;
+ccode['&']= 127;
+ccode['<']= ccode['(']= 254;
+ccode['`']= 249;
+ccode['\'']= 5;
+ccode['"']= 6;
+
+
+
+ccode['@']= ccode[35];
+ccode[35]= 35;
+
+#ifdef DEBUG
+ccode['0']= ccode['1']= ccode['2']= ccode['3']= ccode['4']= 248;
+#endif DEBUG
+
+}
+
+/*:87*//*89:*/
+#line 976 "tangle.web"
+tracing= 0;
+#line 977 "tangle.web"
+
+/*:89*//*104:*/
+#line 1239 "tangle.web"
+mod_text[0]= ' ';
+#line 1240 "tangle.web"
+
+/*:104*//*113:*/
+#line 1385 "tangle.web"
+/*112:*/
+#line 1380 "tangle.web"
+
+#line 1381 "tangle.web"
+next_param_name= 0;
+next_param_name_text= param_name_texts;
+param_names[next_param_name]= next_param_name_text;
+
+/*:112*/
+#line 1385 "tangle.web"
+;
+#line 1386 "tangle.web"
+
+/*:113*/
+#line 55 "tangle.web"
+;
+common_init();
+printf("This is AWK TANGLE (generated at 5:29 PM on April 5, 1993)\n");
+phase_one();
+phase_two();
+wrap_up();
+}
+
+/*:1*//*19:*/
+#line 138 "tangle.web"
+
+#line 139 "tangle.web"
+names_match(p,first,l)
+name_pointer p;
+ASCII *first;
+int l;
+{
+if(((p+1)->byte_start-(p)->byte_start)!=l)return 0;
+return!strncmp(first,p->byte_start,l);
+}
+
+/*:19*//*20:*/
+#line 149 "tangle.web"
+
+#line 150 "tangle.web"
+init_node(node)
+name_pointer node;
+{
+node->equiv_or_xref= (ASCII *)text_info;
+
+}
+init_p(p,t)
+name_pointer p;
+eight_bits t;
+{
+p->dummy.Ilk= t;
+}
+
+
+
+/*:20*//*24:*/
+#line 219 "tangle.web"
+store_two_bytes(x)
+sixteen_bits x;
+{
+if(tok_ptr+2>tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};};
+ *tok_ptr++= x>>8;
+ *tok_ptr++= x&255;
+}
+
+
+/*:24*//*28:*/
+#line 294 "tangle.web"
+push_level(p)
+#line 295 "tangle.web"
+name_pointer p;
+{
+/*29:*/
+#line 306 "tangle.web"
+
+#line 307 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>0){
+printf("\nPushing ");fflush(stdout),write(1,(p)->byte_start,(((p)+1)->byte_start-((p))->byte_start));
+printf(" =nd[%d]",p-name_dir);
+}
+#endif TRACE_MACROS
+
+/*:29*/
+#line 297 "tangle.web"
+;
+if(stack_ptr==stack_end){{printf("\n! Sorry, capacity exceeded: ");err_print("stack");history= 3;wrap_up();};};
+ *stack_ptr= cur_state;
+stack_ptr++;
+cur_state.name_field= p;cur_state.repl_field= (text_pointer)p->equiv_or_xref;
+cur_state.byte_field= cur_state.repl_field->tok_start;cur_state.end_field= (cur_state.repl_field+1)->tok_start;
+cur_state.mod_field= 0;
+}
+
+/*:28*//*30:*/
+#line 321 "tangle.web"
+pop_level()
+#line 322 "tangle.web"
+{int number_of_parameters;
+/*33:*/
+#line 363 "tangle.web"
+
+#line 364 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>0){
+printf("\nPopping ");fflush(stdout),write(1,(cur_state.name_field)->byte_start,(((cur_state.name_field)+1)->byte_start-((cur_state.name_field))->byte_start));
+printf(" =nd[%d]",cur_state.name_field-name_dir);
+}
+
+#endif TRACE_MACROS
+
+
+
+/*:33*/
+#line 323 "tangle.web"
+;
+if(cur_state.repl_field->text_link==0){
+if(cur_state.name_field->dummy.Ilk==1){
+/*31:*/
+#line 338 "tangle.web"
+
+#line 339 "tangle.web"
+number_of_parameters= *(cur_state.repl_field->tok_start);
+/*32:*/
+#line 357 "tangle.web"
+
+#line 358 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>1){
+printf("\nUnstacking %d parameters",number_of_parameters);
+}
+#endif TRACE_MACROS
+/*:32*/
+#line 340 "tangle.web"
+;
+while(number_of_parameters-->0){
+name_ptr--;text_ptr--;
+#ifdef TRACE_MACROS
+byte_ptr-= 2;
+#endif TRACE_MACROS
+}
+#ifdef STAT
+#ifdef STAT_HAS_BEEN_FIXED
+if(tok_ptr>max_tok_ptr)max_tok_ptr= tok_ptr;
+
+
+#endif STAT_HAS_BEEN_FIXED
+#endif STAT
+tok_ptr= text_ptr->tok_start;
+
+
+/*:31*/
+#line 326 "tangle.web"
+;
+}
+}else if(cur_state.repl_field->text_link<2000){
+cur_state.repl_field= cur_state.repl_field->text_link+text_info;
+cur_state.byte_field= cur_state.repl_field->tok_start;cur_state.end_field= (cur_state.repl_field+1)->tok_start;
+return;
+}
+stack_ptr--;
+if(stack_ptr>stack)cur_state= *stack_ptr;
+}
+
+
+/*:30*//*38:*/
+#line 418 "tangle.web"
+sixteen_bits
+#line 419 "tangle.web"
+ get_output()
+{
+sixteen_bits a;
+restart:if(stack_ptr==stack)return 0;
+if(cur_state.byte_field==cur_state.end_field){
+cur_val= -((int)cur_state.mod_field);
+pop_level();
+if(cur_val==0)goto restart;
+out_char(129);return;
+}
+a= *cur_state.byte_field++;
+if(a<128)
+if(a==7){
+/*40:*/
+#line 454 "tangle.web"
+
+#line 455 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2){
+printf(" [#%d]", *cur_state.byte_field);
+}
+#endif TRACE_MACROS
+
+/*:40*/
+#line 432 "tangle.web"
+;
+/*39:*/
+#line 452 "tangle.web"
+
+#line 453 "tangle.web"
+push_level(name_ptr- *cur_state.byte_field++);goto restart;
+/*:39*/
+#line 434 "tangle.web"
+;
+}else
+out_char(a);
+else{
+a= (a-128) *256+ *cur_state.byte_field++;
+switch(a/10240){
+case 0:
+/*41:*/
+#line 461 "tangle.web"
+
+#line 462 "tangle.web"
+if(name_dir[a].dummy.Ilk==1){
+/*42:*/
+#line 475 "tangle.web"
+
+#line 476 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2){
+printf("\nExpanding macro (");fflush(stdout),write(1,(name_dir+a)->byte_start,(((name_dir+a)+1)->byte_start-((name_dir+a))->byte_start));
+printf("=nd[%d])",a);
+}
+#endif TRACE_MACROS
+
+/*:42*/
+#line 463 "tangle.web"
+;
+/*44:*/
+#line 492 "tangle.web"
+
+#line 493 "tangle.web"
+{int number_of_parameters;
+while(cur_state.byte_field==cur_state.end_field&&stack_ptr>stack)pop_level();
+number_of_parameters= *(((text_pointer)name_dir[a].equiv_or_xref)->tok_start);
+if(number_of_parameters>0){
+if(stack_ptr==stack|| *cur_state.byte_field!=40){
+printf("\n! No parameters given for ");
+fflush(stdout),write(1,(a+name_dir)->byte_start,(((a+name_dir)+1)->byte_start-((a+name_dir))->byte_start));
+err_print("");
+goto restart;
+}
+cur_state.byte_field++;
+parm_ptr= name_ptr;
+while(number_of_parameters-->0){
+/*49:*/
+#line 537 "tangle.web"
+
+#line 538 "tangle.web"
+{int bal;
+eight_bits b,oldb;
+sixteen_bits c;
+bal= 0;
+/*59:*/
+#line 647 "tangle.web"
+
+#line 648 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2){
+printf("\nScanning #%d...",number_of_parameters+1);
+}
+#endif TRACE_MACROS
+/*:59*/
+#line 542 "tangle.web"
+;
+while(1){
+b= *cur_state.byte_field++;
+if(b==7){
+b= *cur_state.byte_field++;
+/*56:*/
+#line 613 "tangle.web"
+
+#line 614 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2){
+printf(" <#%d=",b);fflush(stdout),write(1,(name_ptr-b)->byte_start,(((name_ptr-b)+1)->byte_start-((name_ptr-b))->byte_start));printf("=nd[%d]>",
+name_ptr-b-name_dir);
+}
+#endif TRACE_MACROS
+
+/*:56*/
+#line 547 "tangle.web"
+;
+c= name_ptr-name_dir-b;
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= 128+(c/256);};
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= c%256;};
+}else{
+if(b>=128){
+/*57:*/
+#line 621 "tangle.web"
+
+#line 622 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2){
+int c;
+printf(" <");
+c= (b-128) *256+ *cur_state.byte_field;
+switch(c/10240){
+case 0:fflush(stdout),write(1,(name_dir+c)->byte_start,(((name_dir+c)+1)->byte_start-((name_dir+c))->byte_start));
+printf(" =nd[%d]",c);
+break;
+case 1:printf("MODULE");break;
+default:printf("CONTEXT");break;
+}
+printf(">");
+}
+#endif TRACE_MACROS
+
+/*:57*/
+#line 553 "tangle.web"
+;
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= b;};
+b= *cur_state.byte_field++;
+}else if(bal==0&&((number_of_parameters==0&&b==41)
+||(number_of_parameters>0&&b==44))){
+goto done;
+}else if(/*51:*/
+#line 586 "tangle.web"
+(b==2||b==3)
+#line 587 "tangle.web"
+/*:51*/
+#line 559 "tangle.web"
+){
+/*52:*/
+#line 587 "tangle.web"
+
+#line 588 "tangle.web"
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= b;};
+oldb= b;
+/*53:*/
+#line 601 "tangle.web"
+
+#line 602 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2)printf(" <");
+#endif TRACE_MACROS
+/*:53*/
+#line 590 "tangle.web"
+;
+while((b= *cur_state.byte_field++)!=oldb){
+/*54:*/
+#line 605 "tangle.web"
+
+#line 606 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2)printf("%c",b);
+#endif TRACE_MACROS
+/*:54*/
+#line 592 "tangle.web"
+;
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= b;};
+if(cur_state.byte_field>=cur_state.end_field)
+{printf("\n! This can't happen: ");err_print("string or constant didn't end in token list");history= 3;wrap_up();};
+}
+/*55:*/
+#line 609 "tangle.web"
+
+#line 610 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2)printf(">");
+#endif TRACE_MACROS
+/*:55*/
+#line 597 "tangle.web"
+;
+
+
+
+/*:52*/
+#line 560 "tangle.web"
+;
+}else{
+/*58:*/
+#line 638 "tangle.web"
+
+#line 639 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2){
+printf(" <");
+if(31<b&&b<127)printf("%c",b);
+printf(">");
+}
+#endif TRACE_MACROS
+
+/*:58*/
+#line 562 "tangle.web"
+;
+bal+= balances[b];
+}
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= b;};
+}
+}
+done:
+parm_ptr->equiv_or_xref= (ASCII *)text_ptr;
+text_ptr->text_link= 0;
+parm_ptr->dummy.Ilk= 2;
+#ifdef TRACE_MACROS
+if(byte_ptr+2>=byte_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("byte memory");history= 3;wrap_up();};};
+ *byte_ptr++= 35; *byte_ptr++= number_of_parameters+1+48;
+#endif TRACE_MACROS
+if(parm_ptr>=name_dir_end){{printf("\n! Sorry, capacity exceeded: ");err_print("name");history= 3;wrap_up();};};
+(++parm_ptr)->byte_start= byte_ptr;
+if(text_ptr>=text_info_end){{printf("\n! Sorry, capacity exceeded: ");err_print("text");history= 3;wrap_up();};};
+(++text_ptr)->tok_start= tok_ptr;
+/*60:*/
+#line 653 "tangle.web"
+
+#line 654 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>1){
+printf("\nStacked ");fflush(stdout),write(1,(parm_ptr-1)->byte_start,(((parm_ptr-1)+1)->byte_start-((parm_ptr-1))->byte_start));
+printf("=nd[%d]",parm_ptr-1-name_dir);
+}
+#endif TRACE_MACROS
+
+/*:60*/
+#line 580 "tangle.web"
+;
+}
+
+/*:49*/
+#line 507 "tangle.web"
+;
+}
+name_ptr= parm_ptr;
+
+}
+}
+
+/*:44*/
+#line 465 "tangle.web"
+;
+push_level(name_dir+a);
+cur_state.byte_field++;
+goto restart;
+}else if(name_dir[a].dummy.Ilk==2){
+/*43:*/
+#line 483 "tangle.web"
+
+#line 484 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2){
+printf("\nExpanding parameter (");fflush(stdout),write(1,(name_dir+a)->byte_start,(((name_dir+a)+1)->byte_start-((name_dir+a))->byte_start));
+printf("=nd[%d])",a);
+}
+#endif TRACE_MACROS
+
+
+/*:43*/
+#line 470 "tangle.web"
+;
+push_level(name_dir+a);
+goto restart;
+}
+
+/*:41*/
+#line 441 "tangle.web"
+;
+cur_val= a;out_char(130);break;
+case 1:/*61:*/
+#line 664 "tangle.web"
+
+#line 665 "tangle.web"
+a-= 10240;
+if((a+name_dir)->equiv_or_xref!=(ASCII *)text_info)push_level(a+name_dir);
+else if(a!=0){
+printf("\n! Not present: <");fflush(stdout),write(1,(a+name_dir)->byte_start,(((a+name_dir)+1)->byte_start-((a+name_dir))->byte_start));err_print(">");
+
+}
+goto restart;
+
+/*:61*/
+#line 443 "tangle.web"
+;
+default:cur_val= a-20480;if(cur_val>0)cur_state.mod_field= cur_val;
+out_char(129);
+}
+}
+return 1;
+}
+
+
+/*:38*//*63:*/
+#line 714 "tangle.web"
+flush_buffer()
+#line 715 "tangle.web"
+{
+putc('\n',C_file);
+if(line[include_depth]%100==0){
+printf(".");
+if(line[include_depth]%500==0)printf("%d",line[include_depth]);
+fflush(stdout);
+}
+line[include_depth]++;
+}
+
+/*:63*//*67:*/
+#line 764 "tangle.web"
+
+#line 765 "tangle.web"
+phase_two(){
+line[include_depth]= 1;
+if(text_info->text_link==0){
+if(end_output_files==cur_out_file){
+printf("\n! No program text was specified.");{if(history==0)history= 1;};
+
+}
+}else{
+printf("\nWriting the output files: (%s)",C_file_name);fflush(stdout);
+/*27:*/
+#line 283 "tangle.web"
+
+#line 284 "tangle.web"
+stack_ptr= stack+1;cur_state.name_field= name_dir;cur_state.repl_field= text_info->text_link+text_info;
+cur_state.byte_field= cur_state.repl_field->tok_start;cur_state.end_field= (cur_state.repl_field+1)->tok_start;cur_state.mod_field= 0;
+
+/*:27*/
+#line 774 "tangle.web"
+;
+while(stack_ptr>stack)get_output();
+flush_buffer();
+}
+if(end_output_files>cur_out_file){
+if(text_info->text_link==0){
+printf("\nWriting the output files: ");fflush(stdout);
+}
+/*68:*/
+#line 790 "tangle.web"
+
+#line 791 "tangle.web"
+for(an_output_file= end_output_files;an_output_file>cur_out_file;){
+an_output_file--;
+strncpy(output_file_name,( *an_output_file)->byte_start,400);
+output_file_name[(( *an_output_file+1)->byte_start-( *an_output_file)->byte_start)]= '\0';
+fclose(C_file);
+C_file= fopen(output_file_name,"w");
+if(C_file==NULL){
+{printf("! Cannot open output file:");err_print(output_file_name);history= 3;wrap_up();}
+}else{
+printf(" (%s)",output_file_name);fflush(stdout);
+}
+stack_ptr= stack+1;
+cur_state.name_field= ( *an_output_file);
+cur_state.repl_field= (text_pointer)cur_state.name_field->equiv_or_xref;
+cur_state.byte_field= cur_state.repl_field->tok_start;
+cur_state.end_field= (cur_state.repl_field+1)->tok_start;
+cur_state.mod_field= 0;
+while(stack_ptr>stack)get_output();
+flush_buffer();
+}
+
+
+
+/*:68*/
+#line 782 "tangle.web"
+
+}
+printf("\nDone.");
+}
+
+/*:67*//*69:*/
+#line 816 "tangle.web"
+out_char(cur_char)
+#line 817 "tangle.web"
+eight_bits cur_char;
+{
+ASCII *j;
+/*70:*/
+#line 841 "tangle.web"
+
+#line 842 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2){
+switch(cur_char){
+case 10:printf(" [\\n]");break;
+case 2:
+printf("[STRING]");break;
+case 127:
+printf("[JOIN]");break;
+case 3:
+printf("[CONSTANT]");break;
+case 130:
+printf(" [");fflush(stdout),write(1,(cur_val+name_dir)->byte_start,(((cur_val+name_dir)+1)->byte_start-((cur_val+name_dir))->byte_start));printf("]");
+break;
+case 129:
+if(cur_val>0){
+printf(" [%d:]",cur_val);
+}else if(cur_val<0){
+printf(" [:%d]",-cur_val);
+}else{
+printf("[LINE NUMBER]");
+}
+break;
+
+default:
+if(31<cur_char&&cur_char<127){
+printf(" [%c]",cur_char);
+}else{
+printf(" [\\%3o]",cur_char);
+}
+}
+}
+#endif TRACE_MACROS
+
+
+
+
+/*:70*/
+#line 820 "tangle.web"
+;
+switch(cur_char){
+case 10:if(protect)putc(' ',C_file);
+if(protect||out_state==4)putc('\\',C_file);
+
+flush_buffer();if(out_state!=4)out_state= 0;break;
+/*71:*/
+#line 878 "tangle.web"
+
+#line 879 "tangle.web"
+case 130:
+if(out_state==1)putc(' ',C_file);
+for(j= (cur_val+name_dir)->byte_start;j<(name_dir+cur_val+1)->byte_start;
+j++)putc( *j,C_file);
+out_state= 1;break;
+
+/*:71*/
+#line 826 "tangle.web"
+;
+/*72:*/
+#line 885 "tangle.web"
+
+#line 886 "tangle.web"
+case 129:
+if(cur_val>0){
+fprintf(C_file,"%s","##");
+fprintf(C_file,"%d:",cur_val);
+fprintf(C_file,"%s","\n");
+}else if(cur_val<0){
+fprintf(C_file,"%s","##");
+fprintf(C_file,":%d",-cur_val);
+fprintf(C_file,"%s","\n");
+}else{
+sixteen_bits a;
+a= 256 * *cur_state.byte_field++;
+a+= *cur_state.byte_field++;
+fprintf(C_file,"\n%s","#line");
+fprintf(C_file," %d \"",a);
+cur_val= *cur_state.byte_field++;
+cur_val= 256 *(cur_val-128)+ *cur_state.byte_field++;
+for(j= (cur_val+name_dir)->byte_start;j<(name_dir+cur_val+1)->byte_start;
+j++)putc( *j,C_file);
+fprintf(C_file,"\"%s\n",""
+#line 910 "tangle.web"
+);
+}
+break;
+
+#line 1 "outtoks.web"
+/*:72*/
+#line 827 "tangle.web"
+;
+/*75:*/
+#line 46 "outtoks.web"
+
+#line 47 "outtoks.web"
+case 26:
+fprintf(C_file,"%s","==");
+if(out_state!=4)out_state= 0;
+break;
+case 25:
+fprintf(C_file,"%s","&&");
+if(out_state!=4)out_state= 0;
+break;
+case 24:
+fprintf(C_file,"%s","||");
+if(out_state!=4)out_state= 0;
+break;
+case 28:
+fprintf(C_file,"%s","<=");
+if(out_state!=4)out_state= 0;
+break;
+case 23:
+fprintf(C_file,"%s","++");
+if(out_state!=4)out_state= 0;
+break;
+case 27:
+fprintf(C_file,"%s",">=");
+if(out_state!=4)out_state= 0;
+break;
+case 29:
+fprintf(C_file,"%s","!=");
+if(out_state!=4)out_state= 0;
+break;
+case 31:
+fprintf(C_file,"%s",">>");
+if(out_state!=4)out_state= 0;
+break;
+case 22:
+fprintf(C_file,"%s","--");
+if(out_state!=4)out_state= 0;
+break;
+case 30:
+fprintf(C_file,"%s","!~");
+if(out_state!=4)out_state= 0;
+break;
+/*:75*//*76:*/
+#line 87 "outtoks.web"
+
+#line 88 "outtoks.web"
+/*:76*/
+#line 828 "tangle.web"
+
+case 127:out_state= 3;break;
+case 3:if(out_state==4){
+out_state= 1;break;
+}
+if(out_state==1)putc(' ',C_file);out_state= 4;break;
+case 2:if(out_state==4)out_state= 0;
+else out_state= 4;break;
+default:putc(cur_char,C_file);if(out_state!=4)out_state= 0;
+break;
+}
+}
+
+/*:69*//*90:*/
+#line 981 "tangle.web"
+eight_bits skip_ahead()
+#line 982 "tangle.web"
+{
+eight_bits c;
+while(1){
+if(loc>limit&&(get_line()==0))return(255);
+ *(limit+1)= 35;
+while( *loc!=35)loc++;
+if(loc<=limit){
+loc++;c= ccode[ *loc];
+#ifdef DEBUG
+if(c==248){
+tracing= *loc-48;c= 0;
+}
+#endif DEBUG
+loc++;
+if(c!=0|| *(loc-1)=='>')return(c);
+}
+}
+}
+
+/*:90*//*92:*/
+#line 1012 "tangle.web"
+
+#line 1013 "tangle.web"
+skip_comment()
+{
+ASCII c;
+if(1){
+get_line();
+return(comment_continues= 0);
+}else{
+while(1){
+if(loc>limit)
+if(get_line())return(comment_continues= 1);
+else{
+err_print("! Input ended in mid-comment");
+
+return(comment_continues= 0);
+}
+c= *(loc++);
+/*82:*/
+#line 121 "outtoks.web"
+
+
+/*:82*/
+#line 1029 "tangle.web"
+
+if(c==35){
+if(ccode[ *loc]==255){
+err_print("! Section name ended in mid-comment");loc--;
+
+return(comment_continues= 0);
+}
+else loc++;
+}
+}
+}
+}
+/*:92*//*95:*/
+#line 1052 "tangle.web"
+eight_bits get_next()
+#line 1053 "tangle.web"
+{
+eight_bits c;
+while(1){
+if(loc>limit){
+if(get_line()==0)return(255);
+else if(print_where){
+print_where= 0;
+/*125:*/
+#line 1586 "tangle.web"
+
+#line 1587 "tangle.web"
+store_two_bytes(53248);
+if(changing)id_first= change_file_name;
+else id_first= file_name[include_depth];
+id_loc= id_first+strlen(id_first);
+if(changing)store_two_bytes((sixteen_bits)change_line);
+else store_two_bytes((sixteen_bits)line[include_depth]);
+{int a= id_lookup(id_first,id_loc,0)-name_dir;{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= (a/256)+128;};
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a%256;};}
+
+/*:125*/
+#line 1060 "tangle.web"
+;
+}
+else return(10);
+}
+c= *loc;
+if(comment_continues){
+skip_comment();
+if(comment_continues||1)return(10);
+else continue;
+}
+/*81:*/
+#line 109 "outtoks.web"
+
+#line 110 "outtoks.web"
+{int len;len= strlen("##");
+if(loc+len<=limit&&!strncmp(loc,"##",len)){
+loc+= len;
+skip_comment();
+if(comment_continues||1)
+return('\n');
+else continue;
+}
+}
+/*:81*/
+#line 1070 "tangle.web"
+
+loc++;
+if(isdigit(c)||c=='\\'||c=='.')/*97:*/
+#line 1092 "tangle.web"
+{
+#line 1093 "tangle.web"
+id_first= loc-1;
+if( *id_first=='.'&&!isdigit( *loc))goto mistake;
+if( *id_first=='\\')while(isdigit( *loc))loc++;
+else{
+if( *id_first=='0'){
+if( *loc=='x'|| *loc=='X'){
+loc++;while(isxdigit( *loc))loc++;goto found;
+}
+}
+while(isdigit( *loc))loc++;
+if( *loc=='.'){
+loc++;
+while(isdigit( *loc))loc++;
+}
+if( *loc=='e'|| *loc=='E'){
+if( *++loc=='+'|| *loc=='-')loc++;
+while(isdigit( *loc))loc++;
+}
+}
+found:
+id_loc= loc;
+return(3);
+}
+
+/*:97*/
+#line 1072 "tangle.web"
+
+else if(isalpha(c)||c=='_'||c=='$')/*96:*/
+#line 1084 "tangle.web"
+{
+#line 1085 "tangle.web"
+id_first= --loc;
+while(isalpha( *++loc)||isdigit( *loc)|| *loc=='_');
+if( *loc=='$')while(isdigit( *++loc)|| *loc=='$');
+
+id_loc= loc;return(130);
+}
+
+/*:96*/
+#line 1073 "tangle.web"
+
+else if(c=='\''||c=='\"')/*98:*/
+#line 1122 "tangle.web"
+{
+#line 1123 "tangle.web"
+ASCII delim= c;
+
+
+if(delim=='\''&&(loc+1>=limit||
+( *loc!='\\'&& *loc!=35&&loc[1]!='\'')||
+( *loc=='\\'&&(loc+2>=limit||loc[2]!='\''))||
+( *loc==35&&
+(loc+2>=limit||loc[1]!=35||loc[2]!='\''))
+))goto mistake;
+id_first= mod_text+1;
+id_loc= mod_text; *++id_loc= delim;
+while(1){
+if(loc>=limit){
+if( *(limit-1)!='\\'){
+err_print("! String didn't end");loc= limit;break;
+
+}
+if(get_line()==0){
+err_print("! Input ended in middle of string");loc= buffer;break;
+
+}
+else if(++id_loc<=mod_text_end) *id_loc= 10;
+
+}
+if((c= *loc++)==delim){
+if(++id_loc<=mod_text_end) *id_loc= c;
+break;
+}
+if(c=='\\'){
+if(loc>=limit)continue;
+if(++id_loc<=mod_text_end) *id_loc= '\\';
+c= *loc++;
+}
+if(++id_loc<=mod_text_end) *id_loc= c;
+}
+if(id_loc>=mod_text_end){
+printf("\n! String too long: ");
+
+fflush(stdout),write(1,mod_text+1,25);
+printf("...");history= 2;
+}
+id_loc++;
+return(2);
+}
+
+/*:98*/
+#line 1074 "tangle.web"
+
+else if(c==35)/*99:*/
+#line 1171 "tangle.web"
+{
+#line 1172 "tangle.web"
+c= ccode[ *loc++];
+switch(c){
+case 0:continue;
+case 250:while((c= skip_ahead())==35);
+
+if( *(loc-1)!='>')err_print("! Improper @ within control text");
+
+continue;
+case 254:
+cur_module_char= *(loc-1);
+/*103:*/
+#line 1221 "tangle.web"
+{
+#line 1222 "tangle.web"
+ASCII *k;
+/*105:*/
+#line 1241 "tangle.web"
+
+#line 1242 "tangle.web"
+k= mod_text;
+while(1){
+if(loc>limit&&get_line()==0){
+err_print("! Input ended in section name");
+
+loc= buffer+1;break;
+}
+c= *loc;
+/*106:*/
+#line 1265 "tangle.web"
+
+#line 1266 "tangle.web"
+if(c==35){
+c= *(loc+1);
+if(c=='>'){
+loc+= 2;break;
+}
+if(ccode[c]==255){
+err_print("! Section name didn't end");break;
+
+}
+ *(++k)= 35;loc++;
+}
+
+/*:106*/
+#line 1250 "tangle.web"
+;
+loc++;if(k<mod_text_end)k++;
+if(c==' '||c==011){
+c= ' ';if( *(k-1)==' ')k--;
+}
+ *k= c;
+}
+if(k>=mod_text_end){
+printf("\n! Section name too long: ");
+
+fflush(stdout),write(1,mod_text+1,25);
+printf("...");{if(history==0)history= 1;};
+}
+if( *k==' '&&k>mod_text)k--;
+
+/*:105*/
+#line 1223 "tangle.web"
+;
+if(k-mod_text>3&&strncmp(k-2,"...",3)==0)cur_module= prefix_lookup(mod_text+1,k-3);
+else cur_module= mod_lookup(mod_text+1,k);
+if(cur_module_char=='('){
+/*66:*/
+#line 749 "tangle.web"
+
+#line 750 "tangle.web"
+{
+if(cur_out_file>output_files){
+for(an_output_file= cur_out_file;
+an_output_file<end_output_files;an_output_file++)
+if( *an_output_file==cur_module)break;
+if(an_output_file==end_output_files)
+ *--cur_out_file= cur_module;
+}else{
+{{printf("\n! Sorry, capacity exceeded: ");err_print("output files");history= 3;wrap_up();};};
+}
+}
+
+/*:66*/
+#line 1228 "tangle.web"
+
+}
+return(254);
+}
+
+/*:103*/
+#line 1182 "tangle.web"
+;
+case 2:/*107:*/
+#line 1283 "tangle.web"
+{
+#line 1284 "tangle.web"
+id_first= loc++; *(limit+1)= 35; *(limit+2)= '>';
+while( *loc!=35|| *(loc+1)!='>')loc++;
+if(loc>=limit)err_print("! Verbatim string didn't end");
+
+id_loc= loc;loc+= 2;
+return(2);
+}
+
+/*:107*/
+#line 1183 "tangle.web"
+;
+#ifdef DEBUG
+case 248:tracing= *(loc-1)-'0';continue;
+#endif DEBUG
+case 249:/*100:*/
+#line 1194 "tangle.web"
+
+#line 1195 "tangle.web"
+id_first= loc;
+if( *loc=='\\')loc++;
+while( *loc!='\''){
+loc++;
+if(loc>limit){
+err_print("! String didn't end");loc= limit-1;break;
+}
+}
+loc++;
+return(249);
+
+/*:100*/
+#line 1187 "tangle.web"
+;
+case 5:/*101:*/
+#line 1206 "tangle.web"
+{
+#line 1207 "tangle.web"
+id_first= loc;
+while('0'<= *loc&& *loc<'8')loc++;
+id_loc= loc;
+return(5);
+}
+
+/*:101*/
+#line 1188 "tangle.web"
+;
+case 6:/*102:*/
+#line 1213 "tangle.web"
+{
+#line 1214 "tangle.web"
+id_first= loc;
+while(isxdigit( *loc))loc++;
+id_loc= loc;
+return(6);
+}
+
+
+/*:102*/
+#line 1189 "tangle.web"
+;
+default:return(c);
+}
+}
+
+/*:99*/
+#line 1075 "tangle.web"
+
+else if(c==' '||c==011){
+continue;
+}
+mistake:/*74:*/
+#line 3 "outtoks.web"
+
+#line 4 "outtoks.web"
+if(loc+1<=limit){
+if(strncmp("==",loc-1,2)==0){
+loc+= 1;
+return 26;
+}
+else if(strncmp("&&",loc-1,2)==0){
+loc+= 1;
+return 25;
+}
+else if(strncmp("||",loc-1,2)==0){
+loc+= 1;
+return 24;
+}
+else if(strncmp("<=",loc-1,2)==0){
+loc+= 1;
+return 28;
+}
+else if(strncmp("++",loc-1,2)==0){
+loc+= 1;
+return 23;
+}
+else if(strncmp(">=",loc-1,2)==0){
+loc+= 1;
+return 27;
+}
+else if(strncmp("!=",loc-1,2)==0){
+loc+= 1;
+return 29;
+}
+else if(strncmp(">>",loc-1,2)==0){
+loc+= 1;
+return 31;
+}
+else if(strncmp("--",loc-1,2)==0){
+loc+= 1;
+return 22;
+}
+else if(strncmp("!~",loc-1,2)==0){
+loc+= 1;
+return 30;
+}
+}
+/*:74*/
+#line 1079 "tangle.web"
+
+return(c);
+}
+}
+
+/*:95*//*109:*/
+#line 1314 "tangle.web"
+scan_repl(t)
+#line 1315 "tangle.web"
+eight_bits t;
+{
+sixteen_bits a;
+int set_print_where;
+if(t==254){/*125:*/
+#line 1586 "tangle.web"
+
+#line 1587 "tangle.web"
+store_two_bytes(53248);
+if(changing)id_first= change_file_name;
+else id_first= file_name[include_depth];
+id_loc= id_first+strlen(id_first);
+if(changing)store_two_bytes((sixteen_bits)change_line);
+else store_two_bytes((sixteen_bits)line[include_depth]);
+{int a= id_lookup(id_first,id_loc,0)-name_dir;{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= (a/256)+128;};
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a%256;};}
+
+/*:125*/
+#line 1319 "tangle.web"
+;}
+
+
+while(1){
+if(t==1){
+print_where= 0;
+}
+a= get_next();
+if(t==1){
+set_print_where= print_where;
+}
+switch(a){
+/*124:*/
+#line 1529 "tangle.web"
+
+#line 1530 "tangle.web"
+case 130:
+{short n;
+if((n= parameter_number(id_first,id_loc))!=0){
+#ifdef TRACE_MACROS
+if(tracing>1){
+printf("\nIdentified ");fflush(stdout),write(1,id_first,id_loc-id_first);
+printf(" as parameter number %d (%d from back)",n,next_param_name-n+1);
+}
+#endif TRACE_MACROS
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= 7;};
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= next_param_name-n+1;};
+}else{
+a= id_lookup(id_first,id_loc,0)-name_dir;
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= (a/256)+128;};{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a%256;};
+}
+}
+break;
+case 254:if(t!=254)goto done;
+else{
+/*126:*/
+#line 1596 "tangle.web"
+{
+#line 1597 "tangle.web"
+ASCII *try_loc= loc;
+while( *try_loc==' '&&try_loc<limit)try_loc++;
+if( *try_loc=='+'&&try_loc<limit)try_loc++;
+while( *try_loc==' '&&try_loc<limit)try_loc++;
+if( *try_loc=='=')err_print("! Nested named modules. Missing @?");
+
+}
+
+/*:126*/
+#line 1549 "tangle.web"
+;
+a= cur_module-name_dir;
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= (a/256)+168;};
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a%256;};
+/*125:*/
+#line 1586 "tangle.web"
+
+#line 1587 "tangle.web"
+store_two_bytes(53248);
+if(changing)id_first= change_file_name;
+else id_first= file_name[include_depth];
+id_loc= id_first+strlen(id_first);
+if(changing)store_two_bytes((sixteen_bits)change_line);
+else store_two_bytes((sixteen_bits)line[include_depth]);
+{int a= id_lookup(id_first,id_loc,0)-name_dir;{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= (a/256)+128;};
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a%256;};}
+
+/*:125*/
+#line 1553 "tangle.web"
+;break;
+}
+case 3:case 2:
+/*127:*/
+#line 1605 "tangle.web"
+
+#line 1606 "tangle.web"
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a;};
+while(id_first<id_loc){
+if( *id_first==35)id_first++;
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= *id_first++;};
+}
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a;};break;
+
+/*:127*/
+#line 1556 "tangle.web"
+;
+case 249:
+/*128:*/
+#line 1613 "tangle.web"
+{
+#line 1614 "tangle.web"
+int c;
+if( *id_first==35){
+c= xchr[ *id_first++];
+if( *id_first!=35)err_print("! Double @ within string");
+}
+else if( *id_first=='\\'){
+id_first++;
+switch( *id_first){
+case't':c= 9;break;
+case'n':c= 10;break;
+case'b':c= 8;break;
+case'0':c= 0;break;
+case'\\':c= 92;break;
+default:err_print("! Unrecognized escape sequence");
+}
+}
+else c= xchr[ *id_first];
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= 3;};
+
+
+app_decimal((long)c);
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= 3;};
+}
+break;
+
+/*:128*/
+#line 1558 "tangle.web"
+;
+case 5:
+/*129:*/
+#line 1640 "tangle.web"
+{
+#line 1641 "tangle.web"
+long sum= 0;
+while(id_first<id_loc){
+sum= 8 *sum+ *id_first++-'0';
+if(sum>67108864)err_print("! Octal constant exceeds @\"04000000");
+}
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= 3;};
+app_decimal(sum);
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= 3;};
+}
+
+/*:129*/
+#line 1560 "tangle.web"
+;break;
+case 6:
+/*130:*/
+#line 1651 "tangle.web"
+{
+#line 1652 "tangle.web"
+long sum= 0;
+while(id_first<id_loc){
+sum= 16 *sum+
+(isdigit( *id_first)
+? *id_first-'0'
+:isupper( *id_first)
+? *id_first-'A'+10
+: *id_first-'a'+10
+);
+id_first++;
+if(sum>67108864)err_print("! Hex constant exceeds @\"04000000");
+}
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= 3;};
+app_decimal(sum);
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= 3;};
+}
+
+/*:130*/
+#line 1562 "tangle.web"
+;break;
+case 10:
+#ifdef NEWLINES_IN_MACROS
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a;};
+#else
+if(t==1)continue;
+else{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a;};
+#endif NEWLINES_IN_MACROS
+break;
+case 252:case 251:case 253:
+if(t!=254)goto done;
+else{
+err_print("! @d, @f and @u are ignored in C text");continue;
+
+}
+case 255:goto done;
+
+/*:124*/
+#line 1334 "tangle.web"
+
+default:{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a;};
+}
+}
+done:next_control= (eight_bits)a;
+if(text_ptr>text_info_end){{printf("\n! Sorry, capacity exceeded: ");err_print("text");history= 3;wrap_up();};};
+if(t==1){
+/*110:*/
+#line 1358 "tangle.web"
+
+#line 1359 "tangle.web"
+tok_ptr-= 2;
+while( *tok_ptr<128&& *(tok_ptr+1)==10)tok_ptr--;
+tok_ptr+= 2;
+
+/*:110*/
+#line 1341 "tangle.web"
+;
+}
+cur_text= text_ptr;(++text_ptr)->tok_start= tok_ptr;
+print_where= set_print_where;
+}
+
+/*:109*//*116:*/
+#line 1408 "tangle.web"
+
+#line 1409 "tangle.web"
+int parameter_number(first,loc)
+ASCII *first, *loc;
+{
+ASCII *f, *p;
+int n;
+for(n= 0;n<next_param_name;n++){
+if(loc-first==param_names[n+1]-param_names[n]){
+
+for(f= first,p= param_names[n];f<loc;)
+if( *f++!= *p++)goto nomatch;
+return n+1;
+}
+nomatch:continue;
+}
+return 0;
+}
+
+
+/*:116*//*131:*/
+#line 1670 "tangle.web"
+
+#line 1671 "tangle.web"
+app_decimal(c)
+long c;
+{long power;
+if(c==0){{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= '0';};return;}
+if(c<0){{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= '-';};c= -c;}
+for(power= 1;c>=power;power *= 10);
+
+for(power/= 10;power>=1;power/= 10){
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= '0'+c/power;};
+c%= power;
+
+}
+}
+
+
+
+/*:131*//*133:*/
+#line 1697 "tangle.web"
+scan_module()
+#line 1698 "tangle.web"
+{
+name_pointer p;
+text_pointer q;
+sixteen_bits a;
+module_count++;
+if( *(loc-1)=='*')
+printf("*%d",module_count);fflush(stdout);
+/*134:*/
+#line 1714 "tangle.web"
+
+next_control= 0;
+while(1){
+done_scanning:
+while(next_control<=251)
+if((next_control= skip_ahead())==254){
+
+loc-= 2;next_control= get_next();
+}
+if(next_control!=252)break;
+/*117:*/
+#line 1433 "tangle.web"
+
+#line 1434 "tangle.web"
+/*123:*/
+#line 1521 "tangle.web"
+
+#line 1522 "tangle.web"
+while((next_control= get_next())==10);
+
+/*:123*/
+#line 1434 "tangle.web"
+
+/*121:*/
+#line 1484 "tangle.web"
+
+#line 1485 "tangle.web"
+if(next_control!=130){
+err_print("! Macro name must be an identifier");
+
+/*135:*/
+#line 1732 "tangle.web"
+
+#line 1733 "tangle.web"
+/*112:*/
+#line 1380 "tangle.web"
+
+#line 1381 "tangle.web"
+next_param_name= 0;
+next_param_name_text= param_name_texts;
+param_names[next_param_name]= next_param_name_text;
+
+/*:112*/
+#line 1733 "tangle.web"
+;
+p->dummy.Ilk= 0;
+goto done_scanning;
+
+
+/*:135*/
+#line 1488 "tangle.web"
+;
+}else{
+p= id_lookup(id_first,id_loc,1);
+if(p->dummy.Ilk!=1){
+#ifdef WARN_USE_BEFORE_DEF
+printf("\n! Warning: macro name ");
+fflush(stdout),write(1,(p)->byte_start,(((p)+1)->byte_start-((p))->byte_start));
+printf(" was used before it was defined");
+{if(history==0)history= 1;};
+#endif WARN_USE_BEFORE_DEF
+p->dummy.Ilk= 1;
+}else if(p+1!=name_ptr){
+err_print("! Macro name is multiply defined: ");
+}
+}
+
+/*:121*/
+#line 1436 "tangle.web"
+;
+/*120:*/
+#line 1469 "tangle.web"
+
+#line 1470 "tangle.web"
+/*123:*/
+#line 1521 "tangle.web"
+
+#line 1522 "tangle.web"
+while((next_control= get_next())==10);
+
+/*:123*/
+#line 1470 "tangle.web"
+
+if(next_control==40){
+do{
+/*122:*/
+#line 1504 "tangle.web"
+
+#line 1505 "tangle.web"
+/*123:*/
+#line 1521 "tangle.web"
+
+#line 1522 "tangle.web"
+while((next_control= get_next())==10);
+
+/*:123*/
+#line 1505 "tangle.web"
+;
+if(next_control!=130){
+err_print("! Macro parameter name not an identifier");
+
+/*135:*/
+#line 1732 "tangle.web"
+
+#line 1733 "tangle.web"
+/*112:*/
+#line 1380 "tangle.web"
+
+#line 1381 "tangle.web"
+next_param_name= 0;
+next_param_name_text= param_name_texts;
+param_names[next_param_name]= next_param_name_text;
+
+/*:112*/
+#line 1733 "tangle.web"
+;
+p->dummy.Ilk= 0;
+goto done_scanning;
+
+
+/*:135*/
+#line 1509 "tangle.web"
+;
+}else{
+if(parameter_number(id_first,id_loc)!=0){
+err_print("! Duplicate parameters in macro definition");
+
+/*135:*/
+#line 1732 "tangle.web"
+
+#line 1733 "tangle.web"
+/*112:*/
+#line 1380 "tangle.web"
+
+#line 1381 "tangle.web"
+next_param_name= 0;
+next_param_name_text= param_name_texts;
+param_names[next_param_name]= next_param_name_text;
+
+/*:112*/
+#line 1733 "tangle.web"
+;
+p->dummy.Ilk= 0;
+goto done_scanning;
+
+
+/*:135*/
+#line 1514 "tangle.web"
+;
+}else{
+/*114:*/
+#line 1387 "tangle.web"
+
+#line 1388 "tangle.web"
+/*115:*/
+#line 1393 "tangle.web"
+
+#line 1394 "tangle.web"
+if(next_param_name==32)
+{{printf("\n! Sorry, capacity exceeded: ");err_print("parameter names");history= 3;wrap_up();};};
+if(id_loc-id_first>
+param_name_texts_end-next_param_name_text)
+{{printf("\n! Sorry, capacity exceeded: ");err_print("parameter name texts");history= 3;wrap_up();};};
+
+
+/*:115*/
+#line 1388 "tangle.web"
+;
+while(id_first<id_loc)
+ *next_param_name_text++= *id_first++;
+param_names[++next_param_name]= next_param_name_text;
+
+/*:114*/
+#line 1516 "tangle.web"
+;
+}
+}
+
+
+/*:122*/
+#line 1473 "tangle.web"
+;
+/*123:*/
+#line 1521 "tangle.web"
+
+#line 1522 "tangle.web"
+while((next_control= get_next())==10);
+
+/*:123*/
+#line 1474 "tangle.web"
+
+}while(next_control==44);
+if(next_control!=41){
+err_print("! Macro parameter list must end with )");
+/*135:*/
+#line 1732 "tangle.web"
+
+#line 1733 "tangle.web"
+/*112:*/
+#line 1380 "tangle.web"
+
+#line 1381 "tangle.web"
+next_param_name= 0;
+next_param_name_text= param_name_texts;
+param_names[next_param_name]= next_param_name_text;
+
+/*:112*/
+#line 1733 "tangle.web"
+;
+p->dummy.Ilk= 0;
+goto done_scanning;
+
+
+/*:135*/
+#line 1478 "tangle.web"
+;
+}
+next_control= get_next();
+}
+
+
+/*:120*/
+#line 1439 "tangle.web"
+;
+if(next_control!=61){
+err_print("! You must put an = sign before the macro replacement text");
+/*135:*/
+#line 1732 "tangle.web"
+
+#line 1733 "tangle.web"
+/*112:*/
+#line 1380 "tangle.web"
+
+#line 1381 "tangle.web"
+next_param_name= 0;
+next_param_name_text= param_name_texts;
+param_names[next_param_name]= next_param_name_text;
+
+/*:112*/
+#line 1733 "tangle.web"
+;
+p->dummy.Ilk= 0;
+goto done_scanning;
+
+
+/*:135*/
+#line 1442 "tangle.web"
+;
+}
+/*118:*/
+#line 1451 "tangle.web"
+
+#line 1452 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>1){
+printf("\nScanning definition of macro ");fflush(stdout),write(1,(p)->byte_start,(((p)+1)->byte_start-((p))->byte_start));
+}
+#endif TRACE_MACROS
+
+/*:118*/
+#line 1444 "tangle.web"
+;
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= next_param_name;};
+scan_repl(1);
+p->equiv_or_xref= (ASCII *)cur_text;
+/*119:*/
+#line 1458 "tangle.web"
+
+#line 1459 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2){
+printf("\nMacro ");fflush(stdout),write(1,(p)->byte_start,(((p)+1)->byte_start-((p))->byte_start));
+printf("'s replacement text is in text_info[%d]",cur_text-text_info);
+}
+#endif TRACE_MACROS
+
+
+/*:119*/
+#line 1448 "tangle.web"
+;
+/*112:*/
+#line 1380 "tangle.web"
+
+#line 1381 "tangle.web"
+next_param_name= 0;
+next_param_name_text= param_name_texts;
+param_names[next_param_name]= next_param_name_text;
+
+/*:112*/
+#line 1449 "tangle.web"
+;
+
+/*:117*/
+#line 1724 "tangle.web"
+;
+cur_text->text_link= 0;
+}
+
+/*:134*/
+#line 1705 "tangle.web"
+;
+/*136:*/
+#line 1738 "tangle.web"
+
+#line 1739 "tangle.web"
+switch(next_control){
+case 253:p= name_dir;break;
+case 254:p= cur_module;
+/*137:*/
+#line 1750 "tangle.web"
+
+#line 1751 "tangle.web"
+while((next_control= get_next())=='+');
+if(next_control!='='){
+err_print("! C text flushed, = sign is missing");
+
+while((next_control= skip_ahead())!=255);
+return;
+}
+
+/*:137*/
+#line 1742 "tangle.web"
+;
+break;
+default:return;
+}
+/*138:*/
+#line 1759 "tangle.web"
+
+#line 1760 "tangle.web"
+store_two_bytes((sixteen_bits)(53248+module_count));
+
+/*:138*/
+#line 1746 "tangle.web"
+;
+scan_repl(254);
+/*139:*/
+#line 1762 "tangle.web"
+
+#line 1763 "tangle.web"
+if(p==name_dir||p==0){
+(last_unnamed)->text_link= cur_text-text_info;last_unnamed= cur_text;
+}
+else if(p->equiv_or_xref==(ASCII *)text_info)p->equiv_or_xref= (ASCII *)cur_text;
+
+else{
+q= (text_pointer)p->equiv_or_xref;
+while(q->text_link<2000)q= q->text_link+text_info;
+q->text_link= cur_text-text_info;
+}
+cur_text->text_link= 2000;
+
+/*:139*/
+#line 1748 "tangle.web"
+;
+
+/*:136*/
+#line 1706 "tangle.web"
+;
+}
+
+/*:133*//*140:*/
+#line 1775 "tangle.web"
+phase_one(){
+#line 1776 "tangle.web"
+phase= 1;
+module_count= 0;
+reset_input();
+while((next_control= skip_ahead())!=255);
+while(!input_has_ended)scan_module();
+check_complete();
+phase= 2;
+}
+
+/*:140*//*141:*/
+#line 1785 "tangle.web"
+print_stats(){
+#line 1786 "tangle.web"
+printf("\nMemory usage statistics:\n");
+printf("%d names (out of %d)\n",name_ptr-name_dir,4000);
+printf("%d replacement texts (out of %d)\n",text_ptr-text_info,2000);
+printf("%d bytes (out of %d)\n",byte_ptr-byte_mem,90000);
+printf("%d tokens (out of %d)\n",tok_ptr-tok_mem,150000);
+}
+
+/*:141*/
diff --git a/web/spiderweb/src/big-web.ch b/web/spiderweb/src/big-web.ch
new file mode 100644
index 0000000000..6dcf6269d0
--- /dev/null
+++ b/web/spiderweb/src/big-web.ch
@@ -0,0 +1,59 @@
+From oravax!fred@wrath.cs.cornell.edu Thu Feb 9 18:05:48 1989
+Received: from princeton.Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.68)
+ id AA25210; Thu, 9 Feb 89 18:05:46 EST
+Received: from CU-ARPA.CS.CORNELL.EDU by Princeton.EDU (5.58+++/2.5)
+ id AA03857; Thu, 9 Feb 89 18:04:48 EST
+Received: from WRATH.CS.CORNELL.EDU by cu-arpa.cs.cornell.edu (5.61/1.91d)
+ id AA08274; Thu, 9 Feb 89 18:04:18 -0500
+Received: by wrath.cs.cornell.edu (5.61/1.91d)
+ id AA17731; Thu, 9 Feb 89 18:04:14 -0500
+Received: by oravax.UUCP (5.51/5.17)
+ id AA08548; Thu, 9 Feb 89 17:43:00 EST
+Date: Thu, 9 Feb 89 17:43:00 EST
+From: oravax!fred@wrath.cs.cornell.edu (Charles Mills)
+Message-Id: <8902092243.AA08548@oravax.UUCP>
+To: nr@Princeton.EDU
+Subject: Re: tangle and weave
+Status: R
+
+The changes (just like those of stangle which were made in, if I recall
+aright, November) were actually made with a .ch file, big.ch:
+
+big.ch:
+@x
+@d max_refs = 20000 /* number of cross-references; must be less than 65536 */
+@y
+@d max_refs = 40000 /* number of cross-references; must be less than 65536 */
+@z
+@x
+@d max_toks = 20000 /* number of symbols in \cee\ texts being parsed;
+@y
+@d max_toks = 40000 /* number of symbols in \cee\ texts being parsed;
+@z
+@x
+@d max_texts = 2000 /* number of phrases in \cee\ texts being parsed;
+@y
+@d max_texts = 4000 /* number of phrases in \cee\ texts being parsed;
+@z
+@x
+@d max_scraps = 1000 /* number of tokens in \cee\ texts being parsed */
+@y
+@d max_scraps = 1500 /* number of tokens in \cee\ texts being parsed */
+@z
+@x
+@d stack_size = 400 /* number of simultaneous output levels */
+@y
+@d stack_size = 800 /* number of simultaneous output levels */
+@z
+
+make:
+/bin/make -f ../master/WebMakefile \
+ THETANGLE=stangle THEWEAVE=sweave SPIDER=s.spider CHANGES=big.ch$*
+
+Your master source files have not been touched, and even your
+.../ssl/weave.web, though it was regenerated, came out the same
+as before. No anxiety on this score was in order at this end, and
+if any had been expressed to me I'd have squelched it.
+
+fred
+
diff --git a/web/spiderweb/src/c++/c++.spider b/web/spiderweb/src/c++/c++.spider
new file mode 100644
index 0000000000..b368450540
--- /dev/null
+++ b/web/spiderweb/src/c++/c++.spider
@@ -0,0 +1,368 @@
+#
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# modified for c++ by Ed Kademan <kademan@stat.wisc.edu>
+# Thu Aug 10 12:47:13 CDT 1989
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+language C++ extension cc
+
+at_sign @
+
+comment begin <"//"> end newline
+
+default translation <*> mathness yes
+
+token identifier category simp mathness yes
+token number category math mathness yes
+token newline category newline mathness maybe translation <>
+token pseudo_semi category semi mathness maybe translation <"\\relax">
+
+module definition stmt use math
+
+token + category unorbinop
+token - category unorbinop
+token * category unorbinop translation <"{*}">
+token / category dot
+token < category less
+token > category greater
+token = category equals translation <"\\leftarrow"> tangleto <"="-space>
+token . category dot
+token ~ category unop translation <"\\TI">
+token & category unorbinop translation <"\\amp">
+token ^ translation <"\\^"> category binop
+token | category binop
+token ? translation <"\\?"> category question
+token % translation <"\\%"> category binop
+token # translation <"\\#"> category sharp
+token ! category unop translation <"\\neg">
+token \ category backslash translation <"\\backslash">
+token ( category open
+token ) category close
+token [ category open
+token ] category close
+token { translation <"\\{"-indent> category lbrace
+token } translation <"\\}"> category rbrace
+token , category comma translation <",\\;">
+token ; category semi
+token : category colon
+token :: category coloncolon translation <"\\CC">
+token ++ category unop translation <"\\PP">
+token -- category unop translation <"\\MM">
+token != translation <"\\I"> category binop
+token <= translation <"\\L"> category binop
+token >= translation <"\\G"> category binop
+token == translation <"\\S"> category binop
+token && translation <"\\W"> category binop
+token || translation <"\\V"> category binop
+token -> translation <"\\MG"> category binop
+token >> translation <"\\GG"> category binop
+token << translation <"\\LL"> category binop
+
+macros begin
+\def\CC{\mathrel{:{:}}}
+\def\CCE{\mathrel{:{:}=}}
+\def\FE{\mathrel{/=}}
+\def\PP{\mathord{++}}
+\def\PE{\mathrel{+=}}
+\def\MM{\mathord{--}}
+\def\ME{\mathrel{-=}}
+\def\MG{\mathrel{\to}}
+\def\GG{\mathrel{>\!>}}
+\def\LL{\mathrel{<\!<}}
+\def\TE{\mathrel{\ast=}}
+\def\CE{\mathrel{\%=}}
+\def\HE{\mathrel{\uparrow=}}
+\def\AE{\mathrel{\amp=}}
+\def\OE{\mathrel{|=}}
+\let\openbraces=\{
+\let\closebraces=\}
+\def\{{\ifmmode\openbraces\else$\openbraces$\fi}
+\def\}{\ifmmode\closebraces\else$\closebraces$\fi}
+\def\?{\mathrel?}
+\def\s{\ }
+\def\setfilefonts{\let\\=\. \let\|=\. \let\&=\.}
+macros end
+
+default translation <*-"\\"-space>
+
+ilk case_like category case
+ilk do_like category do
+ilk else_like category else
+ilk enum_like category enum
+ilk for_like category for
+ilk if_like category if
+ilk int_like category decl_head translation <*>
+ilk new_like category new
+ilk sizeof_like category sizeof
+ilk struct_like category struct
+ilk switch_like category switch
+ilk this_like category simp
+ilk typedef_like category typedef
+
+default translation <*>
+
+reserved asm ilk sizeof_like
+reserved auto ilk int_like
+reserved break ilk case_like
+reserved case ilk case_like
+reserved char ilk int_like
+reserved class ilk struct_like
+reserved const ilk int_like
+reserved continue ilk case_like
+reserved default ilk case_like
+reserved delete ilk this_like
+reserved do ilk do_like
+reserved double ilk int_like
+reserved else ilk else_like
+reserved enum ilk enum_like
+reserved extern ilk int_like
+reserved float ilk int_like
+reserved for ilk for_like
+reserved friend ilk int_like
+reserved goto ilk case_like
+reserved if ilk if_like
+reserved inline ilk int_like
+reserved int ilk int_like
+reserved long ilk int_like
+reserved new ilk new_like
+reserved operator ilk this_like
+reserved overload ilk int_like
+reserved private ilk case_like
+reserved protected ilk case_like
+reserved public ilk case_like
+reserved register ilk int_like
+reserved return ilk case_like
+reserved short ilk int_like
+reserved sizeof ilk sizeof_like
+reserved static ilk int_like
+reserved struct ilk struct_like
+reserved switch ilk switch_like
+reserved this ilk this_like
+reserved typedef ilk typedef_like
+reserved union ilk struct_like
+reserved unsigned ilk int_like
+reserved virtual ilk int_like
+reserved void ilk int_like
+reserved while ilk for_like
+
+# we indulge in a trick to avoid treating
+# ASCII (*fp)();
+# as a statement (function call). We use instead
+# ASCII ===> (*fp)();
+token ===> translation <"\\relax"> tangleto <space> category decl_head
+
+
+#
+# There appears to be a bug in spidery weave. If the very last line of a
+# web file ends with a preprocessor directive weave fails to print it out.
+# The first line below fixes this problem.
+preproc [ ignore_scrap ] --> preproc newline
+? ignore_scrap --> #1
+# dropped, because we've overflowed yacc!
+#### DON'T DO THIS! it makes it impossible to add translation on the left
+#### ignore_scrap ? --> #2
+
+
+# because of declarations, we have to be very careful about converting
+# simp to math
+
+(math|simp) unop --> math
+math (binop|unorbinop) (math|simp) --> math
+math comma <opt-9> (math|simp) --> math
+# we're not allowed math simp --> statement because math simp could be fn_decl
+math math --> math
+(math|simp) semi --> stmt
+# so to hack the omission above, we include (usually a cast)
+math <"\\"-space> stmt --> stmt
+
+(open|simpopen|question|unop|unorbinop|case) [ simp ] --> (open|simpopen|question|unop|unorbinop|case) math
+[ simp ] binop --> math binop
+# old:
+# [ simp ] equals --> math equals
+# math [ equals ] --> math binop
+
+simp* colon --> tag
+
+# can't have simp open --> open because that causes ( to eat all id's to its left.
+simp open --> simpopen
+
+(open|simpopen) math close --> math
+(open|simpopen) <"\\,"> close --> math
+# following needed for for statements
+open stmt <"\\"-space> --> open
+
+(new|simp|decl_head) <"\\"-space> decl_head --> decl_head
+[ simp ] math (equals|comma|semi) --> decl_head math (equals|comma|semi)
+[ (decl_head|simp) simp ] (simp|math) --> decl_head (simp|math)
+(simp|decl_head) <"\\"-space> (simp|math)* comma --> decl_head
+[ (simp|decl_head) <"\\"-space> (simp|math)* ] semi --> math semi
+(simp|decl_head) <"\\"-space> (simp|math)* equals --> decl_equals
+(open|simpopen) [ (simp|decl_head) <"\\"-space> (simp|math)* equals ] --> (open|simpopen) decl_equals
+decl_equals math comma --> decl_head
+[ decl_equals math ] semi --> math semi
+decl_equals [ simp ] --> decl_equals math
+
+# here we try to deal with casts and argument lists, e.g.
+# (ASCII *) malloc(sizeof (ASCII *));
+# char *malloc(int);
+
+# If the type is predefined, we know we have a cast
+(open|simpopen) decl_head close --> cast
+(open|simpopen) [ decl_head <"\\"-space> simp ] --> (open|simpopen) decl_head
+(open|simpopen) [ decl_head (unorbinop|math) ] --> (open|simpopen) decl_head
+(open|simpopen) decl_head comma --> arglist
+arglist (decl_head|unorbinop|math) --> arglist
+arglist <"\\"-space> simp --> arglist
+arglist comma --> arglist
+arglist close --> math
+
+# and here are some common cases of casts with non-predefined types
+# for other cases you'll have to use "declares"
+(open|simpopen) math <"\\"-space> unorbinop comma --> arglist
+(open|simpopen) math <"\\"-space> unorbinop unorbinop comma --> arglist
+(open|simpopen) math <"\\"-space> unorbinop unorbinop unorbinop comma --> arglist
+(open|simpopen) math <"\\"-space> unorbinop close --> cast
+(open|simpopen) math <"\\"-space> unorbinop unorbinop close --> cast
+(open|simpopen) math <"\\"-space> unorbinop unorbinop unorbinop close --> cast
+
+# the math here seems to be a cast. We don't convert to cast because it looks
+# too much like a cycle
+(open|simpopen) [ math <"\\"-space> simp ] --> (open|simpopen) math
+
+# Here is the destiny of casts
+cast <"\\"-space> (math|simp) --> math
+cast (newline|ignore_scrap) --> cast
+cast --> math
+
+question math colon --> binop
+
+unop math --> math
+<"{"> unorbinop <"}"> math --> math
+<"\\buildrel"> (binop|unorbinop) <"\\over{"> equals <"}"> --> binop
+equals --> binop
+sizeof (math|simp) --> math
+
+struct simp* <"\\"-space> lbrace --> structbrace
+struct lbrace --> structbrace
+struct (simp|decl_head)* colon (simp|decl_head) lbrace --> structbrace
+struct (simp|decl_head)* colon case (simp|decl_head) lbrace --> structbrace
+structbrace [ simp ] --> structbrace decl_head
+structbrace <force> stmt --> structbrace
+structbrace <outdent-force> rbrace --> struct_head
+structbrace <outdent-force> tagged_stmt --> structbrace
+[ struct_head ] simp --> decl_head simp
+# some people say e.g. struct blah {...}; is this K&R?
+[ struct_head ] semi --> math semi
+struct [ simp (newline|ignore_scrap) ] --> struct simp
+struct simp --> decl_head
+decl_head <"\\"-space> struct --> struct
+
+# enumeration types are like structures and unions, but they have math
+# instead of many decls...
+enum simp* <"\\"-space> lbrace --> enumbrace
+enum lbrace --> enumbrace
+enumbrace math rbrace <outdent> --> enum_head
+[ enum_head ] simp --> decl_head simp
+[ enum_head ] semi --> math semi
+enum [ simp (newline|ignore_scrap) ] --> enum simp
+enum simp --> decl_head
+decl_head <"\\"-space> enum --> enum
+
+typedef [ simp ] --> typedef decl_head
+typedef stmt --> stmt
+
+[ math* <indent> ] (lbrace|decl_head|stmt) --> fn_decl (lbrace|decl_head|stmt)
+[ (simp|decl_head) <"\\"-space> math* <indent> ] (lbrace|decl_head|stmt) --> fn_decl (lbrace|decl_head|stmt)
+# The following statment will always have braces and never be tagged
+fn_decl <outdent-force> stmt --> stmt
+math colon fn_decl --> fn_decl
+
+(open|simpopen) [ stmt <"\\"-space> stmt ] --> (open|simpopen) stmt
+
+lbrace <outdent-force> rbrace --> stmt
+lbrace <force> stmt --> lbrace
+lbrace <outdent-force> tagged_stmt --> lbrace
+lbrace (math|simp) <outdent> rbrace --> math
+
+# if math can be followed by a brace, or no.
+# ifmath and ifbrace can have an attached else or else if clause
+# else, for, and while are formatted like if, but can't have an
+# attached else clause, so we use formath and forbrace
+
+if math --> ifmath
+ifmath <"\\"-space> lbrace --> ifbrace
+ifbrace <force> stmt --> ifbrace
+ifbrace <outdent-force> tagged_stmt --> ifbrace
+ifbrace [ rbrace (newline|ignore_scrap) ] --> ifbrace rbrace
+ifbrace rbrace [ else (newline|ignore_scrap) ] --> ifbrace rbrace else
+ifbrace <outdent-force> rbrace <"\\"-space> else if --> if
+ifbrace <outdent-force> rbrace <"\\"-space> else lbrace --> forbrace
+ifbrace <outdent-force> rbrace <"\\"-space> else --> formath
+ifbrace <outdent-force> rbrace --> stmt
+
+# Assume simple statements attached to if will never be tagged
+
+ifmath [ stmt (newline|ignore_scrap) ] --> ifmath stmt
+ifmath stmt [ else (newline|ignore_scrap) ] --> ifmath stmt else
+ifmath <indent-force> stmt <outdent-force> else if --> if
+ifmath <indent-force> stmt <outdent-force> else lbrace --> forbrace
+ifmath <indent-force> stmt <outdent-force> else --> formath
+ifmath <indent-force> stmt <outdent> --> stmt
+
+for math --> formath
+formath <"\\"-space> lbrace --> forbrace
+forbrace <force> stmt --> forbrace
+forbrace <outdent-force> tagged_stmt --> forbrace
+forbrace <outdent-force> rbrace --> stmt
+formath <indent-force> stmt <outdent> --> stmt
+
+# we need an extra indent for switch, becuase the cases will be backed out
+switch math lbrace <indent> --> switchbrace
+switchbrace <outdent-force> tagged_stmt --> switchbrace
+# This next should never happen
+switchbrace <force> stmt --> switchbrace
+switchbrace <outdent-outdent-force> rbrace --> stmt
+
+
+
+# handle do-while (while has category for)
+do lbrace --> dobrace
+dobrace <force> stmt --> dobrace
+dobrace <outdent-force> tagged_stmt --> dobrace
+dobrace rbrace for --> math
+do <indent-force> stmt <outdent-force> for --> math
+
+case semi --> stmt
+case math semi --> stmt
+case colon --> tag
+case math colon --> tag
+tag <force> tag --> tag
+tag <indent-force> stmt --> tagged_stmt
+
+stmt <force> stmt --> stmt
+stmt <outdent-force> tagged_stmt --> stmt
+semi --> stmt
+
+# control sequence \8 puts things on the left margin
+<force-"\\8"> sharp <"{\\let\\\\=\\bf"-space> (simp|if|else) <"}"-indent-"{}"-space> --> preproc
+preproc backslash <force-"\\8\\hskip1em"-space> newline --> preproc
+preproc <force-outdent> newline --> ignore_scrap
+preproc !(less|lesssimp|backslash|newline) --> preproc
+newline --> ignore_scrap
+
+[ less (simp|decl_head) ] (dot|greater) --> lesssimp (dot|greater)
+lesssimp dot simp --> lesssimp
+<"{\\setfilefonts"-space> lesssimp greater <"}"> --> math
+lesssimp --> unop
+less --> binop
+greater --> binop
+dot --> binop
+
+
+(decl_head|simp) coloncolon (decl_head|simp) --> simp
+math coloncolon (decl_head|simp) --> math
+decl_head stmt --> stmt
+
+# The following handles "~" for destructors.
+coloncolon <"\\,"> unop --> coloncolon
+unop decl_head --> decl_head
diff --git a/web/spiderweb/src/c++/make b/web/spiderweb/src/c++/make
new file mode 100644
index 0000000000..bc9e63f905
--- /dev/null
+++ b/web/spiderweb/src/c++/make
@@ -0,0 +1,3 @@
+#!/bin/csh -f
+/bin/make -f ../master/WebMakefile CPUTYPE=`cputype`\
+ THETANGLE=c++tangle THEWEAVE=c++weave SPIDER=c++.spider $*
diff --git a/web/spiderweb/src/c/c.spider b/web/spiderweb/src/c/c.spider
new file mode 100644
index 0000000000..6aac7f3ec9
--- /dev/null
+++ b/web/spiderweb/src/c/c.spider
@@ -0,0 +1,350 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+language C extension c
+
+at_sign @
+
+comment begin <"/*"> end <"*/">
+
+default translation <*> mathness yes
+
+token identifier category simp mathness yes
+token number category math mathness yes
+token newline category newline mathness maybe translation <>
+token pseudo_semi category semi mathness maybe translation <"\\relax">
+
+module definition stmt use math
+
+token + category unorbinop
+token - category unorbinop
+token * category unorbinop translation <"{*}"> tangleto <space-"*">
+# avoid inadvertant /*
+token / category dot
+token < category less translation <>
+token > category greater translation <>
+token = category equals translation <"\\leftarrow"> tangleto <"="-space>
+# avoid inadvertant =-
+token . category dot
+token ~ category unop translation <"\\TI">
+token & category unorbinop translation <"\\amp">
+token ^ translation <"\\^"> category binop
+token | category binop
+token ? translation <"\\?"> category question
+token % translation <"\\%"> category binop
+token # translation <"\\#"> category sharp
+token ! category unop translation <"\\neg">
+token \ category backslash translation <"\\backslash">
+token ( category open
+token ) category close
+token [ category open
+token ] category close
+token { translation <"\\{"-indent> category lbrace
+token } translation <"\\}"> category rbrace
+token , category comma translation <",\\;">
+token ; category semi
+token : category colon
+token ++ category unop translation <"\\PP">
+token -- category unop translation <"\\MM">
+token != translation <"\\I"> category binop
+token <= translation <"\\L"> category binop
+token >= translation <"\\G"> category binop
+token == translation <"\\S"> category binop
+token && translation <"\\W"> category binop
+token || translation <"\\V"> category binop
+token -> translation <"\\MG"> category binop
+token >> translation <"\\GG"> category binop
+token << translation <"\\LL"> category binop
+
+macros begin
+\def\CC{\mathrel{:{:}}}
+\def\CCE{\mathrel{:{:}=}}
+\def\FE{\mathrel{/=}}
+\def\PP{\mathord{++}}
+\def\PE{\mathrel{+=}}
+\def\MM{\mathord{--}}
+\def\ME{\mathrel{-=}}
+\def\MG{\mathrel{\to}}
+\def\GG{\mathrel{>\!>}}
+\def\LL{\mathrel{<\!<}}
+\def\TE{\mathrel{\ast=}}
+\def\CE{\mathrel{\%=}}
+\def\HE{\mathrel{\uparrow=}}
+\def\AE{\mathrel{\amp=}}
+\def\OE{\mathrel{|=}}
+\let\openbraces=\{
+\let\closebraces=\}
+\def\{{\ifmmode\openbraces\else$\openbraces$\fi}
+\def\}{\ifmmode\closebraces\else$\closebraces$\fi}
+\def\?{\mathrel?}
+\def\s{\ }
+macros end
+
+default translation <*-"\\"-space>
+
+ilk case_like category case
+ilk int_like category decl_head translation <*>
+ilk else_like category else
+ilk enum_like category enum
+ilk if_like category if
+ilk for_like category for
+ilk do_like category do
+ilk sizeof_like category sizeof
+ilk struct_like category struct
+ilk switch_like category switch
+ilk typedef_like category typedef
+
+default translation <*>
+
+reserved auto ilk int_like
+reserved break ilk case_like
+reserved case ilk case_like
+reserved char ilk int_like
+reserved continue ilk case_like
+reserved default ilk case_like
+reserved do ilk do_like
+reserved double ilk int_like
+reserved else ilk else_like
+reserved enum ilk enum_like
+reserved extern ilk int_like
+reserved float ilk int_like
+reserved for ilk for_like
+reserved goto ilk case_like
+reserved if ilk if_like
+reserved int ilk int_like
+reserved long ilk int_like
+reserved register ilk int_like
+reserved return ilk case_like
+reserved short ilk int_like
+reserved sizeof ilk sizeof_like
+reserved static ilk int_like
+reserved struct ilk struct_like
+reserved switch ilk switch_like
+reserved typedef ilk typedef_like
+reserved union ilk struct_like
+reserved unsigned ilk int_like
+reserved void ilk int_like
+reserved while ilk for_like
+
+# we indulge in a trick to avoid treating
+# ASCII (*fp)();
+# as a statement (function call). We use instead
+# ASCII ===> (*fp)();
+token ===> translation <"\\relax"> tangleto <space> category decl_head
+
+
+#
+? ignore_scrap --> #1
+# dropped, because we've overflowed yacc!
+#### DON'T DO THIS! it makes it impossible to add translation on the left
+#### ignore_scrap ? --> #2
+
+
+# because of declarations, we have to be very careful about converting
+# simp to math
+
+(math|simp) unop --> math
+math (binop|unorbinop) (math|simp) --> math
+math comma <opt-9> (math|simp) --> math
+# we're not allowed math simp --> statement because math simp could be fn_decl
+math math --> math
+(math|simp) semi --> stmt
+# so to hack the omission above, we include (usually a cast)
+math <"\\"-space> stmt --> stmt
+
+(open|simpopen|question|unop|unorbinop|case) [ simp ] --> (open|simpopen|question|unop|unorbinop|case) math
+[ simp ] binop --> math binop
+# old:
+# [ simp ] equals --> math equals
+# math [ equals ] --> math binop
+
+simp* colon --> tag
+
+# can't have simp open --> open because that causes ( to eat all id's to its left.
+simp open --> simpopen
+
+(open|simpopen) math close --> math
+(open|simpopen) <"\\,"> close --> math
+# following needed for for statements
+open stmt <"\\"-space> --> open
+
+# here we try to deal with casts and argument lists, e.g.
+# (ASCII *) malloc(sizeof (ASCII *));
+# char *malloc(int);
+
+# If the type is predefined, we know we have a cast
+(open|simpopen) decl_head close --> cast
+(open|simpopen) [ decl_head (unorbinop|math|simp) ] --> (open|simpopen) decl_head
+(open|simpopen) decl_head comma --> arglist
+arglist (decl_head|unorbinop|math) --> arglist
+arglist close --> math
+
+# and here are some common cases of casts with non-predefined types
+# for other cases you'll have to use "declares"
+(open|simpopen) math <"\\"-space> unorbinop comma --> arglist
+(open|simpopen) math <"\\"-space> unorbinop unorbinop comma --> arglist
+(open|simpopen) math <"\\"-space> unorbinop unorbinop unorbinop comma --> arglist
+(open|simpopen) math <"\\"-space> unorbinop close --> cast
+(open|simpopen) math <"\\"-space> unorbinop unorbinop close --> cast
+(open|simpopen) math <"\\"-space> unorbinop unorbinop unorbinop close --> cast
+
+# the math here seems to be a cast. We don't convert to cast because it looks
+# too much like a cycle
+(open|simpopen) [ math <"\\"-space> simp ] --> (open|simpopen) math
+
+# Here is the destiny of casts
+cast <"\\"-space> (math|simp) --> math
+cast (newline|ignore_scrap) --> cast
+cast --> math
+
+
+
+question math colon --> binop
+
+unop math --> math
+<"{"> unorbinop <"}"> math --> math
+<"\\buildrel"> (binop|unorbinop) <"\\over{"> equals <"}"> --> binop
+equals --> binop
+sizeof (math|simp) --> math
+
+(simp|decl_head) <"\\"-space> decl_head --> decl_head
+[ simp ] math (equals|comma|semi) --> decl_head math (equals|comma|semi)
+[ (decl_head|simp) simp ] (simp|math) --> decl_head (simp|math)
+(simp|decl_head) <"\\"-space> (simp|math)* comma --> decl_head
+(simp|decl_head) <"\\"-space> (simp|math)* semi --> decl
+(simp|decl_head) <"\\"-space> (simp|math)* equals --> decl_equals
+decl_equals math comma --> decl_head
+decl_equals math semi --> decl
+decl_equals [ simp ] --> decl_equals math
+
+struct simp* <"\\"-space> lbrace --> structbrace
+struct lbrace --> structbrace
+structbrace [ simp ] --> structbrace decl_head
+structbrace <force> decl --> structbrace
+structbrace <outdent-force> rbrace --> struct_head
+[ struct_head ] simp --> decl_head simp
+# some people say e.g. struct blah {...}; is this K&R?
+struct_head semi --> decl
+struct [ simp (newline|ignore_scrap) ] --> struct simp
+struct simp --> decl_head
+decl_head <"\\"-space> struct --> struct
+
+# enumeration types are like structures and unions, but they have math
+# instead of many decls...
+enum simp* <"\\"-space> lbrace --> enumbrace
+enum lbrace --> enumbrace
+enumbrace math rbrace <outdent> --> enum_head
+[ enum_head ] simp --> decl_head simp
+enum_head semi --> decl
+enum [ simp (newline|ignore_scrap) ] --> enum simp
+enum simp --> decl_head
+decl_head <"\\"-space> enum --> enum
+
+typedef [ simp ] --> typedef decl_head
+typedef decl --> decl
+
+
+
+
+[ math* <indent> ] (lbrace|decl_head|decl) --> fn_decl (lbrace|decl_head|decl)
+[ (simp|decl_head) <"\\"-space> math* <indent> ] (lbrace|decl_head|decl) --> fn_decl (lbrace|decl_head|decl)
+fn_decl <force> decl --> fn_decl
+# The following statment will always have braces and never be tagged
+fn_decl <outdent-force> stmt --> function
+# include stmt here to cover module definition
+(stmt|decl|function) <big_force> function --> function
+function <big_force> decl --> decl
+
+(stmt|decl) <force> decl --> decl
+decl <big_force> stmt --> stmt
+decl <outdent-big_force> tagged_stmt --> stmt
+
+
+lbrace <outdent-force> rbrace --> stmt
+lbrace <force> stmt --> lbrace
+lbrace <outdent-force> tagged_stmt --> lbrace
+lbrace (math|simp) <outdent> rbrace --> math
+
+# if math can be followed by a brace, or no.
+# ifmath and ifbrace can have an attached else or else if clause
+# else, for, and while are formatted like if, but can't have an
+# attached else clause, so we use formath and forbrace
+
+if math --> ifmath
+ifmath <"\\"-space> lbrace --> ifbrace
+ifbrace <force> stmt --> ifbrace
+ifbrace <outdent-force> tagged_stmt --> ifbrace
+ifbrace [ rbrace (newline|ignore_scrap) ] --> ifbrace rbrace
+ifbrace rbrace [ else (newline|ignore_scrap) ] --> ifbrace rbrace else
+ifbrace <outdent-force> rbrace <"\\"-space> else if --> if
+ifbrace <outdent-force> rbrace <"\\"-space> else lbrace --> forbrace
+ifbrace <outdent-force> rbrace <"\\"-space> else --> formath
+ifbrace <outdent-force> rbrace --> stmt
+
+# Assume simple statements attached to if will never be tagged
+
+ifmath [ stmt (newline|ignore_scrap) ] --> ifmath stmt
+ifmath stmt [ else (newline|ignore_scrap) ] --> ifmath stmt else
+ifmath <indent-force> stmt <outdent-force> else if --> if
+ifmath <indent-force> stmt <outdent-force> else lbrace --> forbrace
+ifmath <indent-force> stmt <outdent-force> else --> formath
+ifmath <indent-force> stmt <outdent> --> stmt
+
+for math --> formath
+formath <"\\"-space> lbrace --> forbrace
+forbrace <force> stmt --> forbrace
+forbrace <outdent-force> tagged_stmt --> forbrace
+forbrace <outdent-force> rbrace --> stmt
+formath <indent-force> stmt <outdent> --> stmt
+
+# we need an extra indent for switch, becuase the cases will be backed out
+switch math lbrace <indent> --> switchbrace
+switchbrace <outdent-force> tagged_stmt --> switchbrace
+# This next should never happen
+switchbrace <force> stmt --> switchbrace
+switchbrace <outdent-outdent-force> rbrace --> stmt
+
+
+
+# handle do-while (while has category for)
+do lbrace --> dobrace
+dobrace <force> stmt --> dobrace
+dobrace <outdent-force> tagged_stmt --> dobrace
+dobrace <outdent-force> rbrace <"\\"-space> for --> math
+do <indent-force> stmt <outdent-force> for --> math
+
+case semi --> stmt
+case math semi --> stmt
+case colon --> tag
+case math colon --> tag
+tag <force> tag --> tag
+tag <indent-force> stmt --> tagged_stmt
+
+stmt <force> stmt --> stmt
+stmt <outdent-force> tagged_stmt --> stmt
+semi --> stmt
+
+# control sequence \8 puts things on the left margin
+<force-"\\8"> sharp <"{\\let\\\\=\\bf"-space> (simp|if|else) <"}"-indent-"{}"-space> --> preproc
+preproc backslash <force-"\\8\\hskip1em"-space> newline --> preproc
+preproc <force-outdent> newline --> ignore_scrap
+preproc !(less|lesssimp|backslash|newline) --> preproc
+newline --> ignore_scrap
+
+less simp --> lesssimp
+lesssimp dot simp --> lesssimp
+<"\\LN"> lesssimp greater <"\\RN"> --> math
+<"<"> lesssimp --> unop
+less <"<"> --> binop
+greater <">"> --> binop
+dot --> binop
+
+macros begin
+\let\LN\langle
+\let\RN\rangle
+macros end
+
+
+
+
+
diff --git a/web/spiderweb/src/c/local.guide b/web/spiderweb/src/c/local.guide
new file mode 100644
index 0000000000..350b52c64a
--- /dev/null
+++ b/web/spiderweb/src/c/local.guide
@@ -0,0 +1,4 @@
+#define in code should be done verbatim, otherwise trouble with
+parentheses....
+
+===> to force declaration.
diff --git a/web/spiderweb/src/c/make b/web/spiderweb/src/c/make
new file mode 100644
index 0000000000..0261e8df62
--- /dev/null
+++ b/web/spiderweb/src/c/make
@@ -0,0 +1,3 @@
+#!/bin/csh -f
+/bin/make -f ../master/WebMakefile CPUTYPE=`cputype`\
+ THETANGLE=ceetangle THEWEAVE=ceeweave SPIDER=c.spider $*
diff --git a/web/spiderweb/src/c/new.spider b/web/spiderweb/src/c/new.spider
new file mode 100644
index 0000000000..d361bb99a9
--- /dev/null
+++ b/web/spiderweb/src/c/new.spider
@@ -0,0 +1,407 @@
+Return-Path: <smith%zeus@harvard.harvard.edu>
+Received: by jumbo.pa.dec.com; id AA01901; Thu, 26 Jul 90 08:43:40 -0700
+Received: by decpa.pa.dec.com; id AA11390; Thu, 26 Jul 90 08:43:34 -0700
+Received: from cs.Princeton.EDU by Princeton.EDU (5.61++/2.48/princeton)
+ id AA16823; Thu, 26 Jul 90 11:43:18 -0400
+Received: by cs.Princeton.EDU (5.57/1.105)
+ id AA04017; Thu, 26 Jul 90 11:43:53 EDT
+Received: from harvard.harvard.edu by Princeton.EDU (5.61++/2.48/princeton)
+ id AA16820; Thu, 26 Jul 90 11:43:07 -0400
+Message-Id: <9007261543.AA16820@Princeton.EDU>
+Received: by harvard.harvard.edu (5.54/a0.25)
+ (for nr@princeton.edu) id AA00320; Thu, 26 Jul 90 11:43:21 EDT
+Date: Thu, 26 Jul 90 11:43:21 EDT
+Received: by zeus.HARVARD.EDU; Thu, 26 Jul 90 11:41:04 EDT
+From: smith%zeus@harvard.harvard.edu (Steven Smith)
+To: nr@Princeton.EDU
+Subject: Spidery WEB
+
+Prof. Ramsey:
+
+FYI: I've been using your Spidery WEB system and have introduced the
+followng changes to c.spider:
+
+1) c.spider hung on the declaration (cf. K&R p. 123)
+
+ struct {
+ int x;
+ int *y;
+ } *p;
+
+I fixed this by changing
+
+ [ struct_head ] simp --> decl_head simp
+
+to
+ [ struct_head ] (math|simp) --> decl_head (math|simp)
+
+
+2) I introduced the category `asterisk' so that `*' can be used as the
+\mathbin `*' or the \mathord `{*}' by TeX, depending on the context.
+Search for `asterisk' below to see the changes.
+
+Steven Smith
+smith@sandalphon.harvard.edu
+
+
+The file c.spider:
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Cut Here %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+#
+# Alterations:
+# 7/25/90 Steven T. Smith; Allowed declaration of ptr to structures.
+# 7/25/90 Steven T. Smith; Introduced `asterisk' category.
+# 7/25/90 Steven T. Smith; Changed `->' to different \mathord.
+language C extension c
+
+at_sign @
+
+comment begin <"/*"> end <"*/">
+
+default translation <*> mathness yes
+
+token identifier category simp mathness yes
+token number category math mathness yes
+token newline category newline mathness maybe translation <>
+token pseudo_semi category semi mathness maybe translation <"\\relax">
+
+module definition stmt use math
+
+token + category unorbinop
+token - category unorbinop
+token * category asterisk tangleto <space-"*">
+# avoid inadvertant /*
+token / category dot
+token < category less translation <>
+token > category greater translation <>
+token = category equals translation <"\\leftarrow"> tangleto <"="-space>
+# avoid inadvertant =-
+token . category dot
+token ~ category unop translation <"\\TI">
+token & category unorbinop translation <"\\amp">
+token ^ translation <"\\^"> category binop
+token | category binop
+token ? translation <"\\?"> category question
+token % translation <"\\%"> category binop
+token # translation <"\\#"> category sharp
+token ! category unop translation <"\\neg">
+token \ category backslash translation <"\\backslash">
+token ( category open
+token ) category close
+token [ category open
+token ] category close
+token { translation <"\\{"-indent> category lbrace
+token } translation <"\\}"> category rbrace
+token , category comma translation <",\\;">
+token ; category semi
+token : category colon
+token ++ category unop translation <"\\PP">
+token -- category unop translation <"\\MM">
+token != translation <"\\I"> category binop
+token <= translation <"\\L"> category binop
+token >= translation <"\\G"> category binop
+token == translation <"\\S"> category binop
+token && translation <"\\W"> category binop
+token || translation <"\\V"> category binop
+token -> translation <"\\MG"> category binop
+token >> translation <"\\GG"> category binop
+token << translation <"\\LL"> category binop
+
+macros begin
+\def\CC{\mathrel{:{:}}}
+\def\CCE{\mathrel{:{:}=}}
+\def\FE{\mathrel{/=}}
+\def\PP{\mathord{++}}
+\def\PE{\mathrel{+=}}
+\def\MM{\mathord{--}}
+\def\ME{\mathrel{-=}}
+\def\MG{\mathord{-\!\triangleright}}
+#\def\MG{\mathrel{\to}}
+\def\GG{\mathrel{>\!>}}
+\def\LL{\mathrel{<\!<}}
+\def\TE{\mathrel{\ast=}}
+\def\CE{\mathrel{\%=}}
+\def\HE{\mathrel{\uparrow=}}
+\def\AE{\mathrel{\&=}}
+\def\OE{\mathrel{|=}}
+\let\openbraces=\{
+\let\closebraces=\}
+\def\{{\ifmmode\openbraces\else$\openbraces$\fi}
+\def\}{\ifmmode\closebraces\else$\closebraces$\fi}
+\def\?{\mathrel?}
+\def\s{\ }
+macros end
+
+default translation <*-"\\"-space>
+
+ilk case_like category case
+ilk int_like category decl_head translation <*>
+ilk else_like category else
+ilk enum_like category enum
+ilk if_like category if
+ilk for_like category for
+ilk do_like category do
+ilk sizeof_like category sizeof
+ilk struct_like category struct
+ilk switch_like category switch
+ilk typedef_like category typedef
+
+default translation <*>
+
+reserved auto ilk int_like
+reserved break ilk case_like
+reserved case ilk case_like
+reserved char ilk int_like
+reserved continue ilk case_like
+reserved default ilk case_like
+reserved do ilk do_like
+reserved double ilk int_like
+reserved else ilk else_like
+reserved enum ilk enum_like
+reserved extern ilk int_like
+reserved float ilk int_like
+reserved for ilk for_like
+reserved goto ilk case_like
+reserved if ilk if_like
+reserved int ilk int_like
+reserved long ilk int_like
+reserved register ilk int_like
+reserved return ilk case_like
+reserved short ilk int_like
+reserved sizeof ilk sizeof_like
+reserved static ilk int_like
+reserved struct ilk struct_like
+reserved switch ilk switch_like
+reserved typedef ilk typedef_like
+reserved union ilk struct_like
+reserved unsigned ilk int_like
+reserved void ilk int_like
+reserved while ilk for_like
+
+# we indulge in a trick to avoid treating
+# ASCII (*fp)();
+# as a statement (function call). We use instead
+# ASCII ===> (*fp)();
+token ===> translation <"\\relax"> tangleto <space> category decl_head
+
+
+#
+? ignore_scrap --> #1
+# dropped, because we've overflowed yacc!
+#### DON'T DO THIS! it makes it impossible to add translation on the left
+#### ignore_scrap ? --> #2
+
+
+# because of declarations, we have to be very careful about converting
+# simp to math
+
+(math|simp) unop --> math
+math (binop|unorbinop) (math|simp) --> math
+math [ asterisk ] (math|simp) --> math binop (math|simp)
+math comma <opt-9> (math|simp) --> math
+# we're not allowed math simp --> statement because math simp could be fn_decl
+math math --> math
+(math|simp) semi --> stmt
+# so to hack the omission above, we include (usually a cast)
+math <"\\"-space> stmt --> stmt
+
+(open|simpopen|question|unop|unorbinop|case) [ simp ] --> (open|simpopen|question|unop|unorbinop|case) math
+[ simp ] binop --> math binop
+# old:
+# [ simp ] equals --> math equals
+# math [ equals ] --> math binop
+
+simp* colon --> tag
+
+# can't have simp open --> open because that causes ( to eat all id's to its left.
+simp open --> simpopen
+
+(open|simpopen) math close --> math
+(open|simpopen) <"\\,"> close --> math
+# following needed for for statements
+open stmt <"\\"-space> --> open
+
+# here we try to deal with casts and argument lists, e.g.
+# (ASCII *) malloc(sizeof (ASCII *));
+# char *malloc(int);
+
+# If the type is predefined, we know we have a cast
+(open|simpopen) decl_head close --> cast
+(open|simpopen) [ decl_head (unorbinop|math|simp) ] --> (open|simpopen) decl_head
+(open|simpopen) [ decl_head <"\\"-space-"{"> asterisk <"}"> ] --> (open|simpopen) decl_head_ptr
+decl_head_ptr <"{"> asterisk <"}"> --> decl_head_ptr
+decl_head_ptr --> decl_head
+(open|simpopen) decl_head comma --> arglist
+arglist (decl_head|unorbinop|math) --> arglist
+arglist close --> math
+
+# and here are some common cases of casts with non-predefined types
+# for other cases you'll have to use "declares"
+(open|simpopen) math <"\\"-space> unorbinop comma --> arglist
+(open|simpopen) math <"\\"-space> unorbinop unorbinop comma --> arglist
+(open|simpopen) math <"\\"-space> unorbinop unorbinop unorbinop comma --> arglist
+(open|simpopen) math <"\\"-space> unorbinop close --> cast
+(open|simpopen) math <"\\"-space> unorbinop unorbinop close --> cast
+(open|simpopen) math <"\\"-space> unorbinop unorbinop unorbinop close --> cast
+
+# the math here seems to be a cast. We don't convert to cast because it looks
+# too much like a cycle
+(open|simpopen) [ math <"\\"-space> simp ] --> (open|simpopen) math
+
+# Here is the destiny of casts
+cast <"\\"-space> (math|simp) --> math
+cast (newline|ignore_scrap) --> cast
+cast --> math
+
+
+
+question math colon --> binop
+
+unop math --> math
+<"{"> unorbinop <"}"> math --> math
+<"{"> asterisk <"}"> (math|simp) --> math
+<"\\buildrel"> (binop|unorbinop) <"\\over{"> equals <"}"> --> binop
+[ asterisk ] equals --> unorbinop equals
+equals --> binop
+sizeof (math|simp) --> math
+
+(simp|decl_head) <"\\"-space> decl_head --> decl_head
+[ simp ] math (equals|comma|semi) --> decl_head math (equals|comma|semi)
+[ (decl_head|simp) simp ] (simp|math) --> decl_head (simp|math)
+(simp|decl_head) <"\\"-space> (simp|math)* comma --> decl_head
+(simp|decl_head) <"\\"-space> (simp|math)* semi --> decl
+(simp|decl_head) <"\\"-space> (simp|math)* equals --> decl_equals
+decl_equals math comma --> decl_head
+decl_equals math semi --> decl
+decl_equals [ simp ] --> decl_equals math
+
+struct simp* <"\\"-space> lbrace --> structbrace
+struct lbrace --> structbrace
+structbrace [ simp ] --> structbrace decl_head
+structbrace <force> decl --> structbrace
+structbrace <outdent-force> rbrace --> struct_head
+[ struct_head ] (math|simp) --> decl_head (math|simp)
+# N.b. K&R p. 123.
+# some people say e.g. struct blah {...}; is this K&R?
+struct_head semi --> decl
+struct [ simp (newline|ignore_scrap) ] --> struct simp
+struct simp --> decl_head
+decl_head <"\\"-space> struct --> struct
+
+# enumeration types are like structures and unions, but they have math
+# instead of many decls...
+enum simp* <"\\"-space> lbrace --> enumbrace
+enum lbrace --> enumbrace
+enumbrace math rbrace <outdent> --> enum_head
+[ enum_head ] simp --> decl_head simp
+enum_head semi --> decl
+enum [ simp (newline|ignore_scrap) ] --> enum simp
+enum simp --> decl_head
+decl_head <"\\"-space> enum --> enum
+
+typedef [ simp ] --> typedef decl_head
+typedef decl --> decl
+
+
+
+
+[ math* <indent> ] (lbrace|decl_head|decl) --> fn_decl (lbrace|decl_head|decl)
+[ (simp|decl_head) <"\\"-space> math* <indent> ] (lbrace|decl_head|decl) --> fn_decl (lbrace|decl_head|decl)
+fn_decl <force> decl --> fn_decl
+# The following statment will always have braces and never be tagged
+fn_decl <outdent-force> stmt --> function
+# include stmt here to cover module definition
+(stmt|decl|function) <big_force> function --> function
+function <big_force> decl --> decl
+
+(stmt|decl) <force> decl --> decl
+decl <big_force> stmt --> stmt
+decl <outdent-big_force> tagged_stmt --> stmt
+
+
+lbrace <outdent-force> rbrace --> stmt
+lbrace <force> stmt --> lbrace
+lbrace <outdent-force> tagged_stmt --> lbrace
+lbrace (math|simp) <outdent> rbrace --> math
+
+# if math can be followed by a brace, or no.
+# ifmath and ifbrace can have an attached else or else if clause
+# else, for, and while are formatted like if, but can't have an
+# attached else clause, so we use formath and forbrace
+
+if math --> ifmath
+ifmath <"\\"-space> lbrace --> ifbrace
+ifbrace <force> stmt --> ifbrace
+ifbrace <outdent-force> tagged_stmt --> ifbrace
+ifbrace [ rbrace (newline|ignore_scrap) ] --> ifbrace rbrace
+ifbrace rbrace [ else (newline|ignore_scrap) ] --> ifbrace rbrace else
+ifbrace <outdent-force> rbrace <"\\"-space> else if --> if
+ifbrace <outdent-force> rbrace <"\\"-space> else lbrace --> forbrace
+ifbrace <outdent-force> rbrace <"\\"-space> else --> formath
+ifbrace <outdent-force> rbrace --> stmt
+
+# Assume simple statements attached to if will never be tagged
+
+ifmath [ stmt (newline|ignore_scrap) ] --> ifmath stmt
+ifmath stmt [ else (newline|ignore_scrap) ] --> ifmath stmt else
+ifmath <indent-force> stmt <outdent-force> else if --> if
+ifmath <indent-force> stmt <outdent-force> else lbrace --> forbrace
+ifmath <indent-force> stmt <outdent-force> else --> formath
+ifmath <indent-force> stmt <outdent> --> stmt
+
+for math --> formath
+formath <"\\"-space> lbrace --> forbrace
+forbrace <force> stmt --> forbrace
+forbrace <outdent-force> tagged_stmt --> forbrace
+forbrace <outdent-force> rbrace --> stmt
+formath <indent-force> stmt <outdent> --> stmt
+
+# we need an extra indent for switch, becuase the cases will be backed out
+switch math lbrace <indent> --> switchbrace
+switchbrace <outdent-force> tagged_stmt --> switchbrace
+# This next should never happen
+switchbrace <force> stmt --> switchbrace
+switchbrace <outdent-outdent-force> rbrace --> stmt
+
+
+
+# handle do-while (while has category for)
+do lbrace --> dobrace
+dobrace <force> stmt --> dobrace
+dobrace <outdent-force> tagged_stmt --> dobrace
+dobrace rbrace for --> math
+do <indent-force> stmt <outdent-force> for --> math
+
+case semi --> stmt
+case math semi --> stmt
+case colon --> tag
+case math colon --> tag
+tag <force> tag --> tag
+tag <indent-force> stmt --> tagged_stmt
+
+stmt <force> stmt --> stmt
+stmt <outdent-force> tagged_stmt --> stmt
+semi --> stmt
+
+# control sequence \8 puts things on the left margin
+<force-"\\8"> sharp <"{\\let\\\\=\\bf"-space> (simp|if|else) <"}"-indent-"{}"-space> --> preproc
+preproc backslash <force-"\\8\\hskip1em"-space> newline --> preproc
+preproc <force-outdent> newline --> ignore_scrap
+preproc !(less|lesssimp|backslash|newline) --> preproc
+newline --> ignore_scrap
+
+less simp --> lesssimp
+lesssimp dot simp --> lesssimp
+<"\\LN"> lesssimp greater <"\\RN"> --> math
+<"<"> lesssimp --> unop
+less <"<"> --> binop
+greater <">"> --> binop
+dot --> binop
+
+macros begin
+\let\LN\langle
+\let\RN\rangle
+macros end
+
diff --git a/web/spiderweb/src/c/tangle.c b/web/spiderweb/src/c/tangle.c
new file mode 100644
index 0000000000..49add84999
--- /dev/null
+++ b/web/spiderweb/src/c/tangle.c
@@ -0,0 +1,2214 @@
+/*1:*/
+#line 44 "tangle.web"
+
+/*4:*/
+#line 15 "common.h"
+
+#line 16 "common.h"
+#include<stdio.h>
+
+/*:4*//*94:*/
+#line 1046 "tangle.web"
+
+#line 1047 "tangle.web"
+#include"ctype.h"
+
+/*:94*/
+#line 45 "tangle.web"
+
+/*3:*/
+#line 9 "common.h"
+
+typedef short boolean;
+typedef char unsigned eight_bits;
+extern boolean program;
+extern int phase;
+
+/*:3*//*5:*/
+#line 24 "common.h"
+
+typedef char ASCII;
+typedef char outer_char;
+extern ASCII xord[];
+extern outer_char xchr[];
+ASCII mod_text[400+1];
+ASCII *mod_text_end= mod_text+400;
+ASCII *id_first;
+ASCII *id_loc;
+
+/*:5*//*6:*/
+#line 37 "common.h"
+
+#line 38 "common.h"
+extern ASCII buffer[];
+extern ASCII *buffer_end;
+extern ASCII *loc;
+extern ASCII *limit;
+
+/*:6*//*7:*/
+#line 55 "common.h"
+
+typedef struct name_info{
+ASCII *byte_start;
+struct name_info *link;
+union{
+struct name_info *Rlink;
+
+eight_bits Ilk;
+
+}dummy;
+ASCII *equiv_or_xref;
+}name_info;
+typedef name_info *name_pointer;
+typedef name_pointer *hash_pointer;
+extern ASCII byte_mem[];
+extern ASCII *byte_mem_end;
+extern name_info name_dir[];
+extern name_pointer name_dir_end;
+extern name_pointer name_ptr;
+extern ASCII *byte_ptr;
+extern name_pointer hash[];
+extern hash_pointer hash_end;
+extern hash_pointer h;
+extern name_pointer id_lookup();
+extern name_pointer mod_lookup();
+extern name_pointer prefix_lookup();
+
+/*:7*//*8:*/
+#line 98 "common.h"
+
+extern history;
+
+/*:8*//*9:*/
+#line 109 "common.h"
+
+extern include_depth;
+extern FILE *file[];
+extern FILE *change_file;
+extern char C_file_name[];
+extern char tex_file_name[];
+extern char file_name[][60];
+
+extern char change_file_name[];
+extern line[];
+extern change_line;
+extern boolean input_has_ended;
+extern boolean changing;
+
+/*:9*//*10:*/
+#line 124 "common.h"
+
+#line 125 "common.h"
+typedef unsigned short sixteen_bits;
+extern sixteen_bits module_count;
+extern boolean changed_module[];
+extern boolean print_where;
+
+/*:10*//*11:*/
+#line 131 "common.h"
+
+#line 132 "common.h"
+extern int argc;
+extern char * *argv;
+extern no_xref;
+
+/*:11*//*12:*/
+#line 144 "common.h"
+
+FILE *C_file;
+FILE *tex_file;
+#line 81 "tangle.web"
+
+/*:12*/
+#line 46 "tangle.web"
+
+/*14:*/
+#line 107 "tangle.web"
+
+#line 108 "tangle.web"
+typedef struct{
+eight_bits *tok_start;
+sixteen_bits text_link;
+}text;
+typedef text *text_pointer;
+
+/*:14*//*25:*/
+#line 254 "tangle.web"
+
+typedef struct{
+eight_bits *end_field;
+eight_bits *byte_field;
+name_pointer name_field;
+text_pointer repl_field;
+sixteen_bits mod_field;
+}output_state;
+typedef output_state *stack_pointer;
+
+/*:25*/
+#line 47 "tangle.web"
+
+/*15:*/
+#line 114 "tangle.web"
+
+#line 115 "tangle.web"
+text text_info[2000];
+text_pointer text_info_end= text_info+2000-1;
+text_pointer text_ptr;
+eight_bits tok_mem[150000];
+eight_bits *tok_mem_end= tok_mem+150000-1;
+eight_bits *tok_ptr;
+
+/*:15*//*21:*/
+#line 185 "tangle.web"
+
+text_pointer last_unnamed;
+
+/*:21*//*26:*/
+#line 270 "tangle.web"
+
+output_state cur_state;
+
+output_state stack[50+1];
+stack_pointer stack_ptr;
+stack_pointer stack_end= stack+50;
+
+/*:26*//*37:*/
+#line 413 "tangle.web"
+
+int cur_val;
+
+
+/*:37*//*46:*/
+#line 520 "tangle.web"
+
+#line 521 "tangle.web"
+short balances[128];
+/*:46*//*50:*/
+#line 583 "tangle.web"
+
+#line 584 "tangle.web"
+name_pointer parm_ptr;
+
+/*:50*//*62:*/
+#line 706 "tangle.web"
+
+eight_bits out_state;
+boolean protect;
+
+/*:62*//*64:*/
+#line 735 "tangle.web"
+
+name_pointer output_files[256];
+name_pointer *cur_out_file, *end_output_files, *an_output_file;
+char cur_module_char;
+char output_file_name[400];
+
+/*:64*//*78:*/
+#line 143 "outtoks.web"
+char C_file_extension[]= "c";
+/*:78*//*80:*/
+#line 148 "outtoks.web"
+char the_at_sign= 64;
+
+/*:80*//*86:*/
+#line 943 "tangle.web"
+
+eight_bits ccode[128];
+
+/*:86*//*88:*/
+#line 975 "tangle.web"
+short tracing;
+#line 976 "tangle.web"
+/*:88*//*91:*/
+#line 1009 "tangle.web"
+
+#line 1010 "tangle.web"
+boolean comment_continues= 0;
+
+/*:91*//*93:*/
+#line 1043 "tangle.web"
+
+name_pointer cur_module;
+
+/*:93*//*108:*/
+#line 1310 "tangle.web"
+
+text_pointer cur_text;
+eight_bits next_control;
+
+/*:108*//*111:*/
+#line 1373 "tangle.web"
+
+ASCII param_name_texts[256];
+ASCII *param_name_texts_end= param_name_texts+256;
+ASCII *param_names[32];
+short next_param_name;
+ASCII *next_param_name_text;
+
+/*:111*//*132:*/
+#line 1693 "tangle.web"
+
+#line 1694 "tangle.web"
+extern sixteen_bits module_count;
+
+/*:132*/
+#line 48 "tangle.web"
+
+
+main(ac,av)
+char * *av;
+{
+argc= ac;argv= av;
+program= 0;
+/*16:*/
+#line 122 "tangle.web"
+
+#line 123 "tangle.web"
+text_info->tok_start= tok_ptr= tok_mem;
+text_ptr= text_info+1;text_ptr->tok_start= tok_mem;
+
+
+/*:16*//*18:*/
+#line 132 "tangle.web"
+
+name_dir->equiv_or_xref= (ASCII *)text_info;
+
+/*:18*//*22:*/
+#line 188 "tangle.web"
+last_unnamed= text_info;text_info->text_link= 0;
+#line 189 "tangle.web"
+
+/*:22*//*47:*/
+#line 522 "tangle.web"
+
+#line 523 "tangle.web"
+{int i;
+for(i= 0;i<128;i++)balances[i]= 0;
+/*48:*/
+#line 529 "tangle.web"
+
+#line 530 "tangle.web"
+balances[40]= 1;
+balances[41]= -1;
+balances[91]= 1;
+balances[93]= -1;
+balances[123]= 1;
+balances[125]= -1;
+
+/*:48*/
+#line 525 "tangle.web"
+;
+}
+/*:47*//*65:*/
+#line 745 "tangle.web"
+
+#line 746 "tangle.web"
+cur_out_file= end_output_files= output_files+256;
+
+/*:65*//*87:*/
+#line 946 "tangle.web"
+{
+#line 947 "tangle.web"
+int c;
+for(c= 0;c<=127;c++)ccode[c]= 0;
+ccode[' ']= ccode[011]= ccode['*']= 255;
+ccode['@']= '@';
+ccode['=']= 2;
+ccode['d']= ccode['D']= 252;
+ccode['f']= ccode['F']= 251;
+ccode['c']= ccode['C']= 253;
+ccode['u']= ccode['U']= 253;
+ccode['^']= ccode[':']= ccode['.']= ccode['t']= ccode['T']= 250;
+ccode['&']= 127;
+ccode['<']= ccode['(']= 254;
+ccode['`']= 249;
+ccode['\'']= 5;
+ccode['"']= 6;
+
+
+
+ccode['@']= ccode[64];
+ccode[64]= 64;
+
+#ifdef DEBUG
+ccode['0']= ccode['1']= ccode['2']= ccode['3']= ccode['4']= 248;
+#endif DEBUG
+
+}
+
+/*:87*//*89:*/
+#line 976 "tangle.web"
+tracing= 0;
+#line 977 "tangle.web"
+
+/*:89*//*104:*/
+#line 1239 "tangle.web"
+mod_text[0]= ' ';
+#line 1240 "tangle.web"
+
+/*:104*//*113:*/
+#line 1385 "tangle.web"
+/*112:*/
+#line 1380 "tangle.web"
+
+#line 1381 "tangle.web"
+next_param_name= 0;
+next_param_name_text= param_name_texts;
+param_names[next_param_name]= next_param_name_text;
+
+/*:112*/
+#line 1385 "tangle.web"
+;
+#line 1386 "tangle.web"
+
+/*:113*/
+#line 55 "tangle.web"
+;
+common_init();
+printf("This is C TANGLE (generated at 5:29 PM on April 5, 1993)\n");
+phase_one();
+phase_two();
+wrap_up();
+}
+
+/*:1*//*19:*/
+#line 138 "tangle.web"
+
+#line 139 "tangle.web"
+names_match(p,first,l)
+name_pointer p;
+ASCII *first;
+int l;
+{
+if(((p+1)->byte_start-(p)->byte_start)!=l)return 0;
+return!strncmp(first,p->byte_start,l);
+}
+
+/*:19*//*20:*/
+#line 149 "tangle.web"
+
+#line 150 "tangle.web"
+init_node(node)
+name_pointer node;
+{
+node->equiv_or_xref= (ASCII *)text_info;
+
+}
+init_p(p,t)
+name_pointer p;
+eight_bits t;
+{
+p->dummy.Ilk= t;
+}
+
+
+
+/*:20*//*24:*/
+#line 219 "tangle.web"
+store_two_bytes(x)
+sixteen_bits x;
+{
+if(tok_ptr+2>tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};};
+ *tok_ptr++= x>>8;
+ *tok_ptr++= x&255;
+}
+
+
+/*:24*//*28:*/
+#line 294 "tangle.web"
+push_level(p)
+#line 295 "tangle.web"
+name_pointer p;
+{
+/*29:*/
+#line 306 "tangle.web"
+
+#line 307 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>0){
+printf("\nPushing ");fflush(stdout),write(1,(p)->byte_start,(((p)+1)->byte_start-((p))->byte_start));
+printf(" =nd[%d]",p-name_dir);
+}
+#endif TRACE_MACROS
+
+/*:29*/
+#line 297 "tangle.web"
+;
+if(stack_ptr==stack_end){{printf("\n! Sorry, capacity exceeded: ");err_print("stack");history= 3;wrap_up();};};
+ *stack_ptr= cur_state;
+stack_ptr++;
+cur_state.name_field= p;cur_state.repl_field= (text_pointer)p->equiv_or_xref;
+cur_state.byte_field= cur_state.repl_field->tok_start;cur_state.end_field= (cur_state.repl_field+1)->tok_start;
+cur_state.mod_field= 0;
+}
+
+/*:28*//*30:*/
+#line 321 "tangle.web"
+pop_level()
+#line 322 "tangle.web"
+{int number_of_parameters;
+/*33:*/
+#line 363 "tangle.web"
+
+#line 364 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>0){
+printf("\nPopping ");fflush(stdout),write(1,(cur_state.name_field)->byte_start,(((cur_state.name_field)+1)->byte_start-((cur_state.name_field))->byte_start));
+printf(" =nd[%d]",cur_state.name_field-name_dir);
+}
+
+#endif TRACE_MACROS
+
+
+
+/*:33*/
+#line 323 "tangle.web"
+;
+if(cur_state.repl_field->text_link==0){
+if(cur_state.name_field->dummy.Ilk==1){
+/*31:*/
+#line 338 "tangle.web"
+
+#line 339 "tangle.web"
+number_of_parameters= *(cur_state.repl_field->tok_start);
+/*32:*/
+#line 357 "tangle.web"
+
+#line 358 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>1){
+printf("\nUnstacking %d parameters",number_of_parameters);
+}
+#endif TRACE_MACROS
+/*:32*/
+#line 340 "tangle.web"
+;
+while(number_of_parameters-->0){
+name_ptr--;text_ptr--;
+#ifdef TRACE_MACROS
+byte_ptr-= 2;
+#endif TRACE_MACROS
+}
+#ifdef STAT
+#ifdef STAT_HAS_BEEN_FIXED
+if(tok_ptr>max_tok_ptr)max_tok_ptr= tok_ptr;
+
+
+#endif STAT_HAS_BEEN_FIXED
+#endif STAT
+tok_ptr= text_ptr->tok_start;
+
+
+/*:31*/
+#line 326 "tangle.web"
+;
+}
+}else if(cur_state.repl_field->text_link<2000){
+cur_state.repl_field= cur_state.repl_field->text_link+text_info;
+cur_state.byte_field= cur_state.repl_field->tok_start;cur_state.end_field= (cur_state.repl_field+1)->tok_start;
+return;
+}
+stack_ptr--;
+if(stack_ptr>stack)cur_state= *stack_ptr;
+}
+
+
+/*:30*//*38:*/
+#line 418 "tangle.web"
+sixteen_bits
+#line 419 "tangle.web"
+ get_output()
+{
+sixteen_bits a;
+restart:if(stack_ptr==stack)return 0;
+if(cur_state.byte_field==cur_state.end_field){
+cur_val= -((int)cur_state.mod_field);
+pop_level();
+if(cur_val==0)goto restart;
+out_char(129);return;
+}
+a= *cur_state.byte_field++;
+if(a<128)
+if(a==7){
+/*40:*/
+#line 454 "tangle.web"
+
+#line 455 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2){
+printf(" [#%d]", *cur_state.byte_field);
+}
+#endif TRACE_MACROS
+
+/*:40*/
+#line 432 "tangle.web"
+;
+/*39:*/
+#line 452 "tangle.web"
+
+#line 453 "tangle.web"
+push_level(name_ptr- *cur_state.byte_field++);goto restart;
+/*:39*/
+#line 434 "tangle.web"
+;
+}else
+out_char(a);
+else{
+a= (a-128) *256+ *cur_state.byte_field++;
+switch(a/10240){
+case 0:
+/*41:*/
+#line 461 "tangle.web"
+
+#line 462 "tangle.web"
+if(name_dir[a].dummy.Ilk==1){
+/*42:*/
+#line 475 "tangle.web"
+
+#line 476 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2){
+printf("\nExpanding macro (");fflush(stdout),write(1,(name_dir+a)->byte_start,(((name_dir+a)+1)->byte_start-((name_dir+a))->byte_start));
+printf("=nd[%d])",a);
+}
+#endif TRACE_MACROS
+
+/*:42*/
+#line 463 "tangle.web"
+;
+/*44:*/
+#line 492 "tangle.web"
+
+#line 493 "tangle.web"
+{int number_of_parameters;
+while(cur_state.byte_field==cur_state.end_field&&stack_ptr>stack)pop_level();
+number_of_parameters= *(((text_pointer)name_dir[a].equiv_or_xref)->tok_start);
+if(number_of_parameters>0){
+if(stack_ptr==stack|| *cur_state.byte_field!=40){
+printf("\n! No parameters given for ");
+fflush(stdout),write(1,(a+name_dir)->byte_start,(((a+name_dir)+1)->byte_start-((a+name_dir))->byte_start));
+err_print("");
+goto restart;
+}
+cur_state.byte_field++;
+parm_ptr= name_ptr;
+while(number_of_parameters-->0){
+/*49:*/
+#line 537 "tangle.web"
+
+#line 538 "tangle.web"
+{int bal;
+eight_bits b,oldb;
+sixteen_bits c;
+bal= 0;
+/*59:*/
+#line 647 "tangle.web"
+
+#line 648 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2){
+printf("\nScanning #%d...",number_of_parameters+1);
+}
+#endif TRACE_MACROS
+/*:59*/
+#line 542 "tangle.web"
+;
+while(1){
+b= *cur_state.byte_field++;
+if(b==7){
+b= *cur_state.byte_field++;
+/*56:*/
+#line 613 "tangle.web"
+
+#line 614 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2){
+printf(" <#%d=",b);fflush(stdout),write(1,(name_ptr-b)->byte_start,(((name_ptr-b)+1)->byte_start-((name_ptr-b))->byte_start));printf("=nd[%d]>",
+name_ptr-b-name_dir);
+}
+#endif TRACE_MACROS
+
+/*:56*/
+#line 547 "tangle.web"
+;
+c= name_ptr-name_dir-b;
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= 128+(c/256);};
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= c%256;};
+}else{
+if(b>=128){
+/*57:*/
+#line 621 "tangle.web"
+
+#line 622 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2){
+int c;
+printf(" <");
+c= (b-128) *256+ *cur_state.byte_field;
+switch(c/10240){
+case 0:fflush(stdout),write(1,(name_dir+c)->byte_start,(((name_dir+c)+1)->byte_start-((name_dir+c))->byte_start));
+printf(" =nd[%d]",c);
+break;
+case 1:printf("MODULE");break;
+default:printf("CONTEXT");break;
+}
+printf(">");
+}
+#endif TRACE_MACROS
+
+/*:57*/
+#line 553 "tangle.web"
+;
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= b;};
+b= *cur_state.byte_field++;
+}else if(bal==0&&((number_of_parameters==0&&b==41)
+||(number_of_parameters>0&&b==44))){
+goto done;
+}else if(/*51:*/
+#line 586 "tangle.web"
+(b==2||b==3)
+#line 587 "tangle.web"
+/*:51*/
+#line 559 "tangle.web"
+){
+/*52:*/
+#line 587 "tangle.web"
+
+#line 588 "tangle.web"
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= b;};
+oldb= b;
+/*53:*/
+#line 601 "tangle.web"
+
+#line 602 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2)printf(" <");
+#endif TRACE_MACROS
+/*:53*/
+#line 590 "tangle.web"
+;
+while((b= *cur_state.byte_field++)!=oldb){
+/*54:*/
+#line 605 "tangle.web"
+
+#line 606 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2)printf("%c",b);
+#endif TRACE_MACROS
+/*:54*/
+#line 592 "tangle.web"
+;
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= b;};
+if(cur_state.byte_field>=cur_state.end_field)
+{printf("\n! This can't happen: ");err_print("string or constant didn't end in token list");history= 3;wrap_up();};
+}
+/*55:*/
+#line 609 "tangle.web"
+
+#line 610 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2)printf(">");
+#endif TRACE_MACROS
+/*:55*/
+#line 597 "tangle.web"
+;
+
+
+
+/*:52*/
+#line 560 "tangle.web"
+;
+}else{
+/*58:*/
+#line 638 "tangle.web"
+
+#line 639 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2){
+printf(" <");
+if(31<b&&b<127)printf("%c",b);
+printf(">");
+}
+#endif TRACE_MACROS
+
+/*:58*/
+#line 562 "tangle.web"
+;
+bal+= balances[b];
+}
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= b;};
+}
+}
+done:
+parm_ptr->equiv_or_xref= (ASCII *)text_ptr;
+text_ptr->text_link= 0;
+parm_ptr->dummy.Ilk= 2;
+#ifdef TRACE_MACROS
+if(byte_ptr+2>=byte_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("byte memory");history= 3;wrap_up();};};
+ *byte_ptr++= 35; *byte_ptr++= number_of_parameters+1+48;
+#endif TRACE_MACROS
+if(parm_ptr>=name_dir_end){{printf("\n! Sorry, capacity exceeded: ");err_print("name");history= 3;wrap_up();};};
+(++parm_ptr)->byte_start= byte_ptr;
+if(text_ptr>=text_info_end){{printf("\n! Sorry, capacity exceeded: ");err_print("text");history= 3;wrap_up();};};
+(++text_ptr)->tok_start= tok_ptr;
+/*60:*/
+#line 653 "tangle.web"
+
+#line 654 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>1){
+printf("\nStacked ");fflush(stdout),write(1,(parm_ptr-1)->byte_start,(((parm_ptr-1)+1)->byte_start-((parm_ptr-1))->byte_start));
+printf("=nd[%d]",parm_ptr-1-name_dir);
+}
+#endif TRACE_MACROS
+
+/*:60*/
+#line 580 "tangle.web"
+;
+}
+
+/*:49*/
+#line 507 "tangle.web"
+;
+}
+name_ptr= parm_ptr;
+
+}
+}
+
+/*:44*/
+#line 465 "tangle.web"
+;
+push_level(name_dir+a);
+cur_state.byte_field++;
+goto restart;
+}else if(name_dir[a].dummy.Ilk==2){
+/*43:*/
+#line 483 "tangle.web"
+
+#line 484 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2){
+printf("\nExpanding parameter (");fflush(stdout),write(1,(name_dir+a)->byte_start,(((name_dir+a)+1)->byte_start-((name_dir+a))->byte_start));
+printf("=nd[%d])",a);
+}
+#endif TRACE_MACROS
+
+
+/*:43*/
+#line 470 "tangle.web"
+;
+push_level(name_dir+a);
+goto restart;
+}
+
+/*:41*/
+#line 441 "tangle.web"
+;
+cur_val= a;out_char(130);break;
+case 1:/*61:*/
+#line 664 "tangle.web"
+
+#line 665 "tangle.web"
+a-= 10240;
+if((a+name_dir)->equiv_or_xref!=(ASCII *)text_info)push_level(a+name_dir);
+else if(a!=0){
+printf("\n! Not present: <");fflush(stdout),write(1,(a+name_dir)->byte_start,(((a+name_dir)+1)->byte_start-((a+name_dir))->byte_start));err_print(">");
+
+}
+goto restart;
+
+/*:61*/
+#line 443 "tangle.web"
+;
+default:cur_val= a-20480;if(cur_val>0)cur_state.mod_field= cur_val;
+out_char(129);
+}
+}
+return 1;
+}
+
+
+/*:38*//*63:*/
+#line 714 "tangle.web"
+flush_buffer()
+#line 715 "tangle.web"
+{
+putc('\n',C_file);
+if(line[include_depth]%100==0){
+printf(".");
+if(line[include_depth]%500==0)printf("%d",line[include_depth]);
+fflush(stdout);
+}
+line[include_depth]++;
+}
+
+/*:63*//*67:*/
+#line 764 "tangle.web"
+
+#line 765 "tangle.web"
+phase_two(){
+line[include_depth]= 1;
+if(text_info->text_link==0){
+if(end_output_files==cur_out_file){
+printf("\n! No program text was specified.");{if(history==0)history= 1;};
+
+}
+}else{
+printf("\nWriting the output files: (%s)",C_file_name);fflush(stdout);
+/*27:*/
+#line 283 "tangle.web"
+
+#line 284 "tangle.web"
+stack_ptr= stack+1;cur_state.name_field= name_dir;cur_state.repl_field= text_info->text_link+text_info;
+cur_state.byte_field= cur_state.repl_field->tok_start;cur_state.end_field= (cur_state.repl_field+1)->tok_start;cur_state.mod_field= 0;
+
+/*:27*/
+#line 774 "tangle.web"
+;
+while(stack_ptr>stack)get_output();
+flush_buffer();
+}
+if(end_output_files>cur_out_file){
+if(text_info->text_link==0){
+printf("\nWriting the output files: ");fflush(stdout);
+}
+/*68:*/
+#line 790 "tangle.web"
+
+#line 791 "tangle.web"
+for(an_output_file= end_output_files;an_output_file>cur_out_file;){
+an_output_file--;
+strncpy(output_file_name,( *an_output_file)->byte_start,400);
+output_file_name[(( *an_output_file+1)->byte_start-( *an_output_file)->byte_start)]= '\0';
+fclose(C_file);
+C_file= fopen(output_file_name,"w");
+if(C_file==NULL){
+{printf("! Cannot open output file:");err_print(output_file_name);history= 3;wrap_up();}
+}else{
+printf(" (%s)",output_file_name);fflush(stdout);
+}
+stack_ptr= stack+1;
+cur_state.name_field= ( *an_output_file);
+cur_state.repl_field= (text_pointer)cur_state.name_field->equiv_or_xref;
+cur_state.byte_field= cur_state.repl_field->tok_start;
+cur_state.end_field= (cur_state.repl_field+1)->tok_start;
+cur_state.mod_field= 0;
+while(stack_ptr>stack)get_output();
+flush_buffer();
+}
+
+
+
+/*:68*/
+#line 782 "tangle.web"
+
+}
+printf("\nDone.");
+}
+
+/*:67*//*69:*/
+#line 816 "tangle.web"
+out_char(cur_char)
+#line 817 "tangle.web"
+eight_bits cur_char;
+{
+ASCII *j;
+/*70:*/
+#line 841 "tangle.web"
+
+#line 842 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2){
+switch(cur_char){
+case 10:printf(" [\\n]");break;
+case 2:
+printf("[STRING]");break;
+case 127:
+printf("[JOIN]");break;
+case 3:
+printf("[CONSTANT]");break;
+case 130:
+printf(" [");fflush(stdout),write(1,(cur_val+name_dir)->byte_start,(((cur_val+name_dir)+1)->byte_start-((cur_val+name_dir))->byte_start));printf("]");
+break;
+case 129:
+if(cur_val>0){
+printf(" [%d:]",cur_val);
+}else if(cur_val<0){
+printf(" [:%d]",-cur_val);
+}else{
+printf("[LINE NUMBER]");
+}
+break;
+
+default:
+if(31<cur_char&&cur_char<127){
+printf(" [%c]",cur_char);
+}else{
+printf(" [\\%3o]",cur_char);
+}
+}
+}
+#endif TRACE_MACROS
+
+
+
+
+/*:70*/
+#line 820 "tangle.web"
+;
+switch(cur_char){
+case 10:if(protect)putc(' ',C_file);
+if(protect||out_state==4)putc('\\',C_file);
+
+flush_buffer();if(out_state!=4)out_state= 0;break;
+/*71:*/
+#line 878 "tangle.web"
+
+#line 879 "tangle.web"
+case 130:
+if(out_state==1)putc(' ',C_file);
+for(j= (cur_val+name_dir)->byte_start;j<(name_dir+cur_val+1)->byte_start;
+j++)putc( *j,C_file);
+out_state= 1;break;
+
+/*:71*/
+#line 826 "tangle.web"
+;
+/*72:*/
+#line 885 "tangle.web"
+
+#line 886 "tangle.web"
+case 129:
+if(cur_val>0){
+fprintf(C_file,"%s","/*");
+fprintf(C_file,"%d:",cur_val);
+fprintf(C_file,"%s","*/");
+}else if(cur_val<0){
+fprintf(C_file,"%s","/*");
+fprintf(C_file,":%d",-cur_val);
+fprintf(C_file,"%s","*/");
+}else{
+sixteen_bits a;
+a= 256 * *cur_state.byte_field++;
+a+= *cur_state.byte_field++;
+fprintf(C_file,"\n%s","#line");
+fprintf(C_file," %d \"",a);
+cur_val= *cur_state.byte_field++;
+cur_val= 256 *(cur_val-128)+ *cur_state.byte_field++;
+for(j= (cur_val+name_dir)->byte_start;j<(name_dir+cur_val+1)->byte_start;
+j++)putc( *j,C_file);
+fprintf(C_file,"\"%s\n",""
+#line 910 "tangle.web"
+);
+}
+break;
+
+#line 1 "outtoks.web"
+/*:72*/
+#line 827 "tangle.web"
+;
+/*75:*/
+#line 58 "outtoks.web"
+
+#line 59 "outtoks.web"
+case 26:
+fprintf(C_file,"%s","==");
+if(out_state!=4)out_state= 0;
+break;
+case 23:
+fprintf(C_file,"%s","->");
+if(out_state!=4)out_state= 0;
+break;
+case 25:
+fprintf(C_file,"%s","&&");
+if(out_state!=4)out_state= 0;
+break;
+case 24:
+fprintf(C_file,"%s","||");
+if(out_state!=4)out_state= 0;
+break;
+case 21:
+fprintf(C_file,"%s","<<");
+if(out_state!=4)out_state= 0;
+break;
+case 28:
+fprintf(C_file,"%s","<=");
+if(out_state!=4)out_state= 0;
+break;
+case 20:
+if(out_state==4){
+fprintf(C_file,"%s","===>");
+}else{
+fprintf(C_file,"%s"," ");
+}
+if(out_state!=4)out_state= 0;
+break;
+case 31:
+fprintf(C_file,"%s","++");
+if(out_state!=4)out_state= 0;
+break;
+case 27:
+fprintf(C_file,"%s",">=");
+if(out_state!=4)out_state= 0;
+break;
+case 22:
+fprintf(C_file,"%s",">>");
+if(out_state!=4)out_state= 0;
+break;
+case 29:
+fprintf(C_file,"%s","!=");
+if(out_state!=4)out_state= 0;
+break;
+case 30:
+fprintf(C_file,"%s","--");
+if(out_state!=4)out_state= 0;
+break;
+/*:75*//*76:*/
+#line 111 "outtoks.web"
+
+#line 112 "outtoks.web"
+case'=':
+if(out_state==4){
+fprintf(C_file,"%s","=");
+}else{
+fprintf(C_file,"%s","= ");
+}
+if(out_state!=4)out_state= 0;
+break;
+case'*':
+if(out_state==4){
+fprintf(C_file,"%s","*");
+}else{
+fprintf(C_file,"%s"," *");
+}
+if(out_state!=4)out_state= 0;
+break;
+/*:76*/
+#line 828 "tangle.web"
+
+case 127:out_state= 3;break;
+case 3:if(out_state==4){
+out_state= 1;break;
+}
+if(out_state==1)putc(' ',C_file);out_state= 4;break;
+case 2:if(out_state==4)out_state= 0;
+else out_state= 4;break;
+default:putc(cur_char,C_file);if(out_state!=4)out_state= 0;
+break;
+}
+}
+
+/*:69*//*90:*/
+#line 981 "tangle.web"
+eight_bits skip_ahead()
+#line 982 "tangle.web"
+{
+eight_bits c;
+while(1){
+if(loc>limit&&(get_line()==0))return(255);
+ *(limit+1)= 64;
+while( *loc!=64)loc++;
+if(loc<=limit){
+loc++;c= ccode[ *loc];
+#ifdef DEBUG
+if(c==248){
+tracing= *loc-48;c= 0;
+}
+#endif DEBUG
+loc++;
+if(c!=0|| *(loc-1)=='>')return(c);
+}
+}
+}
+
+/*:90*//*92:*/
+#line 1012 "tangle.web"
+
+#line 1013 "tangle.web"
+skip_comment()
+{
+ASCII c;
+if(0){
+get_line();
+return(comment_continues= 0);
+}else{
+while(1){
+if(loc>limit)
+if(get_line())return(comment_continues= 1);
+else{
+err_print("! Input ended in mid-comment");
+
+return(comment_continues= 0);
+}
+c= *(loc++);
+/*82:*/
+#line 163 "outtoks.web"
+
+{int len;len= strlen("*/");
+if(loc+len-1<=limit&&!strncmp(loc-1,"*/",len)){
+loc+= len-1;return(comment_continues= 0);}}
+/*:82*/
+#line 1029 "tangle.web"
+
+if(c==64){
+if(ccode[ *loc]==255){
+err_print("! Section name ended in mid-comment");loc--;
+
+return(comment_continues= 0);
+}
+else loc++;
+}
+}
+}
+}
+/*:92*//*95:*/
+#line 1052 "tangle.web"
+eight_bits get_next()
+#line 1053 "tangle.web"
+{
+eight_bits c;
+while(1){
+if(loc>limit){
+if(get_line()==0)return(255);
+else if(print_where){
+print_where= 0;
+/*125:*/
+#line 1586 "tangle.web"
+
+#line 1587 "tangle.web"
+store_two_bytes(53248);
+if(changing)id_first= change_file_name;
+else id_first= file_name[include_depth];
+id_loc= id_first+strlen(id_first);
+if(changing)store_two_bytes((sixteen_bits)change_line);
+else store_two_bytes((sixteen_bits)line[include_depth]);
+{int a= id_lookup(id_first,id_loc,0)-name_dir;{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= (a/256)+128;};
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a%256;};}
+
+/*:125*/
+#line 1060 "tangle.web"
+;
+}
+else return(10);
+}
+c= *loc;
+if(comment_continues){
+skip_comment();
+if(comment_continues||0)return(10);
+else continue;
+}
+/*81:*/
+#line 151 "outtoks.web"
+
+#line 152 "outtoks.web"
+{int len;len= strlen("/*");
+if(loc+len<=limit&&!strncmp(loc,"/*",len)){
+loc+= len;
+skip_comment();
+if(comment_continues||0)
+return('\n');
+else continue;
+}
+}
+/*:81*/
+#line 1070 "tangle.web"
+
+loc++;
+if(isdigit(c)||c=='\\'||c=='.')/*97:*/
+#line 1092 "tangle.web"
+{
+#line 1093 "tangle.web"
+id_first= loc-1;
+if( *id_first=='.'&&!isdigit( *loc))goto mistake;
+if( *id_first=='\\')while(isdigit( *loc))loc++;
+else{
+if( *id_first=='0'){
+if( *loc=='x'|| *loc=='X'){
+loc++;while(isxdigit( *loc))loc++;goto found;
+}
+}
+while(isdigit( *loc))loc++;
+if( *loc=='.'){
+loc++;
+while(isdigit( *loc))loc++;
+}
+if( *loc=='e'|| *loc=='E'){
+if( *++loc=='+'|| *loc=='-')loc++;
+while(isdigit( *loc))loc++;
+}
+}
+found:
+id_loc= loc;
+return(3);
+}
+
+/*:97*/
+#line 1072 "tangle.web"
+
+else if(isalpha(c)||c=='_'||c=='$')/*96:*/
+#line 1084 "tangle.web"
+{
+#line 1085 "tangle.web"
+id_first= --loc;
+while(isalpha( *++loc)||isdigit( *loc)|| *loc=='_');
+if( *loc=='$')while(isdigit( *++loc)|| *loc=='$');
+
+id_loc= loc;return(130);
+}
+
+/*:96*/
+#line 1073 "tangle.web"
+
+else if(c=='\''||c=='\"')/*98:*/
+#line 1122 "tangle.web"
+{
+#line 1123 "tangle.web"
+ASCII delim= c;
+
+
+if(delim=='\''&&(loc+1>=limit||
+( *loc!='\\'&& *loc!=64&&loc[1]!='\'')||
+( *loc=='\\'&&(loc+2>=limit||loc[2]!='\''))||
+( *loc==64&&
+(loc+2>=limit||loc[1]!=64||loc[2]!='\''))
+))goto mistake;
+id_first= mod_text+1;
+id_loc= mod_text; *++id_loc= delim;
+while(1){
+if(loc>=limit){
+if( *(limit-1)!='\\'){
+err_print("! String didn't end");loc= limit;break;
+
+}
+if(get_line()==0){
+err_print("! Input ended in middle of string");loc= buffer;break;
+
+}
+else if(++id_loc<=mod_text_end) *id_loc= 10;
+
+}
+if((c= *loc++)==delim){
+if(++id_loc<=mod_text_end) *id_loc= c;
+break;
+}
+if(c=='\\'){
+if(loc>=limit)continue;
+if(++id_loc<=mod_text_end) *id_loc= '\\';
+c= *loc++;
+}
+if(++id_loc<=mod_text_end) *id_loc= c;
+}
+if(id_loc>=mod_text_end){
+printf("\n! String too long: ");
+
+fflush(stdout),write(1,mod_text+1,25);
+printf("...");history= 2;
+}
+id_loc++;
+return(2);
+}
+
+/*:98*/
+#line 1074 "tangle.web"
+
+else if(c==64)/*99:*/
+#line 1171 "tangle.web"
+{
+#line 1172 "tangle.web"
+c= ccode[ *loc++];
+switch(c){
+case 0:continue;
+case 250:while((c= skip_ahead())==64);
+
+if( *(loc-1)!='>')err_print("! Improper @ within control text");
+
+continue;
+case 254:
+cur_module_char= *(loc-1);
+/*103:*/
+#line 1221 "tangle.web"
+{
+#line 1222 "tangle.web"
+ASCII *k;
+/*105:*/
+#line 1241 "tangle.web"
+
+#line 1242 "tangle.web"
+k= mod_text;
+while(1){
+if(loc>limit&&get_line()==0){
+err_print("! Input ended in section name");
+
+loc= buffer+1;break;
+}
+c= *loc;
+/*106:*/
+#line 1265 "tangle.web"
+
+#line 1266 "tangle.web"
+if(c==64){
+c= *(loc+1);
+if(c=='>'){
+loc+= 2;break;
+}
+if(ccode[c]==255){
+err_print("! Section name didn't end");break;
+
+}
+ *(++k)= 64;loc++;
+}
+
+/*:106*/
+#line 1250 "tangle.web"
+;
+loc++;if(k<mod_text_end)k++;
+if(c==' '||c==011){
+c= ' ';if( *(k-1)==' ')k--;
+}
+ *k= c;
+}
+if(k>=mod_text_end){
+printf("\n! Section name too long: ");
+
+fflush(stdout),write(1,mod_text+1,25);
+printf("...");{if(history==0)history= 1;};
+}
+if( *k==' '&&k>mod_text)k--;
+
+/*:105*/
+#line 1223 "tangle.web"
+;
+if(k-mod_text>3&&strncmp(k-2,"...",3)==0)cur_module= prefix_lookup(mod_text+1,k-3);
+else cur_module= mod_lookup(mod_text+1,k);
+if(cur_module_char=='('){
+/*66:*/
+#line 749 "tangle.web"
+
+#line 750 "tangle.web"
+{
+if(cur_out_file>output_files){
+for(an_output_file= cur_out_file;
+an_output_file<end_output_files;an_output_file++)
+if( *an_output_file==cur_module)break;
+if(an_output_file==end_output_files)
+ *--cur_out_file= cur_module;
+}else{
+{{printf("\n! Sorry, capacity exceeded: ");err_print("output files");history= 3;wrap_up();};};
+}
+}
+
+/*:66*/
+#line 1228 "tangle.web"
+
+}
+return(254);
+}
+
+/*:103*/
+#line 1182 "tangle.web"
+;
+case 2:/*107:*/
+#line 1283 "tangle.web"
+{
+#line 1284 "tangle.web"
+id_first= loc++; *(limit+1)= 64; *(limit+2)= '>';
+while( *loc!=64|| *(loc+1)!='>')loc++;
+if(loc>=limit)err_print("! Verbatim string didn't end");
+
+id_loc= loc;loc+= 2;
+return(2);
+}
+
+/*:107*/
+#line 1183 "tangle.web"
+;
+#ifdef DEBUG
+case 248:tracing= *(loc-1)-'0';continue;
+#endif DEBUG
+case 249:/*100:*/
+#line 1194 "tangle.web"
+
+#line 1195 "tangle.web"
+id_first= loc;
+if( *loc=='\\')loc++;
+while( *loc!='\''){
+loc++;
+if(loc>limit){
+err_print("! String didn't end");loc= limit-1;break;
+}
+}
+loc++;
+return(249);
+
+/*:100*/
+#line 1187 "tangle.web"
+;
+case 5:/*101:*/
+#line 1206 "tangle.web"
+{
+#line 1207 "tangle.web"
+id_first= loc;
+while('0'<= *loc&& *loc<'8')loc++;
+id_loc= loc;
+return(5);
+}
+
+/*:101*/
+#line 1188 "tangle.web"
+;
+case 6:/*102:*/
+#line 1213 "tangle.web"
+{
+#line 1214 "tangle.web"
+id_first= loc;
+while(isxdigit( *loc))loc++;
+id_loc= loc;
+return(6);
+}
+
+
+/*:102*/
+#line 1189 "tangle.web"
+;
+default:return(c);
+}
+}
+
+/*:99*/
+#line 1075 "tangle.web"
+
+else if(c==' '||c==011){
+continue;
+}
+mistake:/*74:*/
+#line 3 "outtoks.web"
+
+#line 4 "outtoks.web"
+if(loc+3<=limit){
+if(strncmp("===>",loc-1,4)==0){
+loc+= 3;
+return 20;
+}
+}
+if(loc+2<=limit){
+}
+if(loc+1<=limit){
+if(strncmp("==",loc-1,2)==0){
+loc+= 1;
+return 26;
+}
+else if(strncmp("->",loc-1,2)==0){
+loc+= 1;
+return 23;
+}
+else if(strncmp("&&",loc-1,2)==0){
+loc+= 1;
+return 25;
+}
+else if(strncmp("||",loc-1,2)==0){
+loc+= 1;
+return 24;
+}
+else if(strncmp("<<",loc-1,2)==0){
+loc+= 1;
+return 21;
+}
+else if(strncmp("<=",loc-1,2)==0){
+loc+= 1;
+return 28;
+}
+else if(strncmp("++",loc-1,2)==0){
+loc+= 1;
+return 31;
+}
+else if(strncmp(">=",loc-1,2)==0){
+loc+= 1;
+return 27;
+}
+else if(strncmp(">>",loc-1,2)==0){
+loc+= 1;
+return 22;
+}
+else if(strncmp("!=",loc-1,2)==0){
+loc+= 1;
+return 29;
+}
+else if(strncmp("--",loc-1,2)==0){
+loc+= 1;
+return 30;
+}
+}
+/*:74*/
+#line 1079 "tangle.web"
+
+return(c);
+}
+}
+
+/*:95*//*109:*/
+#line 1314 "tangle.web"
+scan_repl(t)
+#line 1315 "tangle.web"
+eight_bits t;
+{
+sixteen_bits a;
+int set_print_where;
+if(t==254){/*125:*/
+#line 1586 "tangle.web"
+
+#line 1587 "tangle.web"
+store_two_bytes(53248);
+if(changing)id_first= change_file_name;
+else id_first= file_name[include_depth];
+id_loc= id_first+strlen(id_first);
+if(changing)store_two_bytes((sixteen_bits)change_line);
+else store_two_bytes((sixteen_bits)line[include_depth]);
+{int a= id_lookup(id_first,id_loc,0)-name_dir;{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= (a/256)+128;};
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a%256;};}
+
+/*:125*/
+#line 1319 "tangle.web"
+;}
+
+
+while(1){
+if(t==1){
+print_where= 0;
+}
+a= get_next();
+if(t==1){
+set_print_where= print_where;
+}
+switch(a){
+/*124:*/
+#line 1529 "tangle.web"
+
+#line 1530 "tangle.web"
+case 130:
+{short n;
+if((n= parameter_number(id_first,id_loc))!=0){
+#ifdef TRACE_MACROS
+if(tracing>1){
+printf("\nIdentified ");fflush(stdout),write(1,id_first,id_loc-id_first);
+printf(" as parameter number %d (%d from back)",n,next_param_name-n+1);
+}
+#endif TRACE_MACROS
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= 7;};
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= next_param_name-n+1;};
+}else{
+a= id_lookup(id_first,id_loc,0)-name_dir;
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= (a/256)+128;};{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a%256;};
+}
+}
+break;
+case 254:if(t!=254)goto done;
+else{
+/*126:*/
+#line 1596 "tangle.web"
+{
+#line 1597 "tangle.web"
+ASCII *try_loc= loc;
+while( *try_loc==' '&&try_loc<limit)try_loc++;
+if( *try_loc=='+'&&try_loc<limit)try_loc++;
+while( *try_loc==' '&&try_loc<limit)try_loc++;
+if( *try_loc=='=')err_print("! Nested named modules. Missing @?");
+
+}
+
+/*:126*/
+#line 1549 "tangle.web"
+;
+a= cur_module-name_dir;
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= (a/256)+168;};
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a%256;};
+/*125:*/
+#line 1586 "tangle.web"
+
+#line 1587 "tangle.web"
+store_two_bytes(53248);
+if(changing)id_first= change_file_name;
+else id_first= file_name[include_depth];
+id_loc= id_first+strlen(id_first);
+if(changing)store_two_bytes((sixteen_bits)change_line);
+else store_two_bytes((sixteen_bits)line[include_depth]);
+{int a= id_lookup(id_first,id_loc,0)-name_dir;{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= (a/256)+128;};
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a%256;};}
+
+/*:125*/
+#line 1553 "tangle.web"
+;break;
+}
+case 3:case 2:
+/*127:*/
+#line 1605 "tangle.web"
+
+#line 1606 "tangle.web"
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a;};
+while(id_first<id_loc){
+if( *id_first==64)id_first++;
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= *id_first++;};
+}
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a;};break;
+
+/*:127*/
+#line 1556 "tangle.web"
+;
+case 249:
+/*128:*/
+#line 1613 "tangle.web"
+{
+#line 1614 "tangle.web"
+int c;
+if( *id_first==64){
+c= xchr[ *id_first++];
+if( *id_first!=64)err_print("! Double @ within string");
+}
+else if( *id_first=='\\'){
+id_first++;
+switch( *id_first){
+case't':c= 9;break;
+case'n':c= 10;break;
+case'b':c= 8;break;
+case'0':c= 0;break;
+case'\\':c= 92;break;
+default:err_print("! Unrecognized escape sequence");
+}
+}
+else c= xchr[ *id_first];
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= 3;};
+
+
+app_decimal((long)c);
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= 3;};
+}
+break;
+
+/*:128*/
+#line 1558 "tangle.web"
+;
+case 5:
+/*129:*/
+#line 1640 "tangle.web"
+{
+#line 1641 "tangle.web"
+long sum= 0;
+while(id_first<id_loc){
+sum= 8 *sum+ *id_first++-'0';
+if(sum>67108864)err_print("! Octal constant exceeds @\"04000000");
+}
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= 3;};
+app_decimal(sum);
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= 3;};
+}
+
+/*:129*/
+#line 1560 "tangle.web"
+;break;
+case 6:
+/*130:*/
+#line 1651 "tangle.web"
+{
+#line 1652 "tangle.web"
+long sum= 0;
+while(id_first<id_loc){
+sum= 16 *sum+
+(isdigit( *id_first)
+? *id_first-'0'
+:isupper( *id_first)
+? *id_first-'A'+10
+: *id_first-'a'+10
+);
+id_first++;
+if(sum>67108864)err_print("! Hex constant exceeds @\"04000000");
+}
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= 3;};
+app_decimal(sum);
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= 3;};
+}
+
+/*:130*/
+#line 1562 "tangle.web"
+;break;
+case 10:
+#ifdef NEWLINES_IN_MACROS
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a;};
+#else
+if(t==1)continue;
+else{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a;};
+#endif NEWLINES_IN_MACROS
+break;
+case 252:case 251:case 253:
+if(t!=254)goto done;
+else{
+err_print("! @d, @f and @u are ignored in C text");continue;
+
+}
+case 255:goto done;
+
+/*:124*/
+#line 1334 "tangle.web"
+
+default:{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= a;};
+}
+}
+done:next_control= (eight_bits)a;
+if(text_ptr>text_info_end){{printf("\n! Sorry, capacity exceeded: ");err_print("text");history= 3;wrap_up();};};
+if(t==1){
+/*110:*/
+#line 1358 "tangle.web"
+
+#line 1359 "tangle.web"
+tok_ptr-= 2;
+while( *tok_ptr<128&& *(tok_ptr+1)==10)tok_ptr--;
+tok_ptr+= 2;
+
+/*:110*/
+#line 1341 "tangle.web"
+;
+}
+cur_text= text_ptr;(++text_ptr)->tok_start= tok_ptr;
+print_where= set_print_where;
+}
+
+/*:109*//*116:*/
+#line 1408 "tangle.web"
+
+#line 1409 "tangle.web"
+int parameter_number(first,loc)
+ASCII *first, *loc;
+{
+ASCII *f, *p;
+int n;
+for(n= 0;n<next_param_name;n++){
+if(loc-first==param_names[n+1]-param_names[n]){
+
+for(f= first,p= param_names[n];f<loc;)
+if( *f++!= *p++)goto nomatch;
+return n+1;
+}
+nomatch:continue;
+}
+return 0;
+}
+
+
+/*:116*//*131:*/
+#line 1670 "tangle.web"
+
+#line 1671 "tangle.web"
+app_decimal(c)
+long c;
+{long power;
+if(c==0){{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= '0';};return;}
+if(c<0){{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= '-';};c= -c;}
+for(power= 1;c>=power;power *= 10);
+
+for(power/= 10;power>=1;power/= 10){
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= '0'+c/power;};
+c%= power;
+
+}
+}
+
+
+
+/*:131*//*133:*/
+#line 1697 "tangle.web"
+scan_module()
+#line 1698 "tangle.web"
+{
+name_pointer p;
+text_pointer q;
+sixteen_bits a;
+module_count++;
+if( *(loc-1)=='*')
+printf("*%d",module_count);fflush(stdout);
+/*134:*/
+#line 1714 "tangle.web"
+
+next_control= 0;
+while(1){
+done_scanning:
+while(next_control<=251)
+if((next_control= skip_ahead())==254){
+
+loc-= 2;next_control= get_next();
+}
+if(next_control!=252)break;
+/*117:*/
+#line 1433 "tangle.web"
+
+#line 1434 "tangle.web"
+/*123:*/
+#line 1521 "tangle.web"
+
+#line 1522 "tangle.web"
+while((next_control= get_next())==10);
+
+/*:123*/
+#line 1434 "tangle.web"
+
+/*121:*/
+#line 1484 "tangle.web"
+
+#line 1485 "tangle.web"
+if(next_control!=130){
+err_print("! Macro name must be an identifier");
+
+/*135:*/
+#line 1732 "tangle.web"
+
+#line 1733 "tangle.web"
+/*112:*/
+#line 1380 "tangle.web"
+
+#line 1381 "tangle.web"
+next_param_name= 0;
+next_param_name_text= param_name_texts;
+param_names[next_param_name]= next_param_name_text;
+
+/*:112*/
+#line 1733 "tangle.web"
+;
+p->dummy.Ilk= 0;
+goto done_scanning;
+
+
+/*:135*/
+#line 1488 "tangle.web"
+;
+}else{
+p= id_lookup(id_first,id_loc,1);
+if(p->dummy.Ilk!=1){
+#ifdef WARN_USE_BEFORE_DEF
+printf("\n! Warning: macro name ");
+fflush(stdout),write(1,(p)->byte_start,(((p)+1)->byte_start-((p))->byte_start));
+printf(" was used before it was defined");
+{if(history==0)history= 1;};
+#endif WARN_USE_BEFORE_DEF
+p->dummy.Ilk= 1;
+}else if(p+1!=name_ptr){
+err_print("! Macro name is multiply defined: ");
+}
+}
+
+/*:121*/
+#line 1436 "tangle.web"
+;
+/*120:*/
+#line 1469 "tangle.web"
+
+#line 1470 "tangle.web"
+/*123:*/
+#line 1521 "tangle.web"
+
+#line 1522 "tangle.web"
+while((next_control= get_next())==10);
+
+/*:123*/
+#line 1470 "tangle.web"
+
+if(next_control==40){
+do{
+/*122:*/
+#line 1504 "tangle.web"
+
+#line 1505 "tangle.web"
+/*123:*/
+#line 1521 "tangle.web"
+
+#line 1522 "tangle.web"
+while((next_control= get_next())==10);
+
+/*:123*/
+#line 1505 "tangle.web"
+;
+if(next_control!=130){
+err_print("! Macro parameter name not an identifier");
+
+/*135:*/
+#line 1732 "tangle.web"
+
+#line 1733 "tangle.web"
+/*112:*/
+#line 1380 "tangle.web"
+
+#line 1381 "tangle.web"
+next_param_name= 0;
+next_param_name_text= param_name_texts;
+param_names[next_param_name]= next_param_name_text;
+
+/*:112*/
+#line 1733 "tangle.web"
+;
+p->dummy.Ilk= 0;
+goto done_scanning;
+
+
+/*:135*/
+#line 1509 "tangle.web"
+;
+}else{
+if(parameter_number(id_first,id_loc)!=0){
+err_print("! Duplicate parameters in macro definition");
+
+/*135:*/
+#line 1732 "tangle.web"
+
+#line 1733 "tangle.web"
+/*112:*/
+#line 1380 "tangle.web"
+
+#line 1381 "tangle.web"
+next_param_name= 0;
+next_param_name_text= param_name_texts;
+param_names[next_param_name]= next_param_name_text;
+
+/*:112*/
+#line 1733 "tangle.web"
+;
+p->dummy.Ilk= 0;
+goto done_scanning;
+
+
+/*:135*/
+#line 1514 "tangle.web"
+;
+}else{
+/*114:*/
+#line 1387 "tangle.web"
+
+#line 1388 "tangle.web"
+/*115:*/
+#line 1393 "tangle.web"
+
+#line 1394 "tangle.web"
+if(next_param_name==32)
+{{printf("\n! Sorry, capacity exceeded: ");err_print("parameter names");history= 3;wrap_up();};};
+if(id_loc-id_first>
+param_name_texts_end-next_param_name_text)
+{{printf("\n! Sorry, capacity exceeded: ");err_print("parameter name texts");history= 3;wrap_up();};};
+
+
+/*:115*/
+#line 1388 "tangle.web"
+;
+while(id_first<id_loc)
+ *next_param_name_text++= *id_first++;
+param_names[++next_param_name]= next_param_name_text;
+
+/*:114*/
+#line 1516 "tangle.web"
+;
+}
+}
+
+
+/*:122*/
+#line 1473 "tangle.web"
+;
+/*123:*/
+#line 1521 "tangle.web"
+
+#line 1522 "tangle.web"
+while((next_control= get_next())==10);
+
+/*:123*/
+#line 1474 "tangle.web"
+
+}while(next_control==44);
+if(next_control!=41){
+err_print("! Macro parameter list must end with )");
+/*135:*/
+#line 1732 "tangle.web"
+
+#line 1733 "tangle.web"
+/*112:*/
+#line 1380 "tangle.web"
+
+#line 1381 "tangle.web"
+next_param_name= 0;
+next_param_name_text= param_name_texts;
+param_names[next_param_name]= next_param_name_text;
+
+/*:112*/
+#line 1733 "tangle.web"
+;
+p->dummy.Ilk= 0;
+goto done_scanning;
+
+
+/*:135*/
+#line 1478 "tangle.web"
+;
+}
+next_control= get_next();
+}
+
+
+/*:120*/
+#line 1439 "tangle.web"
+;
+if(next_control!=61){
+err_print("! You must put an = sign before the macro replacement text");
+/*135:*/
+#line 1732 "tangle.web"
+
+#line 1733 "tangle.web"
+/*112:*/
+#line 1380 "tangle.web"
+
+#line 1381 "tangle.web"
+next_param_name= 0;
+next_param_name_text= param_name_texts;
+param_names[next_param_name]= next_param_name_text;
+
+/*:112*/
+#line 1733 "tangle.web"
+;
+p->dummy.Ilk= 0;
+goto done_scanning;
+
+
+/*:135*/
+#line 1442 "tangle.web"
+;
+}
+/*118:*/
+#line 1451 "tangle.web"
+
+#line 1452 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>1){
+printf("\nScanning definition of macro ");fflush(stdout),write(1,(p)->byte_start,(((p)+1)->byte_start-((p))->byte_start));
+}
+#endif TRACE_MACROS
+
+/*:118*/
+#line 1444 "tangle.web"
+;
+{if(tok_ptr==tok_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("token");history= 3;wrap_up();};}; *tok_ptr++= next_param_name;};
+scan_repl(1);
+p->equiv_or_xref= (ASCII *)cur_text;
+/*119:*/
+#line 1458 "tangle.web"
+
+#line 1459 "tangle.web"
+#ifdef TRACE_MACROS
+if(tracing>2){
+printf("\nMacro ");fflush(stdout),write(1,(p)->byte_start,(((p)+1)->byte_start-((p))->byte_start));
+printf("'s replacement text is in text_info[%d]",cur_text-text_info);
+}
+#endif TRACE_MACROS
+
+
+/*:119*/
+#line 1448 "tangle.web"
+;
+/*112:*/
+#line 1380 "tangle.web"
+
+#line 1381 "tangle.web"
+next_param_name= 0;
+next_param_name_text= param_name_texts;
+param_names[next_param_name]= next_param_name_text;
+
+/*:112*/
+#line 1449 "tangle.web"
+;
+
+/*:117*/
+#line 1724 "tangle.web"
+;
+cur_text->text_link= 0;
+}
+
+/*:134*/
+#line 1705 "tangle.web"
+;
+/*136:*/
+#line 1738 "tangle.web"
+
+#line 1739 "tangle.web"
+switch(next_control){
+case 253:p= name_dir;break;
+case 254:p= cur_module;
+/*137:*/
+#line 1750 "tangle.web"
+
+#line 1751 "tangle.web"
+while((next_control= get_next())=='+');
+if(next_control!='='){
+err_print("! C text flushed, = sign is missing");
+
+while((next_control= skip_ahead())!=255);
+return;
+}
+
+/*:137*/
+#line 1742 "tangle.web"
+;
+break;
+default:return;
+}
+/*138:*/
+#line 1759 "tangle.web"
+
+#line 1760 "tangle.web"
+store_two_bytes((sixteen_bits)(53248+module_count));
+
+/*:138*/
+#line 1746 "tangle.web"
+;
+scan_repl(254);
+/*139:*/
+#line 1762 "tangle.web"
+
+#line 1763 "tangle.web"
+if(p==name_dir||p==0){
+(last_unnamed)->text_link= cur_text-text_info;last_unnamed= cur_text;
+}
+else if(p->equiv_or_xref==(ASCII *)text_info)p->equiv_or_xref= (ASCII *)cur_text;
+
+else{
+q= (text_pointer)p->equiv_or_xref;
+while(q->text_link<2000)q= q->text_link+text_info;
+q->text_link= cur_text-text_info;
+}
+cur_text->text_link= 2000;
+
+/*:139*/
+#line 1748 "tangle.web"
+;
+
+/*:136*/
+#line 1706 "tangle.web"
+;
+}
+
+/*:133*//*140:*/
+#line 1775 "tangle.web"
+phase_one(){
+#line 1776 "tangle.web"
+phase= 1;
+module_count= 0;
+reset_input();
+while((next_control= skip_ahead())!=255);
+while(!input_has_ended)scan_module();
+check_complete();
+phase= 2;
+}
+
+/*:140*//*141:*/
+#line 1785 "tangle.web"
+print_stats(){
+#line 1786 "tangle.web"
+printf("\nMemory usage statistics:\n");
+printf("%d names (out of %d)\n",name_ptr-name_dir,4000);
+printf("%d replacement texts (out of %d)\n",text_ptr-text_info,2000);
+printf("%d bytes (out of %d)\n",byte_ptr-byte_mem,90000);
+printf("%d tokens (out of %d)\n",tok_ptr-tok_mem,150000);
+}
+
+/*:141*/
diff --git a/web/spiderweb/src/concrete-kernel.diff b/web/spiderweb/src/concrete-kernel.diff
new file mode 100644
index 0000000000..eb3929b55d
--- /dev/null
+++ b/web/spiderweb/src/concrete-kernel.diff
@@ -0,0 +1,200 @@
+From stevea@vast.unsw.edu.au Sun Jul 26 20:36:46 1992
+Received: from Princeton.EDU by fs.Princeton.EDU (4.1/1.105)
+ id AA27727; Sun, 26 Jul 92 20:36:44 EDT
+Received: from conch.vast.unsw.edu.au by Princeton.EDU (5.65b/2.93/princeton)
+ id AA14011; Sun, 26 Jul 92 20:36:35 -0400
+Received: from mucket.vast.unsw.edu.au by conch.vast.unsw.edu.au (5.65/1.2)
+ id AA10447; Mon, 27 Jul 92 10:36:25 +1000
+Received: by mucket.vast.unsw.edu.au (5.65/client-1.3)
+ id AA20338; Mon, 27 Jul 92 10:36:24 +1000
+Message-Id: <9207270036.AA20338@mucket.vast.unsw.edu.au>
+To: Norman Ramsey <nr@Princeton.EDU>
+Cc: stevea@vast.unsw.edu.au
+Subject: Re: Minor annoyance in ceeweave...
+In-Reply-To: Your message of "Fri, 24 Jul 92 14:12:49 -0400."
+ <9207241812.AA09444@cs.Princeton.EDU>
+Date: Mon, 27 Jul 92 10:36:23 +1000
+From: stevea@vast.unsw.edu.au
+Status: R
+
+Hi Norman,
+ As requested, here are the diffs. I'd love to try and work the
+NFSS in, but I think that requires LaTeX. Oh well....
+ I've also tacked on the ccbx10 diffs with ccr10. This is a major
+kludge, and I don't recommend using it at anything higher than
+\magstep2.
+
+ Hope they're useful.
+
+ cheers
+ -steve
+
+--------------------<webkernel.tex diffs>---------------------
+19,34c19,22
+< %%
+< %% This has all been modified to utilise the concrete font set created
+< %% by Knuth. The font ccbx10 is a kludged together version of a bold
+< %% face conrete font, which really is bad, but usable at the
+< %% resolutions required (never use this font at high magnification if
+< %% you wish to retain your presentation!). Its probably all a bit of
+< %% overkill, but the definition of many of the \fam's is necessary due
+< %% to the use of \bf etc, in math mode. Many of the script and
+< %% scriptscript fonts will never be used, but it doesn't hurt to be
+< %% sure.
+< %% Any bugs, suggestions, etc, would be welcome.
+< %%
+< %% Steve Avery <stevea@vast.unsw.edu.au> July 27 1992
+< %%
+<
+< \font\titlefont=ccr7 scaled\magstep4 % title on the contents page
+---
+> \font\eightrm=cmr8
+> \font\sc=cmcsc10
+> \let\mainfont=\tenrm
+> \font\titlefont=cmr7 scaled\magstep4 % title on the contents page
+37,68d24
+<
+< \font\tenrm=ccr10 \font\eightrm = ccr8
+< \font\sevenrm = ccr7
+< \font\fiverm = ccr5
+< \font\tentt=cmtt10 \font\seventt = cmtt10 at 7pt
+< \font\fivett = cmtt10 at 5pt
+< \font\tensc=cccsc10 \font\sevensc = cccsc10 at 7pt
+< \font\fivesc = cccsc10 at 5pt
+< \font\tenit=ccmi10 \font\sevenit = ccmi10 at 7pt % Using ccti mixes
+< \font\fiveit = ccmi10 at 5pt % up : and .
+< \font\tensl=ccsl10 \font\sevensl = ccsl10 at 7pt
+< \font\fivesl = ccsl10 at 5pt
+< \font\tenbf=ccbx10 \font\sevenbf = ccbx10 at 7pt
+< \font\fivebf = ccbx10 at 5pt
+<
+< \newfam\itfam \def\it{\fam\itfam\tenit} \textfont\itfam = \tenit
+< \scriptfont\itfam = \sevenit
+< \scriptscriptfont\itfam = \fiveit
+< \newfam\slfam \def\sl{\fam\slfam\tensl} \textfont\slfam = \tensl
+< \scriptfont\slfam = \sevensl
+< \scriptscriptfont\slfam = \fivesl
+< \newfam\bffam \def\bf{\fam\bffam\tenbf} \textfont\bffam = \tenbf
+< \scriptfont\bffam = \sevenbf
+< \scriptscriptfont\bffam = \fivebf
+<
+< \def\rm{\fam0 \tenrm} \textfont0=\tenrm
+< \scriptfont0=\sevenrm
+< \scriptscriptfont0=\fiverm
+< \def\it{\fam1 \tenit} \textfont1=\tenit
+< \scriptfont0=\sevenit
+< \scriptscriptfont0=\fiveit
+<
+70,71d25
+< \let\sc\tensc
+< \let\mainfont=\tenrm
+430d383
+< \mainfont
+
+----------------<diffs between ccr10.mf and ccbx10.mf>-------------
+4c4
+< font_identifier:="CCR"; font_size 10pt#;
+---
+> font_identifier:="CCRBX"; font_size 10pt#;
+6,7c6,7
+< u#:=20/36pt#; % unit width
+< width_adj#:=0pt#; % width adjustment for certain characters
+---
+> u#:=23/36pt#; % unit width
+> width_adj#:=11/36pt#; % width adjustment for certain characters
+9c9
+< cap_serif_fit#:=3/36pt#; % extra sidebar near uppercase serifs
+---
+> cap_serif_fit#:=5/36pt#; % extra sidebar near uppercase serifs
+14c14
+< cap_height#:=246/36pt#; % height of caps
+---
+> cap_height#:=247/36pt#; % height of caps
+16c16
+< x_height#:=165/36pt#; % height of lowercase without ascenders
+---
+> x_height#:=170/36pt#; % height of lowercase without ascenders
+18c18
+< bar_height#:=92/36pt#; % height of crossbar in lowercase e
+---
+> bar_height#:=90/36pt#; % height of crossbar in lowercase e
+23,24c23,24
+< tiny#:=11/36pt#; % diameter of rounded corners
+< fine#:=6/36pt#; % diameter of sharply rounded corners
+---
+> tiny#:=17/36pt#; % diameter of rounded corners
+> fine#:=9/36pt#; % diameter of sharply rounded corners
+26,36c26,36
+< hair#:=21/36pt#; % lowercase hairline breadth
+< stem#:=25/36pt#; % lowercase stem breadth
+< curve#:=27/36pt#; % lowercase curve breadth
+< ess#:=25/36pt#; % breadth in middle of lowercase s
+< flare#:=29/36pt#; % diameter of bulbs or breadth of terminals
+< dot_size#:=38/36pt#; % diameter of dots
+< cap_hair#:=21/36pt#; % uppercase hairline breadth
+< cap_stem#:=27/36pt#; % uppercase stem breadth
+< cap_curve#:=28/36pt#; % uppercase curve breadth
+< cap_ess#:=27/36pt#; % breadth in middle of uppercase s
+< rule_thickness#:=.4pt#; % thickness of lines in math symbols
+---
+> hair#:=40/36pt#; % lowercase hairline breadth
+> stem#:=41/36pt#; % lowercase stem breadth
+> curve#:=41/36pt#; % lowercase curve breadth
+> ess#:=33/36pt#; % breadth in middle of lowercase s
+> flare#:=43/36pt#; % diameter of bulbs or breadth of terminals
+> dot_size#:=56/36pt#; % diameter of dots
+> cap_hair#:=36/36pt#; % uppercase hairline breadth
+> cap_stem#:=48/36pt#; % uppercase stem breadth
+> cap_curve#:=49/36pt#; % uppercase curve breadth
+> cap_ess#:=40/36pt#; % breadth in middle of uppercase s
+> rule_thickness#:=.6pt#; % thickness of lines in math symbols
+39,42c39,42
+< bracket#:=5/36pt#; % vertical distance from serif base to tangent
+< jut#:=30/36pt#; % protrusion of lowercase serifs
+< cap_jut#:=32/36pt#; % protrusion of uppercase serifs
+< beak_jut#:=10/36pt#; % horizontal protrusion of beak serifs
+---
+> bracket#:=3/36pt#; % vertical distance from serif base to tangent
+> jut#:=27/36pt#; % protrusion of lowercase serifs
+> cap_jut#:=34/36pt#; % protrusion of uppercase serifs
+> beak_jut#:=11/36pt#; % horizontal protrusion of beak serifs
+44c44
+< vair#:=21/36pt#; % vertical diameter of hairlines
+---
+> vair#:=30/36pt#; % vertical diameter of hairlines
+46,49c46,49
+< bar#:=21/36pt#; % lowercase bar thickness
+< slab#:=21/36pt#; % serif and arm thickness
+< cap_bar#:=21/36pt#; % uppercase bar thickness
+< cap_band#:=21/36pt#; % uppercase thickness above/below lobes
+---
+> bar#:=31/36pt#; % lowercase bar thickness
+> slab#:=31/36pt#; % serif and arm thickness
+> cap_bar#:=31/36pt#; % uppercase bar thickness
+> cap_band#:=31/36pt#; % uppercase thickness above/below lobes
+51,53c51,53
+< serif_drop#:=5/36pt#; % vertical drop of sloped serifs
+< stem_corr#:=1/36pt#; % for small refinements of stem breadth
+< vair_corr#:=1/36pt#; % for small refinements of hairline height
+---
+> serif_drop#:=4/36pt#; % vertical drop of sloped serifs
+> stem_corr#:=2/36pt#; % for small refinements of stem breadth
+> vair_corr#:=1.5/36pt#; % for small refinements of hairline height
+56,57c56,57
+< o#:=4/36pt#; % amount of overshoot for curves
+< apex_o#:=3/36pt#; % amount of overshoot for diagonal junctions
+---
+> o#:=2/36pt#; % amount of overshoot for curves
+> apex_o#:=1/36pt#; % amount of overshoot for diagonal junctions
+61,64c61,64
+< math_spread:=0; % extra openness of math symbols
+< superness:=8/11; % parameter for superellipses
+< superpull:=1/15; % extra openness inside bowls
+< beak_darkness:=4/30; % fraction of triangle inside beak serifs
+---
+> math_spread:=0.5; % extra openness of math symbols
+> superness:=3/4; % parameter for superellipses
+> superpull:=1/18; % extra openness inside bowls
+> beak_darkness:=4/25; % fraction of triangle inside beak serifs
+
+
diff --git a/web/spiderweb/src/dijkstra/README b/web/spiderweb/src/dijkstra/README
new file mode 100644
index 0000000000..ab315905a0
--- /dev/null
+++ b/web/spiderweb/src/dijkstra/README
@@ -0,0 +1,3 @@
+The spider file for Dijkstra's language of guarded commands isn't really
+very good. One problem is that it's hard to come up with ASCII representations
+of the operators Dijkstra uses. Suggestions will be appreciated.
diff --git a/web/spiderweb/src/dijkstra/binary.web b/web/spiderweb/src/dijkstra/binary.web
new file mode 100644
index 0000000000..b0b2ebe38d
--- /dev/null
+++ b/web/spiderweb/src/dijkstra/binary.web
@@ -0,0 +1,267 @@
+\input itemize
+\def\title{Binary tree insertion}
+\def\topofcontents{\null\vfill
+ \titlefalse % include headline on the contents page
+ \def\rheader{\hfil}
+ \centerline{\titlefont Inserting into an ordered binary tree}
+ \vfill}
+
+@*Preliminaries.
+Our object is to design a verified binary tree insertion routine.
+To make our lives easier, we will employ some simplifications:
+\itemize
+\item We will use iteration instead of recursion.
+\item We will use Dijkstra's language of guarded commands
+\item We will assume the existence of a tree data type, such that
+ if |t| is a tree either |t| is empty (|t=emptyset|) or
+ |t| has a left subtree, a right subtree, and a datum
+ (|t=<<l,d,r>>|). If |t=<<l,d,r>>|, we may write |t.l| for |l|,
+|t.d| for |d|, and |t.r| for |r|.
+\item We will assume sequences; if |s| is a sequence then either |s|
+is empty (|s=empty|) or |s| is an element followed by a sequence (|s=z
+Z|).
+\item We have a membership operator |member| that will test for
+membership in sequences or trees.
+\enditemize
+@ We want to talk about ordered binary trees, so we'll want the
+notion.
+@c
+ordered.emptyset == true;
+ordered.<<l,d,r>>==ordered.l & ordered.r &@|
+(forall y:y member l: y<=d) &@| (forall y: y member r: y>=d);
+
+@ Our mission is to insert a datum |x| into a binary tree |T| such that
+the resulting tree is ordered.
+We'll do this by creating a new tree |t| which is ordered and the
+membership of which is the union of the membership of |t| with
+$\{x\}$.
+We don't care exactly what happens if |x| is already in the tree,
+although we could add a postcondition |x member T ==> T=t|.
+
+If we state our problem formally, we have
+@c
+{PRE: ordered.T}
+{POST: (forall y::y member t <=> y member T | y=x) & ordered.t}
+
+@ Let us develop some notion of ``insertion at a node.''
+Perhaps we can use that as a guide to weakening the postcondition and
+finding a loop invariant.
+In essence what we will want to do is select some empty subtree of
+|T|, and replace it with the tree |<<emptyset,x,emptyset>>|.
+Let us generalize, and imagine that we have a variable |s| that
+represents |T| and points at some node of |T| ``to be replaced.''
+Let |attach.t.s| denote the result of substituting |T| for the subtree
+whose root is that node.
+In particular if |s| points to the root of |T|, then |attach.t.s=t|.
+
+@ How can we compute |attach|? We've already seen that if |s| points
+to the root of |T|, then |attach.t.s=t|.
+Suppose |s| does not point to the root of |T|.
+Then there is an |s`| that points to the parent of the node pointed to by
+|s|.
+Then, there is some |t`| such that |attach.t.s=attach.t`.s`|, and,
+furthermore, either |t`=<<t,d,u>>| or |t`=<<u,d,t>>|, for some |u| and
+|d|.
+
+So, let |s| be a sequence of records, and let each record contain:
+\itemize
+\item A choice (|left| or |right|)
+\item A datum |d|
+\item A tree |u|
+\enditemize
+and define
+@c
+attach.t.empty == t;
+attach.t.(<<left,d,u>> s) == attach.<<t,d,u>>.s;
+attach.t.(<<right,d,u>> s) == attach.<<u,d,t>>.s;
+
+@ Now we can imagine our insertion problem as being broken into two
+parts.
+First, we find the right place to insert |x|.
+This means computing an |s| such that
+|attach.<<emptyset,x,emptyset>>.s| is what we want.
+Second, we have to compute |t| so that
+|t=attach.<<emptyset,x,emptyset>>.s|.
+
+Let's imagine that we already have an |s|.
+Then, we can change our postcondition by substituting |attach.t.s| for
+|t|, and make that our loop invariant.
+We then start out with |t=<<emptyset,x,emptyset>>|, and write a loop
+that adds to |t| while removing from |s|.
+
+Since |s=empty| at the end of the loop, and since |attach.t.empty=t|, the
+invariant conjoined with the negation of the guard gives us the
+postcondition.
+I leave it for the reader to show that the loop body leaves the
+quantity |attach.t.s| unchanged.
+@c
+t := <<emptyset,x,emptyset>>;
+{invariant (forall y::y member attach.t.s <=> y member T | y=x) &
+ ordered.(attach.t.s)}
+{bound #s}
+do s != empty ->
+ let choice, data, tree, S satisfy <<choice,data,tree>> S = s;
+ if choice = left ->
+ t,s := <<t,data,tree>>, S
+ [] choice = right ->
+ t,s := <<tree,data,t>>, S
+ fi
+od
+{POST: (forall y::y member t <=> y member T | y=x) & ordered.t}
+@ It remains for us to compute a suitable |s| in the first part of the
+program.
+Let us write |X| for |<<emptyset,x,emptyset>>|.
+Then we must assign to |s|, establishing
+$$\hbox{| (forall y::y member attach.X.s <=> y member T
+|| y=x) & ordered.(attach.X.s)|.%
+}$$
+Since |y=x <=> y member X|, that is equivalent to
+$$\hbox{
+| (forall y::y member attach.X.s <=> y member T || y member X) &
+ordered.(attach.X.s)|.}$$
+
+Let us imagine we have a variable |t| such that |T=attach.t.s|.
+Then we need
+$$\hbox{|y member attach.X.s <=> y member attach.t.s || y member X|}$$
+Now we make use of a property of |attach|, viz.\
+|(forall X::y member attach.X.s <=> y member X || y member
+attach.emptyset.s)|.
+(The proof is by induction on the length of |s|.)
+From this we can get $$ \hbox{
+|t=emptyset ==> (forall y::y member attach.X.s <=> y member
+attach.t.s || y member X)|.}\eqno(1)$$
+This suggests the following code fragment:
+@c
+t,s := T,empty;
+{invariant T=attach.t.s & ordered.(attach.X.s)}
+do t != emptyset ->
+ /* loop body */@;
+od
+{t=emptyset & T=attach.t.s & ordered.(attach.X.s)}
+/* which, by (1), implies */
+{(forall y::y member attach.X.s <=> y member T | y=x) & ordered.(attach.X.s)}
+
+@ The question is now what loop body will maintain the invariant.
+Since in our earlier loop we made |t| larger and |s| smaller, we can
+imagine inverting that loop to get the new loop.
+We also invert the proof that the value of |attach.t.s| remains
+unchanged.
+
+@c
+{invariant T=attach.t.s & ordered.(attach.X.s)}
+do t != emptyset ->
+ if <<@tfirst guard@>>>@; ->
+ t,s := t.l, <<left,t.d,t.r>> s
+ [] <<@tsecond guard@>>>@; ->
+ t,s := t.r, <<right,t.d,t.l>> s
+ fi
+od
+@ The question remains as to what the guards must be to make the whole
+thing work.
+Taking the first branch, the weakest precondition of
+|ordered.(attach.X.s)| is
+@c
+ordered.(attach.X.(<<left,t.d,t.r>> s))
+!<=>
+ordered.(attach.<<X,t.d,t.r>>.s)
+!<= /* by a lemma to follow */
+ordered.(attach.X.s) &
+ordered.(attach.t.s) &
+x <= t.d
+!<=
+ordered.(attach.X.s) &
+ordered.T &
+T=attach.t.s &
+x <= t.d
+
+@ So if we strengthen our invariant to include |ordered.T|, we can
+make the first guard |x<=t.d|, and the second guard |x>=t.d|, giving
+@c
+{invariant T=attach.t.s & ordered.(attach.X.s) & ordered.T}
+{bound depth.t}
+do t != emptyset ->
+ if x <= t.d ->
+ t,s := t.l, <<left,t.d,t.r>> s
+ [] x >= t.d ->
+ t,s := t.r, <<right,t.d,t.l>> s
+ fi
+od
+{t=emptyset & T=attach.t.s & ordered.(attach.X.s)}
+/* which, by (1), implies */
+{(forall y::y member attach.X.s <=> y member T | y=x) & ordered.(attach.X.s)}
+
+@ Now we have to finish the proof we started earlier.
+We use a clever trick involving inorder traversals.
+For reference, the inorder traversal is defined by
+$$\eqalign{
+|in.emptyset|&|==empty|\cr
+|in.<<l,d,r>>|&|==in.l d in.r|\cr
+}$$
+
+Suppose that
+$$ (\forall s::( \exists l,r:: (\forall t::
+ |in.(attach.t.s)=l in.t r|))) \eqno (2)$$
+(which we will show in just a moment).
+Given |s|, choose such an |l| and |r|. Then we have the lemma we need:
+@c
+ordered.(attach.<<X,t.d,t.r>>.s)
+!<=> /* by (2) */
+sorted.(l x t.d in.(t.r) r)
+!<=
+sorted.(l x r) &
+sorted.(l in.(t.l) t.d in.(t.r) r) &
+x <= t.d
+!<=>
+ordered.(attach.X.s) &
+ordered.(attach.t.s) &
+x <= t.d
+@ We prove (2) by induction on the length of |s|.
+
+If |s=empty|, then |l=empty| and |r=empty| satisfy |in.(attach.t.s)=l
+in.t r|.
+
+If |s!=empty|, then write |s=z Z|.
+Our induction hypothesis is |(exists l`,r`:: (forall
+t::in.(attach.t.Z)=l` in.t r`))|.
+If |z=<<left,data,tree>>|, then let |l=l`| and |r=data in.tree r`|.
+Then, for any |t|,
+$$\eqalign{
+in.(attach.t.s) &=
+|in.(attach.t.(<<left,data,tree>> Z))|\cr
+&=|in.(attach.<<t,data,tree>>.Z)|\cr
+&=|l` in.t data in.tree r`|\cr
+&=|l in.t r|,\cr}$$
+and that's the induction step.
+
+
+@*The finished program.
+Here we put the whole program together:
+@c
+{PRE:ordered.T}
+t,s,X := T, empty, <<emptyset,x,emptyset>>;
+{invariant T=attach.t.s & ordered.(attach.X.s) & ordered.T}
+{bound depth.t}
+do t != emptyset ->
+ if x <= t.d ->
+ t,s := t.l, <<left,t.d,t.r>> s
+ [] x >= t.d ->
+ t,s := t.r, <<right,t.d,t.l>> s
+ fi
+od;
+{(forall y::y member attach.X.s <=> y member T | y=x) & ordered.(attach.X.s)}
+t := X;
+{invariant (forall y::y member attach.t.s <=> y member T | y=x) &
+ ordered.(attach.t.s)}
+{bound #s}
+do s != empty ->
+ let choice, data, tree, S satisfy <<choice,data,tree>> S = s;
+ if choice = left ->
+ t,s := <<t,data,tree>>, S
+ [] choice = right ->
+ t,s := <<tree,data,t>>, S
+ fi
+od
+{POST: (forall y::y member t <=> y member T | y=x) & ordered.t}
+@*Index.
+
+
diff --git a/web/spiderweb/src/dijkstra/d.spider b/web/spiderweb/src/dijkstra/d.spider
new file mode 100644
index 0000000000..1ee5199b4f
--- /dev/null
+++ b/web/spiderweb/src/dijkstra/d.spider
@@ -0,0 +1,155 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+language Dijkstra
+
+at_sign @
+
+comment begin <"#"> end newline
+
+default translation <*> mathness yes
+
+token identifier category math mathness yes
+token number category math mathness yes
+token newline category ignore_scrap mathness maybe translation <>
+token pseudo_semi category semi mathness maybe translation <>
+
+module definition math use math
+
+token + category unorbinop
+token - category unorbinop
+token * category binop
+token / category binop
+token < category binop
+token > category binop
+token = category binop
+token . category binop
+token , category binop translation <",\\,">
+token : category binop
+token :: category binop translation <"\\CC">
+token ! category unop translation <"\\lnot">
+token & category binop translation <"\\land">
+token || category binop translation <"\\lor">
+token | category unop
+token ( category open
+token [ category open
+token ) category close
+token ] category close
+token ` category unop translation <"'"> mathness yes
+token { translation <"\\{"> category lbrace
+token } translation <"\\}"> category close
+token ; category semi
+token # category unop translation <"\\#">
+token := category binop translation <"\\CE">
+token != name not_eq translation <"\\I"> category binop
+token <= name lt_eq translation <"\\L"> category binop
+token >= name gt_eq translation <"\\G"> category binop
+token == name eq_eq translation <"\\S"> category binop
+token <=> translation <"\\IFF"> category binop
+token <-> translation <"\\IFF"> category binop
+token >> translation <"\\rangle"> category close
+token << translation <"\\langle"> category open
+token [] category box translation <"[]">
+# two-characer tokens must have a translation!!!! FIX!
+token -> category arrow translation <"\\RA">
+token => category binop translation <"\\RA">
+token ==> category binop translation <"\\LRA">
+token --> category arrow translation <"\\RA">
+
+# The following tokens are used in writing proofs
+token !<=> category shout translation <"\\IFF">
+token !<= category shout translation <"\\FF">
+token !== category shout translation <"\\S">
+
+math <indent-force> shout <outdent-force> math --> math
+
+
+macros begin
+\def\LRA{\Longrightarrow}
+\def\IFF{\Longleftrightarrow}
+\def\FF{\Longleftarrow}
+\def\DEF{\buildrel\triangle\over=}
+\def\CE{\mathrel{{:}{=}}}
+\def\CC{\mathrel{{:}{:}}}
+\let\RA\rightarrow
+\let\openbraces=\{
+\let\closebraces=\}
+\def\{{\ifmmode\openbraces\else$\openbraces$\fi}
+\def\}{\ifmmode\closebraces\else$\closebraces$\fi}
+macros end
+
+
+ilk if_like category if
+ilk fi_like category fi
+
+reserved if ilk if_like
+reserved fi ilk fi_like
+reserved do ilk if_like
+reserved od ilk fi_like
+
+ilk unop_like category unop translation <*-"\\"-space>
+reserved let ilk unop_like
+reserved invariant ilk unop_like
+reserved bound ilk unop_like
+
+ilk binop_like category binop translation <"\\"-space-*-"\\"-space>
+reserved satisfy ilk binop_like
+reserved sat ilk binop_like
+
+
+default mathness yes
+
+ilk math_like category math
+reserved true ilk math_like
+reserved false ilk math_like
+
+ilk member_like category math translation <"\\member">
+reserved member ilk member_like
+macros begin
+\def\member{\mathbin{\in}}
+macros end
+
+ilk empty_like category math translation <"\\varepsilon"> mathness yes
+reserved empty ilk empty_like
+
+ilk emptyset_like category math translation <"\\emptyset"> mathness yes
+reserved emptyset ilk emptyset_like
+
+ilk cross_like category unop translation <"\\times">
+reserved cross
+
+ilk forall_like category unop translation <"\\forall">
+reserved forall
+
+ilk exists_like category unop translation <"\\exists">
+reserved exists
+
+ilk number_like category unop translation <"\\number">
+reserved number
+macros begin
+\def\number{{\bf N}}
+macros end
+
+
+
+
+math <"\\"-space> math --> math
+math (binop|unorbinop) math --> math
+math unop --> math
+(unop|unorbinop) math --> math
+
+math semi <force> --> unop
+math <force> lbrace --> lbrace
+lbrace math close --> math
+# lbrace math close <force> --> unop
+
+open math close --> math
+open close --> math
+
+? ignore_scrap --> #1
+
+if <"\\"-space> math arrow <indent-force> --> ifbegin
+ifbegin math <outdent-force> box --> if
+ifbegin math <outdent-force> fi --> math
+
+
diff --git a/web/spiderweb/src/dijkstra/make b/web/spiderweb/src/dijkstra/make
new file mode 100644
index 0000000000..2ddee7c9f9
--- /dev/null
+++ b/web/spiderweb/src/dijkstra/make
@@ -0,0 +1,2 @@
+/bin/make -f ../master/WebMakefile CPUTYPE=`cputype` \
+ THETANGLE=dtangle THEWEAVE=dweave SPIDER=d.spider $*
diff --git a/web/spiderweb/src/dijkstra/sp.web b/web/spiderweb/src/dijkstra/sp.web
new file mode 100644
index 0000000000..9725b2ac10
--- /dev/null
+++ b/web/spiderweb/src/dijkstra/sp.web
@@ -0,0 +1,28 @@
+@*Dijkstra's shortest path.
+Obviously the way to prove Dijkstra's algorithm is the way Dijsktra
+would do it himself.
+Consider
+@u
+@<Set |d[u]| to all $\infty$ for all |u| in |V| @>@;
+d[v] := 0;
+W := {v};
+@<For each |u| in |V-W| and $(v,u) \in E$
+ let |d[u]| be the weight of $(v,u)$@>@;
+{@tinvariant: $\forall u \in W$,
+ $d[u]$ is the shortest distance from $v$ to $u$@> &
+ @t$\forall u \in V-W$, $d[u] }
+do |W| != |V| -->
+ @<Let |u| be a vertex in |V-W| with |d[u]| as small as possible@>@;
+ @<For each |w| in |V-W| and $(u,w) \in E$@>@;
+ if d[w] <= d[u] + c(u,w) --> skip
+ [] d [w] >= d[u] + c(u,w) --> d[w] := d[u] + c(u,w)
+ fi;
+ W := W @t$\cup$@> {u}
+od
+
+@*Index.
+
+
+
+
+
diff --git a/web/spiderweb/src/kelem/ac.spider b/web/spiderweb/src/kelem/ac.spider
new file mode 100644
index 0000000000..d65ef11e48
--- /dev/null
+++ b/web/spiderweb/src/kelem/ac.spider
@@ -0,0 +1,496 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+language AC extension ac
+
+at_sign @
+
+comment begin <"/*"> end <"*/">
+
+default translation <*> mathness yes
+
+token identifier category simp mathness yes
+token number category math mathness yes
+token newline category newline mathness maybe translation <>
+token pseudo_semi category semi mathness maybe translation <"\\relax">
+
+module definition stmt use math
+
+token + category unorbinop
+token - category unorbinop
+token * category unorbinop translation <"{*}">
+token / category dot
+token < category less translation <>
+token > category greater translation <>
+token := category equals translation <"\\leftarrow">
+token . category dot
+token ~ category unop translation <"\\TI">
+token & category unorbinop translation <"\\amp">
+token ^ translation <"\\^"> category binop
+token | category binop
+token ? translation <"\\?"> category question
+token % translation <"\\%"> category binop
+token # translation <"\\#"> category sharp
+token ! category unop translation <"\\neg">
+token \ category backslash translation <"\\backslash">
+token ( category open
+token ) category close
+token [ category open
+token ] category close
+token { translation <"\\{"-indent> category lbrace
+token } translation <"\\}"> category rbrace
+token , category comma translation <",\\;">
+token ; category semi
+token : category colon
+token ++ category unop translation <"\\PP">
+token -- category unop translation <"\\MM">
+token != translation <"\\I"> category binop
+token <= translation <"\\L"> category binop
+token >= translation <"\\G"> category binop
+token = translation <"\\S"> category binop
+token && translation <"\\W"> category binop
+token || translation <"\\V"> category binop
+token -> translation <"\\MG"> category binop
+token >> translation <"\\GG"> category binop
+token << translation <"\\LL"> category binop
+
+macros begin
+\def\CC{\mathrel{:{:}}}
+\def\CCE{\mathrel{:{:}=}}
+\def\FE{\mathrel{/=}}
+\def\PP{\mathord{++}}
+\def\PE{\mathrel{+=}}
+\def\MM{\mathord{--}}
+\def\ME{\mathrel{-=}}
+\def\MG{\mathrel{\to}}
+\def\GG{\mathrel{>\!>}}
+\def\LL{\mathrel{<\!<}}
+\def\TE{\mathrel{\ast=}}
+\def\CE{\mathrel{\%=}}
+\def\HE{\mathrel{\uparrow=}}
+\def\AE{\mathrel{\amp=}}
+\def\OE{\mathrel{|=}}
+\let\openbraces=\{
+\let\closebraces=\}
+\def\{{\ifmmode\openbraces\else$\openbraces$\fi}
+\def\}{\ifmmode\closebraces\else$\closebraces$\fi}
+\def\?{\mathrel?}
+\def\s{\ }
+macros end
+
+default translation <*-"\\"-space>
+
+ilk case_like category case
+ilk int_like category decl_head translation <*>
+ilk else_like category else
+ilk enum_like category enum
+ilk if_like category if
+ilk for_like category for
+ilk do_like category do
+ilk sizeof_like category sizeof
+ilk struct_like category struct
+ilk switch_like category switch
+ilk typedef_like category typedef
+ilk IF_like category IF mathness no translation <force-"\\&{IF}"-space-indent> mathness no
+ilk THEN_like category THEN translation <outdent-force-"\\&{THEN}"-space-indent> mathness no
+ilk ELIF_like category ELIF translation <outdent-force-"\\&{ELIF}"-space-indent> mathness no
+ilk ELSE_like category ELSE translation <outdent-force-"\\&{ELSE}"-space-indent> mathness no
+ilk FI_like category FI translation <outdent-force-"\\&{FI}"-force> mathness no
+ilk BEGIN_like category BEGIN translation <force-"\\&{BEGIN}"-force-indent> mathness no
+ilk END_like category END translation <outdent-force-"\\&{END}"-force> mathness no
+ilk WHILE_like category WHILE translation <force-"\\&{WHILE}"-space-indent> mathness no
+ilk FOR_like category FOR translation <force-"\\&{FOR}"-space-indent> mathness no
+ilk AS_like category AS
+ilk EXEC_like category EXEC
+ilk DO_like category DO translation <outdent-force-"\\&{DO}"-space-indent> mathness no
+ilk OD_like category OD translation <outdent-force-"\\&{OD}"-force> mathness no
+ilk SWITCH_like category SWITCH translation <force-"\\&{SWITCH}"-space-indent> mathness no
+ilk IN_like category IN mathness no translation <space-"\\&{IN}"-force>
+ilk CASE_like category CASE translation <outdent-force-"\\&{CASE}"-space-indent> mathness no
+ilk DEFAULT_like category DEFAULT translation <force-outdent-"\\&{DEFAULT}"-space-indent> mathness no
+ilk BREAK_like category BREAK translation <force-"\\&{BREAK}"-space> mathness no
+ilk CONTINUE_like category CONTINUE translation <force-"\\&{CONTINUE}"-force> mathness no
+ilk NI_like category NI translation <outdent-force-"\\&{NI}"-force> mathness no
+ilk unop_like category unop translation <break_space-*-break_space>
+ilk binop_like category binop
+
+default translation <*>
+
+reserved auto ilk int_like
+reserved break ilk case_like
+reserved case ilk case_like
+reserved char ilk int_like
+reserved const ilk int_like
+reserved continue ilk case_like
+reserved default ilk case_like
+reserved do ilk do_like
+reserved double ilk int_like
+reserved else ilk else_like
+reserved enum ilk enum_like
+reserved ENUM ilk enum_like
+reserved extern ilk int_like
+reserved float ilk int_like
+reserved for ilk for_like
+reserved goto ilk case_like
+reserved if ilk if_like
+reserved int ilk int_like
+reserved long ilk int_like
+reserved register ilk int_like
+reserved return ilk case_like
+reserved short ilk int_like
+reserved signed ilk int_like
+reserved sizeof ilk sizeof_like
+reserved static ilk int_like
+reserved struct ilk struct_like
+reserved switch ilk switch_like
+reserved typedef ilk typedef_like
+reserved union ilk struct_like
+reserved unsigned ilk int_like
+reserved void ilk int_like
+reserved volatile ilk int_like
+reserved while ilk for_like
+
+reserved SIZEOF ilk sizeof_like
+reserved STRUCT ilk struct_like
+reserved TYPEDEF ilk typedef_like
+reserved UNION ilk struct_like
+
+reserved AUTO ilk int_like
+reserved BOOL ilk int_like
+reserved CHAR ilk int_like
+reserved CONST ilk int_like
+reserved DOUBLE ilk int_like
+reserved EXTERN ilk int_like
+reserved FILE ilk int_like
+reserved FLOAT ilk int_like
+reserved INT ilk int_like
+reserved INTERN ilk int_like
+reserved LONG ilk int_like
+reserved PROC ilk int_like
+reserved REF ilk int_like
+reserved REGISTER ilk int_like
+reserved SHORT ilk int_like
+reserved SIGNED ilk int_like
+reserved STATIC ilk int_like
+reserved STRING ilk int_like
+reserved UNSIGNED ilk int_like
+reserved VOID ilk int_like
+reserved VOLATILE ilk int_like
+
+reserved AS ilk AS_like
+reserved ASLONGAS ilk AS_like
+reserved BEGIN ilk BEGIN_like
+reserved BREAK ilk BREAK_like
+reserved CASE ilk CASE_like
+reserved CONTINUE ilk CONTINUE_like
+reserved DEFAULT ilk DEFAULT_like
+reserved DO ilk DO_like
+reserved ELIF ilk ELIF_like
+reserved ELSE ilk ELSE_like
+reserved END ilk END_like
+reserved EXEC ilk EXEC_like
+reserved FI ilk FI_like
+reserved FOR ilk FOR_like
+reserved GOTO ilk case_like
+reserved IF ilk IF_like
+reserved IN ilk IN_like
+reserved NI ilk NI_like
+reserved OD ilk OD_like
+reserved RETURN ilk case_like
+reserved SWITCH ilk SWITCH_like
+reserved THEN ilk THEN_like
+reserved WHILE ilk WHILE_like
+
+reserved TRUE ilk int_like
+reserved FALSE ilk int_like
+reserved NORMAL ilk int_like
+reserved ERROR ilk int_like
+reserved UNDEFINED ilk int_like
+reserved NULL ilk int_like
+
+reserved CONT ilk unop_like
+reserved NOT ilk unop_like
+reserved INCR ilk unop_like
+reserved DECR ilk unop_like
+reserved ADDR ilk unop_like
+reserved MOD ilk binop_like
+reserved ANDIF ilk binop_like
+reserved ORIF ilk binop_like
+reserved AND ilk binop_like
+reserved OR ilk binop_like
+reserved EXCLOR ilk binop_like
+reserved XOR ilk binop_like
+reserved COMPLEMENT ilk unop_like
+reserved LSHIFT ilk unop_like
+reserved RSHIFT ilk unop_like
+reserved ASSERT ilk int_like
+
+# we indulge in a trick to avoid treating
+# ASCII (*fp)();
+# as a statement (function call). We use instead
+# ASCII ===> (*fp)();
+token ===> translation <"\\relax"> tangleto <space> category decl_head
+
+
+#
+? ignore_scrap --> #1
+# dropped, because we've overflowed yacc!
+#### DON'T DO THIS! it makes it impossible to add translation on the left
+#### ignore_scrap ? --> #2
+
+
+# because of declarations, we have to be very careful about converting
+# simp to math
+
+(math|simp) unop --> math
+math (binop|unorbinop) (math|simp) --> math
+math comma <opt-9> (math|simp) --> math
+# we're not allowed math simp --> statement because math simp could be fn_decl
+math math --> math
+(math|simp) semi --> stmt
+# so to hack the omission above, we include (usually a cast)
+math <"\\"-space> stmt --> stmt
+
+(open|simpopen|question|unop|unorbinop|case) [ simp ] --> (open|simpopen|question|unop|unorbinop|case) math
+[ simp ] binop --> math binop
+# old:
+# [ simp ] equals --> math equals
+# math [ equals ] --> math binop
+
+simp* colon --> tag
+
+# can't have simp open --> open because that causes ( to eat all id's to its left.
+simp open --> simpopen
+
+(open|simpopen) math close --> math
+(open|simpopen) <"\\,"> close --> math
+# following needed for for statements
+open stmt <"\\"-space> --> open
+
+# here we try to deal with casts and argument lists, e.g.
+# (ASCII *) malloc(sizeof (ASCII *));
+# char *malloc(int);
+
+# If the type is predefined, we know we have a cast
+(open|simpopen) decl_head close --> cast
+(open|simpopen) [ decl_head (unorbinop|math|simp) ] --> (open|simpopen) decl_head
+(open|simpopen) decl_head comma --> arglist
+arglist (decl_head|unorbinop|math) --> arglist
+arglist close --> math
+
+# and here are some common cases of casts with non-predefined types
+# for other cases you'll have to use "declares"
+(open|simpopen) math <"\\"-space> unorbinop comma --> arglist
+(open|simpopen) math <"\\"-space> unorbinop unorbinop comma --> arglist
+(open|simpopen) math <"\\"-space> unorbinop unorbinop unorbinop comma --> arglist
+(open|simpopen) math <"\\"-space> unorbinop close --> cast
+(open|simpopen) math <"\\"-space> unorbinop unorbinop close --> cast
+(open|simpopen) math <"\\"-space> unorbinop unorbinop unorbinop close --> cast
+
+# the math here seems to be a cast. We don't convert to cast because it looks
+# too much like a cycle
+(open|simpopen) [ math <"\\"-space> simp ] --> (open|simpopen) math
+
+# Here is the destiny of casts
+cast <"\\"-space> (math|simp) --> math
+cast (newline|ignore_scrap) --> cast
+cast --> math
+
+
+
+question math colon --> binop
+
+unop math --> math
+<"{"> unorbinop <"}"> math --> math
+<"\\buildrel"> (binop|unorbinop) <"\\over{"> equals <"}"> --> binop
+equals --> binop
+sizeof (math|simp) --> math
+
+(simp|decl_head) <"\\"-space> decl_head --> decl_head
+[ simp ] math (equals|comma|semi) --> decl_head math (equals|comma|semi)
+[ (decl_head|simp) simp ] (simp|math) --> decl_head (simp|math)
+(simp|decl_head) <"\\"-space> (simp|math)* comma --> decl_head
+(simp|decl_head) <"\\"-space> (simp|math)* semi --> decl
+(simp|decl_head) <"\\"-space> (simp|math)* equals --> decl_equals
+decl_equals math comma --> decl_head
+decl_equals math semi --> decl
+decl_equals [ simp ] --> decl_equals math
+
+struct simp* <"\\"-space> lbrace --> structbrace
+struct lbrace --> structbrace
+structbrace [ simp ] --> structbrace decl_head
+structbrace <force> decl --> structbrace
+structbrace <outdent-force> rbrace --> struct_head
+[ struct_head ] simp --> decl_head simp
+# some people say e.g. struct blah {...}; is this K&R?
+struct_head semi --> decl
+struct [ simp (newline|ignore_scrap) ] --> struct simp
+struct simp --> decl_head
+decl_head <"\\"-space> struct --> struct
+
+# enumeration types are like structures and unions, but they have math
+# instead of many decls...
+enum simp* <"\\"-space> lbrace --> enumbrace
+enum lbrace --> enumbrace
+enumbrace math <outdent> rbrace --> enum_head
+[ enum_head ] simp --> decl_head simp
+enum_head semi --> decl
+enum [ simp (newline|ignore_scrap) ] --> enum simp
+enum simp --> decl_head
+decl_head <"\\"-space> enum --> enum
+
+typedef [ simp ] --> typedef decl_head
+typedef decl --> decl
+
+
+
+
+[ math* <indent> ] (lbrace|decl_head|decl) --> fn_decl (lbrace|decl_head|decl)
+[ (simp|decl_head) <"\\"-space> math* <indent> ] (lbrace|decl_head|decl) --> fn_decl (lbrace|decl_head|decl)
+fn_decl <force> decl --> fn_decl
+# The following statment will always have braces and never be tagged
+fn_decl <outdent-force> stmt --> function
+# include stmt here to cover module definition
+(stmt|decl|function) <big_force> function --> function
+function <big_force> decl --> decl
+
+(stmt|decl) <force> decl --> decl
+decl <big_force> stmt --> stmt
+decl <outdent-big_force> tagged_stmt --> stmt
+
+
+BEGIN stmt <force> --> BEGIN
+BEGIN END --> stmt
+BEGIN math END --> stmt
+lbrace <outdent-force> rbrace --> stmt
+lbrace <force> stmt --> lbrace
+lbrace <outdent-force> tagged_stmt --> lbrace
+lbrace (math|simp) <outdent> rbrace --> math
+
+# if math can be followed by a brace, or no.
+# ifmath and ifbrace can have an attached else or else if clause
+# else, for, and while are formatted like if, but can't have an
+# attached else clause, so we use formath and forbrace
+
+if math --> ifmath
+ifmath <"\\"-space> lbrace --> ifbrace
+ifbrace <force> stmt --> ifbrace
+ifbrace <outdent-force> tagged_stmt --> ifbrace
+ifbrace [ rbrace (newline|ignore_scrap) ] --> ifbrace rbrace
+ifbrace rbrace [ else (newline|ignore_scrap) ] --> ifbrace rbrace else
+ifbrace <outdent-force> rbrace <"\\"-space> else if --> if
+ifbrace <outdent-force> rbrace <"\\"-space> else lbrace --> forbrace
+ifbrace <outdent-force> rbrace <"\\"-space> else --> formath
+ifbrace <outdent-force> rbrace --> stmt
+
+# IF THEN ELSE FI
+<force> IF math --> IFmath
+IFmath <outdent-force> THEN --> IFTHEN
+IFTHEN <indent> stmt <force> --> IFTHEN
+IFTHEN <outdent-force> tagged_stmt --> IFTHEN
+# IFTHEN [ (newline|ignore_scrap) ] --> IFTHEN
+IFTHEN <outdent-force> ELIF <indent> math --> IFmath
+IFTHEN [ ELSE (newline|ignore_scrap) ] --> IFTHEN ELSE
+IFTHEN <outdent-force> ELSE <indent> --> IFELSE
+IFELSE stmt --> IFELSE
+IFELSE <outdent-force> tagged_stmt --> IFELSE
+IFTHEN <outdent-force> FI --> stmt
+IFELSE <outdent-force> FI --> stmt
+
+# Assume simple statements attached to if will never be tagged
+
+ifmath [ stmt (newline|ignore_scrap) ] --> ifmath stmt
+ifmath stmt [ else (newline|ignore_scrap) ] --> ifmath stmt else
+ifmath <indent-force> stmt <outdent-force> else if --> if
+ifmath <indent-force> stmt <outdent-force> else lbrace --> forbrace
+ifmath <indent-force> stmt <outdent-force> else --> formath
+ifmath <indent-force> stmt <outdent> --> stmt
+
+for math --> formath
+formath <"\\"-space> lbrace --> forbrace
+forbrace <force> stmt --> forbrace
+forbrace <outdent-force> tagged_stmt --> forbrace
+forbrace <outdent-force> rbrace --> stmt
+formath <indent-force> stmt <outdent> --> stmt
+
+# FOR AS EXEC DO OD
+FOR math <space> AS math <space> EXEC math --> FORmath
+FORmath DO --> FORDO
+FORDO stmt <force> --> FORDO
+FORDO stmt OD --> stmt
+FORDO math OD --> stmt
+
+# WHILE DO OD
+WHILE math DO --> WHILEDO
+WHILEDO stmt <force> --> WHILEDO
+WHILEDO stmt OD --> stmt
+WHILEDO math OD --> stmt
+
+# SWITCH
+SWITCH math IN --> Switch
+Switch stmt <force> --> Switch
+[ Switch math ] (CASE|BREAK|DEFAULT|NI) --> Switch (CASE|BREAK|DEFAULT|NI)
+Switch tagged_stmt <outdent-force> --> Switch
+# Switch CASE tagged_stmt <force> --> Switch
+Switch DEFAULT colon --> Switch
+Switch CONTINUE --> Switch
+Switch BREAK --> Switch
+Switch stmt NI --> stmt
+Switch math NI --> stmt
+
+# we need an extra indent for switch, becuase the cases will be backed out
+switch math lbrace <indent> --> switchbrace
+switchbrace <outdent-force> tagged_stmt --> switchbrace
+# This next should never happen
+switchbrace <force> stmt --> switchbrace
+switchbrace <outdent-outdent-force> rbrace --> stmt
+
+# handle do-while (while has category for)
+do lbrace --> dobrace
+dobrace <force> stmt --> dobrace
+dobrace <outdent-force> tagged_stmt --> dobrace
+dobrace rbrace for --> math
+do <indent-force> stmt <outdent-force> for --> math
+
+case semi --> stmt
+CASE semi --> stmt
+case math semi --> stmt
+CASE math semi --> stmt
+case colon --> tag
+CASE colon --> tag
+case math colon --> tag
+CASE math colon --> tag
+tag <force> tag --> tag
+tag <indent-force> stmt --> tagged_stmt
+
+stmt <force> stmt --> stmt
+stmt <outdent-force> tagged_stmt --> stmt
+semi --> stmt
+
+# control sequence \8 puts things on the left margin
+<force-"\\8"> sharp <"{\\let\\\\=\\bf"-space> (simp|if|else) <"}"-indent-"{}"-space> --> preproc
+preproc backslash <force-"\\8\\hskip1em"-space> newline --> preproc
+preproc <force-outdent> newline --> ignore_scrap
+preproc !(less|lesssimp|backslash|newline) --> preproc
+newline --> ignore_scrap
+
+less simp --> lesssimp
+lesssimp dot simp --> lesssimp
+<"\\LN"> lesssimp greater <"\\RN"> --> math
+<"<"> lesssimp --> unop
+less <"<"> --> binop
+greater <">"> --> binop
+dot --> binop
+
+macros begin
+\let\LN\langle
+\let\RN\rangle
+macros end
+
+simp comma simp --> math
+
+
+
+
+
+
diff --git a/web/spiderweb/src/kelem/ac_guide.web b/web/spiderweb/src/kelem/ac_guide.web
new file mode 100644
index 0000000000..39e48c5555
--- /dev/null
+++ b/web/spiderweb/src/kelem/ac_guide.web
@@ -0,0 +1,292 @@
+%\font\em=cmmi9
+%\font\bf=cmbx9
+\def\LEQU{=\kern-2pt=}
+@* Guide to Algol-like C.
+This is a style guide for writing programs in Algol-like C.
+Algol-like C (hereafter referred to as AC) is based on the syntax of the Algol
+languages (Algol~60 and Algol~68).
+AC is translated into C.
+
+Why AC?
+AC was developed because Algol programs are more readable than C programs.
+A compiler was not developed for this language
+because there are plenty of good C compilers
+and AC is not that different from C.
+
+Several things contribute to C being difficult to read.
+(Even experienced hackers occasionally have lapses
+and misinterpret code.)
+
+One is the use of lots of short symbols.
+Curly braces, single and double operators, = and ==,
+are used to make the language succinct,
+but at the cost of readability.
+As in LISP, finding a matching brace or parenthesis that is lines or pages
+away is difficult.
+Indenting helps.
+Keywords look just like identifiers.
+
+Two of the symbols that are frequently confused are {\tt =} and {\tt ==}.
+The former is assignment and the latter equality checking.
+The argument for using these was put forth by Kernighan and Ritchie:
+``Since assignment is about twice as frequent as equality testing in typical
+C programs, it's appropriate that the operator be half as long.''
+
+However, there is a 432~year precedent of using the symbol {\tt =} for equality.
+The original rationale for using {\tt =} for equality
+was given by Robert Recorde in~1557.
+The explanation was
+{\it ``... to auoide the tediouse repetition of these woordes:
+is equalle to: I will sette as I doe often in woorke vse,
+a paire of paralleles, or Gemowe lines of one lengthe,
+thus: \LEQU, bicause noe .2.\ thynges,
+can be moare equalle.''}
+Granted, spelling is not the same, but = has served as equals in Mathematics
+for centuries.
+Fortran changed the meaning of {\tt =} to assignment and equality
+was spelled {\tt .EQ.}.
+Algol~60 reverted to {\tt =} for equality and used {\tt :=} for assignment.
+This convention was followed by some of its successors: Algol~68,
+Pascal, and Ada.
+PL/I used {\tt =} for both assignment and equality so that one
+could write confusing statements like
+\hbox{\tt a = b = c;}
+(compare {\tt b} with {\tt c} and assign the result to {\tt a}).
+
+Is it really worth using a notation that is contrary to that of the more
+universally used mathematics,
+and thus guaranteed to confuse novices and catch pros
+off-guard in order to type {\tt =} instead of {\tt :=}?
+I think adding a few characters to improve readability and understandability
+is worth the time and effort.
+There are over four centuries of mathematics using {\tt =} for equals.
+Using {\tt =} to mean assignment is begging for confusing code.
+Assignment is a relatively new concept and a new notation is warranted.
+{\tt :=} has enough precedent to serve this purpose.
+
+Consequently, I wrote a pre-processor for C called ac68 that uses {\tt :=} for
+assignment, = for equality, and has all the cumulative operators in the
+style of Algol 68: {\tt +:=}, {\tt -:=}, {\tt *:=}, {\tt \&:=}, {\tt <<:=}, etc.
+Unfortunately, the C and dbx messages refer to the operators that get generated.
+Still, the code is a lot more readable.
+Combined with Spidery WEB, the output is {\it very} readable.
+
+The following sections illustrate how to use the language constructs in AC.
+
+@c
+@<Procedures and functions@>@/
+@<Conditional statements@>@/
+@<Loops@>@/
+@<Data types@>@/
+
+@ Procedures and functions.
+Procedures and functions begin with the word |PROC|,
+followed by the type of the function, the name of the function and then
+the list of arguments.
+Procedures return the |VOID| type.
+An example is the procedure |main|, which is required for all programs,
+shown below.
+Note that the C denotation for a pointer is replaced by the word |REF|,
+which is short for {\bf REFERENCE}.
+(Note that there is a delicate balance between making programs read as
+English text and using cryptic symbols.
+Abbreviations such as |PROC| for {\bf PROCEDURE}
+and |REF| for {\bf REFERENCE} lie between being cryptic and being
+English.)
+|STRING| is used instead of C's {\tt char *} to denote a string.
+|BEGIN| and |END| are used to bracket the procedure text.
+
+@<Procedures and functions@>=
+PROC VOID main(argv, argc, env)
+STRING REF argv;
+INT argc;
+STRING REF env;
+BEGIN
+END
+
+@ Conditional statements.
+The conditional statements are |IF| and |SWITCH|,
+shown below.
+
+@<Conditional statements@>=
+
+ @<IF statements@>@/
+ @<SWITCH statements@>@/
+
+@ The |IF| statement has three parts ---
+a condition (following the |IF|),
+a then-part (following the |THEN|),
+and an optional else-part (following the |ELSE|).
+The |IF| statement ends with the |FI| keyword.
+Statements are {\it separated} by semicolons.
+An arbitrary number of statements may occur in the |THEN|
+and |ELSE| parts,
+thus it is not necessary to add braces when multiple statements are used.
+(In essence, they are {\it always} there by virtue of these keywords,
+but there is no performance penalty introduced by having them there.)
+
+The |FI| keyword shows the end of the |IF| statement
+and helps when nested-|IF| statements are used.
+
+@<IF statements@>=
+IF condition
+THEN statement1;
+ statement2
+ELSE
+ statement3;
+ statement4
+FI
+
+IF condition
+THEN
+ statement1;
+ statement2
+FI
+
+IF condition1
+THEN statements1
+ELSE IF condition2
+ THEN statements2
+ ELSE IF condition3
+ THEN statements3
+ ELSE statements4
+ FI
+ FI
+FI
+
+@ There is an alternate way of writing nested-|IF| statements.
+As can be seen above, the indenting of nested-|IF|s can quickly
+get out of hand.
+An alternate way of writing this is with the |ELIF|-|THEN| keywords
+shown below.
+Note that only a single |FI| is needed to end the |ELIF|.
+
+@c
+IF condition1
+THEN statements1
+ELIF condition2
+THEN statements2
+ELIF condition3
+THEN statements3
+ELSE statements4
+FI
+
+@ The |SWITCH| statement is the other type of conditional statement.
+The |IF| statement evaluates nested alternatives sequentially,
+the |SWITCH| statement evaluates multiple alternatives concurrently.
+In the example below the |SWITCH| evaluates |expression|,
+then checks whether it is equal to |a| or |b|.
+If it is equal to one of these values, the corresponding statements are
+executed.
+If not, the |DEFAULT| statements are executed.
+
+@<SWITCH statements@>=
+SWITCH expression IN
+CASE a: statements_a
+ BREAK
+CASE b: statements_b
+ BREAK
+DEFAULT: statements_d
+ BREAK
+NI
+
+@ There are two types of looping statements --- |FOR| and |WHILE|.
+
+@<Loops@>=
+@<FOR loops@>@/
+@<WHILE loops@>@/
+
+@ |FOR| loops have four parts --- a part that is executed at the
+beginning of the loop,
+a part to check for continuation conditions,
+a part to specify code to be executed at the end of every iteration,
+and the loop body, which is executed during every iteration of the loop
+while the continuation condition is |TRUE|.
+Each of the first three parts may contain multiple expressions
+separated by commas and may include assignment operators.
+The loop body may contain an arbitrary number of statements separated by
+semicolons.
+
+@<FOR loops@>=
+FOR a := initial_value, b := init_b
+AS (a < terminal_value) AND expr_t
+EXEC a INCR
+DO
+ statement1;
+ statement2
+OD
+
+@ |WHILE| loops have two parts ---
+a conditional part that is evaluated before every iteration
+and a loop body that is executed during every iteration that the conditional
+part is |TRUE|.
+The loop body may contain an arbitrary number of statements separated by
+semicolons.
+The remainder of the loop body may be skipped by using the |CONTINUE|
+statement.
+The loop may be terminated by using the |BREAK| statement.
+
+@<WHILE loops@>=
+WHILE condition1
+DO
+ statement1;
+ IF cond2
+ THEN CONTINUE
+ ELIF cond3
+ THEN BREAK
+ FI
+ statement2
+OD
+
+@ This section describes the data types.
+With the exception of |BOOL| and |STRING|,
+the data types shown below are as in C.
+The data type names are in upper case to distinguish them from the variables,
+which are typically written in lower case.
+Structure declarations that are part of type definitions require two names
+--- one for the name of the structure and one for the name of the type.
+A useful style for declaring these is use the same name for both of these,
+but change the capitalization.
+It is encouraged to use understandable names, which often are made up of
+multiple words.
+These words can be separated by capitalizing the first letter of each word,
+as in |AMultiWordIdentifier|.
+This can be combined with underscores as in |A_Multi_Word_Identifier|.
+(I find the latter more readable.)
+The structure name is rarely used,
+so I capitalize the {\it last} letter of each word,
+as in |A_multI_worD_identifieR|.
+I capitalize the first letter of each word in field names in structures
+and capitalize every letter in new types, as in |NEW_TYPE|.
+
+@<Data types@>=
+BEGIN
+INT i; /* integer */
+BOOL b; /* Boolean */
+CHAR c; /* character */
+CHAR REF c, REF REF d; /* a pointer to characters and a pointer to pointers
+to characters */
+STRING s := "a string of characters";
+FLOAT f; /* single-precision floating point */
+DOUBLE d; /* double-precision floating point */
+STRING foo := CONT CONT INCR argv;
+LONG INT li; /* long integer */
+CONST INT ci; /* a constant integer */
+enum hue {red, green, blue }; /* an enumerated type */
+VOLATILE LONG INT clock; /* a volatile long integer */
+AUTO INT aa; /* an automatic integer */
+STATIC INT st_int; /* a static integer */
+REGISTER DOUBLE dr; /* a double-precision floating register */
+ENUM color {red, green, blue}; /* an enumerated type */
+EXTERN INT ei; /* an external integer */
+SHORT s; /* a short integer */
+SIGNED si; /* a signed integer */
+UNSIGNED usi; /* an unsigned integer */
+TYPEDEF STRUCT strucT_namE {INT Integer_1, Another_Integer;
+ STRING The_Name;
+ STRUCT REF strucT_namE;} Struct_Name, REF Struct_Ptr;
+UNION {INT Look; CHAR For_The;} Union_Label;
+END
+
+@ There are a few commonly used data values that have names.
+|TRUE|, |FALSE|, |NORMAL|, |ERROR|, |UNDEFINED|, and |NULL|.
diff --git a/web/spiderweb/src/kelem/indent-troubles b/web/spiderweb/src/kelem/indent-troubles
new file mode 100644
index 0000000000..d31b05125a
--- /dev/null
+++ b/web/spiderweb/src/kelem/indent-troubles
@@ -0,0 +1,40 @@
+From daisy!kelem@uunet.UU.NET Sun Aug 27 00:40:16 1989
+Received: from Princeton.EDU by notecnirp.Princeton.EDU (5.51/1.84)
+ id AA28138; Sun, 27 Aug 89 00:40:11 EDT
+Received: from uunet.UU.NET by Princeton.EDU (5.58+++/2.22)
+ id AA03798; Sun, 27 Aug 89 00:35:15 EDT
+Received: from daisy.UUCP by uunet.uu.net (5.61/1.14) with UUCP
+ id AA15680; Sun, 27 Aug 89 00:35:34 -0400
+Received: by daisy.UUCP (5.51/smail2.2/05-30-89BC)
+ id AA08954; Sat, 26 Aug 89 20:39:23 PDT
+Received: from localhost by snidely.daisy.com (4.0/SMI-4.0)
+ id AA20954; Sat, 26 Aug 89 20:39:03 PDT
+To: princeton.edu!nr@uunet.uu.net
+Subject: trouble with indent in spider
+Date: Sat, 26 Aug 89 20:39:01 -0700
+Message-Id: <20953.620192341@snidely>
+From: daisy!kelem@uunet.UU.NET
+Status: R
+
+I'm having trouble with indenting in spider. I've narrowed it down to one
+construct --- enum (and ENUM which is the same ilk). The token lbrace
+indents and the rule for the rbrace of the enum is supposed to outdent.
+However, the .tex file doesn't have a \2 on the indent line. If I insert one
+manually, it works properly by not indenting subsequent lines.
+
+I have enclosed the shar file for ac.spider and ac_guide.web (and the make).
+If you create a spider language directory called ac and put these in there,
+you should see the same results. The results are visible on page 6 of the
+ac_guide print-out. Both the lines with enum and ENUM cause subsequent lines
+to be indented.
+
+Any idea what's going on? I tried the debugging, but the manual wasn't clear
+about where to put the @1, @2, and @0 --- in the .spider file? In the web
+file? I tried both, but didn't see any traces. My other guess is that I didn't
+see anything because there weren't any unreduced scraps. Still, it would be
+nice to see if some other production was being used instead of the one I thought
+it was supposed to use...
+
+Thanks for any help you can lend...
+Steve Kelem
+---- Cut Here and unpack ----
diff --git a/web/spiderweb/src/kelem/make b/web/spiderweb/src/kelem/make
new file mode 100644
index 0000000000..415fd46ba8
--- /dev/null
+++ b/web/spiderweb/src/kelem/make
@@ -0,0 +1,2 @@
+/bin/make -f ../master/WebMakefile CPUTYPE=`cputype` \
+ THETANGLE=actangle THEWEAVE=acweave SPIDER=ac.spider $*
diff --git a/web/spiderweb/src/kelem/test.web b/web/spiderweb/src/kelem/test.web
new file mode 100644
index 0000000000..c5cd109cd1
--- /dev/null
+++ b/web/spiderweb/src/kelem/test.web
@@ -0,0 +1,19 @@
+%\font\em=cmmi9
+%\font\bf=cmbx9
+\def\LEQU{=\kern-2pt=}
+@* Guide to Algol-like C.
+This is a style guide for writing programs in Algol-like C.
+Algol-like C (hereafter referred to as AC) is based on the syntax of the Algol
+languages (Algol~60 and Algol~68).
+AC is translated into C.
+
+
+@<Data types@>=
+@2
+BEGIN
+INT i; /* integer */
+enum hue {red, green, blue }; /* an enumerated type */
+END
+
+@ There are a few commonly used data values that have names.
+|TRUE|, |FALSE|, |NORMAL|, |ERROR|, |UNDEFINED|, and |NULL|.
diff --git a/web/spiderweb/src/larch/l.spider b/web/spiderweb/src/larch/l.spider
new file mode 100644
index 0000000000..3a275f2711
--- /dev/null
+++ b/web/spiderweb/src/larch/l.spider
@@ -0,0 +1,245 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+language Larch extension larch
+
+comment begin <"%"> end newline
+line begin <"%line">
+
+at_sign @
+
+default mathness yes
+
+ilk all_like category all
+ilk by_like category by
+ilk constrains_like category constrains
+ilk converts_like category gclause
+ilk div_like category binop
+ilk fi_like category fi
+ilk for_like category for
+ilk gen_like category gen
+ilk if_like category if
+ilk implies_like translation <*-indent>
+ilk imports_like category imports
+ilk intro_like category intro translation <*-indent>
+ilk is_like category is
+ilk then_like category then
+ilk trait_like category trait
+ilk with_like category with
+
+reserved all
+reserved assumes ilk imports_like
+reserved by
+reserved constrains
+reserved converts ilk converts_like
+reserved div ilk div_like
+reserved else ilk then_like
+reserved exempts
+reserved fi
+reserved for
+reserved generated ilk gen_like
+reserved if
+reserved implies
+reserved imports
+reserved includes ilk imports_like
+reserved introduces ilk intro_like
+reserved is
+reserved mod ilk div_like
+reserved partitioned ilk gen_like
+reserved rem ilk div_like
+reserved so
+reserved that
+reserved then
+reserved trait
+reserved with
+
+ilk and_like category binop translation <"\\wedge"> mathness yes
+ilk or_like category binop translation <"\\vee"> mathness yes
+ilk not_like category unop translation <"\\neg"> mathness yes
+
+reserved and
+reserved or
+reserved not
+
+ilk forall_like category unop translation <"\\forall"> mathness yes
+reserved forall
+
+
+simp colon trait <indent> --> tbegin
+tbegin ? <outdent-force> tbegin --> tbegin
+tbegin <force> decl --> tbegin
+
+[ intro <outdent-force> ] constrains --> decl constrains
+intro <force> decl --> intro
+math colon --> mcolon
+mcolon (simp|comma) --> mcolon
+mcolon arrow simp --> decl
+
+imports simp with open --> sublist
+
+# following special for David
+imports simp open --> imbrace
+imbrace (math|comma) --> imbrace
+imbrace close with open --> sublist
+imbrace close --> decl
+# end David
+
+imports simp --> decl
+
+sublist for --> subfor
+sublist ? --> sublist
+subfor comma --> sublist
+subfor close --> decl
+subfor ? --> subfor
+
+
+constrains open --> conslist
+conslist math comma <opt-5> --> conslist
+conslist math close so that <indent> --> consintro
+
+consintro <force> decl --> consintro
+[ consintro ] (implies|tbegin) --> decl (implies|tbegin)
+
+simp is gen by --> gclause
+gclause open --> glist
+glist math comma --> glist
+glist math close comma <opt-5> --> gclause
+# do the following because converts is also a gclause
+glist math close <indent-force> exempts --> exemptions
+glist math close --> decl
+
+exemptions math comma <opt-7> --> exemptions
+exemptions math <outdent> --> decl
+
+for all open --> forlist
+forlist (simp|comma|colon) --> forlist
+forlist semi <opt-3> --> forlist
+forlist close <indent> --> forintro
+
+[ forintro <outdent-force> ] (implies|tbegin|gclause) --> decl (implies|tbegin|gclause)
+[ forintro <outdent> ] simp is gen by --> decl simp is gen by
+forintro <force> (relation|decl) --> forintro
+forintro <outdent-force> forintro --> forintro
+
+consintro <force> forintro --> consfor
+consfor <outdent-force> forintro --> consfor
+
+[ consfor <outdent-outdent-force> ] (implies|tbegin|gclause) --> decl (implies|tbegin|gclause)
+[ consfor <outdent> ] simp is gen by --> consintro simp is gen by
+consfor <force> (relation|decl) --> consfor
+
+implies <force> (decl|relation) --> implies
+[ implies ] tbegin --> decl tbegin
+
+math rel --> mathrel
+mathrel math (binop|rel) --> mathrel
+mathrel [ math open ] --> mathrel open
+[ mathrel open math close ] open --> relation open
+mathrel math --> relation
+math open --> open
+math binop math --> math
+unop math --> math
+open math comma --> open
+open math close --> math
+open [ relation ] --> open math
+open [ math <"\\&{WEAVE\\_ERROR!}"> math ] --> open math
+[ math ] math --> relation math
+
+if (math|relation) then --> if
+if (math|relation) fi --> math
+
+
+decl <force> (decl|relation) --> decl
+relation <force> relation --> relation
+relation <force> decl --> decl
+
+module definition decl use math
+
+token identifier category simp mathness yes
+token number category math mathness yes
+token newline category ignore_scrap mathness maybe translation <>
+token pseudo_semi category ignore_scrap mathness maybe translation <>
+
+default mathness yes translation <*>
+
+# use backslash for subscripts
+token \ category backslash translation <"_"> tangleto <"_"> mathness yes
+math backslash <"{"> math <"}"> --> math
+
+token + category binop
+token - category binop
+token * category binop
+token / category binop
+token ** category binop translation <"\\mathbin{{*}{*}}">
+token . category binop
+
+token & category binop translation <"\\wedge">
+token | category binop translation <"\\vee">
+token ~ category unop translation <"\\neg">
+
+token < category rel
+token > category rel
+token = category rel
+token != translation <"\\I"> category rel
+token <= translation <"\\L"> category rel
+token >= translation <"\\G"> category rel
+token => translation <"\\Rightarrow"> category rel
+
+token # translation <"\\#"> category simp
+token ( category open
+token [ category open
+token [[ category open translation <"\\dsl">
+token {[ category open translation <"\\dcl">
+token { category open translation <"\\{">
+token << category open translation <"\\LN">
+token ) category close
+token ] category close
+token ]] category close translation <"\\dsr">
+token ]} category close translation <"\\dcr">
+token } category close translation <"\\}">
+token >> category close translation <"\\RN">
+
+macros begin
+\let\LN\langle
+\let\RN\rangle
+\def\dsl{[\![}
+\def\dsr{]\!]}
+\def\dcl{\{\![}
+\def\dcr{]\!\}}
+macros end
+
+token , category comma mathness yes translation <",\\,">
+token ; category semi
+token : category colon
+token -> translation <"\\MG"> category arrow
+macros begin
+\let\MG\rightarrow
+macros end
+
+
+### Hacks for David: is, when
+default mathness yes
+token <- category binop translation <"\\leftarrow">
+token .. category binop translation <"..">
+token ... category ignore_scrap translation <"\\ldots">
+token /= translation <"\\I"> category rel
+token ^ category hat translation <> mathness maybe
+token :: category binop translation <":"> mathness maybe
+
+hat <"\\"-space> (simp|is) <"\\"-space> hat --> binop
+simp <"\\"-space> hat hat --> unop
+
+open close --> math
+
+##########################
+# the following must be last
+
+simp --> math
+
+# if semi is not in a for list, treat it as a binary operator
+semi --> binop
+
+
+
+? ignore_scrap --> #1
+
diff --git a/web/spiderweb/src/larch/lists.web b/web/spiderweb/src/larch/lists.web
new file mode 100644
index 0000000000..8a1f2bca27
--- /dev/null
+++ b/web/spiderweb/src/larch/lists.web
@@ -0,0 +1,56 @@
+@*Theory of sequences.
+The theory of sequences is built on the theory of stacks.
+The stack theory provides most of the machinery needed for the elementary
+operations on lists: |insert|, |head|, |tail|, and |is_empty|.
+The sequence trait includes
+additional machinery that allows easy specification of concatenation.
+@c
+sequence: trait
+ imports Stack_theory with [nil for empty_stack,
+ cons for push, first for top, rest for pop]
+ introduces
+ enter: C,E -> C % adds e to back of c
+ last: C -> E
+ prefix: C -> C % c with last deleted
+ #.[#]:C, Card -> E % indexed selection (starts at 1)
+ append: C,C -> C % concatenation
+
+ constrains [C] so that C is generated by [new, insert]
+ C is generated by [new, enter]
+ C is partitioned by [first, rest, isEmpty]
+ C is partitioned by [last, prefix, isEmpty]
+
+ for all [e:E]
+ last(enter(new,e)) = e
+ prefix(enter(new,e)) = new
+
+ for all [c:C, e:E]
+ not isEmpty(enter(c,e))
+ last(enter(c,e)) = e
+ prefix(enter(c,e)) = stk
+
+ for all [c:C, e, e1: E]
+ insert(new,e) = enter(new,e)
+ insert(enter(c,e),e1) = enter(insert(c,e1),e)
+
+ for all [c:C, i:Card]
+ c.[1] = first(c)
+ c.[i+1] = rest(c).[i]
+
+ for all [c,c1:C, e:E]
+ append(c,new) = c
+ append(c,insert(c1,e)) = insert(append(c,c1), e)
+
+ implies
+ converts [insert, first, last, rest, prefix],
+ [enter, first, last, rest, prefix],
+ [append],
+ [isEmpty],
+ [size],
+ [#.[#]]
+
+
+ exempts last(new), prefix(new), first(new), rest(new)
+% for all [c:C], c(0)
+
+@*Index. \ No newline at end of file
diff --git a/web/spiderweb/src/larch/make b/web/spiderweb/src/larch/make
new file mode 100644
index 0000000000..3eda1c7845
--- /dev/null
+++ b/web/spiderweb/src/larch/make
@@ -0,0 +1,2 @@
+/bin/make -f ../master/WebMakefile \
+ THETANGLE=ltangle THEWEAVE=lweave SPIDER=l.spider $*
diff --git a/web/spiderweb/src/master/Make.pretty b/web/spiderweb/src/master/Make.pretty
new file mode 100644
index 0000000000..2b0b2b5820
--- /dev/null
+++ b/web/spiderweb/src/master/Make.pretty
@@ -0,0 +1,18 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+
+WEBDIR=/usr/norman/web/src/master
+
+.SUFFIXES: .ada .larch .pretty
+
+.ada.pretty:
+ cat $(WEBDIR)/webhead $*.ada $(WEBDIR)/webtail > $*.web
+ aweave $*
+ awk -f $(WEBDIR)/pretty.awk < $*.tex > $*.pretty
+
+.larch.pretty:
+ cat $(WEBDIR)/webhead $*.larch $(WEBDIR)/webtail > $*.web
+ lweave $*
+ awk -f $(WEBDIR)/pretty.awk < $*.tex > $*.pretty
+
diff --git a/web/spiderweb/src/master/Makefile b/web/spiderweb/src/master/Makefile
new file mode 100644
index 0000000000..caa3debac1
--- /dev/null
+++ b/web/spiderweb/src/master/Makefile
@@ -0,0 +1,18 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+
+OBJECTDIRS=sun3 vax
+
+clean:
+ -rm -f *.tex *.dvi *.log *.wlog *~ *.toc
+ @-for i in $(OBJECTDIRS); do \
+ rm -f $$i/*.o; \
+ done
+ -rm -f *.o
+
+superclean:
+ -rm -f sun3/*.o vax/*.o *.o
+ -rm -f *.c
+ -rm -f *.tex *.dvi *.log *~ *.toc
+
diff --git a/web/spiderweb/src/master/WebMakefile b/web/spiderweb/src/master/WebMakefile
new file mode 100644
index 0000000000..e6d4c84905
--- /dev/null
+++ b/web/spiderweb/src/master/WebMakefile
@@ -0,0 +1,146 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates.
+# To be used for research purposes only.
+# For more information, see file COPYRIGHT in the parent directory.
+
+HOME=/u/norman# # Make no longer inherits environment vars
+
+THETANGLE=tangle
+THEWEAVE=weave
+SPIDER=any.spider
+#
+DVI=dvi
+CFLAGS=-DDEBUG -g -DSTAT
+
+# CPUTYPE is a grim hack that attempts to solve the problem of multiple
+# cpus sharing a file system. In my environment I have to have different
+# copies of object and executable for vax, sun3, next, iris, and other
+# cpu types. If you will be using Spidery WEB in a homogenous processor
+# environment, you can just set CPUTYPE to a constant, or eliminate it
+# entirely.
+#
+# In my environment, the 'cputype' program returns a string that
+# describes the current processor. That means that the easiest thing
+# for you to do is to define a 'cputype' program that does something
+# sensible. A shell script that says 'echo "vax"' is fine.
+
+CPUTYPE=`cputype`
+
+# Change the following three directories to match your installation
+#
+# the odd placement of # is to prevent any trailing spaces from slipping in
+
+WEBROOT=$(HOME)/pu/web/spiderweb# # root of the WEB source distribution
+DEST=$(HOME)/bin/$(CPUTYPE)# # place where the executables go
+MACROS=$(HOME)/lib/tex/inputs/web# # place where the macros go
+
+MASTER=$(WEBROOT)/src/master# # master source directory
+OBDIR=$(MASTER)/$(CPUTYPE)# # common object files
+
+TANGLESRC=tangle
+CTANGLE=ceetangle -I$(MASTER)
+CWEAVE=ceeweave -I$(MASTER)
+AWKTANGLE=awktangle -I$(MASTER)
+COMMONOBJS=$(OBDIR)/common.o $(OBDIR)/pathopen.o
+COMMONC=$(MASTER)/common.c $(MASTER)/pathopen.c
+COMMONSRC=$(COMMONC) $(MASTER)/spider.awk
+
+
+
+# Our purpose is to make tangle and weave
+
+web: tangle weave
+
+tangle: $(COMMONOBJS) $(TANGLESRC).o
+ $(CC) $(CFLAGS) -o $(DEST)/$(THETANGLE) $(COMMONOBJS) $(TANGLESRC).o
+
+weave: $(COMMONOBJS) weave.o
+ $(CC) $(CFLAGS) -o $(DEST)/$(THEWEAVE) $(COMMONOBJS) weave.o
+
+
+source: $(TANGLESRC).c $(COMMONSRC) # make tangle.c and common src, then clean
+ if [ -f WebMakefile ]; then exit 1; fi # don't clean the master!
+ if [ -f spiderman.tex ]; then exit 1; fi # don't clean the manual
+ -rm -f tangle.web weave.* common.* # remove links that may be obsolete
+ -rm -f *.unsorted *.list grammar.web outtoks.web scraps.web
+ -rm -f cycle.test spider.slog
+ -rm -f *.o *.tex *.toc *.dvi *.log *.makelog *~ *.wlog *.printlog
+
+# Here is how we make the common stuff
+
+$(MASTER)/common.c: $(MASTER)/common.web # no change file
+ $(CTANGLE) $(MASTER)/common
+
+$(OBDIR)/common.o: $(MASTER)/common.c $(OBDIR)
+ $(CC) $(CFLAGS) -c $(MASTER)/common.c
+ mv common.o $(OBDIR)
+
+
+$(MASTER)/pathopen.c: $(MASTER)/pathopen.web # no change file
+ $(CTANGLE) $(MASTER)/pathopen
+ mv pathopen.h $(MASTER)
+
+$(OBDIR)/pathopen.o: $(MASTER)/pathopen.c $(OBDIR)
+ $(CC) $(CFLAGS) -c $(MASTER)/pathopen.c
+ mv pathopen.o $(OBDIR)
+
+$(OBDIR):
+ if /bin/test ! -d $(OBDIR) ; then mkdir $(OBDIR) ; fi
+
+## Now we make the tangle and weave source locally
+
+$(TANGLESRC).c: $(MASTER)/$(TANGLESRC).web $(MASTER)/common.h grammar.web
+ -/bin/rm -f $(TANGLESRC).web
+ ln $(MASTER)/$(TANGLESRC).web $(TANGLESRC).web
+# chmod -w $(TANGLESRC).web
+ $(CTANGLE) $(TANGLESRC)
+
+weave.c: $(MASTER)/weave.web $(MASTER)/common.h grammar.web
+ -/bin/rm -f weave.web
+ ln $(MASTER)/weave.web weave.web
+# chmod -w weave.web
+ $(CTANGLE) weave
+
+## Here's where we run SPIDER to create the source
+
+grammar.web: $(MASTER)/cycle.awk $(MASTER)/spider.awk $(SPIDER)
+ echo "date" `date` | cat - $(SPIDER) | awk -f $(MASTER)/spider.awk
+ cat $(MASTER)/transcheck.list trans_keys.unsorted | awk -f $(MASTER)/transcheck.awk
+ awk -f $(MASTER)/cycle.awk < cycle.test
+ sort *.unsorted | awk -f $(MASTER)/nodups.awk
+ mv *web.tex $(MACROS)
+
+## We might have to make spider first.
+
+$(MASTER)/spider.awk: $(MASTER)/spider.web
+ $(AWKTANGLE) $(MASTER)/spider
+ mv cycle.awk nodups.awk transcheck.awk $(MASTER)
+ rm junk.list
+
+
+# $(MASTER)/cycle.awk: $(MASTER)/cycle.web # making spider also makes cycle
+# $(AWKTANGLE) $(MASTER)/cycle
+
+
+# This cleanup applies to every language
+
+clean:
+ if [ -f WebMakefile ]; then exit 1; fi # don't clean the master!
+ if [ -f spiderman.tex ]; then exit 1; fi # don't clean the manual
+ -rm -f tangle.* weave.* common.* # remove links that may be obsolete
+ -rm -f *.unsorted *.list grammar.web outtoks.web scraps.web
+ -rm -f cycle.test spider.slog
+ -rm -f *.c *.o *.tex *.toc *.dvi *.log *.makelog *~ *.wlog *.printlog
+
+
+
+# booting the new distribution
+boot:
+ if [ ! -d $(OBDIR) ]; then mkdir $(OBDIR); fi
+ cd ../master; rm -f *.o; for i in $(COMMONC); do \
+ $(CC) $(CFLAGS) -c $$i; \
+ mv *.o $(OBDIR) ; \
+ done; cd ../c
+ $(CC) $(CFLAGS) -c $(TANGLESRC).c; \
+ $(CC) $(CFLAGS) -o $(DEST)/$(THETANGLE) $(COMMONOBJS) $(TANGLESRC).o
+
+
diff --git a/web/spiderweb/src/master/common.c b/web/spiderweb/src/master/common.c
new file mode 100644
index 0000000000..62d062cf27
--- /dev/null
+++ b/web/spiderweb/src/master/common.c
@@ -0,0 +1,1001 @@
+/*1:*/
+#line 49 "/u/norman/pu/web/dist/src/master/common.web"
+
+#include<stdio.h>
+#ifdef MSDOS
+#define index strchr
+#endif
+
+/*3:*/
+#line 71 "/u/norman/pu/web/dist/src/master/common.web"
+
+extern char the_at_sign;
+
+
+/*:3*//*65:*/
+#line 1052 "/u/norman/pu/web/dist/src/master/common.web"
+extern char C_file_extension[];
+#line 1053 "/u/norman/pu/web/dist/src/master/common.web"
+
+/*:65*/
+#line 55 "/u/norman/pu/web/dist/src/master/common.web"
+
+/*9:*/
+#line 197 "/u/norman/pu/web/dist/src/master/common.web"
+char setting_up;
+#line 198 "/u/norman/pu/web/dist/src/master/common.web"
+
+/*:9*/
+#line 56 "/u/norman/pu/web/dist/src/master/common.web"
+
+/*4:*/
+#line 75 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 76 "/u/norman/pu/web/dist/src/master/common.web"
+typedef short boolean;
+typedef char unsigned eight_bits;
+boolean program;
+
+/*:4*//*6:*/
+#line 159 "/u/norman/pu/web/dist/src/master/common.web"
+
+typedef char ASCII;
+typedef char outer_char;
+
+/*:6*//*7:*/
+#line 167 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 168 "/u/norman/pu/web/dist/src/master/common.web"
+ASCII xord[127+1];
+outer_char xchr[128];
+
+/*:7*//*12:*/
+#line 259 "/u/norman/pu/web/dist/src/master/common.web"
+
+ASCII buffer[500];
+ASCII *buffer_end= buffer+200-2;
+ASCII *limit;
+ASCII *loc;
+
+/*:12*//*14:*/
+#line 312 "/u/norman/pu/web/dist/src/master/common.web"
+
+int include_depth;
+FILE *file[10];
+FILE *change_file;
+char file_name[10][60];
+
+char change_file_name[60];
+int line[10];
+int change_line;
+boolean input_has_ended;
+boolean changing;
+
+/*:14*//*26:*/
+#line 501 "/u/norman/pu/web/dist/src/master/common.web"
+
+typedef unsigned short sixteen_bits;
+sixteen_bits module_count;
+boolean changed_module[2000];
+boolean print_where= 0;
+
+/*:26*//*37:*/
+#line 638 "/u/norman/pu/web/dist/src/master/common.web"
+
+typedef struct name_info{
+ASCII *byte_start;
+ /*41:*/
+#line 677 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 678 "/u/norman/pu/web/dist/src/master/common.web"
+struct name_info *link;
+
+/*:41*//*48:*/
+#line 767 "/u/norman/pu/web/dist/src/master/common.web"
+
+union{
+struct name_info *Rlink;
+
+eight_bits Ilk;
+}dummy;
+
+/*:48*//*55:*/
+#line 906 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 907 "/u/norman/pu/web/dist/src/master/common.web"
+ASCII *equiv_or_xref;
+
+/*:55*/
+#line 641 "/u/norman/pu/web/dist/src/master/common.web"
+
+}name_info;
+typedef name_info *name_pointer;
+ASCII byte_mem[90000];
+ASCII *byte_mem_end= byte_mem+90000-1;
+name_info name_dir[4000];
+name_pointer name_dir_end= name_dir+4000-1;
+
+/*:37*//*39:*/
+#line 663 "/u/norman/pu/web/dist/src/master/common.web"
+
+name_pointer name_ptr;
+ASCII *byte_ptr;
+
+/*:39*//*42:*/
+#line 690 "/u/norman/pu/web/dist/src/master/common.web"
+
+typedef name_pointer *hash_pointer;
+name_pointer hash[353];
+hash_pointer hash_end= hash+353-1;
+hash_pointer h;
+
+/*:42*//*56:*/
+#line 926 "/u/norman/pu/web/dist/src/master/common.web"
+
+int history= 0;
+
+/*:56*//*64:*/
+#line 1039 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 1040 "/u/norman/pu/web/dist/src/master/common.web"
+int argc;
+char * *argv;
+char C_file_name[60];
+char tex_file_name[60];
+int no_xref;
+
+/*:64*//*75:*/
+#line 1165 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 1166 "/u/norman/pu/web/dist/src/master/common.web"
+FILE *C_file;
+FILE *tex_file;
+
+/*:75*/
+#line 57 "/u/norman/pu/web/dist/src/master/common.web"
+
+/*5:*/
+#line 86 "/u/norman/pu/web/dist/src/master/common.web"
+int phase;
+#line 87 "/u/norman/pu/web/dist/src/master/common.web"
+
+/*:5*//*15:*/
+#line 334 "/u/norman/pu/web/dist/src/master/common.web"
+
+ASCII change_buffer[200];
+ASCII *change_limit;
+
+/*:15*//*30:*/
+#line 536 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 1 "pathopen.h"
+
+#line 187"/u/nr/web/src/master/pathopen.web"
+
+#line 188"/u/nr/web/src/master/pathopen.web"
+void pathaddname();
+void pathaddpath();
+void pathreset();
+FILE *pathopen();
+
+#line 538 "/u/norman/pu/web/dist/src/master/common.web"
+/*:30*//*50:*/
+#line 792 "/u/norman/pu/web/dist/src/master/common.web"
+
+name_pointer install_node();
+
+/*:50*/
+#line 58 "/u/norman/pu/web/dist/src/master/common.web"
+
+/*8:*/
+#line 183 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 184 "/u/norman/pu/web/dist/src/master/common.web"
+common_init()
+{
+strncpy(xchr," !\"#$%&'()*+,-./0123456789\
+:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ",128);
+/*11:*/
+#line 238 "/u/norman/pu/web/dist/src/master/common.web"
+
+
+/*:11*/
+#line 188 "/u/norman/pu/web/dist/src/master/common.web"
+;
+/*10:*/
+#line 202 "/u/norman/pu/web/dist/src/master/common.web"
+{
+#line 203 "/u/norman/pu/web/dist/src/master/common.web"
+int i;
+for(i= 0;i<=127;i++)
+xord[i]= 32;
+for(i= 1;i<127;i++)xord[xchr[i]]= i;
+}
+
+/*:10*/
+#line 189 "/u/norman/pu/web/dist/src/master/common.web"
+;
+/*40:*/
+#line 667 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 668 "/u/norman/pu/web/dist/src/master/common.web"
+name_dir->byte_start= byte_ptr= byte_mem;
+name_ptr= name_dir+1;
+name_ptr->byte_start= byte_mem;
+
+/*:40*//*43:*/
+#line 698 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 699 "/u/norman/pu/web/dist/src/master/common.web"
+for(h= hash;h<=hash_end; *h++= NULL);
+
+/*:43*//*49:*/
+#line 774 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 775 "/u/norman/pu/web/dist/src/master/common.web"
+name_dir->dummy.Rlink= NULL;
+
+/*:49*/
+#line 190 "/u/norman/pu/web/dist/src/master/common.web"
+;
+setting_up= 1;
+/*76:*/
+#line 1169 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 1170 "/u/norman/pu/web/dist/src/master/common.web"
+scan_args();
+/*28:*/
+#line 532 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 533 "/u/norman/pu/web/dist/src/master/common.web"
+pathaddpath(getenv("WEBPATH"),':');
+/*:28*/
+#line 1171 "/u/norman/pu/web/dist/src/master/common.web"
+
+if(program==0){
+if((C_file= fopen(C_file_name,"w"))==NULL)
+{printf("! Cannot open output file ");err_print(C_file_name);history= 3;wrap_up();};
+}
+else{
+if((tex_file= fopen(tex_file_name,"w"))==NULL)
+{printf("! Cannot open output file ");err_print(tex_file_name);history= 3;wrap_up();};
+}
+
+/*:76*/
+#line 192 "/u/norman/pu/web/dist/src/master/common.web"
+;
+setting_up= 0;
+}
+
+/*:8*//*13:*/
+#line 269 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 270 "/u/norman/pu/web/dist/src/master/common.web"
+#include<stdio.h>
+input_ln(fp)
+FILE *fp;
+{
+register int c;
+register ASCII *k;
+if(feof(fp))return(0);
+limit= k= buffer;
+while(k<=buffer_end&&(c= getc(fp))!=EOF&&c!='\n')
+if(( *(k++)= xord[c])!=32)limit= k;
+if(k>buffer_end)
+if((c= getc(fp))!=EOF&&c!='\n'){
+ungetc(c,fp);loc= buffer;err_print("\n! Input line too long");
+
+}
+if(c==EOF&&limit==buffer)return(0);
+
+return(1);
+}
+
+/*:13*//*16:*/
+#line 344 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 345 "/u/norman/pu/web/dist/src/master/common.web"
+prime_the_change_buffer()
+{
+change_limit= 0;
+/*17:*/
+#line 358 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 359 "/u/norman/pu/web/dist/src/master/common.web"
+while(1){
+change_line++;
+if(!input_ln(change_file))return;
+if(limit<buffer+2)continue;
+if(buffer[0]!=the_at_sign)continue;
+/*18:*/
+#line 376 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 377 "/u/norman/pu/web/dist/src/master/common.web"
+if(buffer[1]>=88&&buffer[1]<=90||buffer[1]==73)buffer[1]+= 122-90;
+
+/*:18*/
+#line 364 "/u/norman/pu/web/dist/src/master/common.web"
+;
+/*19:*/
+#line 381 "/u/norman/pu/web/dist/src/master/common.web"
+{
+#line 382 "/u/norman/pu/web/dist/src/master/common.web"
+if(buffer[1]==105){
+loc= buffer+2;
+err_print("! No includes allowed in change file");
+
+}
+}
+
+/*:19*/
+#line 365 "/u/norman/pu/web/dist/src/master/common.web"
+;
+if(buffer[1]==120)break;
+if(buffer[1]==121||buffer[1]==122){
+loc= buffer+2;
+err_print("! Where is the matching @x?");
+
+}
+}
+
+/*:17*/
+#line 348 "/u/norman/pu/web/dist/src/master/common.web"
+;
+/*20:*/
+#line 391 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 392 "/u/norman/pu/web/dist/src/master/common.web"
+do{
+change_line++;
+if(!input_ln(change_file)){
+err_print("! Change file ended after @x");
+
+return;
+}
+}while(limit==buffer);
+
+/*:20*/
+#line 349 "/u/norman/pu/web/dist/src/master/common.web"
+;
+/*21:*/
+#line 401 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 402 "/u/norman/pu/web/dist/src/master/common.web"
+{
+change_limit= change_buffer-buffer+limit;
+strncpy(change_buffer,buffer,limit-buffer+1);
+}
+
+/*:21*/
+#line 350 "/u/norman/pu/web/dist/src/master/common.web"
+;
+}
+
+/*:16*//*22:*/
+#line 416 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 417 "/u/norman/pu/web/dist/src/master/common.web"
+check_change()
+{
+int n= 0;
+if((change_limit-change_buffer!=limit-buffer||strncmp(buffer,change_buffer,limit-buffer)))return;
+while(1){
+changing= 1;print_where= 1;change_line++;
+if(!input_ln(change_file)){
+err_print("! Change file ended before @y");
+
+change_limit= 0;changing= 0;print_where= 1;
+return;
+}
+if(limit>buffer+1&&buffer[0]==the_at_sign)
+/*19:*/
+#line 381 "/u/norman/pu/web/dist/src/master/common.web"
+{
+#line 382 "/u/norman/pu/web/dist/src/master/common.web"
+if(buffer[1]==105){
+loc= buffer+2;
+err_print("! No includes allowed in change file");
+
+}
+}
+
+/*:19*/
+#line 430 "/u/norman/pu/web/dist/src/master/common.web"
+;
+/*23:*/
+#line 447 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 448 "/u/norman/pu/web/dist/src/master/common.web"
+if(limit>buffer+1&&buffer[0]==the_at_sign){
+/*18:*/
+#line 376 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 377 "/u/norman/pu/web/dist/src/master/common.web"
+if(buffer[1]>=88&&buffer[1]<=90||buffer[1]==73)buffer[1]+= 122-90;
+
+/*:18*/
+#line 449 "/u/norman/pu/web/dist/src/master/common.web"
+;
+if(buffer[1]==120||buffer[1]==122){
+loc= buffer+2;err_print("! Where is the matching @y?");
+
+}
+else if(buffer[1]==121){
+if(n>0){
+loc= buffer+2;
+err_print("! Hmm... some of the preceding lines failed to match");
+
+}
+return;
+}
+}
+
+/*:23*/
+#line 432 "/u/norman/pu/web/dist/src/master/common.web"
+;
+/*21:*/
+#line 401 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 402 "/u/norman/pu/web/dist/src/master/common.web"
+{
+change_limit= change_buffer-buffer+limit;
+strncpy(change_buffer,buffer,limit-buffer+1);
+}
+
+/*:21*/
+#line 433 "/u/norman/pu/web/dist/src/master/common.web"
+;
+changing= 0;print_where= 1;line[include_depth]++;
+while(!input_ln(file[include_depth])){
+if(include_depth==0){
+err_print("! WEB file ended during a change");
+
+input_has_ended= 1;return;
+}
+include_depth--;print_where= 1;line[include_depth]++;
+}
+if((change_limit-change_buffer!=limit-buffer||strncmp(buffer,change_buffer,limit-buffer)))n++;
+}
+}
+
+/*:22*//*24:*/
+#line 467 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 468 "/u/norman/pu/web/dist/src/master/common.web"
+reset_input()
+{
+limit= buffer;loc= buffer+1;buffer[0]= 32;
+/*25:*/
+#line 480 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 481 "/u/norman/pu/web/dist/src/master/common.web"
+if((file[0]= fopen(file_name[0],"r"))==NULL)
+{printf("! Cannot open input file ");err_print(file_name[0]);history= 3;wrap_up();};
+if((change_file= fopen(change_file_name,"r"))==NULL)
+{printf("! Cannot open change file ");err_print(change_file_name);history= 3;wrap_up();};
+
+/*:25*/
+#line 471 "/u/norman/pu/web/dist/src/master/common.web"
+;
+line[include_depth]= 0;change_line= 0;include_depth= 0;
+changing= 1;prime_the_change_buffer();changing= !changing;
+limit= buffer;loc= buffer+1;buffer[0]= 32;input_has_ended= 0;
+}
+
+/*:24*//*27:*/
+#line 507 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 508 "/u/norman/pu/web/dist/src/master/common.web"
+get_line()
+{
+restart:
+if(changing)changed_module[module_count]= 1;
+else/*34:*/
+#line 574 "/u/norman/pu/web/dist/src/master/common.web"
+{
+#line 575 "/u/norman/pu/web/dist/src/master/common.web"
+line[include_depth]++;
+while(!input_ln(file[include_depth])){
+print_where= 1;
+if(include_depth==0){input_has_ended= 1;break;}
+else{fclose(file[include_depth]);include_depth--;line[include_depth]++;}
+}
+if(!input_has_ended)
+if(limit==change_limit-change_buffer+buffer)
+if(buffer[0]==change_buffer[0])
+if(change_limit>change_buffer)check_change();
+}
+
+/*:34*/
+#line 512 "/u/norman/pu/web/dist/src/master/common.web"
+;
+if(changing){
+/*35:*/
+#line 587 "/u/norman/pu/web/dist/src/master/common.web"
+{
+#line 588 "/u/norman/pu/web/dist/src/master/common.web"
+change_line++;
+if(!input_ln(change_file)){
+err_print("! Change file ended without @z");
+
+buffer[0]= the_at_sign;buffer[1]= 122;limit= buffer+2;
+}
+if(limit>buffer+1)
+if(buffer[0]==the_at_sign){
+/*18:*/
+#line 376 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 377 "/u/norman/pu/web/dist/src/master/common.web"
+if(buffer[1]>=88&&buffer[1]<=90||buffer[1]==73)buffer[1]+= 122-90;
+
+/*:18*/
+#line 596 "/u/norman/pu/web/dist/src/master/common.web"
+;
+/*19:*/
+#line 381 "/u/norman/pu/web/dist/src/master/common.web"
+{
+#line 382 "/u/norman/pu/web/dist/src/master/common.web"
+if(buffer[1]==105){
+loc= buffer+2;
+err_print("! No includes allowed in change file");
+
+}
+}
+
+/*:19*/
+#line 597 "/u/norman/pu/web/dist/src/master/common.web"
+;
+if(buffer[1]==120||buffer[1]==121){
+loc= buffer+2;err_print("! Where is the matching @z?");
+
+}
+else if(buffer[1]==122){
+prime_the_change_buffer();changing= !changing;print_where= 1;
+}
+}
+}
+
+/*:35*/
+#line 514 "/u/norman/pu/web/dist/src/master/common.web"
+;
+if(!changing){
+changed_module[module_count]= 1;goto restart;
+}
+}
+loc= buffer; *limit= 32;
+if( *buffer==the_at_sign&&( *(buffer+1)==105|| *(buffer+1)==73))
+/*33:*/
+#line 546 "/u/norman/pu/web/dist/src/master/common.web"
+{
+#line 547 "/u/norman/pu/web/dist/src/master/common.web"
+ASCII *k, *j;
+loc= buffer+2;
+while(loc<=limit&&( *loc==32|| *loc==9|| *loc==34))loc++;
+if(loc>=limit)err_print("! Include file name not given");
+
+else{
+if(++include_depth<10){
+k= file_name[include_depth];j= loc;
+while( *loc!=32&& *loc!=9&& *loc!=34) *k++= xchr[ *loc++];
+ *k= '\0';
+if((file[include_depth]= pathopen(file_name[include_depth],"r"))==NULL){
+loc= j;
+include_depth--;
+err_print("! Cannot find include file on path");
+
+}
+else{line[include_depth]= 0;print_where= 1;}
+}
+else{
+include_depth--;
+err_print("! Too many nested includes");
+
+}
+}
+goto restart;
+}
+
+/*:33*/
+#line 521 "/u/norman/pu/web/dist/src/master/common.web"
+;
+return(!input_has_ended);
+}
+
+/*:27*//*32:*/
+#line 539 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 540 "/u/norman/pu/web/dist/src/master/common.web"
+void overflow (s)
+char *s;
+{{{printf("\n! Sorry, capacity exceeded: ");err_print(s);history= 3;wrap_up();};};}
+/*:32*//*36:*/
+#line 611 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 612 "/u/norman/pu/web/dist/src/master/common.web"
+check_complete(){
+if(change_limit!=0){
+strncpy(buffer,change_buffer,change_limit-change_buffer+1);
+limit= change_limit-change_buffer+buffer;
+changing= 1;loc= change_limit;
+err_print("! Change file entry did not match");
+
+}
+}
+
+/*:36*//*57:*/
+#line 940 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 941 "/u/norman/pu/web/dist/src/master/common.web"
+err_print(s)
+char *s;
+{
+ASCII *k, *l;
+printf("\n%s",(s==(char *)0)?"Bad error message!!!":s);
+if(setting_up){
+printf("\nError occurred while scanning arguments or opening output files. ");
+}else{
+/*58:*/
+#line 963 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 964 "/u/norman/pu/web/dist/src/master/common.web"
+if(changing)printf(". (l. %d of change file)\n",change_line);
+else if(include_depth==0)printf(". (l. %d)\n",line[include_depth]);
+else printf(". (l. %d of include file %s)\n",line[include_depth],file_name[include_depth]);
+l= (loc>=limit?limit:loc);
+if(l>buffer){
+for(k= buffer;k<l;k++)
+if( *k=='\t')putchar(' ');
+else putchar(xchr[ *k]);
+putchar('\n');
+for(k= buffer;k<l;k++)putchar(' ');
+}
+for(k= l;k<limit;k++)putchar(xchr[ *k]);
+if( *limit==124)putchar('|');
+putchar(' ');
+
+/*:58*/
+#line 949 "/u/norman/pu/web/dist/src/master/common.web"
+;
+}
+fflush(stdout);history= 2;
+}
+
+/*:57*//*62:*/
+#line 1009 "/u/norman/pu/web/dist/src/master/common.web"
+
+wrap_up(){
+putchar('\n');
+/*63:*/
+#line 1017 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 1018 "/u/norman/pu/web/dist/src/master/common.web"
+switch(history){
+case 0:printf("(No errors were found.)\n");break;
+case 1:
+printf("(Did you see the warning message above?)\n");break;
+case 2:
+printf("(Pardon me, but I think I spotted something wrong.)\n");break;
+case 3:printf("(That was a fatal error, my friend.)\n");
+}
+
+/*:63*/
+#line 1012 "/u/norman/pu/web/dist/src/master/common.web"
+;
+if(history>1)exit(1);
+else exit(0);
+}
+
+/*:62*//*66:*/
+#line 1060 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 1061 "/u/norman/pu/web/dist/src/master/common.web"
+scan_args()
+{
+char *dot_pos, *index();
+boolean found_web= 0,found_change= 0;
+no_xref= 0;
+while(--argc>0){
+if( * *(++argv)!='-'){
+if(!found_web)/*67:*/
+#line 1084 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 1085 "/u/norman/pu/web/dist/src/master/common.web"
+{
+if(strlen( *argv)>60-5)
+/*73:*/
+#line 1156 "/u/norman/pu/web/dist/src/master/common.web"
+{printf("! Filename %s too long\n");err_print( *argv);history= 3;wrap_up();};
+#line 1157 "/u/norman/pu/web/dist/src/master/common.web"
+
+/*:73*/
+#line 1087 "/u/norman/pu/web/dist/src/master/common.web"
+;
+if((dot_pos= index( *argv,'.'))==NULL)
+sprintf(file_name[0],"%s.web", *argv);
+else{
+sprintf(file_name[0],"%s", *argv);
+/*68:*/
+#line 1100 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 1101 "/u/norman/pu/web/dist/src/master/common.web"
+{char *p;
+p= dot_pos;
+while( *++p!='\0')
+if( *p=='.')dot_pos= p;
+}
+
+/*:68*/
+#line 1092 "/u/norman/pu/web/dist/src/master/common.web"
+
+ *dot_pos= 0;
+}
+sprintf(tex_file_name,"%s.tex", *argv);
+sprintf(C_file_name,"%s.%s", *argv,C_file_extension);
+found_web= 1;
+}
+
+/*:67*/
+#line 1069 "/u/norman/pu/web/dist/src/master/common.web"
+
+else if(!found_change)/*69:*/
+#line 1107 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 1108 "/u/norman/pu/web/dist/src/master/common.web"
+{
+if(strlen( *argv)>60-5)
+/*73:*/
+#line 1156 "/u/norman/pu/web/dist/src/master/common.web"
+{printf("! Filename %s too long\n");err_print( *argv);history= 3;wrap_up();};
+#line 1157 "/u/norman/pu/web/dist/src/master/common.web"
+
+/*:73*/
+#line 1110 "/u/norman/pu/web/dist/src/master/common.web"
+;
+if((dot_pos= index( *argv,'.'))==NULL)
+sprintf(change_file_name,"%s.ch", *argv);
+else sprintf(change_file_name,"%s", *argv);
+found_change= 1;
+}
+
+/*:69*/
+#line 1070 "/u/norman/pu/web/dist/src/master/common.web"
+
+else/*72:*/
+#line 1147 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 1148 "/u/norman/pu/web/dist/src/master/common.web"
+{
+if(program==0)
+{printf("! Usage: tangle webfile[.web] [changefile[.ch]] [-Ipathname ...]\n");err_print(0);history= 3;wrap_up();}
+else
+{printf("! Usage: weave webfile[.web] [changefile[.ch]] [-x] [-Ipathname ...]\n");err_print(
+0);history= 3;wrap_up();};
+}
+
+/*:72*/
+#line 1071 "/u/norman/pu/web/dist/src/master/common.web"
+;
+}
+else/*71:*/
+#line 1132 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 1133 "/u/norman/pu/web/dist/src/master/common.web"
+{
+switch(( *argv)[1]){
+case'x':
+no_xref= 1;
+break;
+case'I':
+/*29:*/
+#line 534 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 535 "/u/norman/pu/web/dist/src/master/common.web"
+pathaddname( *argv+2);
+/*:29*/
+#line 1139 "/u/norman/pu/web/dist/src/master/common.web"
+
+break;
+default:
+/*74:*/
+#line 1158 "/u/norman/pu/web/dist/src/master/common.web"
+{
+#line 1159 "/u/norman/pu/web/dist/src/master/common.web"
+printf("! Unknown option in argument %s\n", *argv);{if(history==0)history= 1;};
+}
+
+/*:74*/
+#line 1142 "/u/norman/pu/web/dist/src/master/common.web"
+;
+break;
+}
+}
+
+/*:71*/
+#line 1073 "/u/norman/pu/web/dist/src/master/common.web"
+;
+}
+if(!found_web)/*72:*/
+#line 1147 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 1148 "/u/norman/pu/web/dist/src/master/common.web"
+{
+if(program==0)
+{printf("! Usage: tangle webfile[.web] [changefile[.ch]] [-Ipathname ...]\n");err_print(0);history= 3;wrap_up();}
+else
+{printf("! Usage: weave webfile[.web] [changefile[.ch]] [-x] [-Ipathname ...]\n");err_print(
+0);history= 3;wrap_up();};
+}
+
+/*:72*/
+#line 1075 "/u/norman/pu/web/dist/src/master/common.web"
+;
+if(!found_change)/*70:*/
+#line 1117 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 1118 "/u/norman/pu/web/dist/src/master/common.web"
+#ifdef MSDOS
+strcpy(change_file_name,"NUL");
+#else
+strcpy(change_file_name,"/dev/null");
+#endif
+/*:70*/
+#line 1076 "/u/norman/pu/web/dist/src/master/common.web"
+;
+}
+
+/*:66*/
+#line 59 "/u/norman/pu/web/dist/src/master/common.web"
+;
+
+/*:1*//*44:*/
+#line 703 "/u/norman/pu/web/dist/src/master/common.web"
+name_pointer
+#line 704 "/u/norman/pu/web/dist/src/master/common.web"
+ id_lookup(first,last,t)
+ASCII *first;
+ASCII *last;
+eight_bits t;
+{
+ASCII *i= first;
+int h;
+int l;
+name_pointer p;
+if(last==NULL)for(last= first; *last!='\0';last++);
+l= last-first;
+/*45:*/
+#line 725 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 726 "/u/norman/pu/web/dist/src/master/common.web"
+h= *i;while(++i<last)h= (h+h+ *i)%353;
+
+/*:45*/
+#line 715 "/u/norman/pu/web/dist/src/master/common.web"
+;
+/*46:*/
+#line 731 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 732 "/u/norman/pu/web/dist/src/master/common.web"
+p= hash[h];
+while(p&&!names_match(p,first,l,t))p= p->link;
+if(p==NULL){
+p= name_ptr;
+p->link= hash[h];hash[h]= p;
+}
+
+/*:46*/
+#line 716 "/u/norman/pu/web/dist/src/master/common.web"
+;
+if(p==name_ptr)/*47:*/
+#line 743 "/u/norman/pu/web/dist/src/master/common.web"
+{
+#line 744 "/u/norman/pu/web/dist/src/master/common.web"
+if(byte_ptr+l>byte_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("byte memory");history= 3;wrap_up();};};
+if(name_ptr>=name_dir_end){{printf("\n! Sorry, capacity exceeded: ");err_print("name");history= 3;wrap_up();};};
+strncpy(byte_ptr,first,l);
+(++name_ptr)->byte_start= byte_ptr+= l;
+init_p(p,t);
+}
+
+/*:47*/
+#line 717 "/u/norman/pu/web/dist/src/master/common.web"
+;
+return(p);
+}
+
+/*:44*//*51:*/
+#line 795 "/u/norman/pu/web/dist/src/master/common.web"
+name_pointer
+#line 796 "/u/norman/pu/web/dist/src/master/common.web"
+ mod_lookup(k,l)
+ASCII *k;
+ASCII *l;
+{
+short c= 2;
+name_pointer p= name_dir->dummy.Rlink;
+name_pointer q= name_dir;
+while(p){
+c= web_strcmp(k,l+1,p->byte_start,(p+1)->byte_start);
+q= p;
+switch(c){
+case 0:p= p->link;continue;
+case 2:p= p->dummy.Rlink;continue;
+case 1:return p;
+default:err_print("! Incompatible section names");return NULL;
+
+}
+}
+return(install_node(q,c,k,l-k+1));
+}
+
+/*:51*//*52:*/
+#line 820 "/u/norman/pu/web/dist/src/master/common.web"
+
+#line 821 "/u/norman/pu/web/dist/src/master/common.web"
+web_strcmp(j,j1,k,k1)
+ASCII *j;
+ASCII *j1;
+ASCII *k;
+ASCII *k1;
+{
+while(k<k1&&j<j1&& *j== *k)k++,j++;
+if(k==k1)if(j==j1)return 1;
+else return 4;
+else if(j==j1)return 3;
+else if( *j< *k)return 0;
+else return 2;
+}
+
+/*:52*//*53:*/
+#line 843 "/u/norman/pu/web/dist/src/master/common.web"
+name_pointer
+#line 844 "/u/norman/pu/web/dist/src/master/common.web"
+ install_node(parent,c,j,name_len)
+name_pointer parent;
+int c;
+ASCII *j;
+int name_len;
+{
+name_pointer node= name_ptr;
+if(byte_ptr+name_len>byte_mem_end){{printf("\n! Sorry, capacity exceeded: ");err_print("byte memory");history= 3;wrap_up();};};
+if(name_ptr==name_dir_end){{printf("\n! Sorry, capacity exceeded: ");err_print("name");history= 3;wrap_up();};};
+if(c==0)parent->link= node;else parent->dummy.Rlink= node;
+node->link= NULL;node->dummy.Rlink= NULL;
+init_node(node);
+strncpy(byte_ptr,j,name_len);
+(++name_ptr)->byte_start= byte_ptr+= name_len;
+return(node);
+}
+
+/*:53*//*54:*/
+#line 867 "/u/norman/pu/web/dist/src/master/common.web"
+name_pointer
+#line 868 "/u/norman/pu/web/dist/src/master/common.web"
+ prefix_lookup(k,l)
+ASCII *k;
+ASCII *l;
+{
+short c= 2;
+short count= 0;
+name_pointer p= name_dir->dummy.Rlink;
+name_pointer q= NULL;
+
+name_pointer r= NULL;
+while(p){
+c= web_strcmp(k,l+1,p->byte_start,(p+1)->byte_start);
+switch(c){
+case 0:p= p->link;break;
+case 2:p= p->dummy.Rlink;break;
+default:r= p;count++;q= p->dummy.Rlink;p= p->link;
+}
+if(p==NULL){
+p= q;q= NULL;
+}
+}
+if(count==0)err_print("! Name does not match");
+
+if(count>1)err_print("! Ambiguous prefix");
+
+return(r);
+}
+
+/*:54*/
diff --git a/web/spiderweb/src/master/common.h b/web/spiderweb/src/master/common.h
new file mode 100644
index 0000000000..fdce4ce9e2
--- /dev/null
+++ b/web/spiderweb/src/master/common.h
@@ -0,0 +1,146 @@
+@ Here's stuff from the file |'common.web'| that has to be included in
+|'tangle.web'| and |'weave.web'|.
+
+General stuff:
+
+@d tangle = 0
+@d weave = 1
+
+@<Common code for \.{WEAVE} and \.{TANGLE}@>=
+typedef short boolean;
+typedef char unsigned eight_bits;
+extern boolean program; /* \.{WEAVE} or \.{TANGLE}? */
+extern int phase; /* which phase are we in? */
+
+@ @<Include files@>=
+#include <stdio.h>
+
+@ Code related to the character set:
+@d tab_mark = 011 /* ASCII code used as tab-skip */
+@d line_feed = 012 /* ASCII code thrown away at end of line */
+@d form_feed = 014 /* ASCII code used at end of page */
+@d carriage_return = 015 /* ASCII code used at end of line */
+
+@<Common code...@>=
+typedef char ASCII; /* type of characters inside \.{WEB} */
+typedef char outer_char; /* type of characters outside \.{WEB} */
+extern ASCII xord[]; /* specifies conversion of input characters */
+extern outer_char xchr[]; /* specifies conversion of output characters */
+ASCII mod_text[longest_name+1]; /* name being sought for */
+ASCII *mod_text_end = mod_text+longest_name; /* end of |mod_text| */
+ASCII *id_first; /* where the current identifier begins in the buffer */
+ASCII *id_loc; /* just after the current identifier in the buffer */
+
+@ Code related to input routines:
+Killed |buf_size|; already in weave and tangle.
+
+@<Common code...@>=
+extern ASCII buffer[]; /* where each line of input goes */
+extern ASCII *buffer_end; /* end of |buffer| */
+extern ASCII *loc; /* points to the next character to be read from the buffer*/
+extern ASCII *limit; /* points to the last character in the buffer */
+
+@ Code related to identifier and module name storage:
+Killed |max_bytes|, |max_names|, and |hash_size| --- all duplicated.
+
+@d length(c) = ((c+1)->byte_start-(c)->byte_start) /* the length of a name */
+@d print_id(c) = ASCII_write((c)->byte_start,length((c)))
+ /* print identifier or module name */
+@d llink = link /* left link in binary search tree for module names */
+@d rlink = dummy.Rlink /* right link in binary search tree for module names */
+@d ilk = dummy.Ilk /* ilk in checking identifiers */
+@d root = name_dir->rlink /* the root of the binary search tree
+ for module names */
+
+@<Common code...@>=
+typedef struct name_info {
+ ASCII *byte_start; /* beginning of the name in |byte_mem| */
+ struct name_info *link;
+ union {
+ struct name_info *Rlink; /* right link in binary search tree for module
+ names */
+ eight_bits Ilk; /* used by identifiers in \.{WEAVE} (and for checking
+ macros in \.{TANGLE}?) */
+ } dummy;
+ ASCII *equiv_or_xref; /* info corresponding to names */
+} name_info; /* contains information about an identifier or module name */
+typedef name_info *name_pointer; /* pointer into array of |name_info|s */
+typedef name_pointer *hash_pointer;
+extern ASCII byte_mem[]; /* characters of names */
+extern ASCII *byte_mem_end; /* end of |byte_mem| */
+extern name_info name_dir[]; /* information about names */
+extern name_pointer name_dir_end; /* end of |name_dir| */
+extern name_pointer name_ptr; /* first unused position in |byte_start| */
+extern ASCII *byte_ptr; /* first unused position in |byte_mem| */
+extern name_pointer hash[]; /* heads of hash lists */
+extern hash_pointer hash_end; /* end of |hash| */
+extern hash_pointer h; /* index into hash-head array */
+extern name_pointer id_lookup(); /* looks up a string in the identifier table */
+extern name_pointer mod_lookup(); /* finds module name */
+extern name_pointer prefix_lookup(); /* finds module name given a prefix */
+
+@ Code related to error handling:
+@d spotless = 0 /* |history| value for normal jobs */
+@d harmless_message = 1 /* |history| value when non-serious info was printed */
+@d error_message = 2 /* |history| value when an error was noted */
+@d fatal_message = 3 /* |history| value when we had to stop prematurely */
+@d mark_harmless = {if (history==spotless) history=harmless_message;}
+@d mark_error = history=error_message
+@d confusion(s) = fatal("\n! This can't happen: ",s)
+@d fatal(s1,s2) = {
+ printf(s1); err_print(s2);
+ history=fatal_message; wrap_up();
+}
+@d overflow(s) = {
+ fatal("\n! Sorry, capacity exceeded: ",s);
+}
+
+@<Common...@>=
+extern history; /* indicates how bad this run was */
+
+@ Code related to file handling:
+@f line x /* make |line| an unreserved word */
+@d max_file_name_length = 60
+@d cur_file = file[include_depth] /* current file */
+@d cur_file_name = file_name[include_depth] /* current file name */
+@d web_file_name = file_name[0] /* main source file name */
+@d cur_line = line[include_depth] /* number of current line in current file */
+
+@<Common code...@>=
+extern include_depth; /* current level of nesting */
+extern FILE *file[]; /* stack of non-change files */
+extern FILE *change_file; /* change file */
+extern char C_file_name[]; /* name of |C_file| */
+extern char tex_file_name[]; /* name of |tex_file| */
+extern char file_name[][max_file_name_length];
+ /* stack of non-change file names */
+extern char change_file_name[]; /* name of change file */
+extern line[]; /* number of current line in the stacked files */
+extern change_line; /* number of current line in change file */
+extern boolean input_has_ended; /* if there is no more input */
+extern boolean changing; /* if the current line is from |change_file| */
+
+@ Code related to module numbers:
+@<Common code...@>=
+typedef unsigned short sixteen_bits;
+extern sixteen_bits module_count; /* the current module number */
+extern boolean changed_module[]; /* is the module changed? */
+extern boolean print_where; /* tells \.{TANGLE} to print line and file info */
+
+@ Code related to command line arguments:
+@<Common code...@>=
+extern int argc; /* copy of |ac| parameter to |main| */
+extern char **argv; /* copy of |av| parameter to |main| */
+extern no_xref; /* should \.{WEAVE} print an index? */
+
+@ Code relating to output:
+@d update_terminal = fflush(stdout) /* empty the terminal output buffer */
+@d new_line = putchar('\n') @d putxchar = putchar
+@d ASCII_write(a,b) = fflush(stdout), write(1,a,b) /* write on the standard output */
+@d line_write(c) = write(fileno(C_file),c) /* write on the C output file */
+@d C_printf(c,a) = fprintf(C_file,c,a)
+@d C_putc(c) = putc(c,C_file)
+
+@<Common code...@>=
+FILE *C_file; /* where output of \.{TANGLE} goes */
+FILE *tex_file; /* where output of \.{WEAVE} goes */
diff --git a/web/spiderweb/src/master/common.web b/web/spiderweb/src/master/common.web
new file mode 100644
index 0000000000..5a1c3fa901
--- /dev/null
+++ b/web/spiderweb/src/master/common.web
@@ -0,0 +1,1198 @@
+% Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+% Not to be sold, but may be used freely for any purpose
+% For more information, see file COPYRIGHT in the parent directory
+
+% This file is part of Spidery WEB
+
+% This program by Norman Ramsey is based on programs Silvio Levy
+% and D. E. Knuth. Silvio Levy wrote most of the code.
+% It is distributed WITHOUT ANY WARRANTY, express or implied.
+% Dec 1987
+
+% Here is TeX material that gets inserted after \input webmac
+
+\message{OK, entering \string\batchmode...}
+\batchmode
+
+\def\hang{\hangindent 3em\indent\ignorespaces}
+\font\ninerm=cmr9
+\let\mc=\ninerm % medium caps
+\def\cee{C}
+\def\pb{$\.|\ldots\.|$} % C brackets (|...|)
+\def\v{\char'174} % vertical (|) in typewriter font
+\def\ceeref{{\it The C Reference Manual}}
+\mathchardef\RA="3221 % right arrow
+\mathchardef\BA="3224 % double arrow
+
+\def\title{Spidery COMMON}
+\def\contentspagenumber{1} % should be odd
+\def\topofcontents{\null\vfill
+ \titlefalse % include headline on the contents page
+ \def\rheader{\hfil}
+ \centerline{\titlefont Common Code in Spidery {\ttitlefont WEB}}
+ \vfill
+}
+
+
+@* Introduction. This file contains code common
+to both \.{TANGLE} and \.{WEAVE}, that roughly concerns the following
+problems: character uniformity, input routines, error handling and
+parsing of command line. We have tried to concentrate in this file
+all the system dependencies, so as to maximize portability.
+
+In the texts below we will
+sometimes use \.{WEB} to refer to either of the two component
+programs, if no confusion can arise.
+
+Here is the overall appearance of this file:
+
+@u@1
+#include <stdio.h>
+#ifdef MSDOS
+#define index strchr
+#endif
+
+@<External variables@>@;
+@<Global variables@>@;
+@<Definitions that should agree with \.{TANGLE} and \.{WEAVE}@>@;
+@<Other definitions@>@;
+@<Functions@>;
+
+@ In certain cases \.{TANGLE} and \.{WEAVE} should do almost, but not
+quite, the same thing. In these case we've written common code for
+both, differentiating between the two by means of the global variable
+|program|.
+
+@d tangle = 0
+@d weave = 1
+
+@ Give us an at sign that isn't always `@@':
+@d at_sign = the_at_sign
+@<External...@>=
+extern char the_at_sign;
+
+
+@ @<Definitions...@>=
+typedef short boolean;
+typedef char unsigned eight_bits;
+boolean program; /* \.{WEAVE} or \.{TANGLE}? */
+
+@ \.{CWEAVE} operates in three phases: first it inputs the source
+file and stores cross-reference data, then it inputs the source once again and
+produces the \TeX\ output file, and finally it sorts and outputs the index.
+Similarly, \.{CTANGLE} operates in two phases.
+The global variable |phase| tells which phase we are in.
+
+@<Other...@>= int phase; /* which phase are we in? */
+
+@* The character set.
+One of the main goals in the design of \.{WEB} has been to make it readily
+portable between a wide variety of computers. Yet \.{WEB} by its very
+nature must use a greater variety of characters than most computer
+programs deal with, and character encoding is one of the areas in which
+existing machines differ most widely from each other.
+
+To resolve this problem, all input to \.{WEAVE} and \.{TANGLE} is converted
+to an internal seven-bit code that is essentially standard ASCII, the
+``American Standard Code for Information Interchange.'' The conversion
+is done immediately when each character is read in. Conversely,
+characters are converted from ASCII to the user's external
+representation just before they are output.
+
+Such an internal code can be accessed by users of \.{WEB} by means of
+constructions like \.{@@`A'}, which should be distinguished from
+\.{'A'}. The former is transformed by
+\.{TANGLE} into an integer that is the internal code of \.A, but
+the latter, a |char| constant, is not touched by
+\.{WEB}, and will be interpreted by the \cee\ complier according to
+the machine's character set. (Actually, of course, it gets translated
+into \.{WEB}'s internal code just like any other character in the
+input file, but then it gets translated back at output time.)
+@^ASCII code@>
+
+Here is a table of the standard visible ASCII codes (\.{ } stands for
+a blank space):
+$$\def\:{\char\count255\global\advance\count255 by 1}
+\count255='40
+\vbox{
+\hbox{\hbox to 40pt{\it\hfill0\/\hfill}%
+\hbox to 40pt{\it\hfill1\/\hfill}%
+\hbox to 40pt{\it\hfill2\/\hfill}%
+\hbox to 40pt{\it\hfill3\/\hfill}%
+\hbox to 40pt{\it\hfill4\/\hfill}%
+\hbox to 40pt{\it\hfill5\/\hfill}%
+\hbox to 40pt{\it\hfill6\/\hfill}%
+\hbox to 40pt{\it\hfill7\/\hfill}}
+\vskip 4pt
+\hrule
+\def\^{\vrule height 10.5pt depth 4.5pt}
+\halign{\hbox to 0pt{\hskip -24pt\O{#0}\hfill}&\^
+\hbox to 40pt{\tt\hfill#\hfill\^}&
+&\hbox to 40pt{\tt\hfill#\hfill\^}\cr
+04&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+05&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+06&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+07&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+10&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+11&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+12&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+13&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+14&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+15&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+16&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+17&\:&\:&\:&\:&\:&\:&\:\cr}
+\hrule width 280pt}$$
+
+We introduce new types to distinguish between the transliterated characters
+and the characters in the outside world. Let all
+``interesting'' values that a |char| variable may take lie between
+|first_text_char| and |last_text_char|; for the ASCII code we can
+take |first_text_char=0| and |last_text_char=@'177|. We will tell \.{WEB}
+to convert all input characters in this range to its own code, and balk at
+characters outside the range. We make two assumptions:
+|first_text_char>=0| and |char| has room for at least eight bits.
+@^system dependencies@>
+
+@d first_text_char = 0 /* lowest interesting value of a |char| */
+@d last_text_char = @'177 /* highest interesting value of a |char| */
+
+@<Definitions...@>=
+typedef char ASCII; /* type of characters inside \.{WEB} */
+typedef char outer_char; /* type of characters outside \.{WEB} */
+
+@ The \.{WEAVE} and \.{TANGLE} processors convert between ASCII code and
+the user's external character set by means of arrays |xord| and |xchr|
+that are analogous to PASCAL's |ord| and |chr| functions.
+
+@<Definitions...@>=
+ASCII xord[last_text_char+1]; /* specifies conversion of input characters */
+outer_char xchr[@'200]; /* specifies conversion of output characters */
+
+@ Every system supporting \cee\ must be able to read and write the 95
+visible characters of standard ASCII above (although not necessarily using the
+ASCII codes to represent them). Conversely, these characters, plus
+the newline, are sufficient to write any \cee\ program. Other
+characters are desirable mainly in strings, and they can be referred
+to by means of escape sequences like \.{'\t'}.
+
+The basic implementation of \.{WEB}, then, only has to assign an
+|xord| to these 95 characters (newlines are swallowed by the reading
+routines). The easiest way to do this is to assign the characters to
+their positions in |xchr| and then invert the correspondence:
+
+@<Functions...@>=
+common_init()
+{
+ strncpy(xchr," !\"#$%&'()*+,-./0123456789\
+:;<=>?@@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ",@'200);
+ @<System-dependent parts of character set@>;
+ @<Invert |xchr| to get |xord|@>;
+ @<Initialize pointers@>;
+ setting_up=1;
+ @<Scan arguments and open output files@>;
+ setting_up=0;
+}
+
+@ We use this variable to tell us what to do in |err_print|.
+@<Global var...@>=char setting_up;
+
+@ The following system-independent code makes the |xord| array contain
+a suitable inverse to the information in |xchr|.
+
+@<Invert |xchr|...@>= {
+ int i; /* to invert the correspondence */
+ for (i=first_text_char; i<=last_text_char; i++)
+ xord[i]=@'40; /* ASCII code for space */
+ for (i=1; i<@'177; i++) xord[xchr[i]]=i;
+}
+
+@ Some \cee\ compilers, accept an extended character
+set, so that one can type things like \.^^Z\ instead of \.{!=}.
+If that's the case in your system, you should change this module,
+assigning positions |@'1| to |@'37| in the most convenient way;
+for example, at MIT you can just say
+$$\hbox{|for (i=1; i<=@'37; i++) xchr[i]=i;|}$$
+since \.{WEB}'s character set is essentially identical to MIT's,
+even with respect to characters less than |@'40| (see the definitions
+below). If, however, the changes do not conform with these
+definitions you should change the definitions as well.
+@^system dependencies@>
+@^notes to myself@>
+
+@d and_and = @'4 /* `\.{\&\&}' */
+@d tab_mark = @'11 /* ASCII code used as tab-skip */
+@d line_feed = @'12 /* ASCII code thrown away at end of line */
+@d form_feed = @'14 /* ASCII code used at end of page */
+@d carriage_return = @'15 /* ASCII code used at end of line */
+@d gt_gt = @'20 /* `\.{>>}'; this doesn't exist in MIT */
+@d lt_lt = @'22 /* `\.{<<}'; this doesn't exist in MIT */
+@d plus_plus = @'13 /* `\.{++}'; this corresponds to MIT's up-arrow */
+@d minus_minus = @'1 /* `\.{--}'; this corresponds to MIT's down-arrow */
+@d minus_gt = @'31 /* `\.{->}' */
+@d not_eq = @'32 /* `\.{!=}' */
+@d lt_eq = @'34 /* `\.{<=}' */
+@d gt_eq = @'35 /* `\.{>=}' */
+@d eq_eq = @'36 /* `\.{==}' */
+@d or_or = @'37 /* `\.{\vert\vert}' */
+
+@<System-dependent parts of character set@>= /* nothing needs to be done */
+
+@* Input routines. The lowest level of input to the \.{WEB} programs
+is performed by |input_ln|, which must be told which file to read from.
+The return value of |input_ln| is 1 if the read is successful and 0 if
+not (generally this means the file has ended). The conventions
+of \TeX\ are followed; i.e., the characters of the next line of the file
+are translated to |ASCII| code and copied into the |buffer| array,
+and the global variable |limit| is set to the first unoccupied position.
+Trailing blanks are ignored. The value of |limit| must be strictly less
+than |buf_size|, so that |buffer[buf_size-1]| is never filled.
+
+We assume that none of the |ASCII| values of |*j| for |buffer<=j<limit|
+is equal to 0, |@'177|, |line_feed|, |form_feed|, or |carriage_return|.
+Since |buf_size| is strictly less than |long_buf_size|,
+some of \.{WEB}'s routines use the fact that it is safe to refer to
+|*(limit+2)| without overstepping the bounds of the array.
+
+@d buf_size = 200 /* for \.{WEAVE} and \.{TANGLE} */
+@d long_buf_size = 500 /* for \.{WEAVE} */
+
+@<Definitions...@>=
+ASCII buffer[long_buf_size]; /* where each line of input goes */
+ASCII *buffer_end=buffer+buf_size-2; /* end of |buffer| */
+ASCII *limit; /* points to the last character in the buffer */
+ASCII *loc; /* points to the next character to be read from the buffer */
+
+@ In the unlikely event that you standard I/O library does not
+support |feof|, |getc| and |ungetc| you may have to change things here.
+@^system dependencies@>
+
+@<Func...@>=
+#include <stdio.h>
+input_ln(fp) /* copies a line into |buffer| or returns 0 */
+FILE *fp; /* what file to read from */
+{
+ register int c; /* the character read */
+ register ASCII *k; /* where next character goes */
+ if (feof(fp)) return(0); /* we have hit end-of-file */
+ limit = k = buffer; /* beginning of buffer */
+ while (k<=buffer_end && (c=getc(fp)) != EOF && c!='\n')
+ if ((*(k++) = xord[c]) != @` ') limit = k;
+ if (k>buffer_end)
+ if ((c=getc(fp))!=EOF && c!='\n') {
+ ungetc(c,fp); loc=buffer; err_print("\n! Input line too long");
+@.Input line too long@>
+ }
+ if (c==EOF && limit==buffer) return(0); /* there was nothing after
+ the last newline */
+ return(1);
+}
+
+@ Now comes the problem of deciding which file to read from next.
+Recall that the actual text that \.{WEB} should process comes from two
+streams: a |web_file|, which can contain possibly nested include
+commands `|@i|', and a |change_file|, which should not contain
+includes. The |web_file| together with the currently open include
+files form a stack |file|, whose names are stored in a parallel stack
+|file_name|. The boolean |changing| tells whether or not we're reading
+form the |change_file|.
+
+The line number of each open file is also kept for error reporting and
+for the benefit of \.{TANGLE}.
+
+@f line x /* make |line| an unreserved word */
+@d max_include_depth = 10 /* maximum number of source files open
+ simultaneously, not counting the change file */
+@d max_file_name_length = 60
+@d cur_file = file[include_depth] /* current file */
+@d cur_file_name = file_name[include_depth] /* current file name */
+@d cur_line = line[include_depth] /* number of current line in current file */
+@d web_file = file[0] /* main source file */
+@d web_file_name = file_name[0] /* main source file name */
+
+@<Definitions...@>=
+int include_depth; /* current level of nesting */
+FILE *file[max_include_depth]; /* stack of non-change files */
+FILE *change_file; /* change file */
+char file_name[max_include_depth][max_file_name_length];
+ /* stack of non-change file names */
+char change_file_name[max_file_name_length]; /* name of change file */
+int line[max_include_depth]; /* number of current line in the stacked files */
+int change_line; /* number of current line in change file */
+boolean input_has_ended; /* if there is no more input */
+boolean changing; /* if the current line is from |change_file| */
+
+@ When |changing=0|, the next line of |change_file| is kept in
+|change_buffer|, for purposes of comparison with the next
+line of |cur_file|. After the change file has been completely input, we
+set |change_limit=change_buffer|, so that no further matches will be made.
+
+Here's a shorthand expression for inequality between the two lines:
+
+@d lines_dont_match = (change_limit-change_buffer != limit-buffer ||
+ strncmp(buffer, change_buffer, limit-buffer))
+
+@<Other...@>=
+ASCII change_buffer[buf_size]; /* where next line of |change_file| is kept */
+ASCII *change_limit; /* points to the last character in |change_buffer| */
+
+@ Procedure |prime_the_change_buffer| sets |change_buffer| in preparation
+for the next matching operation. Since blank lines in the change file are
+not used for matching, we have |(change_limit==0 && !changing)| if and
+only if the change file is exhausted. This procedure is called only
+when |changing| is 1; hence error messages will be reported correctly.
+
+@<Func...@>=
+prime_the_change_buffer()
+{
+ change_limit=0; /* this value will be used if the change file ends */
+ @<Skip over comment lines in the change file; |return| if end of file@>;
+ @<Skip to the next nonblank line; |return| if end of file@>;
+ @<Move |buffer| and |limit| to |change_buffer| and |change_limit|@>;
+}
+
+@ While looking for a line that begins with \.{@@x} in the change file,
+we allow lines that begin with \.{@@}, as long as they don't begin with
+\.{@@y} or \.{@@z} (which would probably indicate that the change file is
+fouled up).
+
+@<Skip over comment lines in the change file...@>=
+while(1) {
+ change_line++;
+ if (!input_ln(change_file)) return;
+ if (limit<buffer+2) continue;
+ if (buffer[0]!=the_at_sign) continue;
+ @<Lowercasify |buffer[1]|@>;
+ @<Check for erroneous \.{@@i}@>;
+ if (buffer[1]==@`x') break;
+ if (buffer[1]==@`y' || buffer[1]==@`z') {
+ loc=buffer+2;
+ err_print("! Where is the matching @@x?");
+@.Where is the match...@>
+ }
+}
+
+@ This line of code makes |"@@X"| equivalent to |"@@x"| and so on.
+
+@<Lowerc...@>=
+if (buffer[1]>=@`X' && buffer[1]<=@`Z' || buffer[1]==@`I') buffer[1]+=@`z'-@`Z';
+
+@ We do not allow includes in a change file, so as to avoid confusion.
+
+@<Check for erron...@>= {
+ if (buffer[1]==@`i') {
+ loc=buffer+2;
+ err_print("! No includes allowed in change file");
+@.No includes allowed...@>
+ }
+}
+
+@ Here we are looking at lines following the \.{@@x}.
+
+@<Skip to the next nonblank line...@>=
+do {
+ change_line++;
+ if (!input_ln(change_file)) {
+ err_print("! Change file ended after @@x");
+@.Change file ended...@>
+ return;
+ }
+} while (limit==buffer);
+
+@ @<Move |buffer| and |limit| to |change_buffer| and |change_limit|@>=
+{
+ change_limit=change_buffer-buffer+limit;
+ strncpy(change_buffer,buffer,limit-buffer+1);
+}
+
+@ The following procedure is used to see if the next change entry should
+go into effect; it is called only when |changing| is 0.
+The idea is to test whether or not the current
+contents of |buffer| matches the current contents of |change_buffer|.
+If not, there's nothing more to do; but if so, a change is called for:
+All of the text down to the \.{@@y} is supposed to match. An error
+message is issued if any discrepancy is found. Then the procedure
+prepares to read the next line from |change_file|.
+
+@<Func...@>=
+check_change() /* switches to |change_file| if the buffers match */
+{
+ int n=0; /* the number of discrepancies found */
+ if (lines_dont_match) return;
+ while (1) {
+ changing=1; print_where=1; change_line++;
+ if (!input_ln(change_file)) {
+ err_print("! Change file ended before @@y");
+@.Change file ended...@>
+ change_limit=0; changing=0; print_where=1;
+ return;
+ }
+ if (limit>buffer+1 && buffer[0]==the_at_sign)
+ @<Check for erron...@>;
+ @<If the current line starts with \.{@@y},
+ report any discrepancies and |return|@>;@/
+ @<Move |buffer| and |limit|...@>;@/
+ changing=0; print_where=1; cur_line++;
+ while (!input_ln(cur_file)) { /* pop the stack or quit */
+ if (include_depth==0) {
+ err_print("! WEB file ended during a change");
+@.WEB file ended...@>
+ input_has_ended=1; return;
+ }
+ include_depth--; print_where=1; cur_line++;
+ }
+ if (lines_dont_match) n++;
+ }
+}
+
+@ @<If the current line starts with \.{@@y}...@>=
+if (limit>buffer+1 && buffer[0]==the_at_sign) {
+ @<Lowerc...@>;
+ if (buffer[1]==@`x' || buffer[1]==@`z') {
+ loc=buffer+2; err_print("! Where is the matching @@y?");
+@.Where is the match...@>
+ }
+ else if (buffer[1]==@`y') {
+ if (n>0) {
+ loc=buffer+2;
+ err_print("! Hmm... some of the preceding lines failed to match");
+@.Hmm... some of the preceding...@>
+ }
+ return;
+ }
+}
+
+@ The |reset_input| procedure, which gets \.{CWEAVE} ready to read the
+user's \.{WEB} input, is used at the beginning of phases one and two.
+
+@<Func...@>=
+reset_input()
+{
+ limit=buffer; loc=buffer+1; buffer[0]=@` ';
+ @<Open input files@>;
+ cur_line=0; change_line=0; include_depth=0;
+ changing=1; prime_the_change_buffer(); changing=!changing;
+ limit=buffer; loc=buffer+1; buffer[0]=@` '; input_has_ended=0;
+}
+
+@ The following code opens the input files.
+@^system dependencies@>
+For the input files, we {\em don't} look on the search path.
+@<Open input files@>=
+if ((web_file=fopen(web_file_name,"r"))==NULL)
+ fatal("! Cannot open input file ", web_file_name);
+if ((change_file=fopen(change_file_name,"r"))==NULL)
+ fatal("! Cannot open change file ", change_file_name);
+
+@ The |get_line| procedure is called when |loc>limit|; it puts the next
+line of merged input into the buffer and updates the other variables
+appropriately. A space is placed at the right end of the line.
+This procedure returns |!input_has_ended| because we often want to
+check the value of that variable after calling the procedure.
+
+If we've just changed from the |cur_file| to the |change_file|, or if
+the |cur_file| has changed, we tell \.{TANGLE} to print this
+information in the \cee\ file by means of the |print_where| flag.
+
+@d max_modules = 2000 /* number of identifiers, strings, module names;
+ must be less than 10240 */
+
+
+
+@<Defin...@>=
+typedef unsigned short sixteen_bits;
+sixteen_bits module_count; /* the current module number */
+boolean changed_module[max_modules]; /* is the module changed? */
+boolean print_where=0; /* tells \.{TANGLE} to print line and file info */
+
+@ @<Fun...@>=
+get_line() /* inputs the next line */
+{
+ restart:
+ if (changing) changed_module[module_count]=1;
+ else @<Read from |cur_file| and maybe turn on |changing|@>;
+ if (changing) {
+ @<Read from |change_file| and maybe turn off |changing|@>;
+ if (! changing) {
+ changed_module[module_count]=1; goto restart;
+ }
+ }
+ loc=buffer; *limit=@` ';
+ if (*buffer==the_at_sign && (*(buffer+1)==@`i' || *(buffer+1)==@`I'))
+ @<Push stack and go to |restart|@>;
+ return (!input_has_ended);
+}
+
+@ When a \.{@@i} line is found in the |cur_file|, we must temporarily
+stop reading it and start reading from the named include file. The
+\.{@@i} line should give a complete file name with or without \.{"..."};
+\.{WEB} will look for include files in standard directories using
+the |pathopen| module.
+That is set up at the beginning using the {\tt -I} arguments
+and the {\tt WEBPATH} environment variable.
+@<Add environment variable |"WEBPATH"| to search path@>=
+ pathaddpath(getenv("WEBPATH"),':');
+@ @<Add path name from {\tt -I} to search path@>=
+ pathaddname(*argv+2);
+@ @<Other...@>=
+@i pathopen.h
+@ We need to define an |overflow| {\em function} for |pathopen| to call.
+@ @<Functions@>=
+void @= overflow @>(s)
+ char *s;
+{ overflow(s);}
+@ The included file name should only contain visible ASCII characters,
+since the characters are translated into ASCII and back again.
+
+@<Push stack and...@>= {
+ ASCII *k, *j;
+ loc=buffer+2;
+ while (loc<=limit && (*loc==@` '||*loc==@`\t'||*loc==@`"')) loc++;
+ if (loc>=limit) err_print("! Include file name not given");
+@.Include file name not given@>
+ else {
+ if (++include_depth<max_include_depth) {
+ k=cur_file_name; j=loc;
+ while (*loc!=@` '&&*loc!=@`\t'&&*loc!=@`"') *k++=xchr[*loc++];
+ *k='\0';
+ if ((cur_file=pathopen(cur_file_name,"r"))==NULL) {
+ loc=j;
+ include_depth--;
+ err_print("! Cannot find include file on path");
+@.Cannot find include file on path@>
+ }
+ else {cur_line=0; print_where=1;}
+ }
+ else {
+ include_depth--;
+ err_print("! Too many nested includes");
+@.Too many nested includes@>
+ }
+ }
+ goto restart;
+}
+
+@ @<Read from |cur_file|...@>= {
+ cur_line++;
+ while (!input_ln(cur_file)) { /* pop the stack or quit */
+ print_where=1;
+ if (include_depth==0) {input_has_ended=1; break;}
+ else {fclose(cur_file); include_depth--; cur_line++;}
+ }
+ if (!input_has_ended)
+ if (limit==change_limit-change_buffer+buffer)
+ if (buffer[0]==change_buffer[0])
+ if (change_limit>change_buffer) check_change();
+}
+
+@ @<Read from |change_file|...@>= {
+ change_line++;
+ if (!input_ln(change_file)) {
+ err_print("! Change file ended without @@z");
+@.Change file ended...@>
+ buffer[0]=the_at_sign; buffer[1]=@`z'; limit=buffer+2;
+ }
+ if (limit>buffer+1) /* check if the change has ended */
+ if (buffer[0]==the_at_sign) {
+ @<Lowerc...@>;
+ @<Check for erron...@>;
+ if (buffer[1]==@`x' || buffer[1]==@`y') {
+ loc=buffer+2; err_print("! Where is the matching @@z?");
+@.Where is the match...@>
+ }
+ else if (buffer[1]==@`z') {
+ prime_the_change_buffer(); changing=!changing; print_where=1;
+ }
+ }
+}
+
+@ At the end of the program, we will tell the user if the change file
+had a line that didn't match any relevant line in |web_file|.
+
+@<Funct...@>=
+check_complete(){
+ if (change_limit!=0) { /* |changing| is 0 */
+ strncpy(buffer,change_buffer,change_limit-change_buffer+1);
+ limit=change_limit-change_buffer+buffer;
+ changing=1; loc=change_limit;
+ err_print("! Change file entry did not match");
+ @.Change file entry did not match@>
+ }
+}
+
+@* Storage of identifiers and module names.
+Both \.{WEAVE} and \.{TANGLE} store identifiers, module names and
+other strings in a large array of |ASCII|s, called |byte_mem|.
+Information about the names is kept in the array |name_dir|, whose
+elements are structures of type \&{name\_info}, containing a pointer into
+the |byte_mem| array (the address where the name begins) and other data.
+A \&{name\_pointer} variable is a pointer into |name_dir|.
+
+This module has to go after the module that defines the types of the
+other elements, so it has a special name.
+
+@d max_bytes = 90000 /* the number of bytes in identifiers,
+ index entries, and module names */
+@d max_names = 4000 /* number of identifiers, strings, module names;
+ must be less than 10240 */
+
+@<Definitions that...@>=
+typedef struct name_info {
+ ASCII *byte_start; /* beginning of the name in |byte_mem| */
+ ===> @<More elements of |name_info| structure@>@;
+} name_info; /* contains information about an identifier or module name */
+typedef name_info *name_pointer; /* pointer into array of |name_info|s */
+ASCII byte_mem[max_bytes]; /* characters of names */
+ASCII *byte_mem_end = byte_mem+max_bytes-1; /* end of |byte_mem| */
+name_info name_dir[max_names]; /* information about names */
+name_pointer name_dir_end = name_dir+max_names-1; /* end of |name_dir| */
+
+@ The actual sequence of characters in the name pointed to by a
+|name_pointer| |p| appears in positions
+|p->byte_start| to |(p+1)->byte_start|, inclusive.
+The |print_id| macro prints this text on the user's terminal.
+
+@d length(c) = (c+1)->byte_start-(c)->byte_start /* the length of a name */
+@d print_id(c) = ASCII_write((c)->byte_start,length((c)))
+ /* print identifier or module name */
+
+@ The first unused position in |byte_mem| and |name_dir| is
+kept in |byte_ptr| and |name_ptr|, respectively. Thus we
+usually have |name_ptr->byte_start=byte_ptr|, and certainly
+we want to keep |name_ptr<=name_dir_end| and |byte_ptr<=byte_mem_end|.
+
+@<Defini...@>=
+name_pointer name_ptr; /* first unused position in |byte_start| */
+ASCII *byte_ptr; /* first unused position in |byte_mem| */
+
+@ @<Init...@>=
+name_dir->byte_start=byte_ptr=byte_mem; /* position zero in both arrays */
+name_ptr=name_dir+1; /* |name_dir[0]| will not be used */
+name_ptr->byte_start=byte_mem; /* this makes name 0 of length zero */
+
+@ The names of identifiers are found by computing a hash address |h| and
+then looking at strings of bytes signified by the |name_pointer|s
+|hash[h]|, |hash[h]->link|, |hash[h]->link->link|, \dots,
+until either finding the desired name or encountering the null pointer.
+
+@<More elements of |name...@>=
+struct name_info *link;
+
+@ The hash table itself
+consists of |hash_size| entries of type |name_pointer|, and is
+updated by the |id_lookup| procedure, which finds a given identifier
+and returns the appropriate |name_pointer|. The matching is done by the
+function |names_match|, which is slightly different in
+\.{WEAVE} and \.{TANGLE}. If there is no match for the identifier,
+it is inserted into the table.
+
+@d hash_size = 353 /* should be prime */
+
+@<Defini...@>=
+typedef name_pointer *hash_pointer;
+name_pointer hash[hash_size]; /* heads of hash lists */
+hash_pointer hash_end = hash+hash_size-1; /* end of |hash| */
+hash_pointer h; /* index into hash-head array */
+
+@ Initially all the hash lists are empty.
+
+@<Init...@>=
+for (h=hash; h<=hash_end; *h++=NULL) ;
+
+@ Here is the main procedure for finding identifiers:
+
+@u name_pointer
+id_lookup(first,last,t) /* looks up a string in the identifier table */
+ASCII *first; /* first character of string */
+ASCII *last; /* last character of string plus one */
+eight_bits t; /* the |ilk|; used by \.{WEAVE} and by \.{TANGLE} for macros */
+{
+ ASCII *i=first; /* position in |buffer| */
+ int h; /* hash code */
+ int l; /* length of the given identifier */
+ name_pointer p; /* where the identifier is being sought */
+ if (last==NULL) for (last=first; *last!='\0'; last++);
+ l=last-first; /* compute the length */
+ @<Compute the hash code |h|@>;
+ @<Compute the name location |p|@>;
+ if (p==name_ptr) @<Enter a new name into the table at position |p|@>;
+ return(p);
+}
+
+@ A simple hash code is used: If the sequence of
+ASCII codes is $c_1c_2\ldots c_n$, its hash value will be
+$$(2^{n-1}c_1+2^{n-2}c_2+\cdots+c_n)\,\bmod\,|hash_size|.$$
+
+@<Compute the hash...@>=
+h=*i; while (++i<last) h=(h+h+*i) % hash_size;
+
+@ If the identifier is new, it will be placed in position |p=name_ptr|,
+otherwise |p| will point to its existing location.
+
+@<Compute the name location...@>=
+p=hash[h];
+while (p && !names_match(p,first,l,t)) p=p->link;
+if (p==NULL) {
+ p=name_ptr; /* the current identifier is new */
+ p->link=hash[h]; hash[h]=p; /* insert |p| at beginning of hash list */
+}
+
+@ The information associated with a new identifier must be initialized
+in a slightly different way in \.{WEAVE} than in \.{TANGLE}; hence the
+|init_p| procedure.
+
+@<Enter a new name...@>= {
+ if (byte_ptr+l>byte_mem_end) overflow("byte memory");
+ if (name_ptr>=name_dir_end) overflow("name");
+ strncpy(byte_ptr,first,l);
+ (++name_ptr)->byte_start=byte_ptr+=l;
+ init_p(p,t); /* set ilk */
+}
+
+@ The names of modules are stored in |byte_mem| together
+with the identifier names, but a hash table is not used for them because
+\.{TANGLE} needs to be able to recognize a module name when given a prefix of
+that name. A conventional binary seach tree is used to retrieve module names,
+with fields called |llink| and |rlink| (where |llink| takes the place
+of |link|). The root of this tree is stored in |name_dir->rlink|;
+this will be the only information in |name_dir[0]|.
+
+Since the space used by |rlink| has a different function for
+identifiers than for module names, we declare it as a |union|.
+
+@d llink = link /* left link in binary search tree for module names */
+@d rlink = dummy.Rlink /* right link in binary search tree for module names */
+@d root = name_dir->rlink /* the root of the binary search tree
+ for module names */
+
+@<More elements of |name...@>=
+union {
+ struct name_info *Rlink; /* right link in binary search tree for module
+ names */
+ eight_bits Ilk; /* used by identifiers in \.{WEAVE} only */
+} dummy;
+
+@ @<Init...@>=
+root=NULL; /* the binary search tree starts out with nothing in it */
+
+@ The |mod_lookup| procedure finds a module name in the
+search tree, after inserting it if necessary, and returns a pointer to
+where it was found.
+
+According to the rules of \.{WEB}, no module name should be a proper
+prefix of another, so a ``clean'' comparison should occur between any
+two names. The result of |mod_lookup| is |NULL| if this prefix condition
+is violated. An error message is printed when such violations are detected.
+
+@d less = 0 /* the first name is lexicographically less than the second */
+@d equal = 1 /* the first name is equal to the second */
+@d greater = 2 /* the first name is lexicographically greater than the second */
+@d prefix = 3 /* the first name is a proper prefix of the second */
+@d extension = 4 /* the first name is a proper extension of the second */
+
+@<Other...@>=
+name_pointer install_node();
+
+@ @u name_pointer
+mod_lookup(k,l) /* finds module name */
+ASCII *k; /* first character of name */
+ASCII *l; /* last character of name */
+{
+ short c = greater; /* comparison between two names */
+ name_pointer p = root; /* current node of the search tree */
+ name_pointer q = name_dir; /* father of node |p| */
+ while (p) {
+ c=web_strcmp(k,l+1,p->byte_start,(p+1)->byte_start);
+ q=p;
+ switch(c) {
+ case less: p=p->llink; continue;
+ case greater: p=p->rlink; continue;
+ case equal: return p;
+ default: err_print("! Incompatible section names"); return NULL;
+@.Incompatible section names@>
+ }
+ }
+ return(install_node(q,c,k,l-k+1));
+}
+
+@ This function is like |strcmp|, but it does not assume the strings
+are null-terminated.
+
+@u
+web_strcmp(j,j1,k,k1) /* fuller comparison than |strcmp| */
+ASCII *j; /* beginning of first string */
+ASCII *j1; /* end of first string plus one */
+ASCII *k; /* beginning of second string */
+ASCII *k1; /* end of second string plus one */
+{
+ while (k<k1 && j<j1 && *j==*k) k++, j++;
+ if (k==k1) if (j==j1) return equal;
+ else return extension;
+ else if (j==j1) return prefix;
+ else if (*j<*k) return less;
+ else return greater;
+}
+
+@ The reason we initialized |c| to |greater| is so that
+|name_pointer| will make |name_dir->rlink| point to the root of the tree
+when |q=name_dir|, that is, the first time it is called.
+
+The information associated with a new node must be initialized
+in a slightly different way in \.{WEAVE} than in \.{TANGLE}; hence the
+|init_node| procedure.
+
+@u name_pointer
+install_node(parent,c,j,name_len) /* install a new node in the tree */
+name_pointer parent; /* parent of new node */
+int c; /* right or left? */
+ASCII *j; /* where replacement text starts */
+int name_len; /* length of replacement text */
+{
+ name_pointer node=name_ptr; /* new node */
+ if (byte_ptr+name_len>byte_mem_end) overflow("byte memory");
+ if (name_ptr==name_dir_end) overflow("name");
+ if (c==less) parent->llink=node; else parent->rlink=node;
+ node->llink=NULL; node->rlink=NULL;
+ init_node(node);
+ strncpy(byte_ptr,j,name_len);
+ (++name_ptr)->byte_start=byte_ptr+=name_len;
+ return(node);
+}
+
+@ The |prefix_lookup| procedure is supposed to find exactly one module
+name that has $|k|\ldots|l|$ as a prefix. Actually the algorithm
+silently accepts also the situation that some module name is a prefix of
+$|k|\ldots|l|$, because the user who painstakingly typed in more than
+necessary probably doesn't want to be told about the wasted effort.
+
+@u name_pointer
+prefix_lookup(k,l) /* finds module name given a prefix */
+ASCII *k; /* first char of prefix */
+ASCII *l; /* last char of prefix */
+{
+ short c = greater; /* comparison between two names */
+ short count = 0; /* the number of hits */
+ name_pointer p = root; /* current node of the search tree */
+ name_pointer q = NULL;
+ /* another place to resume the search after one is done */
+ name_pointer r = NULL; /* extension found */
+ while (p) {
+ c=web_strcmp(k,l+1,p->byte_start,(p+1)->byte_start);
+ switch(c) {
+ case less: p=p->llink; break;
+ case greater: p=p->rlink; break;
+ default: r=p; count++; q=p->rlink; p=p->llink;
+ }
+ if (p==NULL) {
+ p=q; q=NULL;
+ }
+ }
+ if (count==0) err_print("! Name does not match");
+@.Name does not match@>
+ if (count>1) err_print("! Ambiguous prefix");
+@.Ambiguous prefix@>
+ return(r); /* the result will be |NULL| if there was no match */
+}
+
+@ The last component of |name_info| is different for \.{TANGLE} and
+\.{WEAVE}. In \.{TANGLE}, if |p| is a pointer to a module name,
+|p->equiv| is a pointer to its replacement text, an element of the
+array |text_info|. In \.{WEAVE}, on the other hand, if
+|p| points to an identifier, |p->xref| is a pointer to its
+list of cross-references, an element of the array |xmem|. The make-up
+of |text_info| and |xmem| is discussed in the \.{TANGLE} and \.{WEAVE}
+source files, respectively; here we just declare a common field
+|equiv_or_xref| as a pointer to an |ASCII|.
+
+@<More elements of |name...@>=
+ASCII *equiv_or_xref; /* info corresponding to names */
+
+@* Reporting errors to the user.
+A global variable called |history| will contain one of four values
+at the end of every run: |spotless| means that no unusual messages were
+printed; |harmless_message| means that a message of possible interest
+was printed but no serious errors were detected; |error_message| means that
+at least one error was found; |fatal_message| means that the program
+terminated abnormally. The value of |history| does not influence the
+behavior of the program; it is simply computed for the convenience
+of systems that might want to use such information.
+
+@d spotless = 0 /* |history| value for normal jobs */
+@d harmless_message = 1 /* |history| value when non-serious info was printed */
+@d error_message = 2 /* |history| value when an error was noted */
+@d fatal_message = 3 /* |history| value when we had to stop prematurely */
+@d mark_harmless = {if (history==spotless) history=harmless_message;}
+@d mark_error = history=error_message
+
+@<Definit...@>=
+int history=spotless; /* indicates how bad this run was */
+
+@ The command `|err_print("! Error message")|' will report a syntax error to
+the user, by printing the error message at the beginning of a new line and
+then giving an indication of where the error was spotted in the source file.
+Note that no period follows the error message, since the error routine
+will automatically supply a period.
+
+The actual error indications are provided by a procedure called |error|.
+However, error messages are not actually reported during phase one,
+since errors detected on the first pass will be detected again
+during the second.
+
+@<Functions...@>=
+err_print(s) /* prints `\..' and location of error message */
+char *s;
+{
+ ASCII *k,*l; /* pointers into |buffer| */
+ printf("\n%s",(s==(char *)0) ? "Bad error message!!!" : s);
+ if (setting_up) {
+printf("\nError occurred while scanning arguments or opening output files. ");
+ } else {
+ @<Print error location based on input buffer@>;
+ }
+ fflush(stdout); mark_error;
+}
+
+@ The error locations can be indicated by using the global variables
+|loc|, |cur_line|, |cur_file_name| and |changing|,
+which tell respectively the first
+unlooked-at position in |buffer|, the current line number, the current
+file, and whether the current line is from |change_file| or |cur_file|.
+This routine should be modified on systems whose standard text editor
+has special line-numbering conventions.
+@^system dependencies@>
+
+@<Print error location based on input buffer@>=
+if (changing) printf(". (l. %d of change file)\n", change_line);
+else if (include_depth==0) printf(". (l. %d)\n", cur_line);
+ else printf(". (l. %d of include file %s)\n", cur_line, cur_file_name);
+l= (loc>=limit? limit: loc);
+if (l>buffer) {
+ for (k=buffer; k<l; k++)
+ if (*k=='\t') putchar(' ');
+ else putchar(xchr[*k]); /* print the characters already read */
+ putchar('\n');
+ for (k=buffer; k<l; k++) putchar(' '); /* space out the next line */
+}
+for (k=l; k<limit; k++) putchar(xchr[*k]); /* print the part not yet read */
+if (*limit==@`|') putchar('|'); /* end of \cee\ text in module names */
+putchar(' '); /* to separate the message from future asterisks */
+
+@ When no recovery from some error has been provided, we have to wrap
+up and quit as graciously as possible. This is done by calling the
+function |wrap_up| at the end of the code.
+
+@d fatal(s1,s2) = {
+ printf(s1); err_print(s2);
+ history=fatal_message; wrap_up();
+}
+
+@ Sometimes the program's behavior is far different from what it should be,
+and \.{WEB} prints an error message that is really for the \.{WEB}
+maintenance person, not the user. In such cases the program says
+|confusion("indication of where we are")|.
+
+@d confusion(s) = fatal("\n! This can't happen: ",s)
+@.This can't happen@>
+
+@ An overflow stop occurs if \.{WEB}'s tables aren't large enough.
+
+@d overflow(s) = {
+ fatal("\n! Sorry, capacity exceeded: ",s);
+}
+@.Sorry, x capacity exceeded@>
+
+@ Some implementations may wish to pass the |history| value to the
+operating system so that it can be used to govern whether or not other
+programs are started. Here, for instance, we pass the operating system
+a status of 0 if and only if only harmless messages were printed.
+@^system dependencies@>
+
+@<Func...@>=
+wrap_up() {
+ putchar('\n');
+ @<Print the job |history|@>;
+ if (history > harmless_message) exit(1);
+ else exit(0);
+}
+
+@ @<Print the job |history|@>=
+switch (history) {
+case spotless: printf("(No errors were found.)\n"); break;
+case harmless_message:
+ printf("(Did you see the warning message above?)\n"); break;
+case error_message:
+ printf("(Pardon me, but I think I spotted something wrong.)\n"); break;
+case fatal_message: printf("(That was a fatal error, my friend.)\n");
+} /* there are no other cases */
+
+@* Command line arguments.
+The user calls \.{CWEAVE} and \.{CTANGLE} with arguments on the command line.
+These are either file names or flags (beginning with |'-'|).
+The following globals are for communicating the user's desires to the rest
+of the program. The various file name variables contain strings with
+the names of those files.
+
+The only flag that affects \.{CWEAVE} is |"-x"|, whose status is kept in
+|no_xref|; it means the cross-referencing information---the index, the
+module name list, and the table of contents---is to be suppressed.
+No flags affect \.{CTANGLE}.
+
+@<Defin...@>=
+int argc; /* copy of |ac| parameter to |main| */
+char **argv; /* copy of |av| parameter to |main| */
+char C_file_name[max_file_name_length]; /* name of |C_file| */
+char tex_file_name[max_file_name_length]; /* name of |tex_file| */
+int no_xref; /* should \.{WEAVE} print an index? */
+
+@ We now must look at the command line arguments and set the file names
+accordingly. At least one file name must be present: the \.{WEB}
+file. It may have an extension, or it may omit it to get |".web"|
+added. The \TeX\ output file name is formed by replacing the \.{WEB}
+file name extension by |".tex"|, and the \cee\ file name by replacing
+the extension by |C_file_extension|
+@<External...@>=extern char C_file_extension[];
+
+@ If there is another file name present among the arguments, it is the
+change file, again either with an extension or without one to get |".ch"|
+An omitted change file argument means that |"/dev/null"| should be used,
+when no changes are desired.
+@^system dependencies@>
+
+@<Function...@>=
+scan_args()
+{
+ char *dot_pos, *index(); /* position of |'.'| in the argument */
+ boolean found_web=0,found_change=0; /* have these names have been seen? */
+ no_xref=0;
+ while (--argc > 0) {
+ if (**(++argv)!='-') {
+ if (!found_web) @<Make
+ |web_file_name|, |tex_file_name| and |C_file_name|@>@;
+ else if (!found_change) @<Make |change_file_name| from |fname|@>@;
+ else @<Print usage error message and quit@>;
+ }
+ else @<Handle flag argument@>;
+ }
+ if (!found_web) @<Print usage error message and quit@>;
+ if (!found_change) @<Set up null change file@>;
+}
+
+@ We use all of |*argv| for the |web_file_name| if there is a |'.'| in it,
+otherwise add |".web"|. The other file names come from adding things
+after the dot. We must check that there is enough room in
+|web_file_name| and the other arrays for the argument.
+
+@<Make |web_file_name|...@>=
+{
+ if (strlen(*argv) > max_file_name_length-5)
+ @<Complain about argument length@>;
+ if ((dot_pos=index(*argv,'.'))==NULL)
+ sprintf(web_file_name,"%s.web",*argv);
+ else {
+ sprintf(web_file_name,"%s",*argv);
+ @<Advance |dot_pos| to the last |'.'| in |*argv|@>
+ *dot_pos=0; /* string now ends where the dot was */
+ }
+ sprintf(tex_file_name,"%s.tex",*argv);
+ sprintf(C_file_name,"%s.%s",*argv,C_file_extension);
+ found_web=1;
+}
+
+@ @<Advance |dot_pos| to the last |'.'| in |*argv|@>=
+{ char *p;
+ p=dot_pos;
+ while (*++p != '\0')
+ if (*p=='.') dot_pos=p;
+}
+
+@ @<Make |change_file_name|...@>=
+{
+ if (strlen(*argv) > max_file_name_length-5)
+ @<Complain about argument length@>;
+ if ((dot_pos=index(*argv,'.'))==NULL)
+ sprintf(change_file_name,"%s.ch",*argv);
+ else sprintf(change_file_name,"%s",*argv);
+ found_change=1;
+}
+
+@ @<Set up null...@>=
+#ifdef MSDOS
+strcpy(change_file_name,"NUL");
+#else
+strcpy(change_file_name,"/dev/null");
+#endif
+@
+We have two possible flags:
+\medskip
+\halign{\tabskip=1em\tt#\hfil&#\hfil\cr
+\omit{\bf Argument}\hfil&\omit\bf Function\hfil\cr
+-x&Turns off \.{WEAVE} cross-reference.\cr
+-I<pathname>&%
+Adds {\tt <pathname>} to the directories searched for included files.\cr
+}
+@<Handle flag...@>=
+{
+ switch((*argv)[1]) {
+ case 'x':
+ no_xref=1;
+ break;
+ case 'I':
+ @<Add path name from {\tt -I} to search path@>@;
+ break;
+ default:
+ @<Complain about unknown option@>;
+ break;
+ }
+}
+
+@ @<Print usage error message and quit@>=
+{
+if (program==tangle)
+fatal("! Usage: tangle webfile[.web] [changefile[.ch]] [-Ipathname ...]\n",0)@;
+else
+fatal("! Usage: weave webfile[.web] [changefile[.ch]] [-x] [-Ipathname ...]\n",
+ 0);
+}
+
+@ @<Complain about arg...@>= fatal("! Filename %s too long\n", *argv);
+
+@ @<Complain about unk...@>= {
+printf("! Unknown option in argument %s\n", *argv); mark_harmless;
+}
+
+@* Output. Here is the code that opens the output file:
+@^system dependencies@>
+
+@<Defin...@>=
+FILE *C_file; /* where output of \.{TANGLE} goes */
+FILE *tex_file; /* where output of \.{WEAVE} goes */
+
+@ @<Scan arguments and open output files@>=
+scan_args();
+@<Add environment variable |"WEBPATH"| to search path@>@;
+if (program==tangle) {
+ if ((C_file=fopen(C_file_name,"w"))==NULL)
+ fatal("! Cannot open output file ", C_file_name);
+}
+else {
+ if ((tex_file=fopen(tex_file_name,"w"))==NULL)
+ fatal("! Cannot open output file ", tex_file_name);
+}
+
+@ The |update_terminal| procedure is called when we want
+to make sure that everything we have output to the terminal so far has
+actually left the computer's internal buffers and been sent.
+@^system dependencies@>
+
+@d update_terminal = fflush(stdout) /* empty the terminal output buffer */
+
+@ Terminal output uses |putchar| and |putc| when we have to
+translate from \.{WEB}'s code into the external character code,
+and |printf| when we just want to print strings.
+@^system dependencies@>
+@d new_line = putchar('\n') @d putxchar = putchar
+@d ASCII_write(a,b) = fflush(stdout), write(1,a,b) /* write on the standard output */
+@d line_write(c) = write(fileno(C_file),c) /* write on the C output file */
+@d C_printf(c,a) = fprintf(C_file,c,a)
+@d C_putc(c) = putc(c,C_file)
+
+@* Index.
diff --git a/web/spiderweb/src/master/cycle.awk b/web/spiderweb/src/master/cycle.awk
new file mode 100644
index 0000000000..602544b18a
--- /dev/null
+++ b/web/spiderweb/src/master/cycle.awk
@@ -0,0 +1,86 @@
+##157:
+
+#line 22 "cycle.web"
+
+#line 23 "cycle.web"
+NF==4&&$3=="-->"{
+incoming[$4]+=1
+if(incoming[$2]==""){
+incoming[$2]=0
+}
+successors[$2]=successors[$2]" "$4
+outgoing_edges[$2]=outgoing_edges[$2]$0"\n"
+next
+}
+!/^ *$/{
+print"What's all this?",$0
+exit 1
+}
+END{
+##158:
+
+#line 57 "cycle.web"
+
+#line 58 "cycle.web"
+for(node in incoming){
+if(incoming[node]==0){
+work[high++]=node
+}
+}
+
+##:158
+
+#line 38 "cycle.web"
+
+n=0
+while(n<high){
+##159:
+
+#line 64 "cycle.web"
+
+#line 65 "cycle.web"
+thisnode=work[n]
+temp=successors[thisnode]
+m=split(temp,newnodes," ")
+for(j=1;j<=m;j++){
+thisnode=newnodes[j]
+incoming[thisnode]-=1
+if(incoming[thisnode]==0){
+work[high++]=thisnode
+}
+}
+
+##:159
+
+#line 42 "cycle.web"
+
+n++
+}
+for(node in incoming){
+if(incoming[node]!=0){
+##160:
+
+#line 76 "cycle.web"
+
+#line 77 "cycle.web"
+if(cycle==0){
+print"There is a potential cycle here somewhere -- check the context"
+cycle=1
+}
+printf"%s",outgoing_edges[node]
+#line 2527 "/u/norman/pu/web/dist/src/master/spider.web"
+##:160
+
+#line 47 "cycle.web"
+
+}
+}
+if(cycle==0){
+print"There can't possibly be a cycle in the graph"
+}else{
+exit 0
+}
+}
+
+##:157
+
diff --git a/web/spiderweb/src/master/cycle.web b/web/spiderweb/src/master/cycle.web
new file mode 100644
index 0000000000..fed5efc20a
--- /dev/null
+++ b/web/spiderweb/src/master/cycle.web
@@ -0,0 +1,81 @@
+% Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+% Not to be sold, but may be used freely for any purpose
+% For more information, see file COPYRIGHT in the parent directory
+
+#*Detecting cycles in a directed graph of productions.
+{\tt SPIDER} writes a list of possibly cyclic productions on
+{\tt cycle.test}. The program {\tt cycle.awk} reads those and
+reports on whether there can be a cycle in the graph.
+If there were a cycle, it might lead to an infinite loop in \.{WEAVE}.
+One should inspect contexts to see if that could really happen.
+
+# Input is a list of edges in the form
+$$\hbox{\tt name leftnode --> rightnode}$$
+We detect a cycle if one exists.
+
+# We will use the following strategy: assemble all the edges, then
+read through them to label each node with the number of incoming edges
+and then the names of the successor nodes.
+We will then put nodes with no incoming edges on the work list, and
+remove them one by one, decrementing the incoming counts of their successors.
+If anything is left, there must be a cycle.
+#(cycle.awk#>=
+NF==4 && $3=="-->" {
+ incoming[$4]+=1
+ if (incoming[$2]=="") {
+ incoming[$2]=0
+ }
+ successors[$2]=successors[$2] " " $4
+ outgoing_edges[$2]=outgoing_edges[$2] $0 "\n"
+ next
+ }
+#=!/^ *$/#> {
+ print "What's all this?", $0
+ exit 1
+ }
+END {
+ #<Put all nodes with no incoming edges in |work[n]|, where
+ |0 <= n < high|#>
+ n=0
+ while (n<high) {
+ #<For each successor of |work[n]|, decrement the
+ incoming edge count and add to |work[]| if zero#>
+ n++
+ }
+ for (node in incoming) {
+ if (incoming[node]!=0) {
+ #<Announce a cycle and set |cycle=1|#>
+ }
+ }
+ if (cycle==0) {
+ print "There can't possibly be a cycle in the graph"
+ } else {
+ exit 0 ## no error until we check context
+ }
+ }
+
+# #<Put all nodes with no incoming edges in...#>=
+for (node in incoming) {
+ if (incoming[node]==0) {
+ work[high++]=node
+ }
+ }
+
+# #<For each successor...#>=
+thisnode=work[n]
+temp=successors[thisnode]
+m = split(temp,newnodes," ")
+for (j=1; j<=m; j++) {
+ thisnode=newnodes[j]
+ incoming[thisnode]-=1
+ if (incoming[thisnode]==0) {
+ work[high++]=thisnode
+ }
+ }
+
+# #<Announce a cycle...#>=
+if (cycle==0) {
+ print "There is a potential cycle here somewhere -- check the context"
+ cycle=1
+ }
+printf "%s", outgoing_edges[node]
diff --git a/web/spiderweb/src/master/junk.list b/web/spiderweb/src/master/junk.list
new file mode 100644
index 0000000000..0d21e78e20
--- /dev/null
+++ b/web/spiderweb/src/master/junk.list
@@ -0,0 +1,22 @@
+##163:
+
+#line 2555 "spider.web"
+
+#line 2556 "spider.web"
+good translations
+break_space
+force
+big_force
+opt
+backup
+big_cancel
+cancel
+indent
+outdent
+math_rel
+math_bin
+math_op
+test translations
+
+##:163
+
diff --git a/web/spiderweb/src/master/multitang.ch b/web/spiderweb/src/master/multitang.ch
new file mode 100644
index 0000000000..349a54d866
--- /dev/null
+++ b/web/spiderweb/src/master/multitang.ch
@@ -0,0 +1,107 @@
+@x 423
+output:
+@y
+output.
+We have made some modifications to \.{TANGLE} so it will write output
+on multiple files.
+We do this very simply: if a module name is introduced by \.{@@(}
+instead of \.{@@<}, we treat it as the name of a file.
+All these special modules are saved on a stack, |output_files|.
+We write them out after we've done the unnamed module.
+@z
+@x 425
+@c
+@y
+@d max_files 256
+@<Glob...@>=
+name_pointer output_files[max_files];
+name_pointer *cur_file, *end_output_files;
+char cur_module_char; /* is it |'<'| or |'('| */
+char output_file_name[longest_name]; /* name of the file */
+
+@ We make |end_output_files| point jsut beyond the end of
+|output_files|.
+|cur_file| starts out there. Every time we see a new file, we
+decrement |cur_file| and then write it in.
+@<Set initial...@>=
+cur_file=end_output_files=output_files+max_files;
+
+@ @<Add |cur_module| to the output file stack, or complain we're out
+of room@>=
+{
+if (cur_file>output_files)
+ *--curfile=cur_module;
+else {
+ overflow("output files");
+}
+}
+
+@ Here is the output switch, then...
+
+@c
+@z
+@x 434
+ printf("\nWriting the output file"); update_terminal;
+@y
+ printf("\nWriting the output files: (%s)",C_file_name); update_terminal;
+@z
+@x 438
+ printf("\nDone.");
+@y
+ @<Write all the named output files@>
+ printf("\nDone.");
+@z
+@x 442
+@ First we go through the list of replacement texts and copy the ones
+@y
+@ To write the named output files, we proceed as for the unnamed
+module.
+The only subtlety is that we have to open each one.
+@<Write all the named output files@>=
+for (;cur_file<end_output_files; cur_file++) {
+ strncpy(output_file_name,(*curfile)->byte_start, longest_name);
+ output_file_name[length(*curfile)]='\0';
+ fclose(C_file);
+ C_file=fopen(output_file_name,"w");
+ if (C_file <=0) {
+ fatal("! Cannot open output file:",output_file_name)
+ } else {
+ printf("(%s)",output_file_name); update_terminal;
+ }
+ stack_ptr=stack+1;
+ cur_name= (*cur_file);
+ cur_repl= cur_name->equiv_or_xref;
+ cur_byte=cur_repl->tok_start;
+ cur_end=(cur_repl+1)->tok_start;
+ /* cur_mod= it */;
+ while (stack_ptr > stack) get_output();
+ flush_buffer();
+}
+
+
+
+@ First we go through the list of replacement texts and copy the ones
+@z
+@x 575
+ ccode['&']=join; ccode['<']=module_name;
+@y
+ ccode['&']=join;
+ ccode['<']=ccode['(']=module_name;
+@z
+@x 778
+ case module_name: @<Scan the module name and make |cur_module|
+ point to it@>;
+@y
+ case module_name:
+ cur_module_char=*(loc-1);
+ @<Scan the module name and make |cur_module| point to it@>;
+@z
+@x 803
+ return(module_name);
+@y
+ if (cur_module_char=='(') {
+ @<Add |cur_module| to the output file stack, or complain we're out
+ of room@>
+ }
+ return(module_name);
+@z
diff --git a/web/spiderweb/src/master/newdefs.awk b/web/spiderweb/src/master/newdefs.awk
new file mode 100644
index 0000000000..1432a2e60f
--- /dev/null
+++ b/web/spiderweb/src/master/newdefs.awk
@@ -0,0 +1,11 @@
+## Used to convert old Levy CWEB style definitions to Spidery WEB definitions
+/#d|@d/ {
+ for (i=1; i<NF; i++) {
+ if ($i=="#d"||$i=="@d") {
+ $(i+1) = $(i+1) " ="
+ }
+ }
+ print
+ next
+}
+{print}
diff --git a/web/spiderweb/src/master/nodups.awk b/web/spiderweb/src/master/nodups.awk
new file mode 100644
index 0000000000..e22f1d3f65
--- /dev/null
+++ b/web/spiderweb/src/master/nodups.awk
@@ -0,0 +1,13 @@
+##161:
+
+#line 2529 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2530 "/u/norman/pu/web/dist/src/master/spider.web"
+{if($0==last){
+print"Error: duplicate name",$0,"on lines",NR-1"-"NR
+exit-1
+}
+last=$0
+}
+##:161
+
diff --git a/web/spiderweb/src/master/pathopen.c b/web/spiderweb/src/master/pathopen.c
new file mode 100644
index 0000000000..626a7117c5
--- /dev/null
+++ b/web/spiderweb/src/master/pathopen.c
@@ -0,0 +1,122 @@
+/*4:*/
+#line 88 "/u/norman/pu/web/dist/src/master/pathopen.web"
+
+/*9:*/
+#line 171 "/u/norman/pu/web/dist/src/master/pathopen.web"
+#include<stdio.h>
+
+/*:9*/
+#line 89 "/u/norman/pu/web/dist/src/master/pathopen.web"
+
+
+static int nextpath= 0;
+static char pathtexts[1024];
+static char *searchpath[64]= {pathtexts};
+static char *maxpathtexts= pathtexts+1024;
+
+void pathreset()
+{
+nextpath= 0;
+searchpath[nextpath]= pathtexts;
+}
+
+/*:4*//*5:*/
+#line 103 "/u/norman/pu/web/dist/src/master/pathopen.web"
+
+void pathaddname(name)
+char *name;
+{char *t= searchpath[nextpath];
+if(name==NULL)return;
+if(nextpath>=64)overflow("paths");
+while( *name){
+if(t>=maxpathtexts)overflow("path texts");
+ *t++= *name++;
+}
+/*6:*/
+#line 118 "/u/norman/pu/web/dist/src/master/pathopen.web"
+
+if(t==searchpath[nextpath])nextpath--;
+else if(t==searchpath[nextpath]+1&&
+ *searchpath[nextpath]=='/')
+t--;
+
+/*:6*/
+#line 114 "/u/norman/pu/web/dist/src/master/pathopen.web"
+
+searchpath[++nextpath]= t;
+}
+
+/*:5*//*7:*/
+#line 125 "/u/norman/pu/web/dist/src/master/pathopen.web"
+
+#line 126 "/u/norman/pu/web/dist/src/master/pathopen.web"
+void pathaddpath(path,path_separator)
+char *path;
+char path_separator;
+{
+char *t= searchpath[nextpath];
+if(path!=NULL){
+while( *path){
+if(nextpath>=64)overflow("paths");
+while( *path!=path_separator&& *path!='\0'){
+if(t>=maxpathtexts)overflow("path texts");
+ *t++= *path++;
+}
+/*6:*/
+#line 118 "/u/norman/pu/web/dist/src/master/pathopen.web"
+
+if(t==searchpath[nextpath])nextpath--;
+else if(t==searchpath[nextpath]+1&&
+ *searchpath[nextpath]=='/')
+t--;
+
+/*:6*/
+#line 138 "/u/norman/pu/web/dist/src/master/pathopen.web"
+
+searchpath[++nextpath]= t;
+if( *path)path++;
+}
+}
+}
+
+/*:7*//*8:*/
+#line 151 "/u/norman/pu/web/dist/src/master/pathopen.web"
+
+FILE *pathopen(name)
+char *name;
+{
+FILE *fp;
+char pathname[1024];
+char *s, *t;
+int i;
+
+if(( *(name)=='/'))
+return fopen(name,"r");
+else{
+if((fp= fopen(name,"r"))!=NULL)return fp;
+for(i= 0;i<nextpath;i++){
+/*10:*/
+#line 173 "/u/norman/pu/web/dist/src/master/pathopen.web"
+
+#line 174 "/u/norman/pu/web/dist/src/master/pathopen.web"
+for(s= pathname,t= searchpath[i];t<searchpath[i+1];){
+ *s++= *t++;
+if(s>pathname+1024)overflow("path name length");
+}
+ *s++= '/';
+if(s>pathname+1024)overflow("path name length");
+t= name;
+while( *s++= *t++)
+if(s>pathname+1024)overflow("path name length");
+if((fp= fopen(pathname,"r"))!=NULL)return fp;
+
+
+/*:10*/
+#line 165 "/u/norman/pu/web/dist/src/master/pathopen.web"
+
+}
+}
+return NULL;
+}
+
+/*:8*/
diff --git a/web/spiderweb/src/master/pathopen.h b/web/spiderweb/src/master/pathopen.h
new file mode 100644
index 0000000000..7fbb7cf479
--- /dev/null
+++ b/web/spiderweb/src/master/pathopen.h
@@ -0,0 +1,9 @@
+/*11:*/
+#line 187 "/u/norman/pu/web/dist/src/master/pathopen.web"
+
+#line 188 "/u/norman/pu/web/dist/src/master/pathopen.web"
+void pathaddname();
+void pathaddpath();
+void pathreset();
+FILE *pathopen();
+/*:11*/
diff --git a/web/spiderweb/src/master/pathopen.web b/web/spiderweb/src/master/pathopen.web
new file mode 100644
index 0000000000..6e374eacc5
--- /dev/null
+++ b/web/spiderweb/src/master/pathopen.web
@@ -0,0 +1,192 @@
+% Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+% Not to be sold, but may be used freely for any purpose
+% For more information, see file COPYRIGHT in the parent directory
+
+\def\title{Finding a file on a path}
+@*Introduction.
+This module is intended to make it easy for applications to open
+a file that is not necessarily in the current directory,
+but is somewhere on a search path.
+The notion is to specify the path ahead of time, so that
+calls to |fopen(n,"r")| can be replaced with calls to |pathopen(n)|.
+{\em No ASCII conversions are done; everything is in the character set of the
+local machine.}
+
+@ The functions we export are:
+\medskip
+\noindent{\tabskip=0ptplus1fil
+\halign to \hsize{\vrule height 10pt depth3.5pt width0pt
+ \hfil#\tabskip=2em&\vtop{\hsize=4in
+ \noindent\ignorespaces#\par}
+ \tabskip=0ptplus1fil\cr
+\omit\hfil\strut{\bf Function name and signature}&
+\omit\bf What it does\hfil\cr
+\noalign{\smallskip}
+|pathreset()|&
+Initializes the system to search the empty path.
+This initialization is performed statically, so programs needn't call
+|pathreset|, but then they may not be serially reusable.
+\cr
+|pathaddname(char *)|&
+Adds the name to the search path (FIFO).
+If the first argument is |NULL| or points to the empty string,
+|pathaddname| is a no-op.
+\cr
+|pathaddpath(char *, char)|&
+Adds the given path to the search path (FIFO).
+The second argument is the character that is used to separate names on
+the path, e.g. |pathaddpath(getenv("PATH"),':')|.
+If the first argument is |NULL| or points to the empty string,
+|pathaddpath| is a no-op.
+\cr
+|FILE *pathopen(char *)|&
+Attempts to open (for read)
+the given name, first in the current directory, then,
+if the name is not absolute (i.e. on UNIX doesn't begin with |'/'|),
+tries to open the name in each directory on the search path.
+If some |fopen| succeeds, it returns a pointer to a stream, otherwise it
+returns |NULL|.
+\cr
+}}
+
+@ We expect to be able to import:
+\medskip
+\noindent{\tabskip=0ptplus1fil
+\halign to \hsize{\vrule height 10pt depth3.5pt width0pt
+ \hfil#\tabskip=2em&\vtop{\hsize=4in
+ \noindent\ignorespaces#\par}
+ \tabskip=0ptplus1fil\cr
+\omit\hfil\strut{\bf Function name and signature}&
+\omit\bf What it does\hfil\cr
+\noalign{\smallskip}
+|overflow(char *)|&
+The |pathopen| routines will call |overflow| if they run out of space,
+e.g.~|overflow("path texts")|.
+\cr
+}}
+
+@ Here we set up the search path.
+It is a list of directories; if |pathopen| is handed a relative file name,
+it will look for it first in the current directory, and then in each
+directory on the search path.
+We allow up to |maxpaths| directories to be on the path,
+and we set aside |pathtextlength| bytes for the names of those directories.
+We perform the initialization statically, so we don't {\em have} to call
+|pathreset|.
+
+We use Knuth's technique for storing the names: all the bytes are stored
+in |pathtexts|.
+Pointers to the directories are stored in |searchpath|; the name of
+the |i|th directory is found in $|*(searchpath[i])|\ldots|*(seachpath[i+1])|$,
+where we start counting |i| from zero.
+|nextpath| contains the number directories already stored, and
+|searchpath[nextpath]| points to the first free byte in |pathtexts|.
+This is all a little odd for those used to C's null-terminated strings, but
+it becomes second nature after a while.
+@d maxpaths = 64
+@d pathtextlength = 1024
+@u
+@<Included files@>@;
+
+static int nextpath=0;
+static char pathtexts[pathtextlength];
+static char *searchpath[maxpaths]={pathtexts};
+static char *maxpathtexts = pathtexts+pathtextlength;
+
+void pathreset()
+{
+ nextpath=0;
+ searchpath[nextpath]=pathtexts;
+}
+
+@ Here's how we add a name to the path
+@u
+void pathaddname(name)
+ char *name;
+{ char *t=searchpath[nextpath];
+ if (name==NULL) return;
+ if (nextpath>=maxpaths) overflow ("paths");
+ while (*name) {
+ if (t>=maxpathtexts) overflow("path texts");
+ *t++=*name++;
+ }
+ @<If path is null, decrement |nextpath| to cancel addition,
+ and if path is root, make it null@>@;
+ searchpath[++nextpath]=t;
+}
+
+@ @<If path is null...@>=
+if (t==searchpath[nextpath]) nextpath--;
+else if (t==searchpath[nextpath]+1 &&
+ *searchpath[nextpath]==directory_separator) /* path is root */
+ t--;
+
+@ Adding a path is slightly more complicated.
+@u
+void pathaddpath(path,path_separator)
+ char *path;
+ char path_separator;
+{
+ char *t=searchpath[nextpath];
+ if (path!=NULL) {
+ while (*path) {
+ if (nextpath>=maxpaths) overflow ("paths");
+ while(*path!=path_separator && *path!='\0') {
+ if (t>=maxpathtexts) overflow("path texts");
+ *t++=*path++;
+ }
+ @<If path is null...@>@;
+ searchpath[++nextpath]=t;
+ if (*path) path++; /* skip separator */
+ }
+ }
+}
+
+@ Now we define the function that attempts to open a file, searching
+on the path.
+We need to know whether a file name is absolute:
+@d directory_separator = '/' /* not converted to ASCII */
+@d absolute(n) = (*(n)==directory_separator)
+@d maxpathnamelength = 1024 /* longest path name we can create */
+@u
+FILE *pathopen(name)
+ char *name;
+{
+ FILE *fp; /* the stream we try to get */
+ char pathname[maxpathnamelength]; /* used to create pathnames */
+ char *s, *t; /* used to copy prefixes */
+ int i; /* used to search pathnames */
+
+ if (absolute(name))
+ return fopen(name,"r");
+ else {
+ if ((fp=fopen(name,"r"))!=NULL) return fp;
+ for (i=0; i<nextpath; i++) {
+ @<Try to open on path |i|, returning if not |NULL|@>@;
+ }
+ }
+ return NULL;
+}
+
+@ @<Included...@>=#include <stdio.h>
+
+@ @<Try to open on path |i|...@>=
+for(s=pathname,t=searchpath[i]; t<searchpath[i+1];) {
+ *s++ = *t++;
+ if (s>pathname+maxpathnamelength) overflow("path name length");
+}
+*s++=directory_separator;
+if (s>pathname+maxpathnamelength) overflow("path name length");
+t=name;
+while(*s++=*t++)
+ if (s>pathname+maxpathnamelength) overflow("path name length");
+if ((fp=fopen(pathname,"r"))!=NULL) return fp;
+
+
+@ As a final service, we write declarations on file {\tt pathopen.h}
+@(pathopen.h@>=
+void pathaddname();
+void pathaddpath();
+void pathreset();
+FILE *pathopen();
+@* Index.
diff --git a/web/spiderweb/src/master/pretty.awk b/web/spiderweb/src/master/pretty.awk
new file mode 100644
index 0000000000..39ec7a1a38
--- /dev/null
+++ b/web/spiderweb/src/master/pretty.awk
@@ -0,0 +1,2 @@
+/^\\Y/,/\\par$/ {print; next}
+{next}
diff --git a/web/spiderweb/src/master/spider.awk b/web/spiderweb/src/master/spider.awk
new file mode 100644
index 0000000000..d8d0d74a10
--- /dev/null
+++ b/web/spiderweb/src/master/spider.awk
@@ -0,0 +1,4799 @@
+##3:
+
+#line 53 "/u/norman/pu/web/dist/src/master/spider.web"
+
+BEGIN{
+##9:
+
+#line 181 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 182 "/u/norman/pu/web/dist/src/master/spider.web"
+logfile="spider.slog"
+
+##:9
+##10:
+
+#line 185 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 186 "/u/norman/pu/web/dist/src/master/spider.web"
+translationfile="trans_keys.unsorted"
+
+##:10
+##11:
+
+#line 190 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 191 "/u/norman/pu/web/dist/src/master/spider.web"
+scrapfile="scraps.web"
+print"@*Scrap code generated by {\\tt SPIDER}.">scrapfile
+ttokfile="outtoks.web"
+print"@*Token code generated by {\\tt SPIDER}.">ttokfile
+##:11
+##12:
+
+#line 197 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 198 "/u/norman/pu/web/dist/src/master/spider.web"
+reserved="scraps.web"
+
+##:12
+##13:
+
+#line 202 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 203 "/u/norman/pu/web/dist/src/master/spider.web"
+tokennamefile="names.unsorted"
+##:13
+##14:
+
+#line 206 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 207 "/u/norman/pu/web/dist/src/master/spider.web"
+ilkfile="names.unsorted"
+##:14
+##15:
+
+#line 210 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 211 "/u/norman/pu/web/dist/src/master/spider.web"
+categoryfile="names.unsorted"
+##:15
+##16:
+
+#line 213 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 214 "/u/norman/pu/web/dist/src/master/spider.web"
+grammarfile="grammar.web"
+print"@*Grammar code generated by {\\tt SPIDER}.">grammarfile
+##:16
+##17:
+
+#line 219 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 220 "/u/norman/pu/web/dist/src/master/spider.web"
+tlang="outtoks.web"
+wlang="scraps.web"
+
+##:17
+##18:
+
+#line 225 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 226 "/u/norman/pu/web/dist/src/master/spider.web"
+productions="productions.list"
+
+##:18
+##19:
+
+#line 229 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 230 "/u/norman/pu/web/dist/src/master/spider.web"
+cycles="cycle.test"
+
+
+
+##:19
+##37:
+
+#line 525 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 526 "/u/norman/pu/web/dist/src/master/spider.web"
+default_translation="<*>"
+default_mathness="maybe"
+
+
+##:37
+##46:
+
+#line 727 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 728 "/u/norman/pu/web/dist/src/master/spider.web"
+highesttoken=200
+tokennumber=highesttoken
+
+##:46
+##61:
+
+#line 943 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 944 "/u/norman/pu/web/dist/src/master/spider.web"
+tokennumbers["identifier"]=tokennumber;tokennumber--
+tokenname["identifier"]="identifier"
+
+##:61
+##63:
+
+#line 969 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 970 "/u/norman/pu/web/dist/src/master/spider.web"
+tokennumbers["constant"]=tokennumber;tokennumber--
+tokenname["constant"]="constant"
+tokennumbers["string"]=tokennumber;tokennumber--
+tokenname["string"]="string"
+
+
+##:63
+##138:
+
+#line 2246 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2247 "/u/norman/pu/web/dist/src/master/spider.web"
+at_sign="@@"
+
+
+##:138
+##146:
+
+#line 2397 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2398 "/u/norman/pu/web/dist/src/master/spider.web"
+texof["\\"]="\\BS"
+texof["{"]="\\{"
+texof["}"]="\\{"
+texof["$"]="\\$"
+texof["&"]="\\amp"
+texof["#"]="\\#"
+texof["^"]="\\H"
+texof["_"]="\\_"
+texof["~"]="\\TI"
+texof["%"]="\\%"
+
+##:146
+##150:
+
+#line 2475 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2476 "/u/norman/pu/web/dist/src/master/spider.web"
+sharp_line_open="\"#line\""
+sharp_line_close="\"\""
+
+##:150
+##152:
+
+#line 2495 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2496 "/u/norman/pu/web/dist/src/master/spider.web"
+month["Jan"]="January"
+month["Feb"]="February"
+month["Mar"]="March"
+month["Apr"]="April"
+month["May"]="May"
+month["Jun"]="June"
+month["Jul"]="July"
+month["Aug"]="August"
+month["Sep"]="September"
+month["Oct"]="October"
+month["Nov"]="November"
+month["Dec"]="December"
+
+##:152
+
+#line 55 "/u/norman/pu/web/dist/src/master/spider.web"
+
+exitcode=0
+}
+
+##6:
+
+#line 100 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 101 "/u/norman/pu/web/dist/src/master/spider.web"
+/^#|^ *$/{
+
+print $0>logfile
+next
+}
+
+##:6
+
+#line 59 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##35:
+
+#line 498 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 499 "/u/norman/pu/web/dist/src/master/spider.web"
+/^default /{
+print"Setting defaults...">logfile
+start_place=2
+##36:
+
+#line 518 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 519 "/u/norman/pu/web/dist/src/master/spider.web"
+this_translation=default_translation
+this_mathness=default_mathness
+this_name=""
+this_category=""
+this_tangleto=""
+##:36
+
+#line 503 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##29:
+
+#line 434 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 435 "/u/norman/pu/web/dist/src/master/spider.web"
+for(i=start_place;i<NF;){
+if($i=="tangleto"){
+i++
+this_tangleto=$i
+i++
+}else if($i=="translation"){
+i++
+this_translation=$i
+i++
+}else if($i=="mathness"){
+i++
+this_mathness=$i
+i++
+}else if($i=="category"){
+i++
+this_category=$i
+categories[$i]=1
+i++
+}else if($i=="name"){
+i++
+this_name="SP_"$i
+i++
+}else{
+print"Error: unrecognized token description",$i,"on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 459 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+}
+##5:
+
+#line 91 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 92 "/u/norman/pu/web/dist/src/master/spider.web"
+if(i<=NF){
+print"Error: leftover fields",$i,"... on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 94 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+
+##:5
+
+#line 462 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:29
+
+#line 506 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##30:
+
+#line 466 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 467 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_name!=""){
+print"Error: name doesn't apply on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 469 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+##:30
+
+#line 507 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##32:
+
+#line 476 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 477 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_category!=""){
+print"Error: category doesn't apply on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 479 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+##:32
+
+#line 508 "/u/norman/pu/web/dist/src/master/spider.web"
+
+default_translation=this_translation
+default_mathness=this_mathness
+print"\tdefault translation is",default_translation>logfile
+print"\tdefault mathness is",default_mathness>logfile
+next
+}
+
+##:35
+##39:
+
+#line 570 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 571 "/u/norman/pu/web/dist/src/master/spider.web"
+/^token /{
+print"Token",$2>logfile
+if($2=="identifier"){
+##40:
+
+#line 595 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 596 "/u/norman/pu/web/dist/src/master/spider.web"
+##36:
+
+#line 518 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 519 "/u/norman/pu/web/dist/src/master/spider.web"
+this_translation=default_translation
+this_mathness=default_mathness
+this_name=""
+this_category=""
+this_tangleto=""
+##:36
+
+#line 597 "/u/norman/pu/web/dist/src/master/spider.web"
+
+this_translation=""
+start_place=3
+##29:
+
+#line 434 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 435 "/u/norman/pu/web/dist/src/master/spider.web"
+for(i=start_place;i<NF;){
+if($i=="tangleto"){
+i++
+this_tangleto=$i
+i++
+}else if($i=="translation"){
+i++
+this_translation=$i
+i++
+}else if($i=="mathness"){
+i++
+this_mathness=$i
+i++
+}else if($i=="category"){
+i++
+this_category=$i
+categories[$i]=1
+i++
+}else if($i=="name"){
+i++
+this_name="SP_"$i
+i++
+}else{
+print"Error: unrecognized token description",$i,"on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 459 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+}
+##5:
+
+#line 91 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 92 "/u/norman/pu/web/dist/src/master/spider.web"
+if(i<=NF){
+print"Error: leftover fields",$i,"... on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 94 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+
+##:5
+
+#line 462 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:29
+
+#line 602 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##30:
+
+#line 466 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 467 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_name!=""){
+print"Error: name doesn't apply on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 469 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+##:30
+
+#line 603 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##31:
+
+#line 471 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 472 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_tangleto!=""){
+print"Error: tangleto doesn't apply on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 474 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+##:31
+
+#line 604 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##34:
+
+#line 486 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 487 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_category==""){
+print"Error: you must give a category on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 489 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+##:34
+
+#line 605 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##33:
+
+#line 481 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 482 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_translation!=""){
+print"Error: translation doesn't apply on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 484 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+##:33
+
+#line 606 "/u/norman/pu/web/dist/src/master/spider.web"
+
+id_category=this_category
+id_mathness=this_mathness
+
+##:40
+
+#line 574 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}else if($2=="number"){
+##41:
+
+#line 611 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 612 "/u/norman/pu/web/dist/src/master/spider.web"
+print"Warning: numeric constants and strings are",\
+"identified in this WEAVE."
+print"Warning: numeric constants and strings are",\
+"identified in this WEAVE.">logfile
+##36:
+
+#line 518 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 519 "/u/norman/pu/web/dist/src/master/spider.web"
+this_translation=default_translation
+this_mathness=default_mathness
+this_name=""
+this_category=""
+this_tangleto=""
+##:36
+
+#line 617 "/u/norman/pu/web/dist/src/master/spider.web"
+
+this_translation=""
+start_place=3
+##29:
+
+#line 434 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 435 "/u/norman/pu/web/dist/src/master/spider.web"
+for(i=start_place;i<NF;){
+if($i=="tangleto"){
+i++
+this_tangleto=$i
+i++
+}else if($i=="translation"){
+i++
+this_translation=$i
+i++
+}else if($i=="mathness"){
+i++
+this_mathness=$i
+i++
+}else if($i=="category"){
+i++
+this_category=$i
+categories[$i]=1
+i++
+}else if($i=="name"){
+i++
+this_name="SP_"$i
+i++
+}else{
+print"Error: unrecognized token description",$i,"on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 459 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+}
+##5:
+
+#line 91 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 92 "/u/norman/pu/web/dist/src/master/spider.web"
+if(i<=NF){
+print"Error: leftover fields",$i,"... on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 94 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+
+##:5
+
+#line 462 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:29
+
+#line 622 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##30:
+
+#line 466 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 467 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_name!=""){
+print"Error: name doesn't apply on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 469 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+##:30
+
+#line 623 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##31:
+
+#line 471 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 472 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_tangleto!=""){
+print"Error: tangleto doesn't apply on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 474 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+##:31
+
+#line 624 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##34:
+
+#line 486 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 487 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_category==""){
+print"Error: you must give a category on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 489 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+##:34
+
+#line 625 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##33:
+
+#line 481 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 482 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_translation!=""){
+print"Error: translation doesn't apply on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 484 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+##:33
+
+#line 626 "/u/norman/pu/web/dist/src/master/spider.web"
+
+number_category=this_category
+number_mathness=this_mathness
+
+##:41
+
+#line 576 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}else if($2=="newline"){
+##42:
+
+#line 631 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 632 "/u/norman/pu/web/dist/src/master/spider.web"
+##36:
+
+#line 518 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 519 "/u/norman/pu/web/dist/src/master/spider.web"
+this_translation=default_translation
+this_mathness=default_mathness
+this_name=""
+this_category=""
+this_tangleto=""
+##:36
+
+#line 633 "/u/norman/pu/web/dist/src/master/spider.web"
+
+start_place=3
+##29:
+
+#line 434 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 435 "/u/norman/pu/web/dist/src/master/spider.web"
+for(i=start_place;i<NF;){
+if($i=="tangleto"){
+i++
+this_tangleto=$i
+i++
+}else if($i=="translation"){
+i++
+this_translation=$i
+i++
+}else if($i=="mathness"){
+i++
+this_mathness=$i
+i++
+}else if($i=="category"){
+i++
+this_category=$i
+categories[$i]=1
+i++
+}else if($i=="name"){
+i++
+this_name="SP_"$i
+i++
+}else{
+print"Error: unrecognized token description",$i,"on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 459 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+}
+##5:
+
+#line 91 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 92 "/u/norman/pu/web/dist/src/master/spider.web"
+if(i<=NF){
+print"Error: leftover fields",$i,"... on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 94 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+
+##:5
+
+#line 462 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:29
+
+#line 637 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##30:
+
+#line 466 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 467 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_name!=""){
+print"Error: name doesn't apply on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 469 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+##:30
+
+#line 638 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##31:
+
+#line 471 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 472 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_tangleto!=""){
+print"Error: tangleto doesn't apply on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 474 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+##:31
+
+#line 639 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##34:
+
+#line 486 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 487 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_category==""){
+print"Error: you must give a category on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 489 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+##:34
+
+#line 640 "/u/norman/pu/web/dist/src/master/spider.web"
+
+newline_category=this_category
+newline_mathness=this_mathness
+newline_translation=this_translation
+
+##:42
+
+#line 578 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}else if($2=="pseudo_semi"){
+##43:
+
+#line 646 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 647 "/u/norman/pu/web/dist/src/master/spider.web"
+##36:
+
+#line 518 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 519 "/u/norman/pu/web/dist/src/master/spider.web"
+this_translation=default_translation
+this_mathness=default_mathness
+this_name=""
+this_category=""
+this_tangleto=""
+##:36
+
+#line 648 "/u/norman/pu/web/dist/src/master/spider.web"
+
+start_place=3
+##29:
+
+#line 434 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 435 "/u/norman/pu/web/dist/src/master/spider.web"
+for(i=start_place;i<NF;){
+if($i=="tangleto"){
+i++
+this_tangleto=$i
+i++
+}else if($i=="translation"){
+i++
+this_translation=$i
+i++
+}else if($i=="mathness"){
+i++
+this_mathness=$i
+i++
+}else if($i=="category"){
+i++
+this_category=$i
+categories[$i]=1
+i++
+}else if($i=="name"){
+i++
+this_name="SP_"$i
+i++
+}else{
+print"Error: unrecognized token description",$i,"on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 459 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+}
+##5:
+
+#line 91 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 92 "/u/norman/pu/web/dist/src/master/spider.web"
+if(i<=NF){
+print"Error: leftover fields",$i,"... on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 94 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+
+##:5
+
+#line 462 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:29
+
+#line 652 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##30:
+
+#line 466 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 467 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_name!=""){
+print"Error: name doesn't apply on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 469 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+##:30
+
+#line 653 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##31:
+
+#line 471 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 472 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_tangleto!=""){
+print"Error: tangleto doesn't apply on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 474 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+##:31
+
+#line 654 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##34:
+
+#line 486 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 487 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_category==""){
+print"Error: you must give a category on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 489 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+##:34
+
+#line 655 "/u/norman/pu/web/dist/src/master/spider.web"
+
+pseudo_semi_category=this_category
+pseudo_semi_mathness=this_mathness
+pseudo_semi_translation=this_translation
+
+##:43
+
+#line 580 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}else if($2~/[a-zA-ZA-Z0-9]+/){
+
+print"Error: unknown token species:",$2
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 584 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}else{
+##44:
+
+#line 677 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 678 "/u/norman/pu/web/dist/src/master/spider.web"
+this_string=$2
+##45:
+
+#line 700 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 701 "/u/norman/pu/web/dist/src/master/spider.web"
+old_string=this_string
+this_string=""
+
+
+idx=index(old_string,"{space}")
+while(idx!=0){
+temp=substr(old_string,1,idx-1)
+this_string=this_string temp" "
+old_string=substr(old_string,idx+7)
+idx=index(old_string,"{space}")
+}
+this_string=this_string old_string
+
+##:45
+
+#line 679 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+$2=this_string
+
+##49:
+
+#line 767 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 768 "/u/norman/pu/web/dist/src/master/spider.web"
+if($2=="@"){
+$2="@@"
+tokenname[$2]="'@@'"
+tokenlength[$2]=1
+}else if($2=="'"||$2=="\\"){
+$2="\\"$2
+tokenname[$2]="'"$2"'"
+tokenlength[$2]=1
+}else if(length($2)>1){
+##50:
+
+#line 793 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 794 "/u/norman/pu/web/dist/src/master/spider.web"
+tokenname[$2]="SP_gen_token_"tokennumber
+tokennumbers[$2]=tokennumber
+tokennumber--
+
+temp=sprintf("strncmp(\"%s\",loc-1,%d)==0",$2,length($2))
+tokentest[$2]=temp
+tokenlength[$2]=length($2)
+
+
+##:50
+
+#line 777 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}else{
+temp=sprintf("'%s'",$2)
+tokenname[$2]=temp
+tokenlength[$2]=1
+}
+
+##:49
+
+#line 684 "/u/norman/pu/web/dist/src/master/spider.web"
+
+if(tokens[$2]!=""){
+print"Warning: token",$2,"defined twice"
+}
+tokens[$2]=1
+##51:
+
+#line 804 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 805 "/u/norman/pu/web/dist/src/master/spider.web"
+##36:
+
+#line 518 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 519 "/u/norman/pu/web/dist/src/master/spider.web"
+this_translation=default_translation
+this_mathness=default_mathness
+this_name=""
+this_category=""
+this_tangleto=""
+##:36
+
+#line 806 "/u/norman/pu/web/dist/src/master/spider.web"
+
+this_name=tokenname[$2]
+start_place=3
+##29:
+
+#line 434 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 435 "/u/norman/pu/web/dist/src/master/spider.web"
+for(i=start_place;i<NF;){
+if($i=="tangleto"){
+i++
+this_tangleto=$i
+i++
+}else if($i=="translation"){
+i++
+this_translation=$i
+i++
+}else if($i=="mathness"){
+i++
+this_mathness=$i
+i++
+}else if($i=="category"){
+i++
+this_category=$i
+categories[$i]=1
+i++
+}else if($i=="name"){
+i++
+this_name="SP_"$i
+i++
+}else{
+print"Error: unrecognized token description",$i,"on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 459 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+}
+##5:
+
+#line 91 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 92 "/u/norman/pu/web/dist/src/master/spider.web"
+if(i<=NF){
+print"Error: leftover fields",$i,"... on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 94 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+
+##:5
+
+#line 462 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:29
+
+#line 811 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##34:
+
+#line 486 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 487 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_category==""){
+print"Error: you must give a category on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 489 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+##:34
+
+#line 812 "/u/norman/pu/web/dist/src/master/spider.web"
+
+tokencategory[$2]=this_category
+tokenmathness[$2]=this_mathness
+tokentranslation[$2]=this_translation
+tokenname[$2]=this_name
+tokentangleto[$2]=this_tangleto
+
+##:51
+
+#line 689 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##53:
+
+#line 828 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 829 "/u/norman/pu/web/dist/src/master/spider.web"
+if(tokenlength[$2]>1&&tokennumbers[$2]==""){
+print"This can't happen: token",$2,"is long",\
+"but has no number"
+exitcode=-1
+}
+
+
+##:53
+
+#line 690 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##52:
+
+#line 821 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 822 "/u/norman/pu/web/dist/src/master/spider.web"
+temp=tokenlength[$2]
+if(temp>maxtokenlength){
+maxtokenlength=temp
+}
+
+##:52
+
+#line 691 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+
+##:44
+
+#line 586 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+categories[this_category]=1
+
+next
+}
+
+##:39
+##75:
+
+#line 1183 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1184 "/u/norman/pu/web/dist/src/master/spider.web"
+/^ilk /{
+print"Ilk",$2>logfile
+##36:
+
+#line 518 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 519 "/u/norman/pu/web/dist/src/master/spider.web"
+this_translation=default_translation
+this_mathness=default_mathness
+this_name=""
+this_category=""
+this_tangleto=""
+##:36
+
+#line 1187 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##76:
+
+#line 1206 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1207 "/u/norman/pu/web/dist/src/master/spider.web"
+if($2~/^[a-zA-Z_]+_like$/&&$0!~/ category /){
+
+this_category=substr($2,1,length($2)-5)
+categories[this_category]=1
+}
+
+##:76
+
+#line 1188 "/u/norman/pu/web/dist/src/master/spider.web"
+
+this_name=""
+start_place=3
+##29:
+
+#line 434 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 435 "/u/norman/pu/web/dist/src/master/spider.web"
+for(i=start_place;i<NF;){
+if($i=="tangleto"){
+i++
+this_tangleto=$i
+i++
+}else if($i=="translation"){
+i++
+this_translation=$i
+i++
+}else if($i=="mathness"){
+i++
+this_mathness=$i
+i++
+}else if($i=="category"){
+i++
+this_category=$i
+categories[$i]=1
+i++
+}else if($i=="name"){
+i++
+this_name="SP_"$i
+i++
+}else{
+print"Error: unrecognized token description",$i,"on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 459 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+}
+##5:
+
+#line 91 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 92 "/u/norman/pu/web/dist/src/master/spider.web"
+if(i<=NF){
+print"Error: leftover fields",$i,"... on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 94 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+
+##:5
+
+#line 462 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:29
+
+#line 1193 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##34:
+
+#line 486 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 487 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_category==""){
+print"Error: you must give a category on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 489 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+##:34
+
+#line 1194 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##30:
+
+#line 466 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 467 "/u/norman/pu/web/dist/src/master/spider.web"
+if(this_name!=""){
+print"Error: name doesn't apply on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 469 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+##:30
+
+#line 1195 "/u/norman/pu/web/dist/src/master/spider.web"
+
+ilk_category[$2]=this_category
+ilk_mathness[$2]=this_mathness
+ilk_translation[$2]=this_translation
+next
+}
+
+
+##:75
+##77:
+
+#line 1220 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1221 "/u/norman/pu/web/dist/src/master/spider.web"
+/^reserved /{
+print"Reserved word",$2>logfile
+if($0!~/ ilk /){
+##78:
+
+#line 1246 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1247 "/u/norman/pu/web/dist/src/master/spider.web"
+temp=$2"_like"
+reservedilk[$2]=temp
+if(ilk_translation[temp]==""){
+ilk_translation[temp]=default_translation
+}
+has_reserved[temp]=1
+if(ilk_mathness[temp]==""){
+ilk_mathness[temp]=default_mathness
+}
+
+if(ilk_category[temp]==""){
+ilk_category[temp]=$2
+categories[$2]=1
+}
+ilk_is_made_up[temp]=1
+
+
+
+##:78
+
+#line 1224 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+for(i=3;i<=NF;){
+if($i=="ilk"){
+i++
+reservedilk[$2]=$i
+has_reserved[$i]=1
+i++
+}else{
+print"Error: bad reserved word attribute:",$i,\
+"on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 1235 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+}
+##5:
+
+#line 91 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 92 "/u/norman/pu/web/dist/src/master/spider.web"
+if(i<=NF){
+print"Error: leftover fields",$i,"... on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 94 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+
+##:5
+
+#line 1238 "/u/norman/pu/web/dist/src/master/spider.web"
+
+next
+}
+
+##:77
+##129:
+
+#line 2071 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2072 "/u/norman/pu/web/dist/src/master/spider.web"
+/^language /{
+language=$2
+extension=language
+for(i=3;i<NF;){
+if($i=="extension"){
+i++
+extension=$i
+i++
+}else if($i=="version"){
+i++
+version=$i
+i++
+}else{
+print"Error: unknown language property",$i,\
+"on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 2087 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+}
+##5:
+
+#line 91 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 92 "/u/norman/pu/web/dist/src/master/spider.web"
+if(i<=NF){
+print"Error: leftover fields",$i,"... on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 94 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+
+##:5
+
+#line 2090 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##131:
+
+#line 2125 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2126 "/u/norman/pu/web/dist/src/master/spider.web"
+macrofile=extension"web.tex"
+print"\\input webkernel.tex">macrofile
+
+
+##:131
+
+#line 2091 "/u/norman/pu/web/dist/src/master/spider.web"
+
+next
+}
+
+##:129
+##132:
+
+#line 2132 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2133 "/u/norman/pu/web/dist/src/master/spider.web"
+/^macros begin$/,/^macros end$/{
+if(begunmacs==0){
+begunmacs=1
+next
+}
+if($0~/^macros end$/){
+begunmacs=0
+next
+}
+if(macrofile==""){
+if(complained==0){
+print"Error: you must give \"language\"",\
+"before \"macros\""
+complained=1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 2147 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+}else{
+print $0>macrofile
+}
+next
+}
+
+
+
+##:132
+##133:
+
+#line 2163 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2164 "/u/norman/pu/web/dist/src/master/spider.web"
+/^module /{
+for(i=2;i<NF;){
+if($i=="definition"){
+i++
+mod_def_cat=$i
+categories[$i]=1
+print"Module definition category set to",$i>logfile
+i++
+}else if($i=="use"){
+i++
+mod_use_cat=$i
+categories[$i]=1
+print"Module use category set to",$i>logfile
+i++
+}else{
+print"Error: unknown module property",$i,\
+"on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 2181 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+}
+##5:
+
+#line 91 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 92 "/u/norman/pu/web/dist/src/master/spider.web"
+if(i<=NF){
+print"Error: leftover fields",$i,"... on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 94 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+
+##:5
+
+#line 2184 "/u/norman/pu/web/dist/src/master/spider.web"
+
+next
+}
+
+##:133
+##135:
+
+#line 2213 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2214 "/u/norman/pu/web/dist/src/master/spider.web"
+/^at_sign /{
+if(NF==2&&length($2)==1){
+if($2=="@"){
+at_sign="@@"
+}else{
+at_sign=$2
+}
+}else{
+print"Error: I can't understand",$0
+print" Give me an at sign of length 1"
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 2224 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+next
+}
+
+##:135
+##139:
+
+#line 2254 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2255 "/u/norman/pu/web/dist/src/master/spider.web"
+/^comment /{
+print $0>logfile
+for(i=2;i<NF;){
+if($i=="begin"){
+i++
+if($i~/^<.*>$/){
+transstring=$i
+wherestring="in \"comment begin\" on line "NR-1
+##27:
+
+#line 389 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 390 "/u/norman/pu/web/dist/src/master/spider.web"
+temp=substr(transstring,2,length(transstring)-2)
+trcnt=split(temp,trtok,"-")
+outstring=""
+for(tridx=1;tridx<=trcnt;tridx++){
+alternate=trtok[tridx]
+##25:
+
+#line 366 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 367 "/u/norman/pu/web/dist/src/master/spider.web"
+if(alternate=="space"){
+alternate="\" \""
+}else if(alternate=="dash"){
+alternate="\"-\""
+}
+
+
+##:25
+
+#line 395 "/u/norman/pu/web/dist/src/master/spider.web"
+
+if(alternate~/^[0-9]$/){
+print"Digit not allowed in restricted translation",wherestring
+exitcode=-1
+}else if(alternate~/^[a-zA-Z_]+$/){
+print"Key word not allowed in restricted translation",wherestring
+exitcode=-1
+}else if(alternate~/^\"([^"]*\\\")*[^"]*\"$/){
+temp=substr(alternate,2,length(alternate)-2)
+outstring=outstring temp
+}else if(alternate~/^\*$/){
+print"<*> not allowed in restricted translation",wherestring
+exitcode=-1
+}else{
+print"Bogus restricted translation",wherestring
+exitcode=-1
+}
+}
+outstring="\""outstring"\""
+
+
+
+##:27
+
+#line 2264 "/u/norman/pu/web/dist/src/master/spider.web"
+
+begin_comment_string=outstring
+i++
+}else{
+print"Error: \"comment begin\" must have a restricted translation"
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 2269 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+}else if($i=="end"){
+i++
+if($i=="newline"){
+comments_end_with_newline=1
+end_comment_string="\"\\n\""
+}else if($i~/^<.*>$/){
+comments_end_with_newline=0
+transstring=$i
+wherestring="in \"comment end\" on line "NR-1
+##27:
+
+#line 389 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 390 "/u/norman/pu/web/dist/src/master/spider.web"
+temp=substr(transstring,2,length(transstring)-2)
+trcnt=split(temp,trtok,"-")
+outstring=""
+for(tridx=1;tridx<=trcnt;tridx++){
+alternate=trtok[tridx]
+##25:
+
+#line 366 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 367 "/u/norman/pu/web/dist/src/master/spider.web"
+if(alternate=="space"){
+alternate="\" \""
+}else if(alternate=="dash"){
+alternate="\"-\""
+}
+
+
+##:25
+
+#line 395 "/u/norman/pu/web/dist/src/master/spider.web"
+
+if(alternate~/^[0-9]$/){
+print"Digit not allowed in restricted translation",wherestring
+exitcode=-1
+}else if(alternate~/^[a-zA-Z_]+$/){
+print"Key word not allowed in restricted translation",wherestring
+exitcode=-1
+}else if(alternate~/^\"([^"]*\\\")*[^"]*\"$/){
+temp=substr(alternate,2,length(alternate)-2)
+outstring=outstring temp
+}else if(alternate~/^\*$/){
+print"<*> not allowed in restricted translation",wherestring
+exitcode=-1
+}else{
+print"Bogus restricted translation",wherestring
+exitcode=-1
+}
+}
+outstring="\""outstring"\""
+
+
+
+##:27
+
+#line 2282 "/u/norman/pu/web/dist/src/master/spider.web"
+
+end_comment_string=outstring
+}else{
+print"Error: \"comment end\" must have a restricted translation"
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 2286 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+i++
+}else{
+print"Error: bad comment attribute:",$i
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 2291 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+}
+##5:
+
+#line 91 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 92 "/u/norman/pu/web/dist/src/master/spider.web"
+if(i<=NF){
+print"Error: leftover fields",$i,"... on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 94 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+
+##:5
+
+#line 2294 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##145:
+
+#line 2376 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2377 "/u/norman/pu/web/dist/src/master/spider.web"
+if(macrofile!=""){
+this_string=substr(begin_comment_string,2,length(begin_comment_string)-2)
+##147:
+
+#line 2410 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2411 "/u/norman/pu/web/dist/src/master/spider.web"
+tex_string=""
+while(length(this_string)>0){
+c=substr(this_string,1,1)
+this_string=substr(this_string,2)
+cprime=texof[c]
+if(cprime==""){
+tex_string=tex_string c
+}else{
+tex_string=tex_string cprime
+}
+}
+
+##:147
+
+#line 2379 "/u/norman/pu/web/dist/src/master/spider.web"
+
+printf"\\def\\commentbegin{%s}\n",tex_string>macrofile
+if(comments_end_with_newline==0){
+this_string=substr(end_comment_string,2,length(end_comment_string)-2)
+##147:
+
+#line 2410 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2411 "/u/norman/pu/web/dist/src/master/spider.web"
+tex_string=""
+while(length(this_string)>0){
+c=substr(this_string,1,1)
+this_string=substr(this_string,2)
+cprime=texof[c]
+if(cprime==""){
+tex_string=tex_string c
+}else{
+tex_string=tex_string cprime
+}
+}
+
+##:147
+
+#line 2383 "/u/norman/pu/web/dist/src/master/spider.web"
+
+printf"\\def\\commentend{%s}\n",tex_string>macrofile
+}else{
+print"\\def\\commentend{\\relax}">macrofile
+}
+}else{
+print"Error: I can't write comment info to the macro file---"
+print" you haven't given me any \"language\" information"
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 2391 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+
+
+##:145
+
+#line 2295 "/u/norman/pu/web/dist/src/master/spider.web"
+
+next
+}
+
+##:139
+##148:
+
+#line 2428 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2429 "/u/norman/pu/web/dist/src/master/spider.web"
+/^line /{
+print $0>logfile
+for(i=2;i<NF;){
+if($i=="begin"){
+i++
+if($i~/^<.*>$/){
+transstring=$i
+wherestring="in \"line begin\" on line "NR-1
+##27:
+
+#line 389 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 390 "/u/norman/pu/web/dist/src/master/spider.web"
+temp=substr(transstring,2,length(transstring)-2)
+trcnt=split(temp,trtok,"-")
+outstring=""
+for(tridx=1;tridx<=trcnt;tridx++){
+alternate=trtok[tridx]
+##25:
+
+#line 366 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 367 "/u/norman/pu/web/dist/src/master/spider.web"
+if(alternate=="space"){
+alternate="\" \""
+}else if(alternate=="dash"){
+alternate="\"-\""
+}
+
+
+##:25
+
+#line 395 "/u/norman/pu/web/dist/src/master/spider.web"
+
+if(alternate~/^[0-9]$/){
+print"Digit not allowed in restricted translation",wherestring
+exitcode=-1
+}else if(alternate~/^[a-zA-Z_]+$/){
+print"Key word not allowed in restricted translation",wherestring
+exitcode=-1
+}else if(alternate~/^\"([^"]*\\\")*[^"]*\"$/){
+temp=substr(alternate,2,length(alternate)-2)
+outstring=outstring temp
+}else if(alternate~/^\*$/){
+print"<*> not allowed in restricted translation",wherestring
+exitcode=-1
+}else{
+print"Bogus restricted translation",wherestring
+exitcode=-1
+}
+}
+outstring="\""outstring"\""
+
+
+
+##:27
+
+#line 2438 "/u/norman/pu/web/dist/src/master/spider.web"
+
+sharp_line_open=outstring
+i++
+}else{
+print"Error: \"line begin\" must have a restricted translation"
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 2443 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+}else if($i=="end"){
+i++
+if($i~/^<.*>$/){
+transstring=$i
+wherestring="in \"line end\" on line "NR-1
+##27:
+
+#line 389 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 390 "/u/norman/pu/web/dist/src/master/spider.web"
+temp=substr(transstring,2,length(transstring)-2)
+trcnt=split(temp,trtok,"-")
+outstring=""
+for(tridx=1;tridx<=trcnt;tridx++){
+alternate=trtok[tridx]
+##25:
+
+#line 366 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 367 "/u/norman/pu/web/dist/src/master/spider.web"
+if(alternate=="space"){
+alternate="\" \""
+}else if(alternate=="dash"){
+alternate="\"-\""
+}
+
+
+##:25
+
+#line 395 "/u/norman/pu/web/dist/src/master/spider.web"
+
+if(alternate~/^[0-9]$/){
+print"Digit not allowed in restricted translation",wherestring
+exitcode=-1
+}else if(alternate~/^[a-zA-Z_]+$/){
+print"Key word not allowed in restricted translation",wherestring
+exitcode=-1
+}else if(alternate~/^\"([^"]*\\\")*[^"]*\"$/){
+temp=substr(alternate,2,length(alternate)-2)
+outstring=outstring temp
+}else if(alternate~/^\*$/){
+print"<*> not allowed in restricted translation",wherestring
+exitcode=-1
+}else{
+print"Bogus restricted translation",wherestring
+exitcode=-1
+}
+}
+outstring="\""outstring"\""
+
+
+
+##:27
+
+#line 2452 "/u/norman/pu/web/dist/src/master/spider.web"
+
+sharp_line_close=outstring
+}else{
+print"Error: \"line end\" must have a restricted translation"
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 2456 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+i++
+}else{
+print"Error: bad line attribute:",$i,"on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 2461 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+}
+##5:
+
+#line 91 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 92 "/u/norman/pu/web/dist/src/master/spider.web"
+if(i<=NF){
+print"Error: leftover fields",$i,"... on line",NR-1
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 94 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+
+##:5
+
+#line 2464 "/u/norman/pu/web/dist/src/master/spider.web"
+
+next
+}
+
+##:148
+##151:
+
+#line 2481 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2482 "/u/norman/pu/web/dist/src/master/spider.web"
+/^date /{
+
+mo=month[$3]
+day=$4
+year=$7
+time=$5
+##153:
+
+#line 2510 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2511 "/u/norman/pu/web/dist/src/master/spider.web"
+hour=substr(time,1,2)
+if(hour>=12)
+ampm="PM"
+else
+ampm="AM"
+
+if(hour==0){
+hour=12
+}else if(hour>12){
+hour=hour-12
+}
+minute=substr(time,4,2)
+
+
+##:153
+
+#line 2488 "/u/norman/pu/web/dist/src/master/spider.web"
+
+date=sprintf("(generated at %d:%s %s on %s %d, %d)",\
+hour,minute,ampm,mo,day,year)
+next
+}
+
+##:151
+
+#line 60 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##88:
+
+#line 1442 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1443 "/u/norman/pu/web/dist/src/master/spider.web"
+/-->/{
+##89:
+
+#line 1471 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1472 "/u/norman/pu/web/dist/src/master/spider.web"
+lowpos=0;highpos=0;pos=1
+prodnum=prodnum+1
+inputline[prodnum]=$0
+print"Parsing production",prodnum,$0>logfile
+
+
+##:89
+
+#line 1444 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##90:
+
+#line 1492 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1493 "/u/norman/pu/web/dist/src/master/spider.web"
+trans[pos]=""
+for(i=1;i<=NF;i++){
+if($i~/<.*>/){
+##92:
+
+#line 1525 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1526 "/u/norman/pu/web/dist/src/master/spider.web"
+transstring=$i
+selfstring=""
+wherestring=sprintf("in production on line %d",NR-1)
+append_keyword="app"
+##24:
+
+#line 336 "/u/norman/pu/web/dist/src/master/spider.web"
+
+temp=substr(transstring,2,length(transstring)-2)
+trcnt=split(temp,trtok,"-")
+outstring=""
+for(tridx=1;tridx<=trcnt;tridx++){
+alternate=trtok[tridx]
+##25:
+
+#line 366 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 367 "/u/norman/pu/web/dist/src/master/spider.web"
+if(alternate=="space"){
+alternate="\" \""
+}else if(alternate=="dash"){
+alternate="\"-\""
+}
+
+
+##:25
+
+#line 342 "/u/norman/pu/web/dist/src/master/spider.web"
+
+if(alternate~/^[0-9]$/){
+temp=sprintf("\tapp_str(\"%s\");\n",alternate)
+outstring=outstring temp
+}else if(alternate~/^[a-zA-Z_]+$/){
+translation_keywords[alternate]=1
+temp=sprintf("\t%s(%s);\n",append_keyword,alternate)
+
+outstring=outstring temp
+}else if(alternate~/^\"([^"]*\\\")*[^"]*\"$/){
+temp=sprintf("\tapp_str(%s);\n",alternate)
+outstring=outstring temp
+}else if(alternate~/^\*$/){
+##26:
+
+#line 377 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 378 "/u/norman/pu/web/dist/src/master/spider.web"
+if(selfstring==""){
+print"Translation \"<*>\" makes no sense",wherestring
+exitcode=-1
+}
+
+##:26
+
+#line 355 "/u/norman/pu/web/dist/src/master/spider.web"
+
+outstring=outstring selfstring
+}else{
+print"Bogus translation",wherestring
+exitcode=-1
+}
+}
+
+##:24
+
+#line 1531 "/u/norman/pu/web/dist/src/master/spider.web"
+
+trans[pos]=trans[pos]outstring
+
+##:92
+
+#line 1496 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}else if($i~/^!?[a-zA-Z_]+(\*\*?)?$/){
+##93:
+
+#line 1543 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1544 "/u/norman/pu/web/dist/src/master/spider.web"
+field[pos]=$i
+##96:
+
+#line 1606 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1607 "/u/norman/pu/web/dist/src/master/spider.web"
+temp=substr($i,1,1)
+if(temp=="!"){
+negation=1
+$i=substr($i,2)
+}else{
+negation=0
+}
+
+##:96
+
+#line 1545 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##98:
+
+#line 1638 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1639 "/u/norman/pu/web/dist/src/master/spider.web"
+if($i~/^([a-zA-Z_]+|\(([a-zA-Z_]+\|)*[a-zA-Z_]+\))\*\*$/){
+temp=sprintf("\tmake_underlined(pp+%d);\n",pos-1)
+trans[pos]=trans[pos]temp
+$i=substr($i,1,length($i)-2)
+}else if($i~/^([a-zA-Z_]+|\(([a-zA-Z_]+\|)*[a-zA-Z_]+\))\*$/){
+temp=sprintf("\tmake_underlined(pp+%d);\n",pos-1)
+trans[pos]=trans[pos]temp
+$i=substr($i,1,length($i)-1)
+}else if($i~/\*$/){
+print"Error: can't remove stars in production on line",NR-1
+##91:
+
+#line 1519 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1520 "/u/norman/pu/web/dist/src/master/spider.web"
+prodnum--
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 1521 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:91
+
+#line 1649 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+##:98
+
+#line 1547 "/u/norman/pu/web/dist/src/master/spider.web"
+
+cat=$i
+categories[cat]=1
+if(negation==0){
+test[pos]=sprintf("(pp+%d)->cat==SP_%s",pos-1,cat)
+}else{
+test[pos]=sprintf("((pp+%d)->cat!=SP_%s && (pp+%d)->cat != 0)",\
+pos-1,cat,pos-1)
+}
+##95:
+
+#line 1597 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1598 "/u/norman/pu/web/dist/src/master/spider.web"
+if(pos>highestpos[cat]){
+highestpos[cat]=pos
+}
+
+##:95
+
+#line 1556 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##97:
+
+#line 1619 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1620 "/u/norman/pu/web/dist/src/master/spider.web"
+pos=pos+1
+trans[pos]=""
+
+##:97
+
+#line 1557 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:93
+
+#line 1498 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}else if($i~/^!?\(([a-zA-Z_]+\|)*[a-zA-Z_]+\)(\*\*?)?$/){
+##94:
+
+#line 1567 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1568 "/u/norman/pu/web/dist/src/master/spider.web"
+field[pos]=$i
+##96:
+
+#line 1606 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1607 "/u/norman/pu/web/dist/src/master/spider.web"
+temp=substr($i,1,1)
+if(temp=="!"){
+negation=1
+$i=substr($i,2)
+}else{
+negation=0
+}
+
+##:96
+
+#line 1569 "/u/norman/pu/web/dist/src/master/spider.web"
+
+if(negation==0){
+test[pos]="("
+}else{
+temp=sprintf("(pp+%d)->cat==0",pos-1)
+test[pos]="!("temp"||"
+}
+##98:
+
+#line 1638 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1639 "/u/norman/pu/web/dist/src/master/spider.web"
+if($i~/^([a-zA-Z_]+|\(([a-zA-Z_]+\|)*[a-zA-Z_]+\))\*\*$/){
+temp=sprintf("\tmake_underlined(pp+%d);\n",pos-1)
+trans[pos]=trans[pos]temp
+$i=substr($i,1,length($i)-2)
+}else if($i~/^([a-zA-Z_]+|\(([a-zA-Z_]+\|)*[a-zA-Z_]+\))\*$/){
+temp=sprintf("\tmake_underlined(pp+%d);\n",pos-1)
+trans[pos]=trans[pos]temp
+$i=substr($i,1,length($i)-1)
+}else if($i~/\*$/){
+print"Error: can't remove stars in production on line",NR-1
+##91:
+
+#line 1519 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1520 "/u/norman/pu/web/dist/src/master/spider.web"
+prodnum--
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 1521 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:91
+
+#line 1649 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+##:98
+
+#line 1577 "/u/norman/pu/web/dist/src/master/spider.web"
+
+temp=substr($i,2,length($i)-2)
+m=split(temp,tok,"|")
+for(j=1;j<=m;j++){
+cat=tok[j]
+categories[cat]=1
+##95:
+
+#line 1597 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1598 "/u/norman/pu/web/dist/src/master/spider.web"
+if(pos>highestpos[cat]){
+highestpos[cat]=pos
+}
+
+##:95
+
+#line 1584 "/u/norman/pu/web/dist/src/master/spider.web"
+
+temp=sprintf("(pp+%d)->cat==SP_%s",pos-1,cat)
+test[pos]=test[pos]temp
+if(j!=m)
+test[pos]=test[pos]"||\n"
+}
+test[pos]=test[pos]")"
+##97:
+
+#line 1619 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1620 "/u/norman/pu/web/dist/src/master/spider.web"
+pos=pos+1
+trans[pos]=""
+
+##:97
+
+#line 1591 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+
+##:94
+
+#line 1500 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}else if($i=="?"){
+##99:
+
+#line 1654 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1655 "/u/norman/pu/web/dist/src/master/spider.web"
+field[pos]=$i
+test[pos]=sprintf("(pp+%d)->cat!=0",pos-1)
+highwildcard=pos
+##97:
+
+#line 1619 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1620 "/u/norman/pu/web/dist/src/master/spider.web"
+pos=pos+1
+trans[pos]=""
+
+##:97
+
+#line 1658 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+
+
+##:99
+
+#line 1502 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}else if($i=="["){
+lowpos=pos
+}else if($i=="]"){
+highpos=pos
+}else if($i=="-->"){
+break
+}else{
+print"Error: bad field is",$i,"in production on line",NR-1
+##91:
+
+#line 1519 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1520 "/u/norman/pu/web/dist/src/master/spider.web"
+prodnum--
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 1521 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:91
+
+#line 1511 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+}
+i++
+
+
+##:90
+
+#line 1445 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##100:
+
+#line 1679 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1680 "/u/norman/pu/web/dist/src/master/spider.web"
+arrowpos=pos
+if(lowpos==0&&highpos==0){
+lowpos=1
+highpos=arrowpos
+
+}else if(lowpos==0||highpos==0){
+print"Error: square brackets don't balance in",\
+"production on line",NR-1
+##91:
+
+#line 1519 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1520 "/u/norman/pu/web/dist/src/master/spider.web"
+prodnum--
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 1521 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:91
+
+#line 1688 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+##:100
+
+#line 1446 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##101:
+
+#line 1693 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1694 "/u/norman/pu/web/dist/src/master/spider.web"
+if(arrowpos-1>highestposoverall){
+highestposoverall=arrowpos-1
+}
+
+##:101
+
+#line 1447 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##102:
+
+#line 1708 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1709 "/u/norman/pu/web/dist/src/master/spider.web"
+for(hup=arrowpos-1;field[hup]=="?";){
+hup--
+}
+for(;hup>highestunknownpos;hup--){
+temp=field[hup]
+temp=substr(temp,1,1)
+if(temp=="?"||temp=="!"){
+highestunknownpos=hup
+break
+}
+}
+
+##:102
+
+#line 1448 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##103:
+
+#line 1722 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1723 "/u/norman/pu/web/dist/src/master/spider.web"
+for(pos=1;pos<lowpos;pos++){
+##105:
+
+#line 1733 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1734 "/u/norman/pu/web/dist/src/master/spider.web"
+if(i>NF||$i!=field[pos]){
+print"Error: token mismatch is: found",$i,\
+"sought",field[pos],"on line",NR-1
+##91:
+
+#line 1519 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1520 "/u/norman/pu/web/dist/src/master/spider.web"
+prodnum--
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 1521 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:91
+
+#line 1737 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+##:105
+
+#line 1724 "/u/norman/pu/web/dist/src/master/spider.web"
+
+i++
+}
+
+##:103
+
+#line 1449 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##106:
+
+#line 1746 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1747 "/u/norman/pu/web/dist/src/master/spider.web"
+
+if(i>NF){
+print"Error: no target category in production on line",NR-1
+##91:
+
+#line 1519 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1520 "/u/norman/pu/web/dist/src/master/spider.web"
+prodnum--
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 1521 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:91
+
+#line 1750 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+if($i~/#[0-9]+/){
+$i=substr($i,2)
+##117:
+
+#line 1867 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1868 "/u/norman/pu/web/dist/src/master/spider.web"
+if((0+$i)<1||(0+$i)>=0+arrowpos){
+print"Error: can't take token number",$i,"of",arrowpos-1,\
+"tokens","in production on line",NR-1
+##91:
+
+#line 1519 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1520 "/u/norman/pu/web/dist/src/master/spider.web"
+prodnum--
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 1521 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:91
+
+#line 1871 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+##:117
+
+#line 1754 "/u/norman/pu/web/dist/src/master/spider.web"
+
+targetcategory[prodnum]="Unnamed category"
+temp=sprintf("(pp+%d)->cat",$i-1)
+unnamed_cat[prodnum]=temp
+}else if($i~/[a-zA-Z][a-zA-Z_]*/){
+targetcategory[prodnum]=$i
+categories[$i]=1
+}else{
+print"Error: unrecognizable target token",$i,\
+"in production on line",NR-1
+##91:
+
+#line 1519 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1520 "/u/norman/pu/web/dist/src/master/spider.web"
+prodnum--
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 1521 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:91
+
+#line 1764 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+i++
+
+##:106
+
+#line 1450 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##104:
+
+#line 1728 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1729 "/u/norman/pu/web/dist/src/master/spider.web"
+for(pos=highpos;pos<arrowpos;pos++){
+##105:
+
+#line 1733 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1734 "/u/norman/pu/web/dist/src/master/spider.web"
+if(i>NF||$i!=field[pos]){
+print"Error: token mismatch is: found",$i,\
+"sought",field[pos],"on line",NR-1
+##91:
+
+#line 1519 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1520 "/u/norman/pu/web/dist/src/master/spider.web"
+prodnum--
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 1521 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:91
+
+#line 1737 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+##:105
+
+#line 1730 "/u/norman/pu/web/dist/src/master/spider.web"
+
+i++
+}
+##:104
+
+#line 1451 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##107:
+
+#line 1769 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1770 "/u/norman/pu/web/dist/src/master/spider.web"
+if(i<=NF){
+print"Error: used only "i-1" of "NF" tokens",\
+"in production on line",NR-1
+##91:
+
+#line 1519 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1520 "/u/norman/pu/web/dist/src/master/spider.web"
+prodnum--
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 1521 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:91
+
+#line 1773 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+
+##:107
+
+#line 1452 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##108:
+
+#line 1779 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1780 "/u/norman/pu/web/dist/src/master/spider.web"
+prodtest[prodnum]=""
+for(pos=1;pos<arrowpos;pos++){
+if(pos>1){
+prodtest[prodnum]=prodtest[prodnum]" &&\n\t\t"
+}
+prodtest[prodnum]=prodtest[prodnum]test[pos]
+}
+
+##:108
+
+#line 1454 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##109:
+
+#line 1789 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1790 "/u/norman/pu/web/dist/src/master/spider.web"
+prodtrans[prodnum]=""
+for(pos=lowpos;pos<highpos;pos++){
+prodtrans[prodnum]=prodtrans[prodnum]trans[pos]
+
+temp=sprintf("\tapp1(pp+%d);\n",pos-1)
+prodtrans[prodnum]=prodtrans[prodnum]temp
+##114:
+
+#line 1830 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1831 "/u/norman/pu/web/dist/src/master/spider.web"
+temp=field[pos]
+tempa=substr(temp,1,1)
+if(tempa!="!"){
+if(temp~/^\(([a-zA-Z_]+\|)*[a-zA-Z_]+\)(\*\*?)?$/){
+
+##115:
+
+#line 1853 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1854 "/u/norman/pu/web/dist/src/master/spider.web"
+while(temp~/\*$/){
+temp=substr(temp,1,length(temp)-1)
+}
+
+##:115
+
+#line 1836 "/u/norman/pu/web/dist/src/master/spider.web"
+
+temp=substr(temp,2,length(temp)-2)
+m=split(temp,tok,"|")
+for(j=1;j<=m;j++){
+alternate=tok[j]
+reduced[alternate]=1
+}
+}else if(temp~/^[a-zA-Z_]+(\*\*?)?$/){
+##115:
+
+#line 1853 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1854 "/u/norman/pu/web/dist/src/master/spider.web"
+while(temp~/\*$/){
+temp=substr(temp,1,length(temp)-1)
+}
+
+##:115
+
+#line 1844 "/u/norman/pu/web/dist/src/master/spider.web"
+
+reduced[temp]=1
+}else if(temp!="?"){
+print"Confusion: unintelligible field[pos]:",temp,\
+"in production on line",NR-1
+##91:
+
+#line 1519 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1520 "/u/norman/pu/web/dist/src/master/spider.web"
+prodnum--
+##4:
+
+#line 79 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 80 "/u/norman/pu/web/dist/src/master/spider.web"
+exitcode=-1
+next
+
+
+##:4
+
+#line 1521 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:91
+
+#line 1849 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+}
+
+##:114
+
+#line 1798 "/u/norman/pu/web/dist/src/master/spider.web"
+
+}
+prodtrans[prodnum]=prodtrans[prodnum]trans[highpos]
+
+##:109
+
+#line 1456 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##110:
+
+#line 1803 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1804 "/u/norman/pu/web/dist/src/master/spider.web"
+ppstart[prodnum]=lowpos-1
+tokensreduced[prodnum]=highpos-lowpos
+
+##:110
+
+#line 1458 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##111:
+
+#line 1808 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1809 "/u/norman/pu/web/dist/src/master/spider.web"
+if(highpos-lowpos==1){
+printf"%d: %s --> %s\n",prodnum,field[lowpos],\
+targetcategory[prodnum]>cycles
+wrotecycles=1
+}
+
+##:111
+
+#line 1460 "/u/norman/pu/web/dist/src/master/spider.web"
+
+next
+}
+
+##:88
+
+#line 61 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##7:
+
+#line 108 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 109 "/u/norman/pu/web/dist/src/master/spider.web"
+{
+print"Warning: I don't know what to do with this line:"
+print" ",$0
+print"Warning: I don't know what to do with this line:">logfile
+print" ",$0>logfile
+}
+
+
+##:7
+
+#line 62 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+END{
+##54:
+
+#line 847 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 848 "/u/norman/pu/web/dist/src/master/spider.web"
+tempfile=scrapfile
+##55:
+
+#line 854 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 855 "/u/norman/pu/web/dist/src/master/spider.web"
+print"@ Here we input tokens of more than one character">tempfile
+print"@<Compress two-symbol operator@>=">tempfile
+##56:
+
+#line 863 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 864 "/u/norman/pu/web/dist/src/master/spider.web"
+for(len=maxtokenlength;len>=2;len--){
+printf"if (loc+%d<=limit) {\n",len-1>tempfile
+##57:
+
+#line 871 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 872 "/u/norman/pu/web/dist/src/master/spider.web"
+notfirst=0
+for(t in tokentest){
+if(tokenlength[t]==len){
+printf"\t">tempfile
+if(notfirst==1){
+printf"else ">tempfile
+}
+notfirst=1
+printf"if (%s) {\n",tokentest[t]>tempfile
+printf"\t\tloc += %d;\n",len-1>tempfile
+printf"\t\treturn %s;\n\t\t}\n",tokenname[t]>tempfile
+}
+}
+
+
+##:57
+
+#line 866 "/u/norman/pu/web/dist/src/master/spider.web"
+
+printf"\t}\n">tempfile
+}
+##58:
+
+#line 887 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 888 "/u/norman/pu/web/dist/src/master/spider.web"
+for(t in tokentest){
+if(tokenlength[t]==1){
+print"This can't happen: token",t,"is of length 1 but",\
+"it has a test"
+exitcode=-1
+}
+}
+
+
+
+##:58
+
+#line 869 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:56
+
+#line 858 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:55
+
+#line 849 "/u/norman/pu/web/dist/src/master/spider.web"
+
+tempfile=ttokfile
+##55:
+
+#line 854 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 855 "/u/norman/pu/web/dist/src/master/spider.web"
+print"@ Here we input tokens of more than one character">tempfile
+print"@<Compress two-symbol operator@>=">tempfile
+##56:
+
+#line 863 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 864 "/u/norman/pu/web/dist/src/master/spider.web"
+for(len=maxtokenlength;len>=2;len--){
+printf"if (loc+%d<=limit) {\n",len-1>tempfile
+##57:
+
+#line 871 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 872 "/u/norman/pu/web/dist/src/master/spider.web"
+notfirst=0
+for(t in tokentest){
+if(tokenlength[t]==len){
+printf"\t">tempfile
+if(notfirst==1){
+printf"else ">tempfile
+}
+notfirst=1
+printf"if (%s) {\n",tokentest[t]>tempfile
+printf"\t\tloc += %d;\n",len-1>tempfile
+printf"\t\treturn %s;\n\t\t}\n",tokenname[t]>tempfile
+}
+}
+
+
+##:57
+
+#line 866 "/u/norman/pu/web/dist/src/master/spider.web"
+
+printf"\t}\n">tempfile
+}
+##58:
+
+#line 887 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 888 "/u/norman/pu/web/dist/src/master/spider.web"
+for(t in tokentest){
+if(tokenlength[t]==1){
+print"This can't happen: token",t,"is of length 1 but",\
+"it has a test"
+exitcode=-1
+}
+}
+
+
+
+##:58
+
+#line 869 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:56
+
+#line 858 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:55
+
+#line 851 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:54
+##59:
+
+#line 904 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 905 "/u/norman/pu/web/dist/src/master/spider.web"
+print"Writing out predefined scraps">logfile
+##60:
+
+#line 917 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 918 "/u/norman/pu/web/dist/src/master/spider.web"
+if(id_category!=""){
+print"@ @<Append an identifier scrap@>=">scrapfile
+print"p=id_lookup(id_first, id_loc,normal);">scrapfile
+print"if (p->ilk==normal) {">scrapfile
+print" small_app(id_flag+p-name_dir);">scrapfile
+printf" app_scrap(SP_%s,%s_math);",\
+id_category,id_mathness>scrapfile
+appended[id_category]=1
+print" /* not a reserved word */">scrapfile
+print"}">scrapfile
+print"else if reserved(p) {">scrapfile
+print"@<Decide on reserved word scraps@>;">scrapfile
+print"}">scrapfile
+print"else {">scrapfile
+print" err_print(\"! Identifier with unmentioned ilk\");">scrapfile
+print"@.Identifier with unmentioned ilk@>">scrapfile
+print"}">scrapfile
+}else{
+print"Error: I don't know what to do with an identifier"
+print" Please give me a \"token identifier ...\""
+exitcode=-1
+}
+
+##:60
+
+#line 906 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##62:
+
+#line 948 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 949 "/u/norman/pu/web/dist/src/master/spider.web"
+print"Warning: TeX strings have the same category as ",\
+"numeric constants in this WEAVE."
+print"Warning: TeX strings have the same category as ",\
+"numeric constants in this WEAVE.">logfile
+if(number_category!=""){
+print"@ For some reason strings, constants,",\
+" and \TeX\ strings are identified.">scrapfile
+print"That has to be fixed.">scrapfile
+print"@<Do the |app_scrap| for a string or constant@>=">scrapfile
+printf"app_scrap(SP_%s,%s_math);\n",number_category,\
+number_mathness>scrapfile
+appended[number_category]=1
+}else{
+print"Error: I don't know what to do with a numeric constant"
+print" Please give me a \"token number ...\""
+exitcode=-1
+}
+
+
+##:62
+
+#line 907 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##64:
+
+#line 977 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 978 "/u/norman/pu/web/dist/src/master/spider.web"
+if(newline_category!=""){
+print"@ @<Append a newline scrap@>=">scrapfile
+transstring=newline_translation
+selfstring="small_app(next_control);"
+wherestring="in translation of token newline"
+append_keyword="small_app"
+##24:
+
+#line 336 "/u/norman/pu/web/dist/src/master/spider.web"
+
+temp=substr(transstring,2,length(transstring)-2)
+trcnt=split(temp,trtok,"-")
+outstring=""
+for(tridx=1;tridx<=trcnt;tridx++){
+alternate=trtok[tridx]
+##25:
+
+#line 366 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 367 "/u/norman/pu/web/dist/src/master/spider.web"
+if(alternate=="space"){
+alternate="\" \""
+}else if(alternate=="dash"){
+alternate="\"-\""
+}
+
+
+##:25
+
+#line 342 "/u/norman/pu/web/dist/src/master/spider.web"
+
+if(alternate~/^[0-9]$/){
+temp=sprintf("\tapp_str(\"%s\");\n",alternate)
+outstring=outstring temp
+}else if(alternate~/^[a-zA-Z_]+$/){
+translation_keywords[alternate]=1
+temp=sprintf("\t%s(%s);\n",append_keyword,alternate)
+
+outstring=outstring temp
+}else if(alternate~/^\"([^"]*\\\")*[^"]*\"$/){
+temp=sprintf("\tapp_str(%s);\n",alternate)
+outstring=outstring temp
+}else if(alternate~/^\*$/){
+##26:
+
+#line 377 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 378 "/u/norman/pu/web/dist/src/master/spider.web"
+if(selfstring==""){
+print"Translation \"<*>\" makes no sense",wherestring
+exitcode=-1
+}
+
+##:26
+
+#line 355 "/u/norman/pu/web/dist/src/master/spider.web"
+
+outstring=outstring selfstring
+}else{
+print"Bogus translation",wherestring
+exitcode=-1
+}
+}
+
+##:24
+
+#line 985 "/u/norman/pu/web/dist/src/master/spider.web"
+
+print outstring>scrapfile
+printf" app_scrap(SP_%s,%s_math);\n",newline_category,\
+newline_mathness>scrapfile
+appended[newline_category]=1
+}else{
+print"Error: I don't know what to do with a newline"
+print" Please give me a \"token newline ...\""
+exitcode=-1
+}
+
+##:64
+
+#line 908 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##65:
+
+#line 997 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 998 "/u/norman/pu/web/dist/src/master/spider.web"
+if(pseudo_semi_category!=""){
+print"@ @<Append a |pseudo_semi| scrap@>=">scrapfile
+transstring=pseudo_semi_translation
+selfstring="small_app(next_control);"
+wherestring="in translation of token pseudo_semi"
+append_keyword="small_app"
+##24:
+
+#line 336 "/u/norman/pu/web/dist/src/master/spider.web"
+
+temp=substr(transstring,2,length(transstring)-2)
+trcnt=split(temp,trtok,"-")
+outstring=""
+for(tridx=1;tridx<=trcnt;tridx++){
+alternate=trtok[tridx]
+##25:
+
+#line 366 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 367 "/u/norman/pu/web/dist/src/master/spider.web"
+if(alternate=="space"){
+alternate="\" \""
+}else if(alternate=="dash"){
+alternate="\"-\""
+}
+
+
+##:25
+
+#line 342 "/u/norman/pu/web/dist/src/master/spider.web"
+
+if(alternate~/^[0-9]$/){
+temp=sprintf("\tapp_str(\"%s\");\n",alternate)
+outstring=outstring temp
+}else if(alternate~/^[a-zA-Z_]+$/){
+translation_keywords[alternate]=1
+temp=sprintf("\t%s(%s);\n",append_keyword,alternate)
+
+outstring=outstring temp
+}else if(alternate~/^\"([^"]*\\\")*[^"]*\"$/){
+temp=sprintf("\tapp_str(%s);\n",alternate)
+outstring=outstring temp
+}else if(alternate~/^\*$/){
+##26:
+
+#line 377 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 378 "/u/norman/pu/web/dist/src/master/spider.web"
+if(selfstring==""){
+print"Translation \"<*>\" makes no sense",wherestring
+exitcode=-1
+}
+
+##:26
+
+#line 355 "/u/norman/pu/web/dist/src/master/spider.web"
+
+outstring=outstring selfstring
+}else{
+print"Bogus translation",wherestring
+exitcode=-1
+}
+}
+
+##:24
+
+#line 1005 "/u/norman/pu/web/dist/src/master/spider.web"
+
+print outstring>scrapfile
+printf" app_scrap(SP_%s,%s_math);\n",pseudo_semi_category,\
+pseudo_semi_mathness>scrapfile
+appended[pseudo_semi_category]=1
+}else{
+printf"Error: I don't know what to do with a pseudo_semi (%s;)",\
+substr(at_sign,1,1)
+print" Please give me a \"token pseudo_semi ...\""
+exitcode=-1
+}
+
+##:65
+
+#line 909 "/u/norman/pu/web/dist/src/master/spider.web"
+
+print"Writing out token scraps">logfile
+##66:
+
+#line 1018 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1019 "/u/norman/pu/web/dist/src/master/spider.web"
+print"@ @<Cases for ordinary tokens@>=">scrapfile
+for(t in tokens){
+temp=tokenname[t]
+printf"case %s:\n",temp>scrapfile
+transstring=tokentranslation[t]
+selfstring="small_app(next_control);"
+wherestring=sprintf("in translation of token %s",t)
+append_keyword="small_app"
+##24:
+
+#line 336 "/u/norman/pu/web/dist/src/master/spider.web"
+
+temp=substr(transstring,2,length(transstring)-2)
+trcnt=split(temp,trtok,"-")
+outstring=""
+for(tridx=1;tridx<=trcnt;tridx++){
+alternate=trtok[tridx]
+##25:
+
+#line 366 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 367 "/u/norman/pu/web/dist/src/master/spider.web"
+if(alternate=="space"){
+alternate="\" \""
+}else if(alternate=="dash"){
+alternate="\"-\""
+}
+
+
+##:25
+
+#line 342 "/u/norman/pu/web/dist/src/master/spider.web"
+
+if(alternate~/^[0-9]$/){
+temp=sprintf("\tapp_str(\"%s\");\n",alternate)
+outstring=outstring temp
+}else if(alternate~/^[a-zA-Z_]+$/){
+translation_keywords[alternate]=1
+temp=sprintf("\t%s(%s);\n",append_keyword,alternate)
+
+outstring=outstring temp
+}else if(alternate~/^\"([^"]*\\\")*[^"]*\"$/){
+temp=sprintf("\tapp_str(%s);\n",alternate)
+outstring=outstring temp
+}else if(alternate~/^\*$/){
+##26:
+
+#line 377 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 378 "/u/norman/pu/web/dist/src/master/spider.web"
+if(selfstring==""){
+print"Translation \"<*>\" makes no sense",wherestring
+exitcode=-1
+}
+
+##:26
+
+#line 355 "/u/norman/pu/web/dist/src/master/spider.web"
+
+outstring=outstring selfstring
+}else{
+print"Bogus translation",wherestring
+exitcode=-1
+}
+}
+
+##:24
+
+#line 1028 "/u/norman/pu/web/dist/src/master/spider.web"
+
+print outstring>scrapfile
+printf"\tapp_scrap(SP_%s,%s_math);\n",tokencategory[t],\
+tokenmathness[t]>scrapfile
+temp=tokencategory[t]
+appended[temp]=1
+
+print"\tbreak;">scrapfile
+}
+
+##:66
+
+#line 911 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+
+
+
+##:59
+##67:
+
+#line 1047 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1048 "/u/norman/pu/web/dist/src/master/spider.web"
+print"@ @<Cases for tokens to be output@>=">ttokfile
+for(t in tokennumbers){
+##69:
+
+#line 1099 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1100 "/u/norman/pu/web/dist/src/master/spider.web"
+if(t=="string"||t=="constant"||t=="identifier")
+continue
+
+
+
+##:69
+
+#line 1050 "/u/norman/pu/web/dist/src/master/spider.web"
+
+printf"case %s:\n",tokenname[t]>ttokfile
+this_tangleto=tokentangleto[t]
+if(this_tangleto==""){
+printf"\tC_printf(\"%%s\",\"%s\");\n",t>ttokfile
+}else{
+printf"\tif (out_state==verbatim) {\n">ttokfile
+printf"\t\tC_printf(\"%%s\",\"%s\");\n",t>ttokfile
+printf"\t} else {\n">ttokfile
+##70:
+
+#line 1106 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1107 "/u/norman/pu/web/dist/src/master/spider.web"
+oldwherestring=wherestring
+wherestring="for tangleto "wherestring
+
+transstring=this_tangleto
+##27:
+
+#line 389 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 390 "/u/norman/pu/web/dist/src/master/spider.web"
+temp=substr(transstring,2,length(transstring)-2)
+trcnt=split(temp,trtok,"-")
+outstring=""
+for(tridx=1;tridx<=trcnt;tridx++){
+alternate=trtok[tridx]
+##25:
+
+#line 366 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 367 "/u/norman/pu/web/dist/src/master/spider.web"
+if(alternate=="space"){
+alternate="\" \""
+}else if(alternate=="dash"){
+alternate="\"-\""
+}
+
+
+##:25
+
+#line 395 "/u/norman/pu/web/dist/src/master/spider.web"
+
+if(alternate~/^[0-9]$/){
+print"Digit not allowed in restricted translation",wherestring
+exitcode=-1
+}else if(alternate~/^[a-zA-Z_]+$/){
+print"Key word not allowed in restricted translation",wherestring
+exitcode=-1
+}else if(alternate~/^\"([^"]*\\\")*[^"]*\"$/){
+temp=substr(alternate,2,length(alternate)-2)
+outstring=outstring temp
+}else if(alternate~/^\*$/){
+print"<*> not allowed in restricted translation",wherestring
+exitcode=-1
+}else{
+print"Bogus restricted translation",wherestring
+exitcode=-1
+}
+}
+outstring="\""outstring"\""
+
+
+
+##:27
+
+#line 1112 "/u/norman/pu/web/dist/src/master/spider.web"
+
+printf"\tC_printf(\"%%s\",%s);\n",outstring>ttokfile
+
+wherestring=oldwherestring
+
+
+
+##:70
+
+#line 1059 "/u/norman/pu/web/dist/src/master/spider.web"
+
+printf"\t}\n">ttokfile
+}
+print"\tif (out_state!=verbatim) out_state=misc;">ttokfile
+print"break;">ttokfile
+}
+
+##:67
+##68:
+
+#line 1068 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1069 "/u/norman/pu/web/dist/src/master/spider.web"
+print"@ @<Cases for tokens to be output@>=">ttokfile
+for(t in tokentangleto){
+##69:
+
+#line 1099 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1100 "/u/norman/pu/web/dist/src/master/spider.web"
+if(t=="string"||t=="constant"||t=="identifier")
+continue
+
+
+
+##:69
+
+#line 1071 "/u/norman/pu/web/dist/src/master/spider.web"
+
+if(tokennumbers[t]!=""||tokentangleto[t]=="")
+continue
+if(t=="@"){
+thistangletokname="@@"
+}else if(t=="\\"||t=="'"){
+thistangletokname="\\"t
+}else{
+thistangletokname=t
+}
+printf"case '%s':\n",thistangletokname>ttokfile
+this_tangleto=tokentangleto[t]
+if(this_tangleto==""){
+print"This can't happen -- null tangleto for",t,wherestring
+exitcode=-1
+}else{
+printf"\tif (out_state==verbatim) {\n">ttokfile
+printf"\t\tC_printf(\"%%s\",\"%s\");\n",t>ttokfile
+printf"\t} else {\n">ttokfile
+##70:
+
+#line 1106 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1107 "/u/norman/pu/web/dist/src/master/spider.web"
+oldwherestring=wherestring
+wherestring="for tangleto "wherestring
+
+transstring=this_tangleto
+##27:
+
+#line 389 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 390 "/u/norman/pu/web/dist/src/master/spider.web"
+temp=substr(transstring,2,length(transstring)-2)
+trcnt=split(temp,trtok,"-")
+outstring=""
+for(tridx=1;tridx<=trcnt;tridx++){
+alternate=trtok[tridx]
+##25:
+
+#line 366 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 367 "/u/norman/pu/web/dist/src/master/spider.web"
+if(alternate=="space"){
+alternate="\" \""
+}else if(alternate=="dash"){
+alternate="\"-\""
+}
+
+
+##:25
+
+#line 395 "/u/norman/pu/web/dist/src/master/spider.web"
+
+if(alternate~/^[0-9]$/){
+print"Digit not allowed in restricted translation",wherestring
+exitcode=-1
+}else if(alternate~/^[a-zA-Z_]+$/){
+print"Key word not allowed in restricted translation",wherestring
+exitcode=-1
+}else if(alternate~/^\"([^"]*\\\")*[^"]*\"$/){
+temp=substr(alternate,2,length(alternate)-2)
+outstring=outstring temp
+}else if(alternate~/^\*$/){
+print"<*> not allowed in restricted translation",wherestring
+exitcode=-1
+}else{
+print"Bogus restricted translation",wherestring
+exitcode=-1
+}
+}
+outstring="\""outstring"\""
+
+
+
+##:27
+
+#line 1112 "/u/norman/pu/web/dist/src/master/spider.web"
+
+printf"\tC_printf(\"%%s\",%s);\n",outstring>ttokfile
+
+wherestring=oldwherestring
+
+
+
+##:70
+
+#line 1090 "/u/norman/pu/web/dist/src/master/spider.web"
+
+printf"\t}\n">ttokfile
+}
+print"\tif (out_state!=verbatim) out_state=misc;">ttokfile
+print"break;">ttokfile
+}
+##:68
+##71:
+
+#line 1123 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1124 "/u/norman/pu/web/dist/src/master/spider.web"
+tempfile=scrapfile
+##72:
+
+#line 1131 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1132 "/u/norman/pu/web/dist/src/master/spider.web"
+print"@ Here are the definitions of the token names">tempfile
+for(t in tokennumbers){
+temp=tokennumbers[t]
+if(temp==0)
+continue
+if(tempfile==ttokfile){
+##69:
+
+#line 1099 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1100 "/u/norman/pu/web/dist/src/master/spider.web"
+if(t=="string"||t=="constant"||t=="identifier")
+continue
+
+
+
+##:69
+
+#line 1139 "/u/norman/pu/web/dist/src/master/spider.web"
+
+temp=temp+31+3-highesttoken
+
+}
+printf"@d %s = %s\n",tokenname[t],temp>tempfile
+}
+
+
+##:72
+
+#line 1125 "/u/norman/pu/web/dist/src/master/spider.web"
+
+tempfile=ttokfile
+##72:
+
+#line 1131 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1132 "/u/norman/pu/web/dist/src/master/spider.web"
+print"@ Here are the definitions of the token names">tempfile
+for(t in tokennumbers){
+temp=tokennumbers[t]
+if(temp==0)
+continue
+if(tempfile==ttokfile){
+##69:
+
+#line 1099 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1100 "/u/norman/pu/web/dist/src/master/spider.web"
+if(t=="string"||t=="constant"||t=="identifier")
+continue
+
+
+
+##:69
+
+#line 1139 "/u/norman/pu/web/dist/src/master/spider.web"
+
+temp=temp+31+3-highesttoken
+
+}
+printf"@d %s = %s\n",tokenname[t],temp>tempfile
+}
+
+
+##:72
+
+#line 1127 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:71
+##79:
+
+#line 1268 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1269 "/u/norman/pu/web/dist/src/master/spider.web"
+print"Writing out reserved words and ilks">logfile
+ilkno=64
+print"@ Here is a list of all the ilks">reserved
+for(i in ilk_translation){
+printf"@d SP_%s = %d\n",i,ilkno>reserved
+ilkno++
+}
+
+##:79
+##80:
+
+#line 1279 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1280 "/u/norman/pu/web/dist/src/master/spider.web"
+print" ">reserved
+print"@ Here are the scraps we get from the reserved words">reserved
+print"@d the_word = res_flag+p-name_dir">reserved
+print"@<Decide on reserved word scraps@>=">reserved
+print"switch (p->ilk) {">reserved
+for(t in ilk_translation){
+printf"\tcase SP_%s: \n\t\t",t>reserved
+transstring=ilk_translation[t]
+selfstring="small_app(the_word);"
+wherestring=sprintf("in translation of ilk %s",t)
+append_keyword="small_app"
+##24:
+
+#line 336 "/u/norman/pu/web/dist/src/master/spider.web"
+
+temp=substr(transstring,2,length(transstring)-2)
+trcnt=split(temp,trtok,"-")
+outstring=""
+for(tridx=1;tridx<=trcnt;tridx++){
+alternate=trtok[tridx]
+##25:
+
+#line 366 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 367 "/u/norman/pu/web/dist/src/master/spider.web"
+if(alternate=="space"){
+alternate="\" \""
+}else if(alternate=="dash"){
+alternate="\"-\""
+}
+
+
+##:25
+
+#line 342 "/u/norman/pu/web/dist/src/master/spider.web"
+
+if(alternate~/^[0-9]$/){
+temp=sprintf("\tapp_str(\"%s\");\n",alternate)
+outstring=outstring temp
+}else if(alternate~/^[a-zA-Z_]+$/){
+translation_keywords[alternate]=1
+temp=sprintf("\t%s(%s);\n",append_keyword,alternate)
+
+outstring=outstring temp
+}else if(alternate~/^\"([^"]*\\\")*[^"]*\"$/){
+temp=sprintf("\tapp_str(%s);\n",alternate)
+outstring=outstring temp
+}else if(alternate~/^\*$/){
+##26:
+
+#line 377 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 378 "/u/norman/pu/web/dist/src/master/spider.web"
+if(selfstring==""){
+print"Translation \"<*>\" makes no sense",wherestring
+exitcode=-1
+}
+
+##:26
+
+#line 355 "/u/norman/pu/web/dist/src/master/spider.web"
+
+outstring=outstring selfstring
+}else{
+print"Bogus translation",wherestring
+exitcode=-1
+}
+}
+
+##:24
+
+#line 1293 "/u/norman/pu/web/dist/src/master/spider.web"
+
+if(trcnt>0)
+has_translation[t]=1
+print outstring>reserved
+printf"\tapp_scrap(SP_%s,%s_math);\n",ilk_category[t],\
+ilk_mathness[t]>reserved
+temp=ilk_category[t]
+appended[temp]=1
+
+printf"\t\tbreak;\n">reserved
+}
+print"}">reserved
+
+
+##:80
+##81:
+
+#line 1309 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1310 "/u/norman/pu/web/dist/src/master/spider.web"
+print"@ @<Store all the reserved words@>=">reserved
+for(i in reservedilk){
+printf"id_lookup(\"%s\",NULL,SP_%s);\n",i,reservedilk[i]>reserved
+}
+
+##:81
+##118:
+
+#line 1876 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1877 "/u/norman/pu/web/dist/src/master/spider.web"
+print"Writing out category codes">logfile
+print"@ Here is a list of category codes scraps can have">grammarfile
+i=1
+for(t in categories){
+printf"@d SP_%s = %d\n",t,i>grammarfile
+i++
+}
+print"@c">grammarfile
+##:118
+##119:
+
+#line 1887 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1888 "/u/norman/pu/web/dist/src/master/spider.web"
+print"#ifdef DEBUG">grammarfile
+print"#define PRINT_CAT(A,B) case A: printf(B); break">grammarfile
+print"print_cat(c) /* symbolic printout of a category */">grammarfile
+print"eight_bits c;">grammarfile
+print"{">grammarfile
+print" switch(c) {">grammarfile
+for(t in categories){
+printf"PRINT_CAT(SP_%s,\"%s\");\n",t,t>grammarfile
+}
+print" case 0: printf(\"zero\"); break;">grammarfile
+print" default: printf(\"UNKNOWN\"); break;">grammarfile
+print" }">grammarfile
+print"}">grammarfile
+print"#endif DEBUG">grammarfile
+print" ">grammarfile
+
+##:119
+##123:
+
+#line 1947 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1948 "/u/norman/pu/web/dist/src/master/spider.web"
+print"Writing out grammar">logfile
+print"@ Here is where we define |highestposoverall| and where we">grammarfile
+print"check the productions.">grammarfile
+print"@d highestposoverall =",highestposoverall>grammarfile
+print"@<Test for all of the productions@>=">grammarfile
+for(n=1;n<=prodnum;n++){
+if(n%5==0)
+print"@ @<Test for all of the productions@>="\
+>grammarfile
+##126:
+
+#line 2011 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2012 "/u/norman/pu/web/dist/src/master/spider.web"
+this_string=inputline[n]
+tempi=index(this_string,"|")
+while(tempi!=0){
+tempa=substr(this_string,1,tempi-1)
+tempb=substr(this_string,tempi+1)
+this_string=tempa"\\vert "tempb
+tempi=index(this_string,"|")
+}
+templ="";tempr=this_string
+tempi=index(tempr,"_")
+while(tempi!=0){
+tempa=substr(tempr,1,tempi-1)
+tempr=substr(tempr,tempi+1)
+templ=templ tempa"\\_"
+tempi=index(tempr,"_")
+}
+this_string=templ tempr
+templ="";tempr=this_string
+tempi=index(tempr,"#")
+while(tempi!=0){
+tempa=substr(tempr,1,tempi-1)
+tempr=substr(tempr,tempi+1)
+templ=templ tempa"\\#"
+tempi=index(tempr,"#")
+}
+this_string=templ tempr
+
+
+##:126
+
+#line 1957 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##127:
+
+#line 2041 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2042 "/u/norman/pu/web/dist/src/master/spider.web"
+toolong=this_string;this_string=""
+while(length(toolong)>60){
+idx=59
+idchar=substr(toolong,idx,1)
+while(idx>1&&idchar!=" "){
+idx--
+idchar=substr(toolong,idx,1)
+}
+if(idx==1)
+idx=59
+temp=substr(toolong,1,idx-1)
+toolong=substr(toolong,idx+1)
+this_string=this_string temp"\n"
+}
+this_string=this_string toolong
+
+
+
+##:127
+
+#line 1958 "/u/norman/pu/web/dist/src/master/spider.web"
+
+printf"if (%s) {\n\t/* %d: {\\tt %s} */\n%s",\
+prodtest[n],n,this_string,prodtrans[n]>grammarfile
+##124:
+
+#line 1970 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1971 "/u/norman/pu/web/dist/src/master/spider.web"
+ttk=targetcategory[n]
+if(ttk=="Unnamed category"){
+
+printf"\treduce(pp+%d,%d,%s,%d,%d);\n",ppstart[n],\
+tokensreduced[n],unnamed_cat[n],\
+1-highestposoverall,n>grammarfile
+}else{
+appended[ttk]=1
+
+reduction=highestpos[ttk]
+if(reduction<highestunknownpos){
+reduction=highestunknownpos
+}
+printf"\treduce(pp+%d,%d,SP_%s,%d,%d);\n",ppstart[n],\
+tokensreduced[n],targetcategory[n],\
+1-reduction,n>grammarfile
+}
+
+##:124
+
+#line 1962 "/u/norman/pu/web/dist/src/master/spider.web"
+
+print"\tgoto end_prods;">grammarfile
+printf"} ">grammarfile
+}
+printf"\n">grammarfile
+print"end_prods:">grammarfile
+
+##:123
+##130:
+
+#line 2095 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2096 "/u/norman/pu/web/dist/src/master/spider.web"
+if(language!=""){
+print"@ Here is the language-dependent stuff">tlang
+if(version!="")
+version=", Version "version
+printf"@d banner = \"This is %s TANGLE%s %s\\n\"\n",language,\
+version,date>tlang
+printf"@<Global...@>=char C_file_extension[]=\"%s\";\n",extension \
+>tlang
+
+print"@ Here is the language-dependent stuff">wlang
+if(version!="")
+version=", Version "version
+printf"@d banner = \"This is %s WEAVE%s %s\\n\"\n",language,\
+version,date>wlang
+print"@<Set |out_ptr| and do a |tex_printf| to read the macros@>="\
+>wlang
+printf"*out_ptr='x'; tex_printf(\"\\\\input %sweb.te\");\n",\
+extension>wlang
+printf"@ @<Global...@>=char C_file_extension[]=\"%s\";\n",extension \
+>wlang
+}else{
+print"Error: you haven't given me any \"language\" information"
+exitcode=-1
+}
+
+##:130
+##134:
+
+#line 2189 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2190 "/u/norman/pu/web/dist/src/master/spider.web"
+if(mod_def_cat!=""){
+print"@ @<Call |app_scrap| for a module definition@>=">scrapfile
+printf"app_scrap(SP_%s,no_math);\n",mod_def_cat>scrapfile
+appended[mod_def_cat]=1
+}else{
+print"Error: I don't know what to do with a module definition"
+print" Give me a \"module definition ...\""
+exitcode=-1
+}
+if(mod_use_cat!=""){
+print"@ @<Call |app_scrap| for a module use@>=">scrapfile
+printf"app_scrap(SP_%s,maybe_math);\n",mod_use_cat>scrapfile
+appended[mod_use_cat]=1
+}else{
+print"Error: I don't know what to do with a module use"
+print" Give me a \"module use ...\""
+exitcode=-1
+}
+
+
+##:134
+##136:
+
+#line 2230 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2231 "/u/norman/pu/web/dist/src/master/spider.web"
+tempfile=grammarfile
+##137:
+
+#line 2237 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2238 "/u/norman/pu/web/dist/src/master/spider.web"
+print"@ Here is the |at_sign| for the new web">tempfile
+printf"@d at_sign = @`%s'\n",at_sign>tempfile
+print" ">tempfile
+print"@ Here is |the_at_sign| left for common">tempfile
+print"@<Global...@>=char the_at_sign = at_sign;">tempfile
+print" ">tempfile
+
+##:137
+
+#line 2232 "/u/norman/pu/web/dist/src/master/spider.web"
+
+tempfile=ttokfile
+##137:
+
+#line 2237 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2238 "/u/norman/pu/web/dist/src/master/spider.web"
+print"@ Here is the |at_sign| for the new web">tempfile
+printf"@d at_sign = @`%s'\n",at_sign>tempfile
+print" ">tempfile
+print"@ Here is |the_at_sign| left for common">tempfile
+print"@<Global...@>=char the_at_sign = at_sign;">tempfile
+print" ">tempfile
+
+##:137
+
+#line 2234 "/u/norman/pu/web/dist/src/master/spider.web"
+
+
+##:136
+##140:
+
+#line 2304 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2305 "/u/norman/pu/web/dist/src/master/spider.web"
+print"@ Here we recognize the comment start seqence">ttokfile
+print"@<See a comment starting at |loc| and skip it@>=">ttokfile
+printf"{int len; len=strlen(%s);\n",begin_comment_string>ttokfile
+printf"if (loc+len<=limit && !strncmp(loc,%s,len)) {\n",\
+begin_comment_string>ttokfile
+print"\tloc += len; /* a new thing */">ttokfile
+print"\tskip_comment(); /* scan to end of comment or newline */">ttokfile
+print"\tif (comment_continues || comments_end_with_newline)">ttokfile
+print"\t\treturn('\\n');">ttokfile
+print"\telse continue;\n}\n}">ttokfile
+
+
+##:140
+##141:
+
+#line 2318 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2319 "/u/norman/pu/web/dist/src/master/spider.web"
+print"@ @<See a comment starting at |loc-1| and return |begin_comment|@>="\
+>scrapfile
+printf"{int len; len=strlen(%s);\n",begin_comment_string>scrapfile
+printf"if (loc+len-1<=limit && !strncmp(loc-1,%s,len)) {\n",\
+begin_comment_string>scrapfile
+print"\tloc += len-1;">scrapfile
+print"\t return (begin_comment); /* scan to end of comment or newline */">scrapfile
+print"}\n}">scrapfile
+
+
+
+
+##:141
+##142:
+
+#line 2332 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2333 "/u/norman/pu/web/dist/src/master/spider.web"
+print"@ Here we deal with recognizing the end of comments">ttokfile
+printf"@d comments_end_with_newline = %d\n",comments_end_with_newline>ttokfile
+print"@<Recognize comment end starting at |loc-1|@>=">ttokfile
+if(comments_end_with_newline!=1){
+printf"{int len; len=strlen(%s);\n",end_comment_string>ttokfile
+printf"if (loc+len-1<=limit && !strncmp(loc-1,%s,len)) {\n",\
+end_comment_string>ttokfile
+print"loc += len-1; return(comment_continues=0); }}">ttokfile
+}else{
+print"/* This code will never be executed */ ">ttokfile
+}
+
+##:142
+##143:
+
+#line 2348 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2349 "/u/norman/pu/web/dist/src/master/spider.web"
+printf"@ Here we recognize end of comments">scrapfile
+printf"@d comments_end_with_newline = %d\n",comments_end_with_newline>scrapfile
+print"@<Check for end of comment@>=">scrapfile
+printf"{int len; len=strlen(%s);\n",end_comment_string>scrapfile
+printf"if (loc+len-1<=limit && !strncmp(loc-1,%s,len)) {\n",\
+end_comment_string>scrapfile
+print" loc++; if(bal==1) {if (phase==2) app_tok('}'); return(0);}">scrapfile
+print" else {">scrapfile
+print" err_print(\"! Braces don't balance in comment\");">scrapfile
+print"@.Braces don't balance in comment@>">scrapfile
+print" @<Clear |bal| and |return|@>;">scrapfile
+print" }">scrapfile
+print"}">scrapfile
+print"}">scrapfile
+
+
+##:143
+##144:
+
+#line 2367 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2368 "/u/norman/pu/web/dist/src/master/spider.web"
+print"@ Important tokens:">ttokfile
+printf"@d begin_comment_string = %s\n",begin_comment_string>ttokfile
+printf"@d end_comment_string = %s\n",end_comment_string>ttokfile
+
+##:144
+##149:
+
+#line 2469 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2470 "/u/norman/pu/web/dist/src/master/spider.web"
+print"@ Important tokens:">ttokfile
+printf"@d sharp_line_open = %s\n",sharp_line_open>ttokfile
+printf"@d sharp_line_close = %s\n",sharp_line_close>ttokfile
+
+##:149
+
+#line 65 "/u/norman/pu/web/dist/src/master/spider.web"
+
+print"Writing out lists">logfile
+##21:
+
+#line 304 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 305 "/u/norman/pu/web/dist/src/master/spider.web"
+for(t in translation_keywords){
+print t>translationfile
+}
+
+##:21
+##73:
+
+#line 1149 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1150 "/u/norman/pu/web/dist/src/master/spider.web"
+for(t in tokenname){
+temp=tokenname[t]
+if(substr(temp,1,1)!="'"){
+##74:
+
+#line 1158 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1159 "/u/norman/pu/web/dist/src/master/spider.web"
+tempa=substr(temp,1,3)
+if(tempa=="SP_"){
+temp=substr(temp,4)
+}
+
+
+##:74
+
+#line 1153 "/u/norman/pu/web/dist/src/master/spider.web"
+
+print temp>tokennamefile
+}
+}
+
+##:73
+##83:
+
+#line 1330 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1331 "/u/norman/pu/web/dist/src/master/spider.web"
+for(i in ilk_translation){
+print i>ilkfile
+}
+
+##:83
+##113:
+
+#line 1817 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1818 "/u/norman/pu/web/dist/src/master/spider.web"
+if(wrotecycles==0){
+print"0: dummy --> nodummy">cycles
+}
+
+##:113
+##120:
+
+#line 1905 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1906 "/u/norman/pu/web/dist/src/master/spider.web"
+for(c in categories){
+print c>categoryfile
+}
+
+##:120
+##122:
+
+#line 1929 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1930 "/u/norman/pu/web/dist/src/master/spider.web"
+for(n=1;n<=prodnum;n++){
+printf"%2d: %s\n",n,inputline[n]>productions
+}
+
+##:122
+
+#line 67 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##22:
+
+#line 309 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 310 "/u/norman/pu/web/dist/src/master/spider.web"
+for(t in translation_keywords){
+num_of_translation_keywords++
+}
+printf"You used %d translation keywords.\n",\
+num_of_translation_keywords>logfile
+printf"You used %d translation keywords.\n",num_of_translation_keywords
+
+##:22
+##84:
+
+#line 1335 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1336 "/u/norman/pu/web/dist/src/master/spider.web"
+for(i in ilk_translation)number_of_ilks++
+for(i in reservedilk)number_of_reserved_words++
+printf"You defined %d reserved words of %d ilks.\n",\
+number_of_reserved_words,number_of_ilks
+printf"You defined %d reserved words of %d ilks.\n",\
+number_of_reserved_words,number_of_ilks>logfile
+
+##:84
+##121:
+
+#line 1910 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1911 "/u/norman/pu/web/dist/src/master/spider.web"
+for(c in categories){
+number_of_categories++
+}
+printf"You used %d different categories in %d productions.\n",\
+number_of_categories,prodnum
+printf"You used %d different categories in %d productions.\n",\
+number_of_categories,prodnum>logfile
+printf"The biggest production had %d scraps on its left-hand side.\n",\
+highestposoverall
+printf"The biggest production had %d scraps on its left-hand side.\n",\
+highestposoverall>logfile
+
+
+##:121
+
+#line 68 "/u/norman/pu/web/dist/src/master/spider.web"
+
+##47:
+
+#line 734 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 735 "/u/norman/pu/web/dist/src/master/spider.web"
+if(tokennumber<127){
+print"Error: too many token names for WEAVE --- over by",\
+127-tokennumber
+exitcode=-1
+}
+##:47
+##48:
+
+#line 743 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 744 "/u/norman/pu/web/dist/src/master/spider.web"
+if(highesttoken-tokennumber>31-(11-1)+3){\
+
+print"Error: too many token names for TANGLE --- over by",\
+highesttoken-tokennumber-(31-(11-1)+3)
+exitcode=-1
+}
+
+
+
+##:48
+##82:
+
+#line 1318 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1319 "/u/norman/pu/web/dist/src/master/spider.web"
+for(i in ilk_translation){
+if(has_reserved[i]!=1){
+print"Error: there is no reserved word of ilk",i
+exitcode=-1
+}
+if(has_translation[i]!=1){
+print"Error: ilk",i,"has no translation"
+exitcode=-1
+}
+}
+
+##:82
+##116:
+
+#line 1858 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1859 "/u/norman/pu/web/dist/src/master/spider.web"
+for(c in categories){
+if(reduced[c]!=1){
+print"Warning: category",c,"never reduced"
+}
+}
+
+
+##:116
+##125:
+
+#line 1992 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 1993 "/u/norman/pu/web/dist/src/master/spider.web"
+for(c in categories){
+if(appended[c]!=1){
+if(c=="ignore_scrap"){
+print"Warning: category",c,"never appended"
+}else{
+print"Error: category",c,"never appended"
+exitcode=-1
+}
+}
+}
+
+
+
+##:125
+
+#line 69 "/u/norman/pu/web/dist/src/master/spider.web"
+
+if(exitcode!=0){
+exit exitcode
+}
+}
+
+##:3
+
diff --git a/web/spiderweb/src/master/spider.web b/web/spiderweb/src/master/spider.web
new file mode 100644
index 0000000000..0aca8a4232
--- /dev/null
+++ b/web/spiderweb/src/master/spider.web
@@ -0,0 +1,2580 @@
+% Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+% Not to be sold, but may be used freely for any purpose
+% For more information, see file COPYRIGHT in the parent directory
+
+\message{OK, entering \string\batchmode...}
+\batchmode
+
+\let\RA\rightarrow
+
+\def\vert{{\tt\char'174}}
+\def\pb{$\.|\ldots\.|$} % C brackets (|...|)
+
+\def\title{SPIDER}
+
+\def\topofcontents{\null\vfill
+ \titlefalse % include headline on the contents page
+ \def\rheader{\hfil}
+ \centerline{\titlefont The {\ttitlefont SPIDER} processor}
+ \vfill}
+
+
+\def\syntax##1{\leavevmode\hbox{$\langle\hbox{\sl ##1\/}\rangle$}}
+\def\produces{\leavevmode\hbox{${}::={}$}}
+\def\opt##1{$[$##1$]$}
+
+#*={\tt SPIDER} proper.
+#*Introduction.
+This is an AWK program designed to read a description of a programming
+language and to write out the language-dependent parts of WEB.
+In the main,
+the description of a programming language is
+ a list of all the tokens of the language
+(together with various facts about them) and a grammar for prettyprinting
+code fragments written in that language.
+The ``Spider User's Guide'' describes how to use {\tt SPIDER} to construct
+a {\tt WEB} system for the ALGOL-like language of your choice.
+({\tt SPIDER} may be able to handle LISP and Miranda and other strange
+languages; the experiment hasn't been tried.
+The unusual lexical requirements of FORTRAN are probably beyond it, at
+least until the lexical analysis is modernized.)
+
+# The outline of the program is fairly straightforward.
+We use |exitcode| throughout to monitor error status.
+If we were more Knuthlike, we would have a |history| variable with values of
+|spotless|, and so on.
+This will have to wait until we get macros back into \.{TANGLE}.
+
+We put the pattern-action statement for productions last, because in
+case of a conflict like \.{token~-->~...}, we want the interpretation
+as {\tt token} to win out over
+the interpretation as a prodution.
+
+#u#1
+BEGIN {
+#<Set initial values#>
+exitcode=0
+}
+#@
+#<Ignore comments and blank lines#>
+#<Pattern-action statements#>
+#<Production pattern-action statement#>
+#<Default action for patterns we don't recognize#>
+#@
+END {
+#<Write out all of the WEB code#>
+print "Writing out lists" > logfile
+#<Write lists of everything#>
+#<Write statistics for this \.{SPIDER}#>
+#<Check for errors at the very end#>
+if (exitcode != 0) {
+ exit exitcode
+ }
+}
+
+# There are a couple of actions we may want to perform with just
+about any command.
+If a command fails, we move on to the next, but we remember the fault
+so we can complain at the end.
+#<Punt this command#>=
+ exitcode=-1
+ next
+
+
+# Throughout \.{SPIDER} we always use the variable |i| to step through the
+fields of a command, so that |$i| is always the next field of interest.
+When we thinik we have finished a command,
+we will always want to check to make sure there are no unexamined
+fields left over.
+For error messages, the line number is really |NR-1|, since we put an
+extra line at the beginning with the date.
+#<Check that we used everything#>=
+ if (i<=NF) {
+ print "Error: leftover fields", $i, "... on line", NR-1
+ #<Punt...#>
+ }
+
+
+# To \.{SPIDER}, any line beginning with |"## "| is a comment.
+\.{SPIDER} also ignores blank lines.
+#<Ignore comments...#>=
+#=/^##|^ *$/#> {
+ ## comments, blank lines
+ print $0 > logfile
+ next
+ }
+
+# But, if \.{SPIDER} encounters a line we don't recognize, it complains.
+#<Default act...#>=
+ {
+ print "Warning: I don't know what to do with this line:"
+ print " ", $0
+ print "Warning: I don't know what to do with this line:" > logfile
+ print " ", $0 > logfile
+}
+
+
+#*1Files written by {\tt SPIDER}.
+ {\tt SPIDER} writes output to a number of files.
+Because 4.3~BSD AWK is limited in the number of files it can write at
+one time, there is substantial overlap.
+Here is a table:
+\noindent\halign{\vrule height10pt depth3.5pt width0pt
+\it##\hfil\tabskip=1em&\tt##\hfil&\tabskip=0pt
+ \hsize=4in\vtop{\noindent##\strut\par}\cr
+\noalign{\medskip}
+\bf Internal Name&\bf External Name&\omit\bf Description\hfil\cr
+\noalign{\smallskip}
+categoryfile&names.unsorted&
+names of categories, to be checked for duplicates by {\tt nodups.awk}
+\cr
+cycles&cycle.test&
+potential cycles, to be checked by {\tt cycle.web}
+\cr
+grammarfile&grammar.web&
+grammar; included in {\tt weave.web}
+\cr
+ilkfile&names.unsorted&
+names of ilks, to be checked for duplicates by {\tt nodups.awk}
+\cr
+logfile&spider.slog&
+log file, to be consulted when things go wrong
+\cr
+macrofile&*web.tex&
+language specific macro file, {\tt\string\input} by all \TeX{}
+ files created by {\tt weave.web}
+\cr
+productions&productions.list&
+list of the productions (numbered) used in debugging \.{WEAVE}
+\cr
+reserved&scraps.web&
+code for converting the reserved word to scraps.
+{\tt scraps.web} is included by {\tt weave.web}
+\cr
+scrapfile&scraps.web&
+code for converting tokens to scraps.
+{\tt scraps.web} is included by {\tt weave.web}
+\cr
+tlang&outtoks.web&
+Information about what language we're webbing.
+{\tt outtoks.web} is included by {\tt tangle.web}.
+\cr
+tokennamefile&names.unsorted&
+list of names of all the tokens, to be checked by {\tt nodups.awk}
+\cr
+translationfile&trans\_keys.unsorted&
+list of names of all the translation keywords.
+Checked for duplicates by {\tt nodups.awk}, and also for recognizability
+by {\tt transcheck.awk}.
+\cr
+ttokfile&outtoks.web&
+This is the tokenization code for {\tt TANGLE}.
+\cr
+wlang&scraps.web&
+Information about what language we're webbing,
+{\tt scraps.web} is included by {\tt weave.web}.
+\cr
+}
+
+# Every action writes information to a log file.
+This log file can be used to check up on what happened.
+#<Set initial...#>=
+ logfile = "spider.slog"
+
+# Here we write the names of the key words used in translations.
+#<Set initi...#>=
+ translationfile = "trans_keys.unsorted"
+
+# We write tokens out to two files: |scrapfile| for \.{WEAVE}, and
+|ttokfile| for \.{TANGLE}.
+#<Set init...#>=
+ scrapfile = "scraps.web"
+ print "@*Scrap code generated by {\\tt SPIDER}." > scrapfile
+ ttokfile = "outtoks.web"
+ print "@*Token code generated by {\\tt SPIDER}." > ttokfile
+# The reserved word stuff gets a file of its own, or it would in an ideal
+world.
+#<Set init...#>=
+ reserved = "scraps.web" ## use same file; not enough files
+
+# We'll also end up writing a list of token names, for name checking
+purposes.
+#<Set initial...#>=
+ tokennamefile = "names.unsorted" ## cut down on number of output files
+# We also write out every ilk, so we'll be able to look for name
+clashes with translations and so on.
+#<Set init...#>=
+ ilkfile = "names.unsorted" ## cut down on number of output files
+# We also write all the category names to a separate file, so we can
+check for duplicates later.
+#<Set init...#>=
+ categoryfile = "names.unsorted" ## cut down on number of output files
+# We use a special file to write grammar information:
+#<Set init...#>=
+ grammarfile = "grammar.web"
+ print "@*Grammar code generated by {\\tt SPIDER}." > grammarfile
+# We use the language information to write banners and macro information.
+We combine this with other stuff because AWK can't handle more than
+10 output files.
+#<Set initial...#>=
+ tlang = "outtoks.web" ## same as ttokfile
+ wlang = "scraps.web" ## same as scrapfile
+
+# We will write a list of the successfully parsed productions to a
+separate file.
+#<Set init...#>=
+ productions = "productions.list"
+
+# These productions will get fed to {\tt cycle.awk}, which looks for cycles.
+#<Set initial...#>=
+ cycles = "cycle.test"
+
+
+
+#*Processing translations.
+Translations tell \.{WEAVE} or \.{TANGLE} what to write out in
+particular circumstances (e.g.~after scanning a particular token, or
+when firing some production).
+They are described at some length in the ``\.{SPIDER} User's Guide.''
+Translations are enclosed in angle brackets and separated by dashes.
+They can contain key words, digits, the self marker~`{\tt*}',
+or quoted strings.
+Since we can't put a space or dash into strings, we allow the use of
+key words |space| and |dash| to stand for those symbols.
+#^space#>
+#^dash#>
+
+Other key words are interpreted by \.{WEAVE} as prettyprinting instructions:
+
+\yskip\hang |break_space| denotes an optional line break or an en space;
+
+\yskip\hang |force| denotes a line break;
+
+\yskip\hang |big_force| denotes a line break with additional vertical space;
+
+\yskip\hang |opt| denotes an optional line break (with the continuation
+line indented two ems with respect to the normal starting position)---this
+code is followed by an integer |n|, and the break will occur with penalty
+$10n$;
+
+\yskip\hang |backup| denotes a backspace of one em;
+
+\yskip\hang |cancel| obliterates any |break_space| or |force| or |big_force|
+tokens that immediately precede or follow it and also cancels any
+|backup| tokens that follow it;
+
+\yskip\hang |indent| causes future lines to be indented one more em;
+
+\yskip\hang |outdent| causes future lines to be indented one less em.
+
+\yskip\hang |math_rel|, |math_bin|, and |math_op| will be translated into
+\.{\\mathrel\{}, \.{\\mathbin\{}, and \.{\\mathop\{}, respectively.
+
+
+\yskip\noindent All of these tokens are removed from the \TeX\ output that
+comes from programming language text between \pb\ signs; |break_space|
+and |force| and
+|big_force| become single spaces in this mode.
+%The translation of other
+%program texts results in \TeX\
+%control sequences \.{\\1}, \.{\\2},
+%\.{\\3}, \.{\\4}, \.{\\5}, \.{\\6},
+%\.{\\7} corresponding respectively to
+%|indent|, |outdent|, |opt|,
+%|backup|, |break_space|, |force|, and
+%|big_force|. However,
+A sequence of consecutive `\.\ ', |break_space|,
+|force|, and/or |big_force| tokens is first replaced by a single token
+(the maximum of the given ones).
+
+%Some Other control sequences in the \TeX\ output will be
+%`\.{\\\\\{}$\,\ldots\,$\.\}'
+%surrounding identifiers, `\.{\\\&\{}$\,\ldots\,$\.\}' surrounding
+%reserved words, `\.{\\.\{}$\,\ldots\,$\.\}' surrounding strings,
+%`\.{\\C\{}$\,\ldots\,$\.\}$\,$|force|' surrounding comments, and
+%`\.{\\X$n$:}$\,\ldots\,$\.{\\X}' surrounding module names, where
+%|n| is the module number.
+
+# We write out the names of all the key words used translations,
+so we can check that
+\.{WEAVE} can be expected to recognize them.
+This helps us catch the problem early if a translation given is
+not one of the above
+(as opposed to, say, having the C~compiler fail to compile \.{WEAVE}).
+#<Write lists...#>=
+ for (t in translation_keywords) {
+ print t > translationfile
+ }
+
+# #<Write stat...#>=
+for (t in translation_keywords) {
+ num_of_translation_keywords++
+ }
+printf "You used %d translation keywords.\n", \
+ num_of_translation_keywords > logfile
+printf "You used %d translation keywords.\n", num_of_translation_keywords
+
+# If the macro facility worked right,
+we would use the following patterns to recognize items as they occur:
+#d cat_pattern = #=/[a-zA-Z][a-zA-Z_]*/#>
+#d trans_pattern = #=/<(([0-9]|[a-zA-Z][a-zA-Z_]*|"([^"]*\\")*[^"]*"|\*)-)*#>#&
+ #=([0-9]|[a-zA-Z][a-zA-Z_]*|"([^"]*\\")*[^"]*"|\*)>/#>
+
+# Here's where we swallow a translation and spit out the \.{WEAVE} code
+to handle that translation.
+Since AWK has no functions, we define this as a module.
+
+When we're appending a key word {\it in the process of creating a
+scrap from a token}, we use |small_app| in preference to |app|,
+because |app|'s cleverness about mathness and dollar signs only works when
+reducing existing scraps, not when creating scraps from tokens.
+We'll expect the variable |append_keyword| to be set to either
+|"small_app"| or |"app"|.
+
+
+#<Take translation from |transstring| and write corresponding \.{WEAVE} code to
+|outstring|, using |selfstring| as translation of |"<*>"|#>=
+temp = substr(transstring,2,length(transstring)-2) ## kills awk bug
+trcnt = split(temp,trtok,"-")
+outstring = ""
+for (tridx=1;tridx<=trcnt;tridx++) {
+ alternate=trtok[tridx]
+ #<Convert |"space"| and |"dash"|#>
+ if (alternate ~ #=/^[0-9]$/#>) { ## digit
+ temp = sprintf("\tapp_str(\"%s\");\n",alternate)
+ outstring=outstring temp
+ } else if (alternate ~ #=/^[a-zA-Z_]+$/#>) { ## key word
+ translation_keywords[alternate]=1 ## remember
+ temp = sprintf("\t%s(%s);\n",append_keyword,alternate)
+##Call |app| or |small_app| depending whether we're reducing or creating scraps
+ outstring=outstring temp
+ } else if (alternate ~ #=/^\"([^"]*\\\")*[^"]*\"$/#>) { ## string
+ temp = sprintf("\tapp_str(%s);\n",alternate)
+ outstring=outstring temp
+ } else if (alternate ~ #=/^\*$/#>) { ## self marker
+ #<If |selfstring==""|, complain loudly#>
+ outstring=outstring selfstring
+ } else {
+ print "Bogus translation", wherestring
+ exitcode = -1
+ }
+}
+
+# Here we convert the key words |space| and |dash| to strings.
+We quote the strings, to be sure that they are handled by the string
+mechanism.
+#<Convert |"space"|...#>=
+ if (alternate=="space") {
+ alternate="\" \""
+ } else if (alternate=="dash") {
+ alternate="\"-\""
+ }
+
+
+# There are some places (notably in productions) where the translation
+|"<*>"| makes no sense.
+In this case the caller sets |selfstring=""|, and we complain.
+#<If |selfstring==""|, complain...#>=
+if (selfstring=="") {
+ print "Translation \"<*>\" makes no sense", wherestring
+ exitcode = -1
+ }
+
+# There are times when we may want to convert a translation directly
+into a quoted string, usually for \.{TANGLE}'s benefit.
+Here, the only things allowed are quoted strings and |space| and |dash|.
+We peel off quote marks and concatenate things together, and then we
+put the quote marks back on at the end.
+#<Convert restricted translation in |transstring|
+ to quoted string in |outstring|#>=
+temp = substr(transstring,2,length(transstring)-2) ## kills awk bug
+trcnt = split(temp,trtok,"-")
+outstring = ""
+for (tridx=1;tridx<=trcnt;tridx++) {
+ alternate=trtok[tridx]
+ #<Convert |"space"| and |"dash"|#>
+ if (alternate ~ #=/^[0-9]$/#>) { ## digit
+ print "Digit not allowed in restricted translation", wherestring
+ exitcode = -1
+ } else if (alternate ~ #=/^[a-zA-Z_]+$/#>) { ## key word
+ print "Key word not allowed in restricted translation", wherestring
+ exitcode = -1
+ } else if (alternate ~ #=/^\"([^"]*\\\")*[^"]*\"$/#>) { ## string
+ temp = substr(alternate,2,length(alternate)-2) ## strip quotes
+ outstring=outstring temp
+ } else if (alternate ~ #=/^\*$/#>) { ## self marker
+ print "<*> not allowed in restricted translation", wherestring
+ exitcode = -1
+ } else {
+ print "Bogus restricted translation", wherestring
+ exitcode = -1
+ }
+}
+outstring = "\"" outstring "\"" ## put quotes back on |outstring|
+
+
+
+#*Tokens.
+
+Tokens are pretty complicated.
+Each token has a string by which we recognize it in the input.
+This string is what immediately follows the |token| command.
+Then, there's another string that tells \.{TANGLE} how to write out
+the token.
+Finally, it has a category and a translation (so we can make a scrap out
+of it), and a mathness (to tell us whether it has to be in math
+mode, horizontal mode, or either).
+The
+\.{translation} and \.{mathness} have defaults.
+
+#*2Scanning for token descriptions.
+This module is used everywhere we must scan a line for token descriptions.
+#<Scan this line from |start_place| to finish, looking for
+ \.{translation}$\ldots$ and putting results in
+ |this_translation|$\ldots$#>=
+for (i=start_place;i<NF;) {
+ if ($i=="tangleto") { ## for \.{TANGLE}
+ i++
+ this_tangleto=$i
+ i++
+ } else if ($i=="translation") { ## for \.{WEAVE}
+ i++
+ this_translation=$i
+ i++
+ } else if ($i=="mathness") { ## for \.{WEAVE}
+ i++
+ this_mathness=$i
+ i++
+ } else if ($i=="category") { ## for \.{WEAVE}
+ i++
+ this_category=$i
+ categories[$i]=1
+ i++
+ } else if ($i=="name") { ## for debugging
+ i++
+ this_name="SP_" $i ##OK, so it's hacking...
+ i++
+ } else {
+ print "Error: unrecognized token description", $i, "on line", NR-1
+ #<Punt...#>
+ }
+}
+#<Check that we used everything#>
+
+# We check for the presence or absence of certain empty strings after
+scanning.
+#<Make sure |this_name| is empty#>=
+if (this_name != "") {
+ print "Error: name doesn't apply on line", NR-1
+ #<Punt...#>
+ }
+# #<Make sure |this_tangleto| is empty#>=
+if (this_tangleto != "") {
+ print "Error: tangleto doesn't apply on line", NR-1
+ #<Punt...#>
+ }
+# #<Make sure |this_category| is empty#>=
+if (this_category != "") {
+ print "Error: category doesn't apply on line", NR-1
+ #<Punt...#>
+ }
+# #<Make sure |this_translation| is empty#>=
+if (this_translation != "") {
+ print "Error: translation doesn't apply on line", NR-1
+ #<Punt...#>
+ }
+# #<Make sure |this_category| is not empty#>=
+if (this_category == "") {
+ print "Error: you must give a category on line", NR-1
+ #<Punt...#>
+ }
+
+#*1Setting the default token descriptions.
+\.{SPIDER} maintains default information about {\em mathness}
+and {\em translation}, so these can be omitted from token descriptions.
+We can change the operative defaults at any time by using a
+|"default"| command.
+It too, scans for keywords, using the standard scanning module
+#<Pattern-action...#>=
+#=/^default /#> {
+ print "Setting defaults..." > logfile
+ start_place=2
+ #<Set |this_mathness| etcetera to the defaults and those with no
+ defaults to |""|#>
+ #<Scan this line from |start_place| to finish, looking for
+ \.{translation}$\ldots$ and putting results in
+ |this_translation|$\ldots$#>
+ #<Make sure |this_name| is empty#>
+ #<Make sure |this_category| is empty#>
+ default_translation=this_translation
+ default_mathness=this_mathness
+#@ print "\tdefault translation is", default_translation > logfile
+ print "\tdefault mathness is", default_mathness > logfile
+#@ next
+}
+
+# Normally, we will set all quantities to the defaults before scanning:
+#<Set |this_mathness| etcetera to the defaults and those with no
+defaults to |""|#>=
+ this_translation=default_translation
+ this_mathness=default_mathness
+ this_name=""
+ this_category=""
+ this_tangleto=""
+# When \.{SPIDER} starts up, the defaults are already set:
+#<Set initi...#>=
+ default_translation="<*>"
+ default_mathness="maybe"
+
+
+#*1Recognizing token designators.
+Let's begin by discussing the way \.{WEAVE} and \.{TANGLE} represent
+tokens internally.
+
+\.{WEAVE} and \.{TANGLE} process tokens in a two-step process.
+Both read the token from the input using |get_next|, which returns a
+unique eight-bit number representing the token.
+Generally printable ASCII characters represent themselves, and other
+tokens get numbers in the unprintable range.
+\.{TANGLE} assigns ranges to some tokens ahead of time: |string| is 2,
+|identifier| is #'202, and so on.
+Tokens that we introduce to \.{TANGLE} must have numbers between
+#'13 and #'37 inclusive.
+
+Rather than work with eight-bit numbers themselves, we use names for
+the tokens.
+This makes \.{WEAVE} and \.{TANGLE} easier to debug when things go wrong.
+
+In \.{WEAVE}, the category, mathness, and translation are all
+attached to a scrap based on the eight-bit number returned by
+|get_next|, and this is done at a later time.
+
+In \.{TANGLE}, characters are written to the output file(s) based on
+the token code, which can be either eight bits for simple tokens or
+sixteen for identifiers and things.
+
+Our mission in this section will be to read in all the token
+information from the {\tt token} command,
+and to create the names and numbers used by \.{WEAVE} and \.{TANGLE}
+to represent the tokens.
+In the next section we will
+write the code that processes the tokens for both \.{WEAVE} and
+\.{TANGLE} (lexical analysis in
+|get_next|, and subsequent processing elsewhere).
+You will pardon us if things get a bit tedious.
+
+# The {\tt token} command is used to specify tokens that are not
+reserved words.
+Reserved word tokens get special treatment all their own.
+
+#<Pattern...#>=
+#=/^token /#> {
+ print "Token", $2 > logfile
+ if ($2=="identifier") {
+ #<Process identifier token description#>
+ } else if ($2=="number") {
+ #<Process numeric token description#>
+ } else if ($2=="newline") {
+ #<Process newline token description#>
+ } else if ($2=="pseudo_semi") {
+ #<Process |pseudo_semi| token description#>
+ } else if ($2 ~ #=/[a-zA-ZA-Z0-9]+/#>) {
+ ## we recognize no other names
+ print "Error: unknown token species:", $2
+ #<Punt this command#>
+ } else {
+ #<Process a non-alphanumeric token description#>
+ }
+ categories[this_category]=1 ## is this right?
+#^questions#>
+ next
+}
+
+# Identifiers, numbers (and string literals), newlines, and the special
+token \.{pseduo\_semi} are predefined.
+#<Process identifier token description#>=
+ #<Set |this_mathness| etcetera to the defaults and those with no
+ defaults to |""| #>
+ this_translation=""
+ start_place=3
+ #<Scan this line from |start_place| to finish, looking for
+ \.{translation}$\ldots$ and putting results in
+ |this_translation|$\ldots$#>
+ #<Make sure |this_name| is empty#>
+ #<Make sure |this_tangleto| is empty#>
+ #<Make sure |this_category| is not empty#>
+ #<Make sure |this_translation| is empty#>
+ id_category=this_category
+ id_mathness=this_mathness
+
+# We have yet to implement a separate procedure for numerics and strings!
+#<Process numeric token description#>=
+ print "Warning: numeric constants and strings are",\
+ "identified in this WEAVE."
+ print "Warning: numeric constants and strings are",\
+ "identified in this WEAVE." > logfile
+ #<Set |this_mathness| etcetera to the defaults and those with no
+ defaults to |""| #>
+ this_translation=""
+ start_place=3
+ #<Scan this line from |start_place| to finish, looking for
+ \.{translation}$\ldots$ and putting results in
+ |this_translation|$\ldots$#>
+ #<Make sure |this_name| is empty#>
+ #<Make sure |this_tangleto| is empty#>
+ #<Make sure |this_category| is not empty#>
+ #<Make sure |this_translation| is empty#>
+ number_category=this_category
+ number_mathness=this_mathness
+
+#
+#<Process newline token description#>=
+ #<Set |this_mathness| etcetera to the defaults and those with no
+ defaults to |""| #>
+ start_place=3
+ #<Scan this line from |start_place| to finish, looking for
+ \.{translation}$\ldots$ and putting results in
+ |this_translation|$\ldots$#>
+ #<Make sure |this_name| is empty#>
+ #<Make sure |this_tangleto| is empty#>
+ #<Make sure |this_category| is not empty#>
+ newline_category=this_category
+ newline_mathness=this_mathness
+ newline_translation=this_translation
+
+#
+#<Process |pseudo_semi| token description#>=
+ #<Set |this_mathness| etcetera to the defaults and those with no
+ defaults to |""| #>
+ start_place=3
+ #<Scan this line from |start_place| to finish, looking for
+ \.{translation}$\ldots$ and putting results in
+ |this_translation|$\ldots$#>
+ #<Make sure |this_name| is empty#>
+ #<Make sure |this_tangleto| is empty#>
+ #<Make sure |this_category| is not empty#>
+ pseudo_semi_category=this_category
+ pseudo_semi_mathness=this_mathness
+ pseudo_semi_translation=this_translation
+
+# Here is where things get a bit more interesting; we have to
+consider all the other (non-reserved-word) tokens, and find a way to
+convert them to \.{WEAVE} and \.{TANGLE}'s internal form.
+We take single characters straight, except for those that must be
+escaped one way or another.
+For multicharacter tokens, we have to invent a name and a number,
+which process we will describe below.
+
+
+Tokens have a zillion attributes: not just category, translation, and
+their friends, but things like internal representations, the length of
+the input string, you name it.
+
+We remember the length of the longest token in the system,
+because when we go to
+recognize tokens we will look for the longest first and then on down.
+We maintain that length at the very end here.
+#<Process a non-alphanumeric token description#>=
+ this_string=$2
+ #<Translate |"{space}"| to |" "| in |this_string|#>
+## print NF, "fields on line", NR-1 ## caught a bug in DEC awk
+ $2 = this_string
+## print NF, "fields on line", NR-1
+ #<Set |tokenname[$2]|, |tokenlength[$2]|, and, for long
+ tokens, set |tokentest[$2]| and |tokennumbers[$2]|#>
+ if (tokens[$2]!="") {
+ print "Warning: token", $2, "defined twice"
+ }
+ tokens[$2]=1 ## remember this token
+ #<Set attributes of token |$2|#>
+ #<Make sure token |$2| has a number if it needs one#>
+ #<Update record of maximum token length#>
+
+
+# This code represents and undocumented feature.
+We should replace it by allowing restricted translations
+in |$2|, the then documenting it.
+When doing this, we'll have to match the full |trans_pattern|
+in all its glory; A mere |#=/<.*>/#>| won't do.
+
+#<Translate |"{space}"| to |" "| in |this_string|#>=
+old_string = this_string
+this_string = ""
+## Invariant: |this_string old_string| corresponds to result, and
+## |"{space}"| is translated in |this_string| but not |old_string|
+idx = index(old_string,"{space}")
+while (idx != 0) {
+ temp =substr(old_string,1,idx-1)
+ this_string = this_string temp " "
+ old_string = substr(old_string,idx+7)
+ idx = index(old_string,"{space}")
+}
+this_string = this_string old_string
+
+# Tokens need an internal eight-bit representation.
+For single characters (which are assumed to be printable), we use
+the ASCII code as the internal representation.
+Multicharacter tokens will be assigned a name and a number.
+(The names may be specified by the user or generated by \.{SPIDER}.)
+Unfortunately the numbers for \.{WEAVE} and \.{TANGLE} have to be
+different (the reasons will only depress you).
+We assign \.{WEAVE} numbers by starting numbering from |highesttoken|, and
+working our way down.
+At the moment |hisghesttoken==200|, and I can't remember whether 200 is
+a ``magic number'' or not, so you'd better assume that it is.
+We get the tpoken numbers for \.{TANGLE} by subtracting an offset,
+as you'll see later.
+#<Set initial...#>=
+ highesttoken=200 ## highest numbered token
+ tokennumber=highesttoken
+
+# At the end we check to make sure we haven't used up too many numbers
+for tokens.
+\.{WEAVE} token numbers must be |>=127|.
+#<Check for errors at the...#>=
+if (tokennumber<127) {
+ print "Error: too many token names for WEAVE --- over by",\
+ 127-tokennumber
+ exitcode=-1
+ }
+# \.{TANGLE} tokens must be between #'13 and #'37 inclusive.
+We add three to the number because \.{TANGLE} has special definitions for
+the three tokens taken off the top.
+#<Check for errors...#>=
+if (highesttoken-tokennumber > #'37-(#'13-1)+3) { \
+ ## number of tokens in |#'13|--|#'37|, plus 3
+ print "Error: too many token names for TANGLE --- over by",\
+ highesttoken-tokennumber - (#'37-(#'13-1)+3)
+ exitcode=-1
+ }
+
+
+
+# The token name is what \.{WEAVE} and \.{TANGLE} will use internally
+to refer to the token's internal representation as an eight-bit code.
+We use names instead of using the numbers directly in the vague hope that
+it will make \.{WEAVE} and \.{TANGLE} easier to debug when something goes
+wrong.
+For multi-character tokens, the name will be a \.{WEB} macro that is defined
+to be equal to the token's eight-bit code.
+If the token is a single character, its ``name'' will be that character,
+quoted with single quotes.
+The single-character tokens \.{@}, \.{\\}, and \.{'} require special
+handling, since they have to be escaped in some way to be quoted.
+
+Once we've computed the name, we put it in |tokenname[$2]|.
+#<Set |tokenname[$2]|, |tokenlength[$2]|, and, for long
+ tokens, set |tokentest[$2]| and |tokennumbers[$2]|#>=
+ if ($2=="@") {
+ $2="@@"
+ tokenname[$2]="'@@'"
+ tokenlength[$2]=1
+ } else if ($2=="'" || $2 == "\\") {
+ $2="\\" $2
+ tokenname[$2]="'" $2 "'"
+ tokenlength[$2]=1
+ } else if (length($2)>1) {
+ #<Handle multicharacter tokens#>
+ } else {
+ temp = sprintf("'%s'", $2)
+ tokenname[$2] = temp
+ tokenlength[$2]=1
+ }
+
+# For the long tokens, we generate a name by which we'll refer to the
+token.
+That name will actually be defined to be a number, which we'll take to
+be the current value of |tokennumber|.
+We'll write in |tokentest[$2]| the C~code used to recognize that token,
+and in |tokenlength[$2]| we'll leave that token's length.
+(The length is used both to find long tokens before short ones, and
+to avoid finding long ``tokens'' that
+actually go beyond the end of the line.)
+#<Handle multicharacter tokens#>=
+ tokenname[$2]="SP_gen_token_" tokennumber
+ tokennumbers[$2]=tokennumber
+ tokennumber--
+ ## figure out how to recognize the token
+ temp = sprintf( "strncmp(\"%s\",loc-1,%d)==0", $2, length($2))
+ tokentest[$2]=temp
+ tokenlength[$2]=length($2)
+
+
+# The setting of attributes is as for all tokens:
+#<Set attributes of token |$2|#>=
+ #<Set |this_mathness| etcetera to the defaults and those with no
+ defaults to |""| #>
+ this_name=tokenname[$2]
+ start_place=3
+ #<Scan this line from |start_place| to finish, looking for
+ \.{translation}$\ldots$ and putting results in
+ |this_translation|$\ldots$#>
+ #<Make sure |this_category| is not empty#>
+ tokencategory[$2]=this_category
+ tokenmathness[$2]=this_mathness
+ tokentranslation[$2]=this_translation
+ tokenname[$2]=this_name
+ tokentangleto[$2]=this_tangleto
+
+# We have to remember the length of the longest token so we can
+recognize long tokens before short ones.
+#<Update record of maximum token length#>=
+ temp = tokenlength[$2]
+ if (temp > maxtokenlength) {
+ maxtokenlength=temp
+ }
+
+# We're paranoid.
+#<Make sure token |$2| has a number if it needs one#>=
+ if (tokenlength[$2]>1 && tokennumbers[$2]=="") {
+ print "This can't happen: token", $2, "is long", \
+ "but has no number"
+ exitcode = -1
+ }
+
+
+#*1Writing {\tt WEB}'s lexical analysis code.
+The token recognition problem is the same for \.{WEAVE} and
+\.{TANGLE}.
+Both have routines called |get_next| that recognize the tokens on
+input.
+Most of |get_next| is prefabricated
+(and the same in both \.{WEAVE} and \.{TANGLE}),
+but we have to put in the part that recognizes multi-character
+non-alphanumeric tokens.
+
+We write the same code to both \.{WEAVE} and \.{TANGLE}.
+#<Write out...#>=
+ tempfile = scrapfile
+ #<Write token recognition code to |tempfile|#>
+ tempfile = ttokfile
+ #<Write token recognition code to |tempfile|#>
+
+# This is how we do it.
+#<Write token recognition code to |tempfile|#>=
+print "@ Here we input tokens of more than one character" > tempfile
+print "@<Compress two-symbol operator@>=" > tempfile
+#<Look for multicharacter tokens, starting with the longest,
+ and working down#>
+
+# We look for long tokens, then shorter, and so on.
+We have to make sure we don't look beyond the end of a line.
+#<Look for multicharacter tokens, starting with the longest,
+ and working down#>=
+ for (len=maxtokenlength; len>=2; len--) {
+ printf "if (loc+%d<=limit) {\n", len-1 > tempfile
+ #<Check for tokens in |tokentest| of length |len|#>
+ printf "\t}\n" > tempfile
+ }
+ #<Make sure there are no tokens of length 1 in |tokentest|#>
+
+# #<Check for tokens in |tokentest| of length |len|#>=
+notfirst=0
+for (t in tokentest) {
+ if (tokenlength[t]==len) {
+ printf "\t" > tempfile
+ if (notfirst==1) {
+ printf "else " > tempfile
+ }
+ notfirst=1
+ printf "if (%s) {\n", tokentest[t] > tempfile
+ printf "\t\tloc += %d;\n", len-1 > tempfile
+ printf "\t\treturn %s;\n\t\t}\n", tokenname[t] > tempfile
+ }
+ }
+
+
+# #<Make sure there are no tokens of length 1 in |tokentest|#>=
+for (t in tokentest) {
+ if (tokenlength[t]==1) {
+ print "This can't happen: token", t, "is of length 1 but", \
+ "it has a test"
+ exitcode=-1
+ }
+}
+
+
+
+#*1Writing out {\tt WEAVE}'s token-to-scrap code.
+Here is where we write the code that converts an already-recognized
+token (from |get_next|) into a scrap.
+There are several different kinds of tokens, and each requires a
+slightly different treatment.
+Will write out the code for the different species one at a time.
+#<Write out all...#>=
+ print "Writing out predefined scraps" > logfile
+ #<Write code for identifier scrap#>
+ #<Write code for string or constant scrap#>
+ #<Write code for newline scrap#>
+ #<Write code for |pseudo_semi| scrap#>
+ print "Writing out token scraps" > logfile
+ #<Write code for ordinary token scraps#>
+
+
+
+
+# This is how we write out the information for the identifier.
+#<Write code for identifier scrap#>=
+ if (id_category != "") {
+ print "@ @<Append an identifier scrap@>=" > scrapfile
+ print "p=id_lookup(id_first, id_loc,normal);" > scrapfile
+ print "if (p->ilk==normal) {" > scrapfile
+ print " small_app(id_flag+p-name_dir);" > scrapfile
+ printf " app_scrap(SP_%s,%s_math);", \
+ id_category, id_mathness > scrapfile
+ appended[id_category]=1
+ print " /* not a reserved word */" > scrapfile
+ print "}" > scrapfile
+ print "else if reserved(p) {" > scrapfile
+ print "@<Decide on reserved word scraps@>;" > scrapfile
+ print "}" > scrapfile
+ print "else {" > scrapfile
+ print " err_print(\"! Identifier with unmentioned ilk\");" > scrapfile
+ print "@.Identifier with unmentioned ilk@>" > scrapfile
+ print "}" > scrapfile
+ } else {
+ print "Error: I don't know what to do with an identifier"
+ print " Please give me a \"token identifier ...\""
+ exitcode = -1
+ }
+
+# We hold the name |"identifier"|, and we reserve a number for
+identifiers.
+#<Set initial...#>=
+ tokennumbers["identifier"]=tokennumber; tokennumber--
+ tokenname["identifier"]="identifier"
+
+# This is how we write out the string or constant scrap, at the end.
+#<Write code for string or constant scrap#>=
+print "Warning: TeX strings have the same category as ", \
+ "numeric constants in this WEAVE."
+print "Warning: TeX strings have the same category as ", \
+ "numeric constants in this WEAVE." > logfile
+if (number_category != "") {
+print "@ For some reason strings, constants,",\
+ " and \TeX\ strings are identified." > scrapfile
+print "That has to be fixed." > scrapfile
+print "@<Do the |app_scrap| for a string or constant@>=" > scrapfile
+printf "app_scrap(SP_%s,%s_math);\n", number_category,\
+ number_mathness > scrapfile
+appended[number_category]=1
+} else {
+ print "Error: I don't know what to do with a numeric constant"
+ print " Please give me a \"token number ...\""
+ exitcode = -1
+ }
+
+
+# We hold names and numbers for constants and strings, as well as identifiers.
+#<Set initial...#>=
+ tokennumbers["constant"]=tokennumber; tokennumber--
+ tokenname["constant"]="constant"
+ tokennumbers["string"]=tokennumber; tokennumber--
+ tokenname["string"]="string"
+
+
+#
+#<Write code for newline scrap#>=
+if (newline_category != "") {
+ print "@ @<Append a newline scrap@>=" > scrapfile
+ transstring=newline_translation
+ selfstring="small_app(next_control);"
+ wherestring="in translation of token newline"
+ append_keyword="small_app"
+ #<Take translation from |transstring| and write corresponding \.{WEAVE} code to
+ |outstring|, using |selfstring| as translation of |"<*>"|#>
+ print outstring > scrapfile
+ printf " app_scrap(SP_%s,%s_math);\n", newline_category,\
+ newline_mathness > scrapfile
+ appended[newline_category]=1
+} else {
+ print "Error: I don't know what to do with a newline"
+ print " Please give me a \"token newline ...\""
+ exitcode = -1
+ }
+
+#
+#<Write code for |pseudo_semi| scrap#>=
+if (pseudo_semi_category != "") {
+ print "@ @<Append a |pseudo_semi| scrap@>=" > scrapfile
+ transstring=pseudo_semi_translation
+ selfstring="small_app(next_control);"
+ wherestring="in translation of token pseudo_semi"
+ append_keyword="small_app"
+ #<Take translation from |transstring| and write corresponding \.{WEAVE} code to
+ |outstring|, using |selfstring| as translation of |"<*>"|#>
+ print outstring > scrapfile
+ printf " app_scrap(SP_%s,%s_math);\n", pseudo_semi_category,\
+ pseudo_semi_mathness > scrapfile
+ appended[pseudo_semi_category]=1
+} else {
+ printf "Error: I don't know what to do with a pseudo_semi (%s;)",\
+ substr(at_sign,1,1)
+ print " Please give me a \"token pseudo_semi ...\""
+ exitcode = -1
+ }
+
+# Here is how we write out the code that converts ordinary tokens to scraps:
+#<Write code for ordinary token scraps#>=
+print "@ @<Cases for ordinary tokens@>=" > scrapfile
+for (t in tokens) {
+ temp = tokenname[t]
+ printf "case %s:\n", temp > scrapfile
+ transstring=tokentranslation[t]
+ selfstring="small_app(next_control);"
+ wherestring= sprintf ("in translation of token %s", t)
+ append_keyword="small_app"
+ #<Take translation from |transstring| and write corresponding \.{WEAVE} code to
+ |outstring|, using |selfstring| as translation of |"<*>"|#>
+ print outstring > scrapfile
+ printf "\tapp_scrap(SP_%s,%s_math);\n", tokencategory[t], \
+ tokenmathness[t] > scrapfile
+ temp = tokencategory[t]
+ appended[temp]=1
+#^append check#>
+ print "\tbreak;" > scrapfile
+ }
+
+#*3{\tt TANGLE}'s token-to-output conversion.
+We have to write special cases for things appearing in |tokennumbers|.
+The output conventions for |string|, |constant| and |identifier| are
+fixed by \.{TANGLE}.
+
+One day we have to improve \.{TANGLE}'s treatment of spacing in the output;
+at the moment it just makes sure there are spaces between adjacent identifiers
+or numbers.
+#^future enhancements#>
+#<Write out...#>=
+print "@ @<Cases for tokens to be output@>=" > ttokfile
+for (t in tokennumbers) {
+ #<If |t| is |"string"|, |"constant"|, or |"identifier"|, just |continue|#>
+ printf "case %s:\n", tokenname[t] > ttokfile
+ this_tangleto = tokentangleto[t]
+ if (this_tangleto=="") {
+ printf "\tC_printf(\"%%s\",\"%s\");\n",t > ttokfile
+ } else {
+ printf "\tif (out_state==verbatim) {\n" > ttokfile
+ printf "\t\tC_printf(\"%%s\",\"%s\");\n",t > ttokfile
+ printf "\t} else {\n" > ttokfile
+ #<Write code to print |this_tangleto| onto |ttokfile|#>
+ printf "\t}\n" > ttokfile
+ }
+ print "\tif (out_state!=verbatim) out_state=misc;" > ttokfile
+ print "break;" > ttokfile
+ }
+
+# We also have to write something for the tokens that aren't in |tokennumbers|
+but which have a nonnull |tokentangleto| anyway.
+#<Write out...#>=
+print "@ @<Cases for tokens to be output@>=" > ttokfile
+for (t in tokentangleto) {
+ #<If |t| is |"string"|, |"constant"|, or |"identifier"|, just |continue|#>
+ if (tokennumbers[t]!="" || tokentangleto[t]=="")
+ continue
+ if (t=="@") {
+ thistangletokname = "@@"
+ } else if (t=="\\" || t=="'") {
+ thistangletokname = "\\" t
+ } else {
+ thistangletokname = t
+ }
+ printf "case '%s':\n", thistangletokname > ttokfile
+ this_tangleto = tokentangleto[t]
+ if (this_tangleto=="") {
+ print "This can't happen -- null tangleto for", t, wherestring
+ exitcode = -1
+ } else {
+ printf "\tif (out_state==verbatim) {\n" > ttokfile
+ printf "\t\tC_printf(\"%%s\",\"%s\");\n",t > ttokfile
+ printf "\t} else {\n" > ttokfile
+ #<Write code to print |this_tangleto| onto |ttokfile|#>
+ printf "\t}\n" > ttokfile
+ }
+ print "\tif (out_state!=verbatim) out_state=misc;" > ttokfile
+ print "break;" > ttokfile
+}
+# The tokens for |string|, |constant|, and |identifier| are treated
+specially by \.{TANGLE}; code to handle them already lives in \.{TANGLE}.web.
+Therefore, we don't gum up the works with our scheming.
+#<If |t| is |"string"|, |"constant"|, or |"identifier"|, just |continue|#>=
+if (t=="string"||t=="constant"||t=="identifier")
+ continue
+
+
+
+# This is somewhat like the translation code, but tuned for \.{TANGLE}
+#<Write code to print |this_tangleto| onto |ttokfile|#>=
+oldwherestring = wherestring
+wherestring = "for tangleto " wherestring
+#@
+transstring=this_tangleto
+#<Convert restricted translation in |transstring|
+ to quoted string in |outstring|#>
+printf "\tC_printf(\"%%s\",%s);\n",outstring > ttokfile
+#@
+wherestring=oldwherestring
+
+
+
+#*3Defining the token names.
+ At some point we'll have to define all these names, for both
+\.{TANGLE} and \.{WEAVE}. We may as well
+show how we do that now.
+#<Write out...#>=
+ tempfile = scrapfile
+ #<Write the definitions of the token names to |tempfile|#>
+ tempfile = ttokfile
+ #<Write the definitions of the token names to |tempfile|#>
+
+# We use an ugly trick to get the token numbers different for
+\.{WEAVE} and \.{TANGLE}:
+#<Write the definitions of the token names to |tempfile|#>=
+ print "@ Here are the definitions of the token names" > tempfile
+ for (t in tokennumbers) {
+ temp = tokennumbers[t]
+ if (temp==0)
+ continue ## don't know why we need this!!
+ if (tempfile==ttokfile) { ## output to \.{TANGLE}
+ #<If |t| is |"string"|, |"constant"|, or |"identifier"|,
+ just |continue|#> ## already defined in \.{TANGLE}
+ temp = temp + #'37 + 3 - highesttoken ## hackety hack!
+ ## +3 because three highest are already defined!
+ }
+ printf "@d %s = %s\n", tokenname[t], temp > tempfile
+ }
+
+
+# Some token names are just characters quoted with |'|. We write out
+all the others.
+#<Write lists...#>=
+ for (t in tokenname) {
+ temp = tokenname[t]
+ if (substr(temp,1,1) != "'") {
+ #<Strip opening |"SP_"| from |temp|, if it is there#>
+ print temp > tokennamefile
+ }
+ }
+
+# #<Strip opening |"SP_"| from |temp|, if it is there#>=
+tempa=substr(temp,1,3)
+if (tempa=="SP_") {
+ temp = substr(temp,4) ## remove |"SP_"|
+ }
+
+
+#*Reserved words and ilks.
+\.{TANGLE} doesn't even need the {\it idea} of
+ reserved words; it treats them like
+all other identifiers.
+\.{WEAVE}, however, needs to be able to recognize reserved words to do
+prettyprinting.
+\.{WEAVE} uses a two-tiered system for coping with reserved words.
+I think this system was really designed to make it easier to code
+\.{WEAVE} by hand, and is therefore not of much interest for
+\.{SPIDER}, but we retain it as a matter of least resistance.
+
+Every reserved word belongs to an ilk, and it is the ilks that, like
+tokens, have translations, categories, and so on.
+
+I have made a bewildering array of defaults that is probably full of
+bugs.
+We use a special convention to initialize the |this_| family.
+
+#<Pattern-act...#>=
+#=/^ilk /#> {
+ print "Ilk", $2 > logfile
+ #<Set |this_mathness| etcetera to the defaults and those with no
+ defaults to |""| #>
+ #<If no category is specified, invent a default if you can#>
+ this_name=""
+ start_place=3
+ #<Scan this line from |start_place| to finish, looking for
+ \.{translation}$\ldots$ and putting results in
+ |this_translation|$\ldots$#>
+ #<Make sure |this_category| is not empty#>
+ #<Make sure |this_name| is empty#>
+ ilk_category[$2]=this_category
+ ilk_mathness[$2]=this_mathness
+ ilk_translation[$2]=this_translation
+ next
+}
+
+
+# The pernicious option here is to be able to leave off the category, so
+that an item of ilk |fish_like| will get category |fish|.
+
+#<If no category is specified, invent a default if you can#>=
+ if ($2 ~ #=/^[a-zA-Z_]+_like$/#> && $0 !~ #=/ category /#>) {
+ ## give default category
+ this_category = substr($2,1,length($2)-5)
+ categories[this_category]=1
+ }
+
+# For the reserved words, our only option is to set an ilk.
+We go through wild and assuredly ill-advised gyrations attempting to
+set all the default properties of that ilk.
+If the ilk is omitted, we make a new ilk by attaching the string
+|"_like"| to the name of the reserved word.
+{\bf Don't use this feature; it embarrasses the author.}
+#^ill-advised#>
+#<Pattern-action...#>=
+#=/^reserved /#> {
+ print "Reserved word", $2 > logfile
+ if ($0 !~ #=/ ilk /#>) {
+ #<Attempt to make up an ilk, with all its defaults#>
+ }
+ for (i=3; i<=NF;) {
+ if ($i == "ilk") {
+ i++
+ reservedilk[$2]=$i
+ has_reserved[$i]=1 ## remember that ilk has some reserved word
+ i++
+ } else {
+ print "Error: bad reserved word attribute:", $i, \
+ "on line", NR-1
+ #<Punt...#>
+ }
+ }
+ #<Check that we used everything#>
+ next
+}
+
+# Here is our feeble attempt to make up an ilk for a reserved word for
+which no ilk is given.
+The default ilk for |"with"| is |"with_like"|, and so on.
+{\bf Please, please don't do this.}
+#<Attempt to make up an ilk, with all its defaults#>=
+ temp = $2 "_like"
+ reservedilk[$2]=temp
+ if (ilk_translation[temp]=="") {
+ ilk_translation[temp]=default_translation
+ }
+ has_reserved[temp]=1
+ if (ilk_mathness[temp]=="") {
+ ilk_mathness[temp]=default_mathness
+ }
+ ## and default category for that ilk is the resword itself
+ if (ilk_category[temp]=="") {
+ ilk_category[temp]=$2
+ categories[$2]=1
+ }
+ ilk_is_made_up[temp]=1 ## we really should do something with this
+#^mistakes#>
+
+
+#*1Telling {\tt WEAVE} how to recognize reserved words.
+At the end, we'll write out definitions for the ilk names, and we'll
+write translations of all the ilks.
+#<Write out all...#>=
+print "Writing out reserved words and ilks" > logfile
+ilkno=64
+print "@ Here is a list of all the ilks" > reserved
+for (i in ilk_translation) {
+ printf "@d SP_%s = %d\n", i, ilkno > reserved
+ ilkno++
+ }
+
+# Here is where we write the code that converts reserved word tokens
+into scraps.
+#<Write out all...#>=
+print " " > reserved
+print "@ Here are the scraps we get from the reserved words" > reserved
+print "@d the_word = res_flag+p-name_dir" > reserved
+print "@<Decide on reserved word scraps@>=" > reserved
+print "switch (p->ilk) {" > reserved
+for (t in ilk_translation) {
+ printf "\tcase SP_%s: \n\t\t", t > reserved
+ transstring=ilk_translation[t]
+ selfstring="small_app(the_word);"
+ wherestring= sprintf ("in translation of ilk %s", t)
+ append_keyword="small_app"
+ #<Take translation from |transstring| and
+ write corresponding \.{WEAVE} code to
+ |outstring|, using |selfstring| as translation of |"<*>"|#>
+ if (trcnt>0) ## at least one text in the translation
+ has_translation[t]=1
+ print outstring > reserved
+ printf "\tapp_scrap(SP_%s,%s_math);\n", ilk_category[t], \
+ ilk_mathness[t] > reserved
+ temp=ilk_category[t]
+ appended[temp]=1
+#^append check#>
+ printf "\t\tbreak;\n" > reserved
+ }
+print "}" > reserved
+
+
+# At the end, we'll have to enter each reserved word in the identifier
+table, along with its ilk.
+#<Write out all...#>=
+print "@ @<Store all the reserved words@>=" > reserved
+for (i in reservedilk) {
+ printf "id_lookup(\"%s\",NULL,SP_%s);\n", i, reservedilk[i] > reserved
+}
+
+# At the very end, we'll make sure every ilk has both a reserved word
+and some translation.
+{\bf Perhaps this could be cleaned up a bit?}
+#<Check for errors at...#>=
+ for (i in ilk_translation) {
+ if (has_reserved[i] != 1) {
+ print "Error: there is no reserved word of ilk", i
+ exitcode=-1
+ }
+ if (has_translation[i] != 1) {
+ print "Error: ilk", i, "has no translation"
+ exitcode=-1
+ }
+ }
+
+# #<Write lists...#>=
+ for (i in ilk_translation) {
+ print i > ilkfile
+ }
+
+# #<Write stat...#>=
+for (i in ilk_translation) number_of_ilks++
+for (i in reservedilk) number_of_reserved_words++
+printf "You defined %d reserved words of %d ilks.\n", \
+ number_of_reserved_words, number_of_ilks
+printf "You defined %d reserved words of %d ilks.\n", \
+ number_of_reserved_words, number_of_ilks > logfile
+
+#*The prettyprinting grammar.
+The most intricate part of \.{WEAVE} is its mechanism for converting
+programming language code into \TeX\ code.
+A ``bottom up'' approach is used to parse the
+programming language material, since \.{WEAVE} must deal with fragmentary
+constructions whose overall ``part of speech'' is not known.
+
+At the lowest level, the input is represented as a sequence of entities
+that we shall call {\it scraps}, where each scrap of information consists
+of two parts, its {\it category} and its {\it translation}. The category
+is essentially a syntactic class, and the translation is a token list that
+represents \TeX\ code. Rules of syntax and semantics tell us how to
+combine adjacent scraps into larger ones, and if we are lucky an entire
+program text that starts out as hundreds of small scraps will join
+together into one gigantic scrap whose translation is the desired \TeX\
+code. If we are unlucky, we will be left with several scraps that don't
+combine; their translations will simply be output, one by one.
+
+The combination rules are given as context-sensitive productions that are
+applied from left to right. Suppose that we are currently working on the
+sequence of scraps $s_1\,s_2\ldots s_n$. We try first to find the longest
+production that applies to an initial substring $s_1\,s_2\ldots\,$; but if
+no such productions exist, we find to find the longest production
+applicable to the next substring $s_2\,s_3\ldots\,$; and if that fails, we
+try to match $s_3\,s_4\ldots\,$, etc.
+
+A production applies if the category codes have a given pattern. For
+example, one of the productions is
+$$\hbox{\.{open [ math semi <\.{"\\\\,"}-opt-5> ] -->
+open math}}$$
+and it means that three consecutive scraps whose respective categories are
+|open|, |math|, and |semi| are con\-verted to two scraps whose categories
+are |open| and |math|.
+ The |open| scrap has not changed, while the string \.{<"\\\\,"-opt-5>}
+indicates that the new |math| scrap
+has a translation composed of the translation of the original
+|math| scrap followed by the translation of the |semi| scrap followed
+by `\.{\\,}' followed by `|opt|' followed by `\.5'. (In the \TeX\ file,
+this will specify an additional thin space after the semicolon, followed
+by an optional line break with penalty 50.)
+
+Their is an extensive discussion of the grammar, with examples, in the
+``Spider User's Guide.''
+Y'oughta read it.
+
+#*1Scanning a production.
+ A production in the grammar is written as a sequence of category
+names and translations, followed by a right arrow (\.{-->}), followed
+by a category name.
+When \.{WEAVE} is scanning the sequence of scraps that makes up a
+module, it checks to see whether the categories of those scraps match
+the categories given on the left side of the production.
+If so, the production fires, and the scraps and translations on the
+left side of the arrow are combined into a single, new scrap, and the
+new scrap is given the category from the right side of the arrow.
+The scraps which are combined are called the firing scraps,
+#^firing scraps#>
+and the category given to the combination is called the target category.
+
+Instead of a category name, e.g.~``\.{math},'' one can write a list of
+category names, e.g.~``\.{(open\vert lsquare)}'' instead.
+A scrap matches the list if and only if its category is one of the
+names listed.
+One can also use the wildcard ``\.?'', which any scrap matches.
+
+On the right-hand side, one can write a \## followed by a number in
+place of the target category name.
+If we specify the target category as ``\.{\##2}'', for example, it
+means ``give the new scrap the same category as the second scrap that
+matched the left side of the production.''
+
+# Here is the whole syntax as quoted from the ``Spider User's Guide''
+
+\begingroup\def\\{\par\noindent\ignorespaces}\tt
+\noindent\syntax{production} \produces\\\quad
+\syntax{left context} [ \syntax{firing instructions} ] \syntax{right context}
+--> \syntax{left context} \syntax{target category} \syntax{right
+context}\\
+\syntax{left context} \produces~\syntax{scrap designators}\\
+\syntax{right context} \produces~\syntax{scrap designators}\\
+\syntax{firing instruction} \produces \syntax{scrap designator}\\
+\syntax{firing instruction} \produces \syntax{translation}\\
+\syntax{scrap designator} \produces~?\\
+\syntax{scrap designator} \produces~\opt{!}\syntax{marked category}\\
+\syntax{scrap designator} \produces~\opt{!}\syntax{category alternatives}\\
+\syntax{category alternatives} \produces~(\syntax{optional
+alternatives}\syntax{marked category})\\
+\syntax{optional alternative} \produces~\syntax{marked category}\vert\\
+\syntax{marked category} \produces~\syntax{category name}\opt{*}\\
+\syntax{target category} \produces~\#\syntax{integer}\\
+\syntax{target category} \produces~\syntax{category name}\\
+\endgroup
+
+# Here is the pattern that reads productions.
+In most of the modules below, we read through some of the fields of the
+production.
+We use |i| to remember what field we are about to examine.
+When a module terminates, |$i| is left pointing to the first field of
+interest to the next module.
+#<Production patt...#>=
+#=/-->/#> {
+ #<Set up to parse this production#>
+ #<Read through the fields of the production, up to the arrow#>
+ #<Set |lowpos|, |highpos|, and |arrowpos| to their proper values#>
+ #<Update |highestposoverall|#>
+ #<Update |highestunknownpos|#>
+ #<Check to see that left context matches#>
+ #<Process scrap to which we are translating#>
+ #<Check to see that right context matches#>
+ #<Check to make sure we used all the fields of the production#>
+ #<Compute the appropriate test for this production and put it
+ in |prodtest[prodnum]|#>
+ #<Compute the code to write the new translation, should this
+ production fire, and put it in |prodtrans[prodnum]|#>
+ #<Write the start token in |ppstart[prodnum]| and the number
+ of tokens reduced in |tokensreduced[prodnum]|#>
+ #<If we only reduced one token, write the reduction
+ out to file |cycles| for later testing#>
+ next
+} ## \.{/-->/}
+
+# Each scrap in the production will be given a position |pos|,
+beginning with 1. (Using 1 and not 0 lets us make good use of the fact
+that uninitialized AWK variables will have value zero.)
+We will remember the positions of the scraps that get reduced; they
+will be from |lowpos| to |highpos-1|.
+We keep track of the production number in |prodnum|, and we save a
+copy of the input line in |inputline[prodnum]|.
+#<Set up to parse this production#>=
+ lowpos=0; highpos=0; pos=1
+ prodnum=prodnum+1
+ inputline[prodnum]=$0
+ print "Parsing production", prodnum, $0 > logfile
+
+
+# This is the guts of the parsing. We have to read each field in the
+production, determine whether it is category or translation
+information, and act accordingly.
+Each scrap will be given a position |pos|.
+We will write in |test[pos]| the code needed to decide whether a
+particular scrap matches the pattern given in the production.
+Scraps can match a single category by name, a list of categories, or
+|"?"|, which every scrap matches.
+Categories can be starred, in which case we underline the index entry
+of the first identifier in the scrap's translation.
+
+We also write in |trans[pos]| the code necessary to produce the
+translations preceding the scrap at |pos|.
+
+#<Read through the fields...#>=
+trans[pos]=""
+for (i=1; i<=NF; i++) {
+ if ($i ~ #=/<.*>/#>) { ## should be |trans_pattern|
+ #<Process a translation in |$i|#>
+ } else if ($i ~ #=/^!?[a-zA-Z_]+(\*\*?)?$/#>) { ## |cat_pattern|
+ #<Process a single category#>
+ } else if ($i ~ #=/^!?\(([a-zA-Z_]+\|)*[a-zA-Z_]+\)(\*\*?)?$/#>){
+ #<Process a list of alternative categories#>
+ } else if ($i == "?") {
+ #<Process a category wild card#>
+ } else if ($i == "[") {
+ lowpos=pos
+ } else if ($i == "]") {
+ highpos=pos
+ } else if ($i=="-->") {
+ break
+ } else { ## we don't recognize the field
+ print "Error: bad field is", $i, "in production on line", NR-1
+ #<Forget this production#>
+ }
+}
+i++
+
+
+# When we find a mistake, we just abandon the current production.
+Decrementing |prodnum| will make it as if this production never happened.
+#<Forget this production#>=
+ prodnum--
+ #<Punt this...#>
+
+# We process the translation and add the result to the current
+translation for |pos|.
+#<Process a translation...#>=
+transstring=$i
+selfstring="" ## senseless for productions
+wherestring= sprintf ("in production on line %d", NR-1)
+append_keyword="app"
+#<Take translation from |transstring| and write corresponding \.{WEAVE} code to
+|outstring|, using |selfstring| as translation of |"<*>"|#>
+trans[pos]=trans[pos] outstring
+
+# Here we'll set |test[pos]|.
+The phrase |test[pos]| will be a single C conjunct; if the test for
+each scrap is true, the whole production will fire.
+If we're called upon to make a scrap underlined or reserved, we'll add
+to |trans[pos]|.
+
+If a category is negated we add an extra clause to make
+sure nothing matches the zero category, since {\tt WEAVE} assumes
+no production ever matches a scrap with category zero.
+#<Process a single category#>=
+ field[pos]=$i ## save this field to compare RHS
+ #<Set |negation|, and remove leading |"!"| from |$i| if necessary#>
+ #<Strip stars from |$i| (if any) and add appropriate
+ translations to |trans[pos]|#>
+ cat = $i
+ categories[cat]=1 ## remember |cat| is a category
+ if (negation==0) {
+ test[pos]=sprintf("(pp+%d)->cat==SP_%s",pos-1,cat)
+ } else {
+ test[pos]=sprintf("((pp+%d)->cat!=SP_%s && (pp+%d)->cat != 0)",\
+ pos-1,cat,pos-1)
+ }
+ #<Update the record of the rightmost occurrence of category |cat|#>
+ #<Advance |pos|, making the new |trans[pos]| empty#>
+
+# The list of categories is enclosed in parentheses and the individual
+categories are separated by vertical bars.
+We have to make the test for these things a disjunction, but
+processing is more or less like the processing for a single category.
+
+If a list of alternatives is negated we add an extra clause to make
+sure nothing matches the zero category, since {\tt WEAVE} assumes
+no production ever matches a scrap with category zero.
+#<Process a list of alternative categories#>=
+ field[pos]=$i ## save this field to compare RHS
+ #<Set |negation|, and remove leading |"!"| from |$i| if necessary#>
+ if (negation==0) {
+ test[pos]="(" ## open for a list of good alternatives
+ } else {
+ temp=sprintf("(pp+%d)->cat==0",pos-1)
+ test[pos]="!(" temp "||" ## open for a list of bad alternatives
+ }
+ #<Strip stars from |$i| (if any) and add appropriate
+ translations to |trans[pos]|#>
+ temp = substr($i,2,length($i)-2) ## throw out parens
+ m = split(temp,tok,"|")
+ for (j=1;j<=m;j++) {
+ cat = tok[j]
+ categories[cat]=1 ## remember it's a category
+ #<Update the record of the rightmost occurrence of
+ category |cat|#>
+ temp=sprintf("(pp+%d)->cat==SP_%s",pos-1,cat)
+ test[pos]=test[pos] temp ## add alternative to test
+ if (j!=m)
+ test[pos]=test[pos] "||\n" ## line too long errors
+ }
+ test[pos]= test[pos] ")"
+ #<Advance |pos|, making the new |trans[pos]| empty#>
+
+
+# We keep track of the rightmost occurrence of each category.
+This enables us to backtrack by exactly the right amount when a
+production fires and creates a new scrap.
+#<Update the record of the rightmost occurrence of category |cat|#>=
+ if (pos > highestpos[cat]) {
+ highestpos[cat]=pos
+ }
+
+# If a category or lsit of alternatives is preceded by an exclamation
+point (|"!"|), we set |negation|, and we will test for scraps that are
+{\it not} of that category or are {\it not} of one of the categories
+listed.
+#<Set |negation|...#>=
+temp = substr($i,1,1)
+if (temp=="!") {
+ negation = 1
+ $i = substr($i,2)
+} else {
+ negation = 0
+}
+
+# Since both translations and tokens can add to |trans[pos]| we must
+make sure it is empty whenever we get a new |pos|.
+This device makes that easy.
+
+#<Advance |pos|, making the new |trans[pos]| empty#>=
+ pos=pos+1
+ trans[pos]=""
+
+# If a category is single-starred, we take this construct to be the
+{\it definition} of that item, and we underline the index entry for
+this module.
+The |make_underlined| routine finds the first identifier in the
+translation of the starred scrap, and underlines the index entry for
+that identifier in this module.
+
+If a category is double-starred, we used to try to change the ilk of the
+appropriate identifier to make it a reserved word.
+The only use this ever had was in handling C typedefs, and it should
+probably be removed.
+#^mistakes#>
+In the meanwhile, double starring is like single starring.
+
+#<Strip stars from |$i| (if any) and add appropriate
+ translations to |trans[pos]|#>=
+if ($i ~ #=/^([a-zA-Z_]+|\(([a-zA-Z_]+\|)*[a-zA-Z_]+\))\*\*$/#>) { ## it's double-starred
+ temp = sprintf("\tmake_underlined(pp+%d);\n",pos-1)
+ trans[pos] = trans[pos] temp
+ $i = substr($i,1,length($i)-2)
+} else if ($i ~ #=/^([a-zA-Z_]+|\(([a-zA-Z_]+\|)*[a-zA-Z_]+\))\*$/#>) { ## it's starred
+ temp = sprintf("\tmake_underlined(pp+%d);\n",pos-1)
+ trans[pos] = trans[pos] temp
+ $i = substr($i,1,length($i)-1)
+} else if ($i ~ #=/\*$/#>) { ## a bad star?
+ print "Error: can't remove stars in production on line", NR-1
+ #<Forget this production#>
+}
+
+# Wild cards are easy to process, but we do have to remember that
+not even a wild card matches a scrap of category zero.
+#<Process a category wild card#>=
+ field[pos]=$i ## save this field to compare RHS
+ test[pos]=sprintf("(pp+%d)->cat!=0",pos-1) ## anything nonzero matches
+ highwildcard=pos ## we don't really need this?
+ #<Advance |pos|, making the new |trans[pos]| empty#>
+
+
+
+#
+We reach this point in the program after we will have read the arrow
+into |$i|.
+
+This module establishes in what ranges of |pos| the contexts fall:
+$$\vbox{\halign{##\hfil\tabskip1em&\hfil##\hfil\cr
+\bf Items&\bf Range\cr
+\noalign{\vskip2pt}
+left context&|1..lowpos-1|\cr
+firing instructions&|lowpos..highpos-1|\cr
+right context&|highpos..arrowpos-1|\cr
+}}$$
+If |lowpos| and |highpos| haven't been set by the appearance of square
+brackets, we set them to make the contexts empty.
+None or both should be set.
+
+
+#<Set |lowpos|, |highpos|, and |arrowpos| to their proper values#>=
+ arrowpos=pos
+ if (lowpos==0 && highpos==0) {
+ lowpos=1 ## first transform position
+ highpos=arrowpos ## first token not reduced
+ ## (or one beyond last token position)
+ } else if (lowpos==0 || highpos==0) {
+ print "Error: square brackets don't balance in", \
+ "production on line", NR-1
+ #<Forget this production#>
+ }
+
+# Here is the efficient place to update the rightmost (highest)
+position of {\it any} category.
+#<Update |highestposoverall|#>=
+ if (arrowpos-1 > highestposoverall) {
+ highestposoverall=arrowpos-1
+ }
+
+# Dealing with grammars in which categories can be unnamed (using
+wildcards or negation) can be a pain in the ass.
+What we have to do, when reducing after firing a production, is move
+backwards enough so that we don't miss any earlier productions that
+are supposed to fire.
+This means we have to move back at least far enough so that the new
+scrap will match any unnamed category.
+{\bf But} we don't have to worry about wildcards (|"?"|) at the end of
+a production, because they would have matched anyway, even before the
+current production fired. Hence:
+#<Update |highestunknownpos|#>=
+for (hup=arrowpos-1; field[hup]=="?";) {
+ hup--
+ }
+for (;hup>highestunknownpos;hup--) {
+ temp=field[hup]
+ temp=substr(temp,1,1)
+ if (temp=="?" || temp =="!") {
+ highestunknownpos=hup ## we know |hup>highestunknownpos|
+ break ## redundant, since test will fail
+ }
+}
+
+# Here is the error checking for context sensitive productions.
+#<Check to see that left context matches#>=
+ for (pos=1;pos<lowpos;pos++) {
+ #<Check |$i| against |field[pos]|#>
+ i++
+ }
+
+# #<Check to see that right context matches#>=
+ for (pos=highpos;pos<arrowpos;pos++) {
+ #<Check |$i| against |field[pos]|#>
+ i++
+ }
+# #<Check |$i| against |field[pos]|#>=
+ if (i>NF || $i != field[pos]) {
+ print "Error: token mismatch is: found", $i, \
+ "sought", field[pos], "on line", NR-1
+ #<Forget this...#>
+ }
+
+# We process our target scrap in between checking the left and right
+contexts.
+This scrap can be the name of a category, or it can be ``$\##nnn$'',
+where $nnn$ refers to the number of a category on the left side of the
+arrow.
+In this way it is possible to match wildcards and lists of alternatives.
+#<Process scrap to which we are translating#>=
+ ## i points to the target category
+ if (i>NF) {
+ print "Error: no target category in production on line", NR-1
+ #<Forget this...#>
+ }
+ if ($i ~ #=/##[0-9]+/#>) { ## a number
+ $i = substr($i,2) ## peel off the \##
+ #<Make sure |1 <= $i < arrowpos|#>
+ targetcategory[prodnum]="Unnamed category"
+ temp = sprintf("(pp+%d)->cat", $i-1)
+ unnamed_cat[prodnum]=temp
+ } else if ($i ~ #=/[a-zA-Z][a-zA-Z_]*/#>) { ## a category
+ targetcategory[prodnum]=$i
+ categories[$i]=1 ## remember this is a category
+ } else {
+ print "Error: unrecognizable target token", $i, \
+ "in production on line", NR-1
+ #<Forget this...#>
+ }
+ i++
+
+# We call this at the end to make sure there aren't unused fields left over
+#<Check to make sure we used all the fields of the production#>=
+ if (i<=NF) {
+ print "Error: used only " i-1 " of " NF " tokens", \
+ "in production on line", NR-1
+ #<Forget this...#>
+ }
+
+# After having vetted the whole production, we combine the tests and
+translations for each |pos|.
+#<Compute the appropriate test for this production and put it
+ in |prodtest[prodnum]|#>=
+ prodtest[prodnum]=""
+ for (pos=1;pos<arrowpos;pos++) {
+ if (pos>1) {
+ prodtest[prodnum]=prodtest[prodnum] " &&\n\t\t"
+ }
+ prodtest[prodnum]=prodtest[prodnum] test[pos]
+ }
+
+# #<Compute the code to write the new translation, should this
+ production fire, and put it in |prodtrans[prodnum]|#>=
+ prodtrans[prodnum]=""
+ for (pos=lowpos;pos<highpos;pos++) {
+ prodtrans[prodnum]=prodtrans[prodnum] trans[pos]
+ ## add code to append this scrap
+ temp = sprintf("\tapp1(pp+%d);\n",pos-1)
+ prodtrans[prodnum]=prodtrans[prodnum] temp
+ #<If not negated, record the fact that a token of
+ category satisfying |test[pos]| could have
+ been reduced#>
+ }
+ prodtrans[prodnum]=prodtrans[prodnum] trans[highpos]
+
+# #<Write the start token in |ppstart[prodnum]| and the number
+ of tokens reduced in |tokensreduced[prodnum]|#>=
+ ppstart[prodnum]=lowpos-1
+ tokensreduced[prodnum]=highpos-lowpos
+
+# #<If we only reduced one token, write the reduction
+ out to file |cycles| for later testing#>=
+ if (highpos-lowpos==1) {
+ printf "%d: %s --> %s\n", prodnum, field[lowpos], \
+ targetcategory[prodnum] > cycles
+ wrotecycles = 1
+ }
+
+# If we never even had the possibility of a cycle, we still have to write
+out a dummy file so the cycle checker in the Makefile won't barf.
+# #<Write lists of everything#>=
+if(wrotecycles==0) {
+ print "0: dummy --> nodummy" > cycles
+ }
+
+# For error checking, we keep track of categories that get reduced in
+productions.
+We can't do this while scanning the production, because we don't know
+at the beginning what |lowpos| will be, since we might or might not
+ever see a left square bracket.
+
+If a particular category is never reduced, that merits a warning later on.
+#<If not negated, record the fact that a token of category satisfying
+ |test[pos]| could have been reduced#>=
+temp = field[pos]
+tempa = substr(temp,1,1)
+if (tempa != "!") {
+ if (temp ~ #=/^\(([a-zA-Z_]+\|)*[a-zA-Z_]+\)(\*\*?)?$/#>) {
+ ## list of alternatives
+ #<Remove trailing stars from |temp|#>
+ temp = substr(temp,2,length(temp)-2)
+ m = split(temp,tok,"|")
+ for (j=1;j<=m;j++) {
+ alternate = tok[j]
+ reduced[alternate]=1
+ }
+ } else if (temp ~ #=/^[a-zA-Z_]+(\*\*?)?$/#>) {
+ #<Remove trailing stars from |temp|#>
+ reduced[temp]=1
+ } else if (temp != "?") {
+ print "Confusion: unintelligible field[pos]:", temp, \
+ "in production on line", NR-1
+ #<Forget this...#>
+ }
+}
+
+# #<Remove trailing...#>=
+while (temp ~ #=/\*$/#>) {
+ temp = substr(temp,1,length(temp)-1)
+}
+
+# #<Check for err...#>=
+for (c in categories) {
+ if (reduced[c] != 1) {
+ print "Warning: category", c, "never reduced"
+ }
+}
+
+
+# Here's a check for the target token number
+#<Make sure |1 <= $i < arrowpos|#>=
+if ((0+$i)<1 || (0+$i)>=0+arrowpos) {
+ print "Error: can't take token number", $i, "of", arrowpos-1, \
+ "tokens", "in production on line", NR-1
+ #<Forget this...#>
+ }
+
+#*1Writing the scrap reduction code.
+Before writing the grammar, we want to define all of the category codes.
+#<Write out...#>=
+ print "Writing out category codes" > logfile
+ print "@ Here is a list of category codes scraps can have" > grammarfile
+ i=1
+ for (t in categories) {
+ printf "@d SP_%s = %d\n",t,i > grammarfile
+ i++
+ }
+ print "@c" > grammarfile
+# We also want to make sure we can print the names of categories in
+case we need to debug.
+#<Write out...#>=
+ print "##ifdef DEBUG" > grammarfile
+ print "##define PRINT_CAT(A,B) case A: printf(B); break" > grammarfile
+ print "print_cat(c) /* symbolic printout of a category */" > grammarfile
+ print "eight_bits c;" > grammarfile
+ print "{" > grammarfile
+ print " switch(c) {" > grammarfile
+ for (t in categories) {
+ printf "PRINT_CAT(SP_%s,\"%s\");\n",t,t > grammarfile
+ }
+ print " case 0: printf(\"zero\"); break;" > grammarfile
+ print " default: printf(\"UNKNOWN\"); break;" > grammarfile
+ print " }" > grammarfile
+ print "}" > grammarfile
+ print "##endif DEBUG" > grammarfile
+ print " " > grammarfile
+
+# And there goes the list...
+#<Write lists...#>=
+ for (c in categories) {
+ print c > categoryfile
+ }
+
+# #<Write stat...#>=
+for (c in categories) {
+ number_of_categories++
+}
+printf "You used %d different categories in %d productions.\n", \
+ number_of_categories, prodnum
+printf "You used %d different categories in %d productions.\n", \
+ number_of_categories, prodnum > logfile
+printf "The biggest production had %d scraps on its left-hand side.\n", \
+ highestposoverall
+printf "The biggest production had %d scraps on its left-hand side.\n", \
+ highestposoverall > logfile
+
+
+# We will write a list of the successfully parsed productions to a
+separate file.
+The list will include
+ production numbers, to which the user can refer
+when debugging.
+#<Write lists...#>=
+for (n=1; n<= prodnum; n++) {
+ printf "%2d: %s\n",n,inputline[n] > productions
+ }
+
+# Finally, we write out the code for all of the productions.
+Here is our first view of category checking: we want to make sure that
+each category can be appended, either by |app_scrap| or by |reduce|.
+We also want to make sure each category can be reduced by firing some
+production.
+We track these things using the arrays |appended| and |reduced|.
+
+We write the definition of |highestposoverall|, for safety.
+
+We used to write this code as a very deeply nested if-then-else,
+but that caused a yacc overflow in the generated code for C~{\tt WEAVE}.
+So now we write
+{\tt if (...) \LB...; goto end\_prods;\RB}
+#<Write out...#>=
+print "Writing out grammar" > logfile
+print "@ Here is where we define |highestposoverall| and where we" > grammarfile
+print "check the productions." > grammarfile
+print "@d highestposoverall =", highestposoverall > grammarfile
+print "@<Test for all of the productions@>=" > grammarfile
+for (n=1; n<=prodnum; n++) {
+ if (n%5==0)
+ print "@ @<Test for all of the productions@>=" \
+ > grammarfile ## avoids overflowing \.{WEAVE} of \.{WEAVE}
+ #<Change \vert,\_, and {\tt \##} in |inputline[n]|; put results in |this_string|#>
+ #<Make |this_string| no more than 60 characters wide#>
+ printf "if (%s) {\n\t/* %d: {\\tt %s} */\n%s",\
+ prodtest[n],n,this_string,prodtrans[n] > grammarfile
+ #<Write the |reduce| call, taking note of whether the
+ category is named#>
+ print "\tgoto end_prods;" > grammarfile
+ printf "} " > grammarfile
+ }
+printf "\n" > grammarfile
+print "end_prods:" > grammarfile
+
+# We do different things for a category that is unnamed.
+#<Write the |reduce| call, taking note of whether the category is named#>=
+ ttk=targetcategory[n]
+ if (ttk == "Unnamed category") {
+#^append check#>
+ printf "\treduce(pp+%d,%d,%s,%d,%d);\n",ppstart[n],\
+ tokensreduced[n],unnamed_cat[n],\
+ 1-highestposoverall,n > grammarfile
+ } else {
+ appended[ttk]=1 ## remember we appended this token
+#^append check#>
+ reduction=highestpos[ttk]
+ if (reduction<highestunknownpos) {
+ reduction = highestunknownpos
+ }
+ printf "\treduce(pp+%d,%d,SP_%s,%d,%d);\n",ppstart[n],\
+ tokensreduced[n],targetcategory[n],\
+ 1-reduction,n > grammarfile
+ }
+
+# This is the place we check for errors.
+#^append check#>
+#^reduce check#>
+#<Check for errors...#>=
+for (c in categories) {
+ if (appended[c] != 1) {
+ if (c=="ignore_scrap") { ## appended by \.{WEAVE}
+ print "Warning: category", c, "never appended"
+ } else {
+ print "Error: category", c, "never appended"
+ exitcode=-1
+ }
+ }
+ }
+
+
+
+# It's desirable to put the production in a comment, but we have to
+get rid of the confusing \vert, or \.{WEAVE} will think it introduces
+code.
+We also have to escape underscores and sharp signs, otherwise \TeX\ will
+think we want math mode.
+#<Change \vert,\_, and {\tt \##} in |inputline[n]|; put results in |this_string|#>=
+ this_string = inputline[n]
+ tempi = index(this_string,"|")
+ while (tempi != 0) {
+ tempa = substr(this_string,1,tempi-1)
+ tempb = substr(this_string,tempi+1)
+ this_string = tempa "\\vert " tempb
+ tempi = index(this_string,"|")
+ }
+ templ = ""; tempr = this_string
+ tempi = index(tempr,"_")
+ while (tempi != 0) {
+ tempa = substr(tempr,1,tempi-1)
+ tempr = substr(tempr,tempi+1)
+ templ = templ tempa "\\_"
+ tempi = index(tempr,"_")
+ }
+ this_string = templ tempr
+ templ = ""; tempr = this_string
+ tempi = index(tempr,"##")
+ while (tempi != 0) {
+ tempa = substr(tempr,1,tempi-1)
+ tempr = substr(tempr,tempi+1)
+ templ = templ tempa "\\##"
+ tempi = index(tempr,"##")
+ }
+ this_string = templ tempr
+
+
+# We have to keep these productions from making an input line too long.
+#<Make |this_string| no more than 60 characters wide#>=
+toolong=this_string; this_string=""
+while (length(toolong)>60) {
+ idx=59
+ idchar = substr(toolong,idx,1)
+ while (idx>1 && idchar!=" ") {
+ idx--
+ idchar = substr(toolong,idx,1)
+ }
+ if (idx==1)
+ idx=59
+ temp = substr(toolong,1,idx-1)
+ toolong = substr(toolong,idx+1)
+ this_string = this_string temp "\n"
+}
+this_string = this_string toolong
+
+
+
+#*The rest of {\tt SPIDER}.
+We present the remaining features of \.{SPIDER} in them order we
+used in the ``\.{SPIDER} User's Guide.''
+#*2 Naming the target language.
+\.{SPIDER} is designed to help you build a \.{WEB} system for any
+programming language.
+We need to know the name of the language, and what extension to
+use when writing the tangled unnamed module.
+We use this information to pick a name for the file that will hold
+this \.{WEB}'s special \TeX{} macros, and we write |"\\input webkernel"|
+on that file.
+#<Patt...#>=
+#=/^language /#> {
+ language = $2
+ extension=language
+ for (i=3; i<NF; ) {
+ if ($i=="extension") {
+ i++
+ extension=$i
+ i++
+ } else if ($i=="version") {
+ i++
+ version=$i
+ i++
+ } else {
+ print "Error: unknown language property", $i,\
+ "on line", NR-1
+ #<Punt...#>
+ }
+ }
+ #<Check that we used everything#>
+ #<Write the first line of the macro file#>
+ next
+}
+
+# #<Write out...#>=
+if (language != "") {
+ print "@ Here is the language-dependent stuff" > tlang
+ if (version!="")
+ version = ", Version " version
+ printf "@d banner = \"This is %s TANGLE%s %s\\n\"\n", language, \
+ version, date > tlang
+ printf "@<Global...@>=char C_file_extension[]=\"%s\";\n", extension \
+ > tlang
+#@
+ print "@ Here is the language-dependent stuff" > wlang
+ if (version!="")
+ version = ", Version " version
+ printf "@d banner = \"This is %s WEAVE%s %s\\n\"\n", language, \
+ version, date > wlang
+ print "@<Set |out_ptr| and do a |tex_printf| to read the macros@>=" \
+ > wlang
+ printf "*out_ptr='x'; tex_printf(\"\\\\input %sweb.te\");\n", \
+ extension > wlang
+ printf "@ @<Global...@>=char C_file_extension[]=\"%s\";\n", extension \
+ > wlang
+} else {
+ print "Error: you haven't given me any \"language\" information"
+ exitcode=-1
+}
+
+#*1Defining {\TeX} macros.
+The first thing we do after getting the language is write a line to
+the macro file.
+This makes sure the kernel \.{WEB} macros will be available.
+#<Write the first line of the macro file#>=
+ macrofile = extension "web.tex"
+ print "\\input webkernel.tex" > macrofile
+
+
+# Processing macros is straightforward: everything between \.{macros
+begin} and \.{macros end} gets copied into the macro file.
+#<Patt...#>=
+#=/^macros begin$/,/^macros end$/#> {
+ if (begunmacs==0) {
+ begunmacs=1
+ next
+ }
+ if ($0 ~ #=/^macros end$/#>) {
+ begunmacs=0
+ next
+ }
+ if (macrofile=="") {
+ if (complained==0) {
+ print "Error: you must give \"language\"",\
+ "before \"macros\""
+ complained=1
+ #<Punt...#>
+ }
+ } else {
+ print $0 > macrofile
+ }
+ next
+}
+
+
+
+#*1Handling modules.
+We need to give module names a category, both when we define modules
+and when we use them in other modules.
+
+We might conceivably fool around with mathness, but we don't
+really intend to do so.
+#<Pattern-action...#>=
+#=/^module /#> {
+ for (i=2;i<NF;) {
+ if ($i=="definition") {
+ i++
+ mod_def_cat=$i
+ categories[$i]=1
+ print "Module definition category set to", $i > logfile
+ i++
+ } else if ($i=="use") {
+ i++
+ mod_use_cat=$i
+ categories[$i]=1
+ print "Module use category set to", $i > logfile
+ i++
+ } else {
+ print "Error: unknown module property", $i, \
+ "on line", NR-1
+ #<Punt...#>
+ }
+ }
+ #<Check that we used everything#>
+ next
+}
+
+# Here's how we rig it:
+#<Write out...#>=
+if (mod_def_cat!="") {
+ print "@ @<Call |app_scrap| for a module definition@>=" > scrapfile
+ printf "app_scrap(SP_%s,no_math);\n", mod_def_cat > scrapfile
+ appended[mod_def_cat]=1
+} else {
+ print "Error: I don't know what to do with a module definition"
+ print " Give me a \"module definition ...\""
+ exitcode=-1
+}
+if (mod_use_cat!="") {
+ print "@ @<Call |app_scrap| for a module use@>=" > scrapfile
+ printf "app_scrap(SP_%s,maybe_math);\n", mod_use_cat > scrapfile
+ appended[mod_use_cat]=1
+} else {
+ print "Error: I don't know what to do with a module use"
+ print " Give me a \"module use ...\""
+ exitcode=-1
+}
+
+
+#*1At sign.
+With \.{SPIDER}, we can designate any character we like as the
+``magic at sign.''
+#<Pattern-act...#>=
+#=/^at_sign /#> {
+ if (NF==2 && length($2)==1) {
+ if ($2=="@") {
+ at_sign="@@"
+ } else {
+ at_sign=$2
+ }
+ } else {
+ print "Error: I can't understand", $0
+ print " Give me an at sign of length 1"
+ #<Punt...#>
+ }
+ next
+}
+
+# We write the at sign out to the grammar file and to \.{TANGLE}'s token file
+#<Write out all...#>=
+ tempfile = grammarfile
+ #<Write |at_sign| definion to |tempfile|#>
+ tempfile = ttokfile
+ #<Write |at_sign| definion to |tempfile|#>
+
+# It's trivially done
+#<Write |at_sign| definion to |tempfile|#>=
+ print "@ Here is the |at_sign| for the new web" > tempfile
+ printf "@d at_sign = @`%s'\n", at_sign > tempfile
+ print " " > tempfile
+ print "@ Here is |the_at_sign| left for common" > tempfile
+ print "@<Global...@>=char the_at_sign = at_sign;" > tempfile
+ print " " > tempfile
+
+# We provide a default at sign:
+#<Set init...#>=
+ at_sign="@@"
+
+
+#*1Comments.
+We have to explain how our programming language supports comments.
+We give the strings that initiate and terminate a comment.
+We can say comments are terminated by ``newline'' if that's the case.
+#<Pattern-act...#>=
+#=/^comment /#> {
+ print $0 > logfile
+ for (i=2; i<NF;) {
+ if ($i=="begin") {
+ i++
+ if ($i ~ #=/^<.*>$/#>) {
+ transstring = $i
+ wherestring = "in \"comment begin\" on line " NR-1
+ #<Convert restricted translation in |transstring|
+ to quoted string in |outstring|#>
+ begin_comment_string = outstring
+ i++
+ } else {
+ print "Error: \"comment begin\" must have a restricted translation"
+ #<Punt...#>
+ }
+ } else if ($i=="end") {
+ i++
+ if ($i=="newline") {
+ comments_end_with_newline = 1
+ end_comment_string = "\"\\n\""
+ } else if ($i ~ #=/^<.*>$/#>){
+ comments_end_with_newline = 0
+ transstring = $i
+ wherestring = "in \"comment end\" on line " NR-1
+ #<Convert restricted translation in
+ |transstring|
+ to quoted string in |outstring|#>
+ end_comment_string = outstring
+ } else {
+ print "Error: \"comment end\" must have a restricted translation"
+ #<Punt...#>
+ }
+ i++
+ } else {
+ print "Error: bad comment attribute:", $i
+ #<Punt...#>
+ }
+ }
+ #<Check that we used everything#>
+ #<Write the comment definitions to the macro file#>
+ next
+}
+
+# \.{WEAVE} and \.{TANGLE} must be able to recognize comments.
+Here we give \.{TANGLE}
+ quoted strings that show the beginning and end of a
+comment.
+
+#<Write out...#>=
+print "@ Here we recognize the comment start seqence" > ttokfile
+print "@<See a comment starting at |loc| and skip it@>=" > ttokfile
+ printf "{int len; len=strlen(%s);\n", begin_comment_string > ttokfile
+ printf "if (loc+len<=limit && !strncmp(loc,%s,len)) {\n",\
+ begin_comment_string > ttokfile
+ print "\tloc += len; /* a new thing */" > ttokfile
+ print "\tskip_comment(); /* scan to end of comment or newline */" > ttokfile
+ print "\tif (comment_continues || comments_end_with_newline)" > ttokfile
+ print "\t\treturn('\\n');" > ttokfile
+ print "\telse continue;\n}\n}" > ttokfile
+
+
+# Now this is \.{WEAVE} finding the start of a comment
+#<Write out...#>=
+print "@ @<See a comment starting at |loc-1| and return |begin_comment|@>=" \
+ > scrapfile
+ printf "{int len; len=strlen(%s);\n", begin_comment_string > scrapfile
+ printf "if (loc+len-1<=limit && !strncmp(loc-1,%s,len)) {\n",\
+ begin_comment_string > scrapfile
+ print "\tloc += len-1;" > scrapfile
+ print "\t return (begin_comment); /* scan to end of comment or newline */" > scrapfile
+ print "}\n}" > scrapfile
+
+
+
+
+# Here \.{TANGLE} spots the end of a comment
+#<Write out...#>=
+print "@ Here we deal with recognizing the end of comments" > ttokfile
+printf "@d comments_end_with_newline = %d\n", comments_end_with_newline >ttokfile
+print "@<Recognize comment end starting at |loc-1|@>=" > ttokfile
+if (comments_end_with_newline != 1) {
+ printf "{int len; len=strlen(%s);\n", end_comment_string > ttokfile
+ printf "if (loc+len-1<=limit && !strncmp(loc-1,%s,len)) {\n",\
+ end_comment_string > ttokfile
+ print "loc += len-1; return(comment_continues=0); }}" > ttokfile
+} else {
+ print "/* This code will never be executed */ " > ttokfile
+}
+
+# Now here is \.{WEAVE}.
+\.{WEAVE} copes elsewhere with the situation when
+|comments_end_with_newline| holds, so we don't need to consider it here.
+#<Write out...#>=
+printf "@ Here we recognize end of comments" > scrapfile
+printf "@d comments_end_with_newline = %d\n",comments_end_with_newline >scrapfile
+print "@<Check for end of comment@>=" > scrapfile
+ printf "{int len; len=strlen(%s);\n", end_comment_string > scrapfile
+ printf "if (loc+len-1<=limit && !strncmp(loc-1,%s,len)) {\n",\
+ end_comment_string > scrapfile
+print " loc++; if(bal==1) {if (phase==2) app_tok('}'); return(0);}" > scrapfile
+print " else {" > scrapfile
+print " err_print(\"! Braces don't balance in comment\");" > scrapfile
+print "@.Braces don't balance in comment@>" > scrapfile
+print " @<Clear |bal| and |return|@>;" > scrapfile
+print " }" > scrapfile
+print "}" > scrapfile
+print "}" > scrapfile
+
+
+# We have to give \.{TANGLE} the beginning and ending comment strings, so
+it can use thing in writing its own comments.
+#<Write out...#>=
+ print "@ Important tokens:" > ttokfile
+ printf "@d begin_comment_string = %s\n", begin_comment_string > ttokfile
+ printf "@d end_comment_string = %s\n", end_comment_string > ttokfile
+
+# We also have to write out the starting and ending comment strings to
+the macro file.
+We do this at the time of parsing |#=/^comment /#>|, so the user has a
+chance to override.
+#<Write the comment definitions to the macro file#>=
+if (macrofile!="") {
+ this_string=substr(begin_comment_string,2,length(begin_comment_string)-2)
+ #<Write |this_string| into |tex_string|, escaping \TeX's specials#>
+ printf "\\def\\commentbegin{%s}\n", tex_string > macrofile
+ if (comments_end_with_newline==0) {
+ this_string=substr(end_comment_string,2,length(end_comment_string)-2)
+ #<Write |this_string| into |tex_string|, escaping \TeX's specials#>
+ printf "\\def\\commentend{%s}\n", tex_string > macrofile
+ } else {
+ print "\\def\\commentend{\\relax}" > macrofile
+ }
+} else {
+ print "Error: I can't write comment info to the macro file---"
+ print " you haven't given me any \"language\" information"
+ #<Punt...#>
+ }
+
+
+
+# Escaping \TeX's specials is pretty easy:
+#<Set initial...#>=
+texof["\\"]="\\BS"
+texof["{"]="\\{"
+texof["}"]="\\{"
+texof["$"]="\\$"
+texof["&"]="\\amp"
+texof["##"]="\\##"
+texof["^"]="\\H"
+texof["_"]="\\_"
+texof["~"]="\\TI"
+texof["%"]="\\%"
+
+#
+#<Write |this_string| into |tex_string|, escaping \TeX's specials#>=
+tex_string=""
+while (length(this_string)>0) {
+ c = substr(this_string,1,1)
+ this_string = substr(this_string,2)
+ cprime = texof[c]
+ if (cprime=="") {
+ tex_string = tex_string c
+ } else {
+ tex_string = tex_string cprime
+ }
+}
+
+#*1Controlling line numbering.
+Here we fart around with line numbering for \.{TANGLE}.
+This lets \.{TANGLE} write an indication of the locations of things in
+the \.{WEB} source.
+The C preprocessor accepts these things as \.{\##line} directives.
+#<Pattern-act...#>=
+#=/^line /#> {
+ print $0 > logfile
+ for (i=2; i<NF;) {
+ if ($i=="begin") {
+ i++
+ if ($i ~ #=/^<.*>$/#>) {
+ transstring = $i
+ wherestring = "in \"line begin\" on line " NR-1
+ #<Convert restricted translation in |transstring|
+ to quoted string in |outstring|#>
+ sharp_line_open = outstring
+ i++
+ } else {
+ print "Error: \"line begin\" must have a restricted translation"
+ #<Punt...#>
+ }
+ } else if ($i=="end") {
+ i++
+ if ($i ~ #=/^<.*>$/#>){
+ transstring = $i
+ wherestring = "in \"line end\" on line " NR-1
+ #<Convert restricted translation in
+ |transstring|
+ to quoted string in |outstring|#>
+ sharp_line_close = outstring
+ } else {
+ print "Error: \"line end\" must have a restricted translation"
+ #<Punt...#>
+ }
+ i++
+ } else {
+ print "Error: bad line attribute:", $i, "on line", NR-1
+ #<Punt...#>
+ }
+ } ## |for|
+ #<Check that we used everything#>
+ next
+}
+
+# We have to give \.{TANGLE} the strings for \&{\##line} commands.
+#<Write out...#>=
+ print "@ Important tokens:" > ttokfile
+ printf "@d sharp_line_open = %s\n", sharp_line_open > ttokfile
+ printf "@d sharp_line_close = %s\n", sharp_line_close > ttokfile
+
+# We'll choose some innocuous defaults
+#<Set init...#>=
+sharp_line_open = "\"##line\""
+sharp_line_close = "\"\""
+
+#*1Tracking the generation date.
+We want to be able to note the date on which we generate files.
+#<Patt...#>=
+#=/^date /#> {
+ ## date returned as ``Fri Dec 11 11:31:18 EST 1987''
+ mo = month[$3]
+ day = $4
+ year = $7
+ time = $5
+ #<Set |hour|, |minute|, and |ampm| from |time|#>
+ date = sprintf ("(generated at %d:%s %s on %s %d, %d)",\
+ hour, minute, ampm, mo, day, year)
+ next
+}
+
+# We want the months to have their full names
+#<Set init...#>=
+month["Jan"]="January"
+month["Feb"]="February"
+month["Mar"]="March"
+month["Apr"]="April"
+month["May"]="May"
+month["Jun"]="June"
+month["Jul"]="July"
+month["Aug"]="August"
+month["Sep"]="September"
+month["Oct"]="October"
+month["Nov"]="November"
+month["Dec"]="December"
+
+# We make a ``friendly'' time from |time=="hh:mm:ss"|.
+#<Set |hour|, |minute|, and |ampm| from |time|#>=
+ hour = substr(time,1,2)
+ if (hour >=12)
+ ampm = "PM"
+ else
+ ampm="AM"
+
+ if (hour==0) {
+ hour =12
+ } else if (hour>12) {
+ hour = hour -12
+ }
+ minute = substr(time,4,2)
+
+
+#*=The {\tt SPIDER} tools.
+#i cycle.web
+#*Flagging duplicate names.
+Detects duplicate names in a sorted list.
+#(nodups.awk#>=
+{ if ($0==last) {
+ print "Error: duplicate name", $0, "on lines", NR-1"-"NR
+ exit -1
+ }
+ last = $0
+}
+#*Checking translation keywords for validity.
+#(transcheck.awk#>=
+#=/^good translations$/#>,#=/^test translations$/#> {
+ if ($0 !~ #=/^good translations$|^test translations$/#>) {
+ istranslation[$0]=1
+ }
+ next
+ }
+
+{ if (istranslation[$0]!=1) {
+ print "Error:", $0, "is not a valid translation"
+ exitcode = -1
+ }
+}
+
+END {
+ exit exitcode
+ }
+# This is a copy of {\tt transcheck.list}, which should be the first
+part of the input to {\tt transcheck.awk}.
+Since \.{TANGLE} will insert its own stuff, we can't use it.
+{\tt transcheck.awk} {\em could} be updated to work with the
+tangled output, though, if it seemed desirable.
+#(junk.list#>=
+good translations
+break_space
+force
+big_force
+opt
+backup
+big_cancel
+cancel
+indent
+outdent
+math_rel
+math_bin
+math_op
+test translations
+
+#*=Index.
+This is a combined index to {\tt SPIDER} and the {\tt SPIDER} tools.
+Since the {\tt SPIDER} tools are nearly trivial, it's really just
+{\tt SPIDER}.
+
+
diff --git a/web/spiderweb/src/master/tangle.web b/web/spiderweb/src/master/tangle.web
new file mode 100644
index 0000000000..26266034ca
--- /dev/null
+++ b/web/spiderweb/src/master/tangle.web
@@ -0,0 +1,1800 @@
+% Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+% Not to be sold, but may be used freely for any purpose
+% For more information, see file COPYRIGHT in the parent directory
+
+% This file is part of Spidery WEB
+
+% This program by Norman Ramsey is based on programs Silvio Levy
+% and D. E. Knuth. Silvio Levy wrote most of the code.
+% It is distributed WITHOUT ANY WARRANTY, express or implied.
+% Dec 1987
+
+% Here is TeX material that gets inserted after \input webmac
+
+\message{OK, entering \string\batchmode...}
+\batchmode
+
+\def\hang{\hangindent 3em\indent\ignorespaces}
+\font\ninerm=cmr9
+\let\mc=\ninerm % medium caps
+\def\cee{C}
+\def\pb{$\.|\ldots\.|$} % C brackets (|...|)
+\def\v{\char'174} % vertical (|) in typewriter font
+\def\ceeref{{\it The C Reference Manual}}
+\mathchardef\RA="3221 % right arrow
+\mathchardef\BA="3224 % double arrow
+
+\def\title{Spidery TANGLE}
+\def\contentspagenumber{1} % should be odd
+\def\topofcontents{\null\vfill
+ \titlefalse % include headline on the contents page
+ \def\rheader{\hfil}
+ \centerline{\titlefont The {\ttitlefont Spidery TANGLE} processor}
+ \vfill
+}
+
+@* Introduction.
+\.{TANGLE} has a fairly straightforward outline. It operates in
+two phases: first it reads the source file, saving the \cee\ code in
+compressed form; then outputs the code, after shuffling it around.
+It can be compiled
+with certain optional flags, |DEBUG| and |STAT|, the latter being used
+to keep track of how much of \.{TANGLE}'s resources were actually used.
+
+@u
+@<Include files@>@;
+@<Common code for \.{WEAVE} and \.{TANGLE}@>@;
+@<Typedef declarations@>@;
+@<Global variables@>@;
+
+main (ac, av)
+char **av;
+{
+ argc=ac; argv=av;
+ program=tangle;
+ @<Set initial values@>;
+ common_init();
+ printf(banner); /* print a ``banner line'' */
+ phase_one(); /* read all the user's text and compress it into |tok_mem| */
+ phase_two(); /* output the contents of the compressed tables */
+ wrap_up();
+}
+
+@ The following parameters were sufficient in the original \.{TANGLE} to
+handle \TeX, so they should be sufficient for most applications of \.{TANGLE}.
+
+If you change |max_bytes|, |max_names| or |hash_size| you should also
+change them in the file |"common.web"|.
+
+@d max_bytes = 90000 /* the number of bytes in identifiers,
+ index entries, and module names; used in |"common.web"| */
+@d max_toks = 150000 /* number of bytes in compressed \cee\ code */
+@d max_names = 4000 /* number of identifiers, strings, module names;
+ must be less than 10240; used in |"common.web"| */
+@d max_texts = 2000 /* number of replacement texts, must be less than 10240 */
+@d hash_size = 353 /* should be prime; used in |"common.web"| */
+@d longest_name = 400 /* module names shouldn't be longer than this */
+@d stack_size = 50 /* number of simultaneous levels of macro expansion */
+@d buf_size = 100 /* for \.{WEAVE} and \.{TANGLE} */
+
+@i common.h
+
+@ Should include tlang.web but can't because AWK runs out of files.
+
+@* Data structures exclusive to {\tt TANGLE}.
+We've already seen that the |byte_mem| array holds the names of identifiers,
+strings, and modules;
+the |tok_mem| array holds the replacement texts
+for modules. Allocation is sequential, since things are deleted only
+during Phase II, and only in a last-in-first-out manner.
+
+A \&{text} variable is a structure containing a pointer into
+|tok_mem|, which tells where the corresponding text starts, and an
+integer |text_link|, which, as we shall see later, is used to connect
+pieces of text that have the same name. All the \&{text}s are stored in
+the array |text_info|, and we use a |text_pointer| variable to refer
+to them.
+
+The first position of |tok_mem| that is unoccupied by
+replacement text is called |tok_ptr|, and the first unused location of
+|text_info| is called |text_ptr|. Thus we usually have the identity
+|text_ptr->tok_start=tok_ptr|.
+
+If your machine does not support |char unsigned| you should change
+the definition of \&{eight\_bits} to |short unsigned|.
+@^system dependencies@>
+
+@<Typed...@>=
+typedef struct {
+ eight_bits *tok_start; /* pointer into |tok_mem| */
+ sixteen_bits text_link; /* relates replacement texts */
+} text;
+typedef text *text_pointer;
+
+@ @<Glob...@>=
+text text_info[max_texts];
+text_pointer text_info_end=text_info+max_texts-1;
+text_pointer text_ptr; /* first unused position in |text_info| */
+eight_bits tok_mem[max_toks];
+eight_bits *tok_mem_end=tok_mem+max_toks-1;
+eight_bits *tok_ptr; /* first unused position in |tok_mem| */
+
+@ @<Set init...@>=
+text_info->tok_start=tok_ptr=tok_mem;
+text_ptr=text_info+1; text_ptr->tok_start=tok_mem;
+ /* this makes replacement text 0 of length zero */
+
+@ If |p| is a pointer to a module name, |p->equiv| is a pointer to its
+replacement text, an element of the array |text_info|.
+
+@d equiv = equiv_or_xref /* info corresponding to names */
+
+@ @<Set init...@>=
+name_dir->equiv=(ASCII *)text_info; /* the undefined module has no replacement text */
+
+@ Here's the procedure that decides whether a name of length |l|
+starting at position |first| equals the identifier pointed to by |p|:
+
+@u
+names_match(p,first,l)
+name_pointer p; /* points to the proposed match */
+ASCII *first; /* position of first character of string */
+int l; /* length of identifier */
+{
+ if (length(p)!=l) return 0;
+ return !strncmp(first,p->byte_start,l);
+}
+
+@
+@u
+init_node(node)
+name_pointer node;
+{
+ node->equiv=(ASCII *)text_info;
+
+}
+init_p(p,t)
+name_pointer p;
+eight_bits t;
+{
+ p->ilk=t;
+}
+
+
+
+@*Tokens.
+ Replacement
+ texts, which represent \cee\ code in a compressed format,
+appear in |tok_mem| as mentioned above. The codes in
+these texts are called `tokens'; some tokens occupy two consecutive
+eight-bit byte positions, and the others take just one byte.
+
+If $p$ points to a replacement text, |p->tok_start| is the |tok_mem| position
+of the first eight-bit code of that text. If |p->text_link=0|,
+this is the replacement text for a macro, otherwise it is the replacement
+text for a module. In the latter case |p->text_link| is either equal to
+|module_flag|, which means that there is no further text for this module, or
+|p->text_link| points to a continuation of this replacement text; such
+links are created when several modules have \cee\ texts with the same
+name, and they also tie together all the \cee\ texts of unnamed modules.
+The replacement text pointer for the first unnamed module appears in
+|text_info->text_link|, and the most recent such pointer is |last_unnamed|.
+
+@d module_flag = max_texts /* final |text_link| in module replacement texts */
+
+@<Glob...@>=
+text_pointer last_unnamed; /* most recent replacement text of unnamed module */
+
+@ @<Set init...@>= last_unnamed=text_info; text_info->text_link=0;
+
+@ If the first byte of a token is less than |@'200|, the token occupies a
+single byte. Otherwise we make a sixteen-bit token by combining two consecutive
+bytes |a| and |b|. If |@'200<=a<@'250|, then |(a-@'200)@t${}\times2^8$@>+b|
+to an identifier; if |@'250<=a<@'320|, then
+|(a-@'250)@t${}\times2^8$@>+b| points to a module name; otherwise, i.e., if
+|@'320<=a<@'400|, then |(a-@'320)@t${}\times2^8$@>+b| is the number of the module
+in which the current replacement text appears.
+
+Codes less than @'200 are 7-bit ASCII codes that represent themselves.
+In particular, a single-character identifier like `|x|' will be a one-byte
+token, while all longer identifiers will occupy two bytes.
+
+Some of the 7-bit ASCII codes will not be present, however, so we can
+use them for special purposes. The following symbolic names are used:
+
+\yskip \hang |join| denotes the concatenation of adjacent items with no
+space or line breaks allowed between them (the \.{@@\&} operation of \.{WEB}).
+
+\hang |string| denotes the beginning or end of a string, verbatim
+construction or numerical constant.
+@^ASCII code@>
+
+@d string = @'2
+@d param = @'7
+@d join = @'177 /* ASCII delete will not appear */
+
+@ The following procedure is used to enter a two-byte value into
+|tok_mem| when a replacement text is being generated.
+
+@u store_two_bytes(x)
+sixteen_bits x;
+{
+ if (tok_ptr+2>tok_mem_end) overflow("token");
+ *tok_ptr++=x>>8; /* store high byte */
+ *tok_ptr++=x&@'377; /* store low byte */
+}
+
+
+@* Stacks for output. The output process uses a stack to keep track
+of what is going on at different ``levels'' as the modules are being
+written out. Entries on this stack have five parts:
+
+\yskip\hang |end_field| is the |tok_mem| location where the replacement
+text of a particular level will end;
+
+\hang |byte_field| is the |tok_mem| location from which the next token
+on a particular level will be read;
+
+\hang |name_field| points to the name corresponding to a particular level;
+
+\hang |repl_field| points to the replacement text currently being read
+at a particular level.
+
+\hang |mod_field| is the module number, or zero if this is a macro.
+
+\yskip\noindent The current values of these five quantities are referred to
+quite frequently, so they are stored in a separate place instead of in
+the |stack| array. We call the current values |cur_end|, |cur_byte|,
+|cur_name|, |cur_repl|, and |cur_mod|.
+
+The global variable |stack_ptr| tells how many levels of output are
+currently in progress. The end of all output occurs when the stack is
+empty, i.e., when |stack_ptr=stack|.
+
+@<Typed...@>=
+typedef struct {
+ eight_bits *end_field; /* ending location of replacement text */
+ eight_bits *byte_field; /* present location within replacement text */
+ name_pointer name_field; /* |byte_start| index for text being output */
+ text_pointer repl_field; /* |tok_start| index for text being output */
+ sixteen_bits mod_field; /* module number or zero if not a module */
+} output_state;
+typedef output_state *stack_pointer;
+
+@ @d cur_end = cur_state.end_field /* current ending location in |tok_mem| */
+@d cur_byte = cur_state.byte_field /* location of next output byte in |tok_mem|*/
+@d cur_name = cur_state.name_field /* pointer to current name being expanded */
+@d cur_repl = cur_state.repl_field /* pointer to current replacement text */
+@d cur_mod = cur_state.mod_field /* current module number being expanded */
+
+@<Global...@>=
+output_state cur_state; /* |cur_end|, |cur_byte|, |cur_name|, |cur_repl|
+ and |cur_mod| */
+output_state stack[stack_size+1]; /* info for non-current levels */
+stack_pointer stack_ptr; /* first unused location in the output state stack */
+stack_pointer stack_end=stack+stack_size; /* end of |stack| */
+
+@ To get the output process started, we will perform the following
+initialization steps. We may assume that |text_info->text_link| is nonzero,
+since it points to the \cee\ text in the first unnamed module that generates
+code; if there are no such modules, there is nothing to output, and an
+error message will have been generated before we do any of the initialization.
+
+@<Initialize the output stacks@>=
+stack_ptr=stack+1; cur_name=name_dir; cur_repl=text_info->text_link+text_info;
+cur_byte=cur_repl->tok_start; cur_end=(cur_repl+1)->tok_start; cur_mod=0;
+
+@ When the replacement text for name |p| is to be inserted into the output,
+the following subroutine is called to save the old level of output and get
+the new one going.
+
+We assume that the C compiler can copy structures.
+@^system dependencies@>
+
+@u push_level(p) /* suspends the current level */
+name_pointer p;
+{
+ @<Trace the name of what's pushed (|#ifdef TRACE_MACROS|)@>;
+ if (stack_ptr==stack_end) overflow("stack");
+ *stack_ptr=cur_state;
+ stack_ptr++;
+ cur_name=p; cur_repl=(text_pointer)p->equiv;
+ cur_byte=cur_repl->tok_start; cur_end=(cur_repl+1)->tok_start;
+ cur_mod=0;
+}
+
+@ @<Trace the name of what's pushed (|#ifdef TRACE_MACROS|)@>=
+#ifdef TRACE_MACROS
+ if (tracing>0) {
+ printf("\nPushing "); print_id(p);
+ printf(" =nd[%d]",p-name_dir);
+ }
+#endif TRACE_MACROS
+
+@ When we come to the end of a replacement text, the |pop_level| subroutine
+does the right thing:
+It either moves to the continuation of this replacement
+text or returns the state to the most recently stacked level.
+If this level is the end of a macro definition, it pops all the parameters
+off the stack.
+
+@u pop_level() /* do this when |cur_byte| reaches |cur_end| */
+{ int number_of_parameters;
+@<Trace the name of what's popped (|#ifdef TRACE_MACROS|)@>;
+ if (cur_repl->text_link==0) { /* macro definition */
+ if (cur_name->ilk==macro) {
+ @<Pop the parameters from the parameter stack@>;
+ }
+ } else if (cur_repl->text_link<module_flag) { /* link to a continuation */
+ cur_repl=cur_repl->text_link+text_info; /* stay on the same level */
+ cur_byte=cur_repl->tok_start; cur_end=(cur_repl+1)->tok_start;
+ return;
+ }
+ stack_ptr--; /* go down to the previous level */
+ if (stack_ptr>stack) cur_state=*stack_ptr;
+}
+
+
+@ @<Pop the parameters...@>=
+number_of_parameters=*(cur_repl->tok_start);
+@<Trace number of parms popped (|#ifdef TRACE_MACROS|)@>;
+while (number_of_parameters-->0) {
+ name_ptr--; text_ptr--;
+#ifdef TRACE_MACROS
+byte_ptr-=2;
+#endif TRACE_MACROS
+ }
+#ifdef STAT
+#ifdef STAT_HAS_BEEN_FIXED
+ if (tok_ptr>max_tok_ptr) max_tok_ptr = tok_ptr;
+ /* maximum value of |tok_ptr| occurs just before
+ parameter popping */
+#endif STAT_HAS_BEEN_FIXED
+#endif STAT
+tok_ptr = text_ptr->tok_start;
+
+
+@ @<Trace number of parms popped (|#ifdef TRACE_MACROS|)@>=
+#ifdef TRACE_MACROS
+if (tracing>1) {
+ printf("\nUnstacking %d parameters",number_of_parameters);
+ }
+#endif TRACE_MACROS
+@ @<Trace the name of what's popped (|#ifdef TRACE_MACROS|)@>=
+#ifdef TRACE_MACROS
+ if (tracing>0) {
+ printf("\nPopping "); print_id(cur_name);
+ printf(" =nd[%d]",cur_name-name_dir);
+ }
+
+#endif TRACE_MACROS
+
+
+
+@*1 Expanding macros.
+ The heart of the output procedure is the |get_output| routine, which produces
+the next token of output that is not a reference to a macro. This procedure
+handles all the stacking and unstacking that is necessary.
+
+@ Before we can get on to |get_output|,
+we have to talk about expanding macros.
+Macro parameters must be stacked.
+They are placed in |tok_mem| just
+above the other replacement texts, and dummy parameter ``names'' are
+placed in |byte_start| just after the other names.
+The variables |text_ptr| and |tok_ptr| essentially serve
+as parameter stack pointers during the output phase, so there is
+no need for a separate data structure to handle this problem.
+
+
+@ Here are our invariants (assuming $\#$ represents |param|):
+(1) in a replacement text, $\#n$ always refers to |*(name_ptr-n)|.
+(2) when a parameter is scanned, any $\#n$ are replaced with references
+to the appropriate name, so that the replacement text for a parameter
+never contains a $\#n$.
+(3) |name_ptr| is not changed until all the parameters are scanned;
+otherwise invariant (1) wouldn't work during parameter scanning.
+(4) when all parameters are scanned, |name_ptr| is moved
+so that $\#n$ in the replacement text will be interpreted correctly.
+(5) When we have finished scanning the replacement text for a macro, we
+have to pop |name_ptr| to maintain the invariant in (1).
+
+@ |get_output| returns the value |module_number|
+if the next output begins or ends the replacement text of some module,
+in which case |cur_val| is that module's number (if beginning) or the
+negative of that value (if ending). (A module number of 0 indicates
+not the beginning or ending of a module, but a \&{\#line} command.)
+And it returns the value |identifier|
+if the next output is an identifier of length two or more, in which case
+|cur_val| points to that identifier name.
+
+@d module_number = @'201 /* code returned by |get_output| for module numbers */
+@d identifier = @'202
+@<Global...@>=
+int cur_val; /* additional information corresponding to output token */
+
+
+@ If |get_output| finds that no more output remains, it returns the value zero.
+@u sixteen_bits
+get_output() /* returns next token after macro expansion */
+{
+ sixteen_bits a; /* value of current byte */
+ restart: if (stack_ptr==stack) return 0;
+ if (cur_byte==cur_end) {
+ cur_val=-((int)cur_mod); /* cast needed because of sign extension */
+ pop_level();
+ if (cur_val==0) goto restart;
+ out_char(module_number); return;
+ }
+ a=*cur_byte++;
+ if (a<@'200)
+ if(a==param) {
+ @<Trace parameter number (|#ifdef TRACE_MACROS|)@>;
+ @<Get the parameter number, set up to substitute
+ that parameter, and go to |restart|@>;
+ } else
+ out_char(a); /* one-byte token */
+ else {
+ a=(a-@'200)*@'400+*cur_byte++;
+ switch (a/@'24000) { /* |@'24000=(@'250-@'200)*@'400| */
+ case 0:
+ @<If |a| is a macro, set it up and go to |restart|@>;
+ cur_val=a; out_char(identifier); break;
+ case 1: @<Expand module |a-@'24000|, |goto restart|@>;
+ default: cur_val=a-@'50000; if (cur_val>0) cur_mod=cur_val;
+ out_char(module_number);
+ }
+ }
+ return 1;
+}
+
+
+@ @<Get the parameter number...@>=
+push_level(name_ptr-*cur_byte++); goto restart;
+@ @<Trace parameter number...@>=
+#ifdef TRACE_MACROS
+if (tracing>2) {
+ printf (" [#%d]",*cur_byte);
+ }
+#endif TRACE_MACROS
+
+@ @<If |a| is a macro...@>=
+if (name_dir[a].ilk==macro) {
+ @<Trace macro expansion (|#ifdef TRACE_MACROS|)@>;
+ @<Scan the parameters (if any) and stack them,
+ or go to |restart| if an error occurs@>;
+ push_level(name_dir+a);
+ cur_byte++; /* skip number of parameters */
+ goto restart;
+} else if (name_dir[a].ilk==simple) {
+ @<Trace parameter expansion (|#ifdef TRACE_MACROS|)@>;
+ push_level(name_dir+a);
+ goto restart;
+}
+
+@ @<Trace macro expansion (|#ifdef TRACE_MACROS|)@>=
+#ifdef TRACE_MACROS
+if (tracing>2) {
+ printf("\nExpanding macro ("); print_id(name_dir+a);
+ printf("=nd[%d])",a);
+ }
+#endif TRACE_MACROS
+
+@ @<Trace parameter expansion (|#ifdef TRACE_MACROS|)@>=
+#ifdef TRACE_MACROS
+if (tracing>2) {
+ printf("\nExpanding parameter ("); print_id(name_dir+a);
+ printf("=nd[%d])",a);
+ }
+#endif TRACE_MACROS
+
+
+@ @<Scan the parameters...@>=
+{int number_of_parameters;
+ while (cur_byte==cur_end && stack_ptr>stack) pop_level();
+ number_of_parameters = *(((text_pointer)name_dir[a].equiv)->tok_start);
+ if (number_of_parameters>0) {
+ if (stack_ptr==stack || *cur_byte!=@`(') {
+ printf("\n! No parameters given for ");
+ print_id(a+name_dir);
+ err_print("");
+ goto restart;
+ }
+ cur_byte++; /* skip left parenthesis */
+ parm_ptr = name_ptr; /* maintain |name_ptr| invariant */
+ while (number_of_parameters-->0) {
+ @<Stack a parameter ending in
+ comma or parenthesis@>;
+ }
+ name_ptr=parm_ptr; /* we are about to |push_level|,
+ so this maintains the |name_ptr| invariant */
+ }
+}
+
+@ In scanning parameter lists, we require that parameters be separated
+by commas, and that parentheses balance in parameters.
+The balancing is done with the array |balances|, and {\tt SPIDER}
+could easily be extended to make certain tokens {\tt balance left} and
+other tokens {\tt balance right}, so that {\tt left} and {\tt right}
+tokens balance in parameters.
+@ @<Global variables@>=
+short balances[@'200];
+@ @<Set initial values@>=
+{ int i;
+for (i=0;i<@'200;i++) balances[i]=0;
+@<Set special |balances|@>;
+}
+@ Eventually we will want {\tt SPIDER} to set balances.
+For now let's try just tossing in parenthesis, braces, and square brackets.
+@<Set special |balances|@>=
+balances[@`(']=1;
+balances[@`)']=-1;
+balances[@`[']=1;
+balances[@`]']=-1;
+balances[@`{']=1;
+balances[@`}']=-1;
+
+@ @<Stack a parameter...@>=
+{ int bal; /* used to balance parentheses in parameter lists */
+ eight_bits b, oldb;
+ sixteen_bits c;
+bal=0;
+@<Trace scanning for stack (|#ifdef TRACE_MACROS|)@>;
+while (1) {
+ b=*cur_byte++;
+ if (b==param) { /* convert to name reference */
+ b=*cur_byte++;
+ @<Trace parameter scansion (|#ifdef TRACE_MACROS|)@>;
+ c=name_ptr-name_dir-b; /* |name_ptr-b| points to parm */
+ app_repl(@'200 + (c/@'400));
+ app_repl(c % @'400);
+ } else {
+ if (b>=@'200) {
+ @<Trace scansion of token in |b| (|#ifdef TRACE_MACROS|)@>;
+ app_repl(b);
+ b=*cur_byte++;
+ } else if (bal==0 && ((number_of_parameters==0 && b==@`)')
+ || (number_of_parameters>0 && b==@`,'))) {
+ goto done;
+ } else if (@<|b| opens verbatim or string@>) {
+ @<Copy verbatim or string token list beginning with |b|@>;
+ } else {
+ @<Trace scansion of ordinary token in |b|@>;
+ bal += balances[b];
+ }
+ app_repl(b);
+ }
+}
+done:
+parm_ptr->equiv=(ASCII *)text_ptr;
+text_ptr->text_link=0; /* label a macro */
+parm_ptr->ilk=simple; /* treat parm \# like simple macro */
+#ifdef TRACE_MACROS
+if(byte_ptr+2>=byte_mem_end) overflow("byte memory");
+*byte_ptr++=@`#'; *byte_ptr++=number_of_parameters+1+@`0';
+#endif TRACE_MACROS
+if (parm_ptr>=name_dir_end) overflow ("name");
+(++parm_ptr)->byte_start=byte_ptr;
+ if (text_ptr>=text_info_end) overflow("text");
+ (++text_ptr)->tok_start=tok_ptr;
+@<Trace stacking the parameter (|#ifdef TRACE_MACROS|)@>;
+}
+
+@ @<Global variables@>=
+name_pointer parm_ptr; /* used while stacking parameters */
+
+@ @<|b| opens verbatim or string@>=(b==string||b==constant)
+@ @<Copy verbatim or string...@>=
+app_repl(b);
+oldb=b;
+@<Write |" <"| (|#ifdef TRACE_MACROS|)@>;
+while((b=*cur_byte++)!=oldb) {
+@<Trace scansion of character |b| (|#ifdef TRACE_MACROS|)@>;
+ app_repl(b);
+ if (cur_byte>=cur_end)
+ confusion("string or constant didn't end in token list");
+}
+@<Write |">"| (|#ifdef TRACE_MACROS|)@>;
+
+
+
+@ @<Write |" <"| (|#ifdef TRACE_MACROS|)@>=
+#ifdef TRACE_MACROS
+if(tracing>2) printf(" <");
+#endif TRACE_MACROS
+@ @<Trace scansion of character |b| (|#ifdef TRACE_MACROS|)@>=
+#ifdef TRACE_MACROS
+if (tracing>2) printf("%c",b);
+#endif TRACE_MACROS
+@ @<Write |">"| (|#ifdef TRACE_MACROS|)@>=
+#ifdef TRACE_MACROS
+if(tracing>2) printf(">");
+#endif TRACE_MACROS
+@ @<Trace parameter scansion (|#ifdef TRACE_MACROS|)@>=
+#ifdef TRACE_MACROS
+if (tracing>2) {
+ printf (" <#%d=",b); print_id(name_ptr-b); printf("=nd[%d]>",
+ name_ptr-b-name_dir);
+ }
+#endif TRACE_MACROS
+
+@ @<Trace scansion of token in |b| (|#ifdef TRACE_MACROS|)@>=
+#ifdef TRACE_MACROS
+if (tracing>2) {
+ int c;
+ printf (" <");
+ c=(b-@'200)*@'400+*cur_byte;
+ switch (c/@'24000) {
+ case 0: print_id(name_dir+c);
+ printf(" =nd[%d]",c);
+ break;
+ case 1: printf("MODULE"); break;
+ default: printf("CONTEXT"); break;
+ }
+ printf(">");
+}
+#endif TRACE_MACROS
+
+@ @<Trace scansion of ordinary token in |b|@>=
+#ifdef TRACE_MACROS
+if (tracing>2) {
+ printf (" <");
+ if (@'37<b && b<@'177) printf("%c",b);
+ printf(">");
+}
+#endif TRACE_MACROS
+
+@ @<Trace scanning for stack (|#ifdef TRACE_MACROS|)@>=
+#ifdef TRACE_MACROS
+if (tracing>2) {
+ printf ("\nScanning #%d...", number_of_parameters+1);
+ }
+#endif TRACE_MACROS
+@ @<Trace stacking the parameter (|#ifdef TRACE_MACROS|)@>=
+#ifdef TRACE_MACROS
+if (tracing>1) {
+ printf ("\nStacked "); print_id(parm_ptr-1);
+ printf ("=nd[%d]", parm_ptr-1-name_dir);
+ }
+#endif TRACE_MACROS
+
+@ The user may have forgotten to give any \cee\ text for a module name,
+or the \cee\ text may have been associated with a different name by mistake.
+
+@<Expand module |a-...@>=
+ a-=@'24000;
+ if ((a+name_dir)->equiv!=(ASCII *)text_info) push_level(a+name_dir);
+ else if (a!=0) {
+ printf("\n! Not present: <"); print_id(a+name_dir); err_print(">");
+@.Not present: <section name>@>
+ }
+ goto restart;
+
+@* Producing the output.
+The |get_output| routine above handles most of the complexity of output
+generation, but there is one further consideration that has a nontrivial
+effect on \.{TANGLE}'s algorithms. Namely,
+we want to make sure that the output has spaces and line breaks in
+the right places (e.g., not in the middle of a string or a constant or an
+identifier, not at a `\.{@@\&}' position
+where quantities are being joined together, and certainly after a \.=
+because the C compiler thinks \.{=-} is ambiguous).
+
+The output process can be in one of following states:
+
+\yskip\hang |num_or_id| means that the last item in the buffer is a number or
+identifier, hence a blank space or line break must be inserted if the next
+item is also a number or identifier.
+
+\yskip\hang |unbreakable| means that the last item in the buffer was followed
+by the \.{@@\&} operation that inhibits spaces between it and the next item.
+
+\yskip\hang |verbatim| means we're copying only character tokens, and
+that they are to be output exactly as stored. This is the case during
+strings, verbatim constructions and numerical constants.
+
+\yskip\hang |misc| means none of the above.
+
+\yskip Furthermore, if the variable |protect| is positive, new-lines
+are preceded by a `\.\\'.% note this for /*spider*/
+
+@d misc = 0 /* ``normal'' state */
+@d num_or_id = 1 /* state associated with numbers and identifiers */
+@d unbreakable = 3 /* state associated with \.{@@\&} */
+@d verbatim = 4 /* state in the middle of a string */
+
+@<Global...@>=
+eight_bits out_state; /* current status of partial output */
+boolean protect; /* current status of partial output */
+
+@ Here is a routine that is invoked when we want to output the current line.
+During the output process, |cur_line| equals the number of the next line
+to be output.
+
+@u flush_buffer() /* writes one line to output file */
+{
+ C_putc('\n');
+ if (cur_line % 100 == 0) {
+ printf(".");
+ if (cur_line % 500 == 0) printf("%d",cur_line);
+ update_terminal; /* progress report */
+ }
+ cur_line++;
+}
+
+@* The big output switch. Here then is the routine that does the
+output.
+We have made some modifications to \.{TANGLE} so it will write output
+on multiple files.
+We do this very simply: if a module name is introduced by \.{@@(}
+instead of \.{@@<}, we treat it as the name of a file.
+All these special modules are saved on a stack, |output_files|.
+We write them out after we've done the unnamed module.
+
+@d max_files = 256
+@<Glob...@>=
+name_pointer output_files[max_files];
+name_pointer *cur_out_file, *end_output_files, *an_output_file;
+char cur_module_char; /* is it |'<'| or |'('| */
+char output_file_name[longest_name]; /* name of the file */
+
+@ We make |end_output_files| point jsut beyond the end of
+|output_files|.
+|cur_out_file| starts out there. Every time we see a new file, we
+decrement |cur_out_file| and then write it in.
+@<Set initial...@>=
+cur_out_file=end_output_files=output_files+max_files;
+
+@ @<If it's not there, add |cur_module| to the output file stack, or
+complain we're out of room@>=
+{
+if (cur_out_file>output_files) {
+ for (an_output_file=cur_out_file;
+ an_output_file<end_output_files; an_output_file++)
+ if (*an_output_file==cur_module) break;
+ if (an_output_file==end_output_files)
+ *--cur_out_file=cur_module;
+} else {
+ overflow("output files");
+}
+}
+
+@ Here is the output switch, then...
+
+@u
+phase_two () {
+ cur_line=1;
+ if (text_info->text_link==0) {
+ if(end_output_files==cur_out_file) {
+ printf("\n! No program text was specified."); mark_harmless;
+@.No output was specified@>
+ }
+ } else {
+ printf("\nWriting the output files: (%s)",C_file_name); update_terminal;
+ @<Initialize the output stacks@>;
+ while (stack_ptr>stack) get_output();
+ flush_buffer();
+ }
+ if (end_output_files>cur_out_file) {
+ if(text_info->text_link==0) {
+ printf("\nWriting the output files: "); update_terminal;
+ }
+ @<Write all the named output files@>@;
+ }
+ printf("\nDone.");
+}
+
+@ To write the named output files, we proceed as for the unnamed
+module.
+The only subtlety is that we have to open each one.
+@<Write all the named output files@>=
+for (an_output_file=end_output_files; an_output_file>cur_out_file;) {
+ an_output_file--;
+ strncpy(output_file_name,(*an_output_file)->byte_start, longest_name);
+ output_file_name[length(*an_output_file)]='\0';
+ fclose(C_file);
+ C_file=fopen(output_file_name,"w");
+ if (C_file == NULL) {
+ fatal("! Cannot open output file:",output_file_name)@;
+ } else {
+ printf(" (%s)",output_file_name); update_terminal;
+ }
+ stack_ptr=stack+1;
+ cur_name= (*an_output_file);
+ cur_repl= (text_pointer) cur_name->equiv_or_xref;
+ cur_byte=cur_repl->tok_start;
+ cur_end=(cur_repl+1)->tok_start;
+ cur_mod=0;
+ while (stack_ptr > stack) get_output();
+ flush_buffer();
+}
+
+
+
+@ A many-way switch is used to send the output:
+
+@u out_char(cur_char)
+eight_bits cur_char;
+{
+ ASCII *j; /* pointer into |byte_mem| */
+ @<Trace |cur_char| (|#ifdef TRACE_MACROS|)@>;
+ switch (cur_char) {
+ case @`\n': if (protect) C_putc(' '); /*spider*/
+ if (protect || out_state==verbatim) C_putc('\\'); /*spider*/
+ /*spider*/ /*may need to escape newlines*/
+ flush_buffer(); if (out_state!=verbatim) out_state=misc; break;
+ @/@t\4@>@<Case of an identifier@>;
+ @/@t\4@>@<Case of a module number@>;
+ @<Cases for tokens to be output@>@;
+ case join: out_state=unbreakable; break;
+ case constant: if (out_state==verbatim) {
+ out_state=num_or_id; break;
+ }
+ if(out_state==num_or_id) C_putc(' '); out_state=verbatim; break;
+ case string: if (out_state==verbatim) out_state=misc;
+ else out_state=verbatim; break;
+ default: C_putc(cur_char); if (out_state!=verbatim) out_state=misc;
+ break;
+ }
+}
+
+@ @<Trace |cur_char| (|#ifdef TRACE_MACROS|)@>=
+#ifdef TRACE_MACROS
+if (tracing>2) {
+ switch(cur_char) {
+ case @`\n': printf(" [\\n]"); break;
+ case string:
+ printf( "[STRING]"); break;
+ case join:
+ printf( "[JOIN]"); break;
+ case constant:
+ printf( "[CONSTANT]"); break;
+ case identifier:
+ printf (" ["); print_id(cur_val+name_dir); printf("]");
+ break;
+ case module_number:
+ if (cur_val>0) {
+ printf(" [%d:]", cur_val);
+ } else if(cur_val<0) {
+ printf(" [:%d]", - cur_val);
+ } else {
+ printf( "[LINE NUMBER]");
+ }
+ break;
+
+ default:
+ if (@'37<cur_char && cur_char < @'177) {
+ printf (" [%c]", cur_char);
+ } else {
+ printf(" [\\%3o]",cur_char);
+ }
+ }
+}
+#endif TRACE_MACROS
+
+
+
+
+@ @<Case of an identifier@>=
+case identifier:
+ if (out_state==num_or_id) C_putc(' ');
+ for (j=(cur_val+name_dir)->byte_start; j<(name_dir+cur_val+1)->byte_start;
+ j++) C_putc(*j);
+ out_state=num_or_id; break;
+
+@ @<Case of a mod...@>=
+case module_number:
+ if (cur_val>0) {
+ C_printf("%s",begin_comment_string);
+ C_printf("%d:",cur_val);
+ C_printf("%s",end_comment_string);
+ } else if(cur_val<0) {
+ C_printf("%s",begin_comment_string);
+ C_printf(":%d",-cur_val);
+ C_printf("%s",end_comment_string);
+ } else {
+ sixteen_bits a;
+ a=@'400* *cur_byte++;
+ a+=*cur_byte++; /* gets the line number */
+ C_printf("\n%s",sharp_line_open);
+ C_printf(" %d \"",a);
+ cur_val=*cur_byte++;
+ cur_val=@'400*(cur_val-@'200)+ *cur_byte++; /* points to the file name */
+ for (j=(cur_val+name_dir)->byte_start; j<(name_dir+cur_val+1)->byte_start;
+ j++) C_putc(*j);
+ C_printf("\"%s\n",sharp_line_close);
+ }
+ break;
+
+@i outtoks.web
+@* Introduction to the input phase.
+We have now seen that \.{TANGLE} will be able to output the full
+\cee\ program, if we can only get that program into the byte memory in
+the proper format. The input process is something like the output process
+in reverse, since we compress the text as we read it in and we expand it
+as we write it out.
+
+There are three main input routines. The most interesting is the one that gets
+the next token of a \cee\ text; the other two are used to scan rapidly past
+\TeX\ text in the \.{WEB} source code. One of the latter routines will jump to
+the next token that starts with `\.{@@}', and the other skips to the end
+of a \cee\ comment.
+
+@ Control codes in \.{WEB} begin with `\.{@@}', and the next character
+identifies the code. Some of these are of interest only to \.{WEAVE},
+so \.{TANGLE} ignores them; the others are converted by \.{TANGLE} into
+internal code numbers by the |control_code| table below. The ordering
+of these internal code numbers has been chosen to simplify the program logic;
+larger numbers are given to the control codes that denote more significant
+milestones.
+
+@d ignore = 0 /* control code of no interest to \.{TANGLE} */
+@d octal = @'5
+@d hex = @'6
+@d trace = @'370
+@d ascii_constant = @'371 /* control code for `\.{@@`}' */
+@d control_text = @'372 /* control code for `\.{@@t}', `\.{@@\^}', etc. */
+@d format = @'373 /* control code for `\.{@@f}' */
+@d definition = @'374 /* control code for `\.{@@d}' */
+@d begin_unnamed = @'375 /* control code for `\.{@@u}' */
+@d module_name = @'376 /* control code for `\.{@@<}' */
+@d new_module = @'377 /* control code for `\.{@@\ }' and `\.{@@*}' */
+
+@<Global...@>=
+eight_bits ccode[128]; /* meaning of a char following \.{@@} */
+
+@ @<Set ini...@>= {
+ int c; /* must be |int| so the |for| loop will end */
+ for (c=0; c<=127; c++) ccode[c]=ignore;
+ ccode[' ']=ccode[tab_mark]=ccode['*']=new_module;
+ ccode ['@@'] = '@@';
+ ccode['=']=string;
+ ccode['d']=ccode['D']=definition;
+ ccode['f']=ccode['F']=format;
+ ccode['c']=ccode['C']=begin_unnamed;
+ ccode['u']=ccode['U']=begin_unnamed;
+ ccode['^']=ccode[':']=ccode['.']=ccode['t']=ccode['T']=control_text;
+ ccode['&']=join;
+ ccode['<']=ccode['(']=module_name;
+ ccode['`']=ascii_constant;
+ ccode['\'']=octal;
+ ccode['"']=hex;
+/*Now adjust for |at_sign|... if it is @@, we have no-op followed by quoting */
+/* ... but if it is other, say \#, then \#@@ replaces @@\#, and \#\#
+ quotes itself*/
+ccode['@@']=ccode[at_sign];
+ccode[at_sign]=at_sign;
+
+#ifdef DEBUG
+ccode['0']=ccode['1']=ccode['2']=ccode['3']=ccode['4']=trace;
+#endif DEBUG
+
+}
+
+@ We may want some sort of tracing facility:
+@<Global variables@>=short tracing;
+@ @<Set initial...@>=tracing=0;
+
+@ The |skip_ahead| procedure reads through the input at fairly high speed
+until finding the next non-ignorable control code, which it returns.
+
+@u eight_bits skip_ahead() /* skip to next control code */
+{
+ eight_bits c; /* control code found */
+ while (1) {
+ if (loc>limit && (get_line()==0)) return(new_module);
+ *(limit+1)=at_sign;
+ while (*loc!=at_sign) loc++;
+ if (loc<=limit) {
+ loc++; c=ccode[*loc];
+#ifdef DEBUG
+ if (c==trace) {
+ tracing=*loc-@`0'; c=ignore;
+ }
+#endif DEBUG
+ loc++;
+ if (c!=ignore || *(loc-1)=='>') return(c);
+ }
+ }
+}
+
+@ The |skip_comment| procedure reads through the input at somewhat high
+speed until finding the end-comment token \.{*/} or a new-line, in which
+case |skip_comment| will be called again by |get_next|, since the
+comment is not finished. This is done so that the each newline in the
+C part of a module is copied to the output; otherwise the \&{\#line}
+commands inserted into the C file by the output routines become useless.
+If it comes to the end of the module it prints an error message.
+
+@<Global...@>=
+boolean comment_continues=0; /* are we scanning a comment? */
+
+@ @u
+skip_comment() /* skips over comments */
+{
+ ASCII c; /* current character */
+ if (comments_end_with_newline) {
+ get_line();
+ return (comment_continues=0);
+ } else {
+ while (1) {/*spider*/ /* fix this to recognize end ok */
+ if (loc>limit)
+ if(get_line()) return(comment_continues=1);
+ else{
+ err_print("! Input ended in mid-comment");
+@.Input ended in mid-comment@>
+ return(comment_continues=0);
+ }
+ c=*(loc++);
+ @<Recognize comment end starting at |loc-1|@>@;
+ if (c==at_sign) {
+ if (ccode[*loc]==new_module) {
+ err_print("! Section name ended in mid-comment"); loc--;
+@.Section name ended in mid-comment@>
+ return(comment_continues=0);
+ }
+ else loc++;
+ }
+ }
+ }
+}
+@* Inputting the next token.
+@d constant = @'3
+@<Global...@>=
+name_pointer cur_module; /* name of module just scanned */
+
+@ @<Include...@>=
+#include "ctype.h" /* definition of |isalpha|, |isdigit| and so on */
+
+@ As one might expect, |get_next| consists mostly of a big switch
+that branches to the various special cases that can arise.
+
+@u eight_bits get_next() /* produces the next input token */
+{
+ eight_bits c; /* the current character */
+ while (1) {
+ if (loc>limit) {
+ if (get_line()==0) return(new_module);
+ else if (print_where) {
+ print_where=0;
+ @<Insert the line number into |tok_mem|@>;
+ }
+ else return (@`\n');
+ }
+ c=*loc;
+ if (comment_continues) {
+ skip_comment(); /* scan to end of comment or newline */
+ if (comment_continues || comments_end_with_newline) return(@`\n');
+ else continue;
+ }
+ @<See a comment starting at |loc| and skip it@>@;
+ loc++;
+ if (isdigit(c) || c=='\\' || c=='.') @<Get a constant@>@;/*spider*/
+ else if (isalpha(c) || c=='_' || c=='$') @<Get an identifier@>@;/*spider*/
+ else if (c=='\'' || c=='\"') @<Get a string@>@;/*spider*/
+ else if (c==at_sign) @<Get control code and possible module name@>@;
+ else if (c==' ' || c==tab_mark) {
+ continue; /* ignore spaces and tabs */
+ }
+ mistake: @<Compress two-symbol operator@>@;
+ return(c);
+ }
+}
+
+@ @<Get an identifier@>= {/*spider*/
+ id_first=--loc;
+ while (isalpha(*++loc) || isdigit(*loc) || *loc=='_');
+ if (*loc=='$') while (isdigit(*++loc)||*loc=='$');
+ /* make room for \$\$ and \$nnn suffixes */
+ id_loc=loc; return(identifier);
+}
+
+@ @<Get a constant@>= {/*spider*/
+ id_first=loc-1;
+ if (*id_first=='.' && !isdigit(*loc)) goto mistake; /* not a constant */
+ if (*id_first=='\\') while (isdigit(*loc)) loc++; /* octal constant */
+ else {
+ if (*id_first=='0') {
+ if (*loc=='x' || *loc=='X') { /* hex constant */
+ loc++; while (isxdigit(*loc)) loc++; goto found;
+ }
+ }
+ while (isdigit(*loc)) loc++;
+ if (*loc=='.') {
+ loc++;
+ while (isdigit(*loc)) loc++;
+ }
+ if (*loc=='e' || *loc=='E') { /* float constant */
+ if (*++loc=='+' || *loc=='-') loc++;
+ while (isdigit(*loc)) loc++;
+ }
+ }
+ found:
+ id_loc=loc;
+ return(constant);
+}
+
+@ \cee\ strings and character constants, delimited by double and single
+quotes, respectively, can contain newlines or instances of their own
+delimiters if they are protected by a backslash. We follow this
+convention, but do not allow the string to be longer than |longest_name|.
+
+@<Get a string@>= {/*spider*/
+ ASCII delim = c; /* what started the string */
+@#
+/* if it's not a single-character literal, it's a tick mark or an |at_sign| */
+ if (delim=='\'' && (loc+1>=limit ||
+ (*loc != '\\' && *loc!=at_sign && loc[1]!='\'') ||
+ (*loc=='\\' && (loc+2>=limit||loc[2]!='\'')) ||
+ (*loc==at_sign &&
+ (loc+2>=limit||loc[1]!=at_sign||loc[2]!='\''))
+ )) goto mistake;
+ id_first = mod_text+1;
+ id_loc = mod_text; *++id_loc=delim;
+ while (1) {
+ if (loc>=limit) {
+ if(*(limit-1)!='\\') {
+ err_print("! String didn't end"); loc=limit; break;
+@.String didn't end@>
+ }
+ if(get_line()==0) {
+ err_print("! Input ended in middle of string"); loc=buffer; break;
+@.Input ended in middle of string@>
+ }
+ else if (++id_loc<=mod_text_end) *id_loc=@`\n'; /* will print as
+ \.{"\\\\\\n"} */
+ }
+ if ((c=*loc++)==delim) {
+ if (++id_loc<=mod_text_end) *id_loc=c;
+ break;
+ }
+ if (c=='\\') {
+ if (loc>=limit) continue;
+ if (++id_loc<=mod_text_end) *id_loc = '\\';
+ c=*loc++;
+ }
+ if (++id_loc<=mod_text_end) *id_loc=c;
+ }
+ if (id_loc>=mod_text_end) {
+ printf("\n! String too long: ");
+@.String too long@>
+ ASCII_write(mod_text+1,25);
+ printf("..."); mark_error;
+ }
+ id_loc++;
+ return(string);
+}
+
+@ After an \.{@@} sign has been scanned, the next character tells us
+whether there is more work to do.
+
+@<Get control code and possible module name@>= {
+ c=ccode[*loc++];
+ switch(c) {
+ case ignore: continue;
+ case control_text: while ((c=skip_ahead())==at_sign);
+ /* only \.{@@@@} and \.{@@>} are expected */
+ if (*(loc-1)!='>') err_print("! Improper @@ within control text");
+@.Improper {\AT!} within control text@>
+ continue;
+ case module_name:
+ cur_module_char=*(loc-1);
+ @<Scan the module name and make |cur_module| point to it@>;
+ case string: @<Scan a verbatim string@>;
+#ifdef DEBUG
+ case trace: tracing=*(loc-1)-'0'; continue;
+#endif DEBUG
+ case ascii_constant: @<Scan an ASCII constant@>;
+ case octal: @<Scan an octal constant@>;
+ case hex: @<Scan a hex constant@>;
+ default: return(c);
+ }
+}
+
+@ @<Scan an ASCII...@>=/*spider*/
+ id_first=loc;
+ if (*loc=='\\') loc++;
+ while (*loc!='\'') {
+ loc++;
+ if (loc>limit) {
+ err_print("! String didn't end"); loc=limit-1; break;
+ }
+ }
+ loc++;
+ return(ascii_constant);
+
+@ @<Scan an octal constant@>= {
+ id_first=loc;
+ while ('0'<=*loc && *loc<'8') loc++;
+ id_loc=loc;
+ return(octal);
+}
+
+@ @<Scan a hex constant@>= {
+ id_first=loc;
+ while (isxdigit(*loc)) loc++;
+ id_loc=loc;
+ return(hex);
+}
+
+
+@ @<Scan the module name...@>= {
+ ASCII *k; /* pointer into |mod_text| */
+ @<Put module name into |mod_text|@>;
+ if (k-mod_text>3 && strncmp(k-2,"...",3)==0) cur_module=prefix_lookup(mod_text+1,k-3);
+ else cur_module=mod_lookup(mod_text+1,k);
+ if (cur_module_char=='(') {
+ @<If it's not there, add |cur_module| to the output file stack, or
+ complain we're out of room@>@;
+ }
+ return(module_name);
+}
+
+@ Module names are placed into the |mod_text| array with consecutive spaces,
+tabs, and carriage-returns replaced by single spaces. There will be no
+spaces at the beginning or the end. (We set |mod_text[0]=' '| to facilitate
+this, since the |mod_lookup| routine uses |mod_text[1]| as the first
+character of the name.)
+
+@<Set init...@>=mod_text[0]=' ';
+
+@ @<Put module name...@>=
+k=mod_text;
+while (1) {
+ if (loc>limit && get_line()==0) {
+ err_print("! Input ended in section name");
+@.Input ended in section name@>
+ loc=buffer+1; break;
+ }
+ c=*loc;
+ @<If end of name, |break|@>;
+ loc++; if (k<mod_text_end) k++;
+ if (c==' ' || c==tab_mark) {
+ c=' '; if (*(k-1)==' ') k--;
+ }
+*k=c;
+}
+if (k>=mod_text_end) {
+ printf("\n! Section name too long: ");
+@.Section name too long@>
+ ASCII_write(mod_text+1,25);
+ printf("..."); mark_harmless;
+}
+if (*k==' ' && k>mod_text) k--;
+
+@ @<If end of name,...@>=
+if (c==at_sign) {
+ c=*(loc+1);
+ if (c=='>') {
+ loc+=2; break;
+ }
+ if (ccode[c]==new_module) {
+ err_print("! Section name didn't end"); break;
+@.Section name didn't end@>
+ }
+ *(++k)=at_sign; loc++; /* now |c==*loc| again */
+}
+
+@ At the present point in the program we
+have |*(loc-1)=string|; we set |id_first| to the beginning
+of the string itself, and |id_loc| to its ending-plus-one location in the
+buffer. We also set |loc| to the position just after the ending delimiter.
+
+@<Scan a verbatim string@>= {
+ id_first=loc++; *(limit+1)=at_sign; *(limit+2)='>';
+ while (*loc!=at_sign || *(loc+1)!='>') loc++;
+ if (loc>=limit) err_print("! Verbatim string didn't end");
+@.Verbatim string didn't end@>
+ id_loc=loc; loc+=2;
+ return(string);
+}
+
+@* Scanning a macro definition.
+The rules for generating the replacement texts corresponding to macros and
+\cee\ texts of a module are almost identical; the only differences are that
+
+\yskip \item{a)}Module names are not allowed in macros;
+in fact, the appearance of a module name terminates such macros and denotes
+the name of the current module.
+
+\item{b)}The symbols \.{@@d} and \.{@@f} and \.{@@u} are not allowed after
+module names, while they terminate macro definitions.
+
+\yskip Therefore there is a single procedure |scan_repl| whose parameter
+|t| specifies either |macro| or |module_name|. After |scan_repl| has
+acted, |cur_text| will point to the replacement text just generated, and
+|next_control| will contain the control code that terminated the activity.
+
+@d app_repl(c) = {if (tok_ptr==tok_mem_end) overflow("token"); *tok_ptr++=c;}
+
+@<Global...@>=
+text_pointer cur_text; /* replacement text formed by |scan_repl| */
+eight_bits next_control;
+
+@ @u scan_repl(t) /* creates a replacement text */
+eight_bits t;
+{
+ sixteen_bits a; /* the current token */
+ int set_print_where;
+ if (t==module_name) {@<Insert the line number into |tok_mem|@>;}
+ /* avoid inserting line number in macro replacement texts */
+ /* |print_where| is both tested and set in |get_next| */
+ while (1) {
+ if (t==macro) {
+ print_where = 0;
+ }
+ a=get_next();
+ if (t==macro) {
+ set_print_where = print_where;
+ }
+ switch (a) {
+ @<In cases that |a| is a non-ASCII token (|identifier|,
+ |module_name|, etc.), either process it and change |a| to a byte
+ that should be stored, or |continue| if |a| should be ignored,
+ or |goto done| if |a| signals the end of this replacement text@>@;
+ default: app_repl(a); /* store |a| in |tok_mem| */
+ }
+ }
+ done: next_control=(eight_bits) a;
+ if (text_ptr>text_info_end) overflow("text");
+ if (t==macro) {
+ @<Strip trailing newlines from the replacement text@>;
+ }
+ cur_text=text_ptr; (++text_ptr)->tok_start=tok_ptr;
+ print_where = set_print_where;
+}
+
+@ We don't ever want a macro replacement text to end with newline,
+but for readability of the {\tt WEB} source
+we usually want the last token in a macro definition
+to be a newline token.
+We can't just look for |@`\n'| at the end of the token list, because
+that might be the second half of a two-byte token, in which case it
+certainly {\em wouldn't} be a newline!
+So we look for a two-byte token (|*tok_ptr>=@'200|); as soon as we find one
+we've eliminated all trailing newlines.
+As long as we keep finding one-byte tokens, we drop trailing newlines
+as they come along.
+@<Strip trailing newlines...@>=
+tok_ptr -= 2;
+while (*tok_ptr<@'200 && *(tok_ptr+1)==@`\n') tok_ptr--;
+tok_ptr += 2;
+
+@ We use macros with zero or more parameters, and we give the parameters names.
+In order to scan a macro definition, we need to be able to substitute
+special markers for the parameter names.
+We {\em don't} put the parameter names in the hash table, because they're
+strictly temporary.
+Instead we keep them in temporary storage:
+We allow macros to have up to 32 parameters using 256 text chars.
+
+@d max_param_name_texts = 256
+@d max_param_names = 32
+@<Global variables@>=
+ASCII param_name_texts[max_param_name_texts];
+ASCII *param_name_texts_end = param_name_texts+max_param_name_texts;
+ASCII * param_names[max_param_names]; /* pointers into |param_name_texts| */
+short next_param_name; /* first free spot in |param_names| */
+ASCII * next_param_name_text; /* first free spot in |param_name_texts| */
+
+@ @<Initialize the parameter name area@>=
+next_param_name=0;
+next_param_name_text=param_name_texts;
+param_names[next_param_name]=next_param_name_text;
+
+@ @<Set initial values@>=@<Initialize the parameter name area@>;
+
+@ @<Add identifier to parameter name list@>=
+@<Check for parameter name overflow@>;
+while (id_first<id_loc)
+ *next_param_name_text++=*id_first++;
+param_names[++next_param_name]=next_param_name_text;
+
+@ @<Check for parameter name overflow@>=
+if (next_param_name==max_param_names)
+ overflow ("parameter names");
+if (id_loc - id_first >
+ param_name_texts_end - next_param_name_text)
+ overflow ("parameter name texts");
+
+
+@ The function |parameter_number(first,loc)| returns |0| if the identifier
+is not a parameter, and the number of the parameter if it is a parameter.
+This is not the parameter number we'll store, because for storage we
+want the {\em last} parameter to be {\tt \#1}, the penultimate to
+be {\tt \#2}, and so on.
+This means we have to know the number of parameters only when constructing
+the replacement text, not when scanning the replacement text.
+@u
+int parameter_number(first, loc)
+ ASCII *first, *loc;
+{
+ ASCII *f, *p;
+ int n;
+ for (n=0;n<next_param_name;n++) {
+ if (loc-first==param_names[n+1]-param_names[n]) {
+ /* lengths match */
+ for(f=first,p=param_names[n];f<loc;)
+ if (*f++!=*p++) goto nomatch;
+ return n+1; /* matched parameter */
+ }
+ nomatch: continue; /* need |continue| to avoid syntax error! */
+ }
+ return 0; /* never matched anything */
+}
+
+
+@ While scanning the macro name and parameter list, we ignore newlines.
+We initialize the parameter name area at the beginning, and again
+after scanning each replacement text.
+This makes sure we have an empty parameter name area when scanning the
+replacement text for a module.
+
+@<Scan a macro definition@>=
+@<Set |next_control| to the first non-newline token@>@;
+@<Take the macro name in |next_control|, put it in the hash table.
+ and set |p| to its entry in |name_dir|@>;
+@<Scan the parameter list (if any),
+ and set |next_control| to the non-newline
+ token following the parameter list@>;
+if (next_control!= @`=') {
+ err_print("! You must put an = sign before the macro replacement text");
+ @<Quit scanning the macro definition@>;
+}
+@<Trace macro name (|#ifdef TRACE_MACROS|)@>;
+app_repl(next_param_name); /* store number of parameters in |tok_mem| */
+scan_repl(macro);
+p->equiv=(ASCII *)cur_text;
+@<Trace equivalent text (|#ifdef TRACE_MACROS|)@>;
+@<Initialize the parameter name area@>;
+
+@ @<Trace macro name (|#ifdef TRACE_MACROS|)@>=
+#ifdef TRACE_MACROS
+if (tracing>1) {
+ printf("\nScanning definition of macro "); print_id(p);
+ }
+#endif TRACE_MACROS
+
+@ @<Trace equivalent text (|#ifdef TRACE_MACROS|)@>=
+#ifdef TRACE_MACROS
+if (tracing>2) {
+ printf("\nMacro "); print_id(p);
+ printf("'s replacement text is in text_info[%d]", cur_text-text_info);
+ }
+#endif TRACE_MACROS
+
+
+@ @<Scan the parameter list (if any), and set |next_control| to the
+ non-newline token
+ following the parameter list@>=
+@<Set |next_control| to the first non-newline token@>@;
+if (next_control==@`(') {
+ do {
+ @<Get a parameter name@>;
+ @<Set |next_control| to the first non-newline token@>@;
+ } while (next_control==@`,');
+ if (next_control != @`)') {
+ err_print("! Macro parameter list must end with )");
+ @<Quit scanning the macro definition@>;
+ }
+ next_control=get_next(); /* first token following parameter list */
+}
+
+
+@ @<Take the macro name in |next_control|...@>=
+if (next_control!=identifier) {
+ err_print("! Macro name must be an identifier");
+@.Macro name must be an identifier@>
+ @<Quit scanning the macro definition@>;
+} else {
+ p = id_lookup(id_first,id_loc,macro);
+ if (p->ilk!=macro) {
+#ifdef WARN_USE_BEFORE_DEF
+ printf("\n! Warning: macro name ");
+ print_id(p);
+ printf(" was used before it was defined");
+ mark_harmless;
+#endif WARN_USE_BEFORE_DEF
+ p->ilk=macro;
+ } else if (p+1!=name_ptr) {
+ err_print ("! Macro name is multiply defined: ");
+ }
+}
+
+@ @<Get a parameter name@>=
+@<Set |next_control| to the first non-newline token@>;
+if (next_control!=identifier) {
+ err_print("! Macro parameter name not an identifier");
+@.Macro parameter name...@>
+ @<Quit scanning the macro definition@>;
+} else {
+ if (parameter_number(id_first,id_loc)!=0) {
+ err_print("! Duplicate parameters in macro definition");
+@.Duplicate parameters...@>
+ @<Quit scanning the macro definition@>;
+ } else {
+ @<Add identifier to parameter name list@>;
+ }
+}
+
+
+@ @<Set |next_control| to the first non-newline token@>=
+while ((next_control=get_next())==@`\n');
+
+@ We modify this from the old tangle:
+
+@<In cases that |a| is a non-ASCII token (|identifier|,
+ |module_name|, etc.), either process it and change |a| to a byte
+ that should be stored, or |continue| if |a| should be ignored,
+ or |goto done| if |a| signals the end of this replacement text@>=
+case identifier:
+ { short n;
+ if ((n=parameter_number(id_first,id_loc))!=0) {
+#ifdef TRACE_MACROS
+if(tracing>1) {
+ printf("\nIdentified "); ASCII_write(id_first,id_loc-id_first);
+ printf(" as parameter number %d (%d from back)",n,next_param_name-n+1);
+ }
+#endif TRACE_MACROS
+ app_repl(param);
+ app_repl(next_param_name-n+1); /* reverses numbering */
+ } else { /* not a parameter */
+ a=id_lookup(id_first,id_loc,normal)-name_dir;
+ app_repl((a / @'400)+@'200); app_repl(a % @'400);
+ }
+ }
+ break;
+case module_name: if (t!=module_name) goto done;
+ else {
+ @<Was an |at_sign| missed here?@>;
+ a=cur_module-name_dir;
+ app_repl((a / @'400)+@'250);
+ app_repl(a % @'400);
+ @<Insert the line number into |tok_mem|@>; break;
+ }
+case constant: case string:
+ @<Copy a string or verbatim construction or numerical constant@>;
+case ascii_constant:
+ @<Copy an ASCII constant@>;
+case octal:
+ @<Copy an octal constant@>; break;
+case hex:
+ @<Copy a hex constant@>; break;
+case @`\n':
+#ifdef NEWLINES_IN_MACROS
+ app_repl(a);
+#else
+ if (t==macro) continue;
+ else app_repl(a);
+#endif NEWLINES_IN_MACROS
+ break;
+case definition: case format: case begin_unnamed:
+ if (t!=module_name) goto done;
+ else {
+ err_print("! @@d, @@f and @@u are ignored in C text"); continue;
+@.{\AT!}d, {\AT!}f and {\AT!}u are ignored in C text@>
+ }
+case new_module: goto done;
+
+@ Here is the code for the line number: first a |sixteen_bits| equal
+to |@'150000|; then, if we're dealing with the change file, the line
+number plus |@'100000|; or, if we're dealing with the web file, the
+line number; or, if we're dealing with an include file, the number 0,
+then the line number, followed by the number of characters in the file
+name and the file name.
+
+@<Insert the line...@>=
+store_two_bytes(@'150000);
+if (changing) id_first=change_file_name;
+else id_first=cur_file_name;
+id_loc=id_first+strlen(id_first);
+if (changing) store_two_bytes((sixteen_bits)change_line);
+else store_two_bytes((sixteen_bits)cur_line);
+{int a=id_lookup(id_first,id_loc,normal)-name_dir; app_repl((a / @'400)+@'200);
+ app_repl(a % @'400);}
+
+@ @<Was an |at_sign|...@>= {
+ ASCII *try_loc=loc;
+ while (*try_loc==' ' && try_loc<limit) try_loc++;
+ if (*try_loc=='+' && try_loc<limit) try_loc++;
+ while (*try_loc==' ' && try_loc<limit) try_loc++;
+ if (*try_loc=='=') err_print ("! Nested named modules. Missing @@?");
+@.Nested named modules@>
+}
+
+@ @<Copy a string...@>=
+ app_repl(a); /* |string| or |constant| */
+ while (id_first < id_loc) { /* simplify \.{@@@@} pairs */
+ if (*id_first==at_sign) id_first++;
+ app_repl(*id_first++);
+ }
+ app_repl(a); break;
+
+@ @<Copy an ASCII constant@>= {
+ int c;
+ if (*id_first==at_sign) {
+ c=xchr[*id_first++];
+ if (*id_first!=at_sign) err_print("! Double @@ within string");
+ }
+ else if (*id_first=='\\') {
+ id_first++;
+ switch (*id_first) {
+ case 't':c=@`\t';break;
+ case 'n':c=@`\n';break;
+ case 'b':c=@`\b';break;
+ case '0':c=@`\0';break;
+ case '\\':c=@`\\';break;
+ default: err_print("! Unrecognized escape sequence");
+ }
+ }
+ else c=xchr[*id_first];
+ app_repl(constant);
+/* we don't want octal; we want decimal */
+ /* we know |c<=255| */
+ app_decimal((long)c);
+ app_repl(constant);
+}
+break;
+
+@ Paranoia to work on any 32 bit integer machine...
+@<Copy an octal constant@>= {
+long sum=0;
+while (id_first<id_loc) {
+ sum = 8*sum + *id_first++ - '0';
+ if (sum > @"04000000) err_print("! Octal constant exceeds @@\"04000000");
+ }
+app_repl(constant);
+app_decimal(sum);
+app_repl(constant);
+}
+
+@ @<Copy a hex constant@>= {
+long sum=0;
+while (id_first<id_loc) {
+ sum = 16*sum +
+ (isdigit(*id_first)
+ ? *id_first - '0'
+ : isupper(*id_first)
+ ? *id_first - 'A' + 10
+ : *id_first - 'a' + 10
+ );
+ id_first++;
+ if (sum > @"04000000) err_print("! Hex constant exceeds @@\"04000000");
+ }
+app_repl(constant);
+app_decimal(sum);
+app_repl(constant);
+}
+
+@ This function prints out a decimal constant using |app_repl|.
+@u
+app_decimal(c)
+ long c; /* on entry require |c>=0| */
+{long power;
+ if (c==0) {app_repl('0'); return;}
+ if (c<0) /* should never happen */ {app_repl('-'); c = - c;}
+ for (power=1; c>=power; power *=10);
+ /* now |power/10<=c<power| */
+ for (power /=10; power>=1; power /=10) {
+ app_repl('0'+c/power); /* leading digit $>0$ */
+ c%=power;
+ /* invariant: original c = this c + printed string*power */
+ }
+ }
+
+
+
+@* Scanning a module.
+The |scan_module| procedure starts when `\.{@@\ }' or `\.{@@*}' has been
+sensed in the input, and it proceeds until the end of that module. It
+uses |module_count| to keep track of the current module number; with luck,
+\.{WEAVE} and \.{TANGLE} will both assign the same numbers to modules.
+
+@<Global...@>=
+extern sixteen_bits module_count; /* the current module number */
+
+@ The top level of |scan_module| is trivial.
+@u scan_module()
+{
+ name_pointer p; /* module name for the current module */
+ text_pointer q; /* text for the current module */
+ sixteen_bits a; /* token for left-hand side of definition */
+ module_count++;
+ if (*(loc-1)=='*') /* starred module */
+ printf("*%d",module_count); fflush(stdout);
+ @<Scan the definition part of the current module@>;
+ @<Scan the \cee\ part of the current module@>;
+}
+
+@ We define two kinds of ilks for identifiers: |normal| for ordinary
+identifiers, and |macro| for macros.
+@d normal = 0
+@d macro = 1
+@d simple = 2
+@<Scan the definition part...@>=
+next_control=0;
+while (1) {
+done_scanning:
+ while (next_control<=format)
+ if ((next_control=skip_ahead())==module_name) {
+ /* scan the module name too */
+ loc-=2; next_control=get_next();
+ }
+ if (next_control!=definition) break;
+ @<Scan a macro definition@>;
+ cur_text->text_link=0; /* |text_link=0| characterizes a macro */
+}
+
+@ We initialize the parameter name area at the beginning, and we re-initialize
+any time we have to punt a macro definition.
+This makes sure we have an empty parameter name area when scanning the
+replacement text for a module.
+@<Quit scanning the macro definition@>=
+@<Initialize the parameter name area@>;
+p->ilk=normal; /* turn off macro replacement and hope for the best */
+goto done_scanning;
+
+
+@ @<Scan the \cee...@>=
+switch (next_control) {
+ case begin_unnamed: p=name_dir; break;
+ case module_name: p=cur_module;
+ @<Check that |=| follows this module name, otherwise |return|@>;
+ break;
+ default: return;
+}
+@<Insert the module number into |tok_mem|@>;
+scan_repl(module_name); /* now |cur_text| points to the replacement text */
+@<Update the data structure so that the replacement text is accessible@>;
+
+@ @<Check that |=|...@>=
+while ((next_control=get_next())=='+'); /* allow optional `\.{+=}" */
+if (next_control!='=') {
+ err_print("! C text flushed, = sign is missing");
+@.C text flushed...@>
+ while ((next_control=skip_ahead()) != new_module);
+ return;
+}
+
+@ @<Insert the module number...@>=
+store_two_bytes((sixteen_bits)(@'150000+module_count)); /* |@'150000==@'320*@'400| */
+
+@ @<Update the data...@>=
+if (p==name_dir||p==0) { /* unnamed module, or bad module name */
+ (last_unnamed)->text_link=cur_text-text_info; last_unnamed=cur_text;
+}
+else if (p->equiv==(ASCII *)text_info) p->equiv=(ASCII *)cur_text;
+ /* first module of this name */
+else {
+ q=(text_pointer)p->equiv;
+ while (q->text_link<module_flag) q=q->text_link+text_info; /* find end of list */
+ q->text_link=cur_text-text_info;
+}
+cur_text->text_link=module_flag; /* mark this replacement text as a nonmacro */
+
+@ @u phase_one() {
+ phase=1;
+ module_count=0;
+ reset_input();
+ while ((next_control=skip_ahead())!=new_module);
+ while (!input_has_ended) scan_module();
+ check_complete();
+ phase=2;
+}
+
+@ @u print_stats() {
+ printf("\nMemory usage statistics:\n");
+ printf("%d names (out of %d)\n",name_ptr-name_dir,max_names);
+ printf("%d replacement texts (out of %d)\n",text_ptr-text_info,max_texts);
+ printf("%d bytes (out of %d)\n",byte_ptr-byte_mem,max_bytes);
+ printf("%d tokens (out of %d)\n",tok_ptr-tok_mem,max_toks);
+}
+
+@* Index.
+Here is a cross-reference table for the \.{TANGLE} processor.
+All modules in which an identifier is
+used are listed with that identifier, except that reserved words are
+indexed only when they appear in format definitions, and the appearances
+of identifiers in module names are not indexed. Underlined entries
+correspond to where the identifier was declared. Error messages and
+a few other things like ``ASCII code'' are indexed here too.
diff --git a/web/spiderweb/src/master/transcheck.awk b/web/spiderweb/src/master/transcheck.awk
new file mode 100644
index 0000000000..ec02b62ba3
--- /dev/null
+++ b/web/spiderweb/src/master/transcheck.awk
@@ -0,0 +1,23 @@
+##162:
+
+#line 2537 "/u/norman/pu/web/dist/src/master/spider.web"
+
+#line 2538 "/u/norman/pu/web/dist/src/master/spider.web"
+/^good translations$/,/^test translations$/{
+if($0!~/^good translations$|^test translations$/){
+istranslation[$0]=1
+}
+next
+}
+
+{if(istranslation[$0]!=1){
+print"Error:",$0,"is not a valid translation"
+exitcode=-1
+}
+}
+
+END{
+exit exitcode
+}
+##:162
+
diff --git a/web/spiderweb/src/master/transcheck.list b/web/spiderweb/src/master/transcheck.list
new file mode 100644
index 0000000000..d0ed25c6cf
--- /dev/null
+++ b/web/spiderweb/src/master/transcheck.list
@@ -0,0 +1,14 @@
+good translations
+break_space
+force
+big_force
+opt
+backup
+big_cancel
+cancel
+indent
+outdent
+math_rel
+math_bin
+math_op
+test translations
diff --git a/web/spiderweb/src/master/weave.web b/web/spiderweb/src/master/weave.web
new file mode 100644
index 0000000000..81dfec3f78
--- /dev/null
+++ b/web/spiderweb/src/master/weave.web
@@ -0,0 +1,3250 @@
+% Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+% Not to be sold, but may be used freely for any purpose
+% For more information, see file COPYRIGHT in the parent directory
+
+% This file is part of Spidery WEB
+% This program by Norman Ramsey is based on programs Silvio Levy
+% and D. E. Knuth. Silvio Levy wrote most of the code.
+% It is distributed WITHOUT ANY WARRANTY, express or implied.
+% Dec 1987
+
+% Here is TeX material that gets inserted after \input webmac
+
+\message{Entering \string\batchmode...}
+\batchmode
+
+\def\hang{\hangindent 3em\indent\ignorespaces}
+\font\ninerm=cmr9
+\let\mc=\ninerm % medium caps
+\def\cee{C}
+\def\Pascal{Pascal}
+\def\PASCAL{Ada}
+\def\pb{$\.|\ldots\.|$} % C brackets (|...|)
+\def\v{\.{\char'174}} % vertical (|) in typewriter font
+\def\dleft{[\![} \def\dright{]\!]} % double brackets
+\mathchardef\RA="3221 % right arrow
+\mathchardef\BA="3224 % double arrow
+\def\({} % kludge for alphabetizing certain module names
+
+\def\title{Spidery WEAVE}
+\def\contentspagenumber{1} % should be odd
+\def\topofcontents{\null\vfill
+ \titlefalse % include headline on the contents page
+ \def\rheader{\hfil}
+ \centerline{\titlefont The {\ttitlefont Spidery WEAVE} processor}
+ \vfill}
+\pageno=\contentspagenumber \advance\pageno by 1
+\let\maybe=\iftrue
+
+@* Introduction.
+\.{CWEAVE} has a fairly straightforward outline. It operates in
+three phases: first it inputs the source file and stores cross-reference
+data, then it inputs the source once again and produces the \TeX\ output
+file, and finally it sorts and outputs the index. It can be compiled
+with certain optional flags, |DEBUG| and |STAT|, the latter being used
+to keep track of how much of \.{WEAVE}'s resources were actually used.
+
+@u
+@<Include files@>@;
+@<Common code for \.{WEAVE} and \.{TANGLE}@>@;
+@<Typedef declarations@>@;
+@<Global variables@>@;
+
+main (ac, av)
+char **av;
+{
+ argc=ac; argv=av;
+ program=weave;
+ common_init();
+ @<Set initial values@>;
+ printf(banner); /* print a ``banner line'' */
+ @<Store all the reserved words@>;
+ phase_one(); /* read all the user's text and store the cross-references */
+ phase_two(); /* read all the text again and translate it to \TeX\ form */
+ phase_three(); /* output the cross-reference index */
+#ifdef STAT
+ @<Print statistics about memory usage@>;
+#endif STAT
+ wrap_up();
+}
+
+@ The following parameters were sufficient in the original \.{WEAVE} to
+handle \TeX, so they should be sufficient for most applications of \.{CWEAVE}.
+
+@d max_bytes = 90000 /* the number of bytes in identifiers,
+ index entries, and module names */
+@d max_names = 4000 /* number of identifiers, strings, module names;
+ must be less than 10240 */
+@d max_modules = 2000 /* greater than the total number of modules */
+@d hash_size = 353 /* should be prime */
+@d buf_size = 100 /* maximum length of input line, plus one */
+@d longest_name = 400 /* module names and strings shouldn't be longer than this */
+@d long_buf_size = 500 /* |buf_size+longest_name| */
+@d line_length = 80 /* lines of \TeX\ output have at most this many characters;
+ should be less than 256 */
+@d max_refs = 20000 /* number of cross-references; must be less than 65536 */
+@d max_toks = 20000 /* number of symbols in \cee\ texts being parsed;
+ must be less than 65536 */
+@d max_texts = 2000 /* number of phrases in \cee\ texts being parsed;
+ must be less than 10240 */
+@d max_scraps = 1000 /* number of tokens in \cee\ texts being parsed */
+@d stack_size = 400 /* number of simultaneous output levels */
+
+@i common.h
+
+@ Should include wlang.web but can't because AWK runs out of files.
+
+@* Data structures exclusive to {\tt WEAVE}.
+As explained in \.{common.web}, the field of a |name_info| structure
+that contains the |rlink| of a module name is used for a completely
+different purpose in the case of identifiers. If is then called the
+|ilk| of the identifier, and it is used to
+distinguish between various types of identifiers, as follows:
+
+@ Several types of identifiers are distinguished by their |ilk|:
+
+\yskip\hang |normal| identifiers are part of the \PASCAL\ program and
+will appear in italic type.
+\yskip\hang |roman| identifiers are index entries that appear after
+\.{@@\^} in the \.{WEB} file.
+
+\yskip\hang |wildcard| identifiers are index entries that appear after
+\.{@@:} in the \.{WEB} file.
+
+\yskip\hang |typewriter| identifiers are index entries that appear after
+\.{@@.} in the \.{WEB} file.
+
+\yskip\hang |array_like|, |begin_like|, \dots, |var_like|
+identifiers are \PASCAL\ reserved words whose |ilk| explains how they are
+to be treated when \PASCAL\ code is being formatted.
+
+\yskip\hang Finally, if |c| is an ASCII code, an |ilk| equal to
+|char_like+c| denotes a reserved word that will be converted to character
+|c|.
+
+@d normal = 0 /*ordinary identifiers have |normal| ilk */
+@d roman = 1 /*normal index entries have |roman| ilk */
+@d wildcard = 2 /*user-formatted index entries have |wildcard| ilk */
+@d typewriter = 3 /*`typewriter type' entries have |typewriter| ilk */
+@d reserved(a) = (a->ilk>typewriter) /* tells if a name is a reserved word */
+/* begin with 64 */
+
+/* ilks are generated by spider into file grammar.web */
+
+@ We keep track of the current module number in |module_count|, which
+is the total number of modules that have started. Modules which have
+been altered by a change file entry have their |changed_module| flag
+turned on during the first phase.
+
+@<Global...@>=
+boolean change_exists; /* has any module changed? */
+
+@ The other large memory area in \.{CWEAVE} keeps the cross-reference data.
+All uses of the name |p| are recorded in a linked list beginning at
+|p->xref|, which points into the |xmem| array. The elements of |xmem|
+are structures consisting of an integer, |num|, and a pointer |xlink|
+to another element of |xmem|. If |x=p->xref| is a pointer into |xmem|,
+the value of |x->num| is either a module number where |p| is used,
+or it is |def_flag| plus a module number where |p| is defined,
+or it is |file_flag| plus a module number where the file |p| is defined;
+and |x->xlink| points to the next such cross-reference for |p|,
+if any. This list of cross-references is in decreasing order by
+module number. The next unused slot in |xmem| is |xref_ptr|.
+
+The global variable |xref_switch| is set either to |def_flag|, or to zero,
+depending on whether the next cross-reference to an identifier is to be
+underlined or not in the index. This switch is set to |def_flag| when
+\.{@@!} or \.{@@d} or \.{@@f} is scanned, and it is cleared to zero when
+the next identifier or index entry cross-reference has been made.
+Similarly,
+the global variable |mod_xref_switch| is either |def_flag|,
+|file_flag|, or zero, depending
+on whether a module name is being defined, defined as a file, or used.
+
+@<Type...@>=
+typedef struct xref_info {
+ sixteen_bits num; /* module number plus zero,|def_flag|, or |file_flag| */
+ struct xref_info *xlink; /* pointer to the previous cross-reference */
+} xref_info;
+typedef xref_info *xref_pointer;
+
+@ @<Global...@>=
+xref_info xmem[max_refs]; /* contains cross-reference information */
+xref_pointer xmem_end = xmem+max_refs-1;
+xref_pointer xref_ptr; /* the largest occupied position in |xmem| */
+sixteen_bits xref_switch,mod_xref_switch; /* either zero or |def_flag| */
+
+@ @d def_flag = 10240 /* must be strictly larger than |max_modules| */
+@d file_flag = 2*def_flag
+@d xref = equiv_or_xref
+
+@<Set init...@>=
+name_dir->xref=(ASCII *)xmem;
+xref_ptr=xmem;
+xref_switch=0;
+mod_xref_switch=0;
+xmem->num=0; /* cross-references to undefined modules */
+
+@ A new cross-reference for an identifier is formed by calling |new_xref|,
+which discards duplicate entries and ignores non-underlined references
+to one-letter identifiers or \cee's reserved words.
+
+If the user has sent the |no_xref| flag (the \.{-x} option of the command line),
+it is unnecessary to keep track of cross-references for identifers.
+If one were careful, one could probably make more changes around module
+100 to avoid a lot of identifier looking up.
+
+@d append_xref(c) = if (xref_ptr==xmem_end) stat_overflow("cross-reference");
+ else (++xref_ptr)->num=c;
+
+@u new_xref(p)
+name_pointer p;
+{
+ xref_pointer q; /* pointer to previous cross-reference */
+ sixteen_bits m, n; /* new and previous cross-reference value */
+ if (no_xref) return;
+ if ((reserved(p) || length(p)==1) && xref_switch==0) return;
+ m=module_count+xref_switch; xref_switch=0; q=(xref_pointer)p->xref;
+ if (q != xmem) {
+ n=q->num;
+ if (n==m || n==m+def_flag) return;
+ else if (m==n+def_flag) {
+ q->num=m; return;
+ }
+ }
+ append_xref(m); xref_ptr->xlink=q; p->xref=(ASCII *)xref_ptr;
+}
+
+@ The cross-reference lists for module names are slightly different. Suppose
+that a module name is defined in modules $m_1$, \dots, $m_k$ and used in
+modules $n_1$, \dots, $n_l$. Then its list will contain $m_1+|def_flag|{}$,
+$m_k+|def_flag|{}$, \dots, $m_2+|def_flag|{}$, $n_l$, \dots, $n_1$, in
+this order.
+If the module is a file module (\.{@@(}), read |file_flag| for
+|def_flag|.
+Since no module should ever have both |file_flag| and |def_flag|, we
+check that.
+ After Phase II, however, the order will be
+$m_1+|def_flag|{}$, \dots, $m_k+|def_flag|{}$, $n_1$, \dots, $n_l$.
+
+@u new_mod_xref(p)
+name_pointer p;
+{
+ xref_pointer q,r; /* pointers to previous cross-references */
+ q=(xref_pointer)p->xref; r=xmem;
+ if (q>xmem) {
+ if (mod_xref_switch==0) while (q->num>=def_flag) {
+ r=q; q=q->xlink;
+ }
+ else if (q->num>=def_flag) {
+ @<Make sure |mod_xref_switch| is consistent with |q->num|@>
+ r=q; q=q->xlink;
+ }
+ }
+ append_xref(module_count+mod_xref_switch);
+ xref_ptr->xlink=q; mod_xref_switch=0;
+ if (r==xmem) p->xref=(ASCII *)xref_ptr;
+ else r->xlink=xref_ptr;
+}
+
+@ Consistency check
+@<Make sure |mod_xref_switch| is consistent with |q->num|@>=
+{
+ if ((mod_xref_switch==def_flag && q->num >= file_flag) ||
+ (mod_xref_switch==file_flag && q->num < file_flag)) {
+ printf("\n! You can't use <"); print_id(p);
+ printf("> both as a file and as a named module"); mark_harmless;
+@.You can't use <section name> both as a file...@>
+
+ }
+}
+
+
+@ A third large area of memory is used for sixteen-bit `tokens', which appear
+in short lists similar to the strings of characters in |byte_mem|. Token lists
+are used to contain the result of \cee\ code translated into \TeX\ form;
+further details about them will be explained later. A |text_pointer| variable
+is an index into |tok_start|.
+
+@<Typed...@>=
+typedef sixteen_bits token;
+typedef token *token_pointer;
+typedef token_pointer *text_pointer;
+
+@ The first position of |tok_mem|
+that is unoccupied by replacement text is called |tok_ptr|, and the first
+unused location of |tok_start| is called |text_ptr|.
+Thus, we usually have |*text_ptr=tok_ptr|.
+
+@<Global...@>=
+token tok_mem[max_toks]; /* tokens */
+token_pointer tok_mem_end = tok_mem+max_toks-1; /* end of |tok_mem| */
+token_pointer tok_start[max_texts]; /* directory into |tok_mem| */
+token_pointer tok_ptr; /* first unused position in |tok_mem| */
+text_pointer text_ptr; /* first unused position in |tok_start| */
+text_pointer tok_start_end = tok_start+max_texts-1; /* end of |tok_start| */
+#ifdef STAT
+token_pointer max_tok_ptr; /* largest value of |tok_ptr| */
+text_pointer max_text_ptr; /* largest value of |text_ptr| */
+#endif STAT
+
+@ @<Set init...@>=
+tok_ptr=tok_mem+1; text_ptr=tok_start+1; tok_start[0]=tok_mem+1;
+tok_start[1]=tok_mem+1; /* |tok_start| is the empty token list,
+ and |*textptr==tok_mem+1==tok_ptr| */
+#ifdef STAT
+max_tok_ptr=tok_mem+1; max_text_ptr=tok_start+1;
+#endif STAT
+
+@ @u
+names_match(p,first,l,t)
+name_pointer p; /* points to the proposed match */
+ASCII *first; /* position of first character of string */
+int l; /* length of identifier */
+eight_bits t; /* desired ilk */
+{
+ if (length(p)!=l) return 0;
+ if (p->ilk!=t && !(t==normal && reserved(p))) return 0;
+ return !strncmp(first,p->byte_start,l);
+}
+
+init_p(p,t)
+name_pointer p;
+eight_bits t;
+{
+ p->ilk=t; p->xref=(ASCII*)xmem;
+}
+
+init_node(p)
+name_pointer p;
+{
+ p->xref=(ASCII*)xmem;
+}
+
+@ We have to get Ada's
+reserved words into the hash table, and the simplest way to do this is
+to insert them every time \.{CWEAVE} is run. Since there are relatively
+few reserved words, we use an ad hoc function to simplify the code.
+@^reserved words@>
+There's not enough room to include \.{reserved.web}, since AWK can't open
+enough files.
+We make do with \.{scraps.web}.
+
+
+
+@* Lexical scanning.
+Let us now consider the subroutines that read the \.{WEB} source file
+and break it into meaningful units. There are four such procedures:
+One simply skips to the next `\.{@@\ }' or `\.{@@*}' that begins a
+module; another passes over the \TeX\ text at the beginning of a
+module; the third passes over the \TeX\ text in a \cee\ comment;
+and the last, which is the most interesting, gets the next token of
+a \cee\ text. They all use the pointers |limit| and |loc| into
+the line of input currently being studied.
+
+@ Control codes in \.{WEB}, which begin with `\.{@@}', are converted
+into a numeric code designed to simplify \.{CWEAVE}'s logic; for example,
+larger numbers are given to the control codes that denote more significant
+milestones, and the code of |new_module| should be the largest of
+all. Some of these numeric control codes take the place of ASCII
+control codes that will not otherwise appear in the output of the
+scanning routines.
+@^ASCII code@>
+
+@d ignore = 0 /* control code of no interest to \.{CWEAVE} */
+@d verbatim = @'2 /* extended ASCII alpha will not appear */
+ /* extended ASCII beta will not appear */
+@d begin_comment = @'10 /* ASCII tab mark will not appear */
+@d octal = @'14 /* ASCII carriage return will not appear */
+@d hex = @'15 /* ASCII form feed will not appear */
+@d switch_math_flag = @'175 /* this code will be intercepted without confusion */
+@d underline = @'176 /* this code will be intercepted without confusion */
+@d param = @'177 /* ASCII delete will not appear */
+/* identifier =200 or octal @'310 */
+@#/* following three must be conseccutive for indexing to work */
+@d xref_roman = (identifier+roman) /* control code for `\.{@@\^}' */
+@d xref_wildcard = (identifier+wildcard) /* control code for `\.{@@:}' */
+@d xref_typewriter = (identifier+typewriter) /* control code for `\.{@@.}' */
+@d TeX_string = @'356 /* control code for `\.{@@t}' */
+@d ascii_constant = @'357 /* control code for `\.{@@`}' */
+@d join = @'360 /* control code for `\.{@@\&}' */
+@d thin_space = @'361 /* control code for `\.{@@,}' */
+@d math_break = @'362 /* control code for `\.{@@\char'174}' */
+@d line_force = @'363 /* control code for `\.{@@/}' */
+@d line_break = @'364 /* control code for `\.{@@-}' */
+@d big_line_break = @'365 /* control code for `\.{@@\#}' */
+@d no_line_break = @'366 /* control code for `\.{@@+}' */
+@d pseudo_semi = @'367 /* control code for `\.{@@;}' */
+@d vertical_bar = @'370 /* The `\v' used to mark Ada text */
+@d trace = @'371 /* control code for `\.{@@0}', `\.{@@1}' and `\.{@@2}' */
+@d format = @'373 /* control code for `\.{@@f}' */
+@d definition = @'374 /* control code for `\.{@@d}' */
+@d begin_unnamed = @'375 /* control code for `\.{@@u}' */
+@d module_name = @'376 /* control code for `\.{@@<}' */
+@d new_module = @'377 /* control code for `\.{@@\ }' and `\.{@@*}' */
+
+@ Control codes are converted from ASCII to \.{CWEAVE}'s internal
+representation by means of the table |ccode|.
+
+@<Global...@>=
+eight_bits ccode[128]; /* meaning of a char following \.{@@} */
+
+@ @<Set ini...@>=
+{int c; for (c=0; c<=127; c++) ccode[c]=0;}
+ccode[' ']=ccode[tab_mark]=ccode['*']=new_module;
+ccode['-']=line_break;
+ccode['#']=big_line_break;
+ccode['=']=verbatim;
+ccode['d']=ccode['D']=definition;
+ccode['f']=ccode['F']=format;
+ccode['c']=ccode['C']=begin_unnamed;
+ccode['u']=ccode['U']=begin_unnamed;
+ccode['t']=ccode['T']=TeX_string;
+ccode['&']=join;
+ccode['<']=ccode['(']=module_name;
+ccode['!']=underline; ccode['^']=xref_roman;
+ccode['$']=switch_math_flag;
+ccode[':']=xref_wildcard;
+ccode['.']=xref_typewriter;
+ccode[',']=thin_space;
+ccode['|']=math_break;
+ccode['/']=line_force;
+ccode['+']=no_line_break;
+ccode[';']=pseudo_semi;
+ccode['`']=ascii_constant;
+ccode['\'']=octal;
+ccode['"']=hex;
+@t\4@>@<Special control codes allowed only when debugging@>@;
+@#
+/*Now adjust for |at_sign|... if it is @@, we have no-op followed by quoting */
+/* ... but if it is other, say \#, then \#@@ replaces @@\#, and \#\#
+ quotes itself*/
+ccode['@@']=ccode[at_sign];
+ccode[at_sign]=at_sign;
+
+@ If \.{CWEAVE} is compiled with debugging commands, one can write
+\.{@@2}, \.{@@1}, and \.{@@0} to turn tracing fully on, partly on,
+and off, respectively.
+
+@<Special control codes...@>=
+#ifdef DEBUG
+ccode['0']=ccode['1']=ccode['2']=trace;
+#endif DEBUG
+
+@ The |skip_limbo| routine is used on the first pass to skip through
+portions of the input that are not in any modules, i.e., that precede
+the first module. After this procedure has been called, the value of
+|input_has_ended| will tell whether or not a module has actually been found.
+
+@u skip_limbo() {
+ while(1) {
+ if (loc>limit && get_line()==0) return;
+ *(limit+1)=at_sign;
+ while (*loc!=at_sign) loc++; /* look for |at_sign|, then skip two chars */
+ if (loc++ <=limit) if (ccode[*loc++]==new_module) return;
+ }
+}
+
+@ The |skip_TeX| routine is used on the first pass to skip through
+the \TeX\ code at the beginning of a module. It returns the next
+control code or `\v' found in the input. A |new_module| is
+assumed to exist at the very end of the file.
+
+@u unsigned skip_TeX() /* skip past pure \TeX\ code */
+{
+ while (1) {
+ if (loc>limit && get_line()==0) return(new_module);
+ *(limit+1)=at_sign;
+ while (*loc!=at_sign && *loc!=vertical_char) loc++;
+ if (*loc++ ==vertical_char) return(vertical_bar);
+ if (loc<=limit) return(ccode[*(loc++)]);
+ }
+}
+
+@* Inputting the next token.
+As stated above, \.{WEAVE}'s most interesting lexical scanning routine is the
+|get_next| function that inputs the next token of \cee\ input. However,
+|get_next| is not especially complicated.
+
+The result of |get_next| is either an ASCII code for some special character,
+or it is a special code representing a pair of characters (e.g., `\.{!=}'),
+or it is the numeric value computed by the |ccode|
+table, or it is one of the following special codes:
+
+\yskip\hang |identifier|: In this case the global variables |id_first| and
+|id_loc| will have been set to the beginning and ending-plus-one locations
+in the buffer, as required by the |id_lookup| routine.
+
+\yskip\hang |string|: The string will have been copied into the array
+|mod_text|; |id_first| and |id_loc| are set as above (now they are
+pointers into |mod_text|).
+
+\yskip\hang |constant|: The constant is copied into |mod_text|, with
+slight modifications; |id_first| and |id_loc| are set.
+
+\yskip\noindent Furthermore, some of the control codes cause
+|get_next| to take additional actions:
+
+\yskip\hang |xref_roman|, |xref_wildcard|, |xref_typewriter|, |TeX_string|,
+|verbatim|: The values of |id_first| and |id_loc| will have been set to
+the beginning and ending-plus-one locations in the buffer.
+
+\yskip\hang |module_name|: In this case the global variable |cur_module| will
+point to the |byte_start| entry for the module name that has just been scanned.
+
+\yskip\noindent If |get_next| sees `\.{@@!}'
+it sets |xref_switch| to |def_flag| and goes on to the next token.
+
+\yskip\noindent If |get_next| sees `\.{@@\$}'
+it sets |math_flag| to |!math_flag| and goes on to the next token.
+
+
+
+@<Global...@>=
+name_pointer cur_module; /* name of module just scanned */
+int math_flag;
+
+@ @<Include...@>=
+#include "ctype.h"
+
+@ As one might expect, |get_next| consists mostly of a big switch
+that branches to the various special cases that can arise.
+
+Get next takes one argument that determines whether |vertical_char| is a
+character or gets translated to a |vertical_bar|.
+(Normally, |vertical_char=='|'|.)
+If it does get translated, the following rules apply:
+
+\yskip\hang|'|'| as part of a string or as a noninitial character in a
+multicharacter token is not a |vertical_bar|.
+
+\yskip\hang An initial |"||"| is treated like a single |'|'|, and
+taken to be either a token itself or the initial |'|'| in a
+multicharacter token.
+
+@d vertical_char = @`|'
+@u eight_bits get_next(see_vertical) /* produces the next input token
+*/
+ char see_vertical;
+{
+ eight_bits c; /* the current character */
+ while (1) {
+ if (loc>limit) {
+ if (get_line()==0) return(new_module);
+ else { return (@`\n'); }
+ }
+ c=*(loc++);
+ @<See a comment starting at |loc-1| and return |begin_comment|@>@;
+ if (see_vertical && c==vertical_char) {
+ if (*loc==vertical_char && loc < limit) {
+ loc++;
+ } else {
+ return vertical_bar;
+ }
+ }
+ if (isdigit(c)) @<Get a constant@>@; /*spider*/
+ else if (isalpha(c) || c=='_') @<Get an identifier@>@;/*spider*/
+ else if (c=='\'' || c=='"') @<Get a string@>@;/*spider*/
+ else if (c==at_sign) @<Get control code and possible module name@>@;
+ else if (c==' ' || c==tab_mark) continue; /* ignore spaces and tabs */
+ mistake: @<Compress two-symbol operator@>@;
+ return(c);
+ }
+}
+
+@ @<Set |next_control| to the first non-newline token@>=
+while ((next_control=get_next(0))==@`\n');
+
+@ @<Get an identifier@>= {/*spider*/
+ id_first=--loc;
+ while (isalpha(*++loc) || isdigit(*loc) || *loc=='_');
+ id_loc=loc; return(identifier);
+}
+
+@ Notice that in this section and the next, |id_first| and |id_loc|
+are pointers into the array |mod_text|, not into |buffer|.
+
+@<Get a constant@>= {
+ id_first=id_loc=mod_text+1;
+
+ if (*(loc-1)=='.' && !isdigit(*loc)) goto mistake; /* not a constant */
+ *id_loc++=*(loc-1);
+ while (isdigit(*loc)) *id_loc++=*loc++;
+ if (*loc=='.') {
+ *id_loc++=*loc++;
+ while (isdigit(*loc)) *id_loc++=*loc++;
+ }
+#ifdef C_FLOATING_POINT
+/* no floating point --- it depends too much on C */
+ if (*loc=='e' || *loc=='E') { /* float constant */
+ *id_loc++='_'; loc++;
+ if (*loc=='+' || *loc=='-') *id_loc++=*loc++;
+ while (isdigit(*loc)) *id_loc++=*loc++;
+ }
+#endif C_FLOATING_POINT
+ return(constant);
+}
+
+
+
+@ Here we do octals, which I should say more about later...
+@<Get an octal constant@>= {
+ id_first=id_loc=mod_text+1;
+ *id_loc++='~'; /* marks octal constant */
+ while ('0'<=*loc && *loc<'8') *id_loc++=*loc++;
+ return(constant);
+}
+@ And hexes are even easier...
+@<Get a hex constant@>= {
+ id_first=id_loc=mod_text+1;
+ *id_loc++='^'; /* marks hex constant */
+ while (isxdigit(*loc)) {
+ *id_loc++=(islower(*loc)?toupper(*loc):*loc);
+ loc++;
+ }
+ return(constant);
+}
+
+@ \cee\ strings and character constants, delimited by double and single
+quotes, respectively, can contain newlines or instances of their own
+delimiters if they are protected by a backslash. We follow this
+convention, but do not allow the string to be longer than |longest_name|.
+
+@<Get a string@>= {/*spider*/
+ ASCII delim = c; /* what started the string */
+ id_first = mod_text+1;
+ id_loc = mod_text;
+ if (delim=='`' && *(loc-2)==at_sign) {
+ /* make string begin with |"@@`"| */
+ *++id_loc=at_sign;
+ *++id_loc=at_sign;
+ }
+ /* this is hack for ascii constant */
+@#
+/* if it's not a single-character literal, it's a tick mark or an |at_sign| */
+ if ((delim=='\'' || delim == '`') &&
+ (loc+1>=limit ||
+ (*loc != '\\' && *loc!=at_sign && loc[1]!='\'') ||
+ (*loc=='\\' && (loc+2>=limit||loc[2]!='\'')) ||
+ (*loc==at_sign &&
+ (loc+2>=limit||loc[1]!=at_sign||loc[2]!='\''))
+ )
+ ) goto mistake;
+ *++id_loc=delim;
+ if (delim=='`') delim='\''; /* for |ascii_constant|s */
+ while (1) {
+ if (loc>=limit) {
+ if(*(limit-1)!='\\') {
+ err_print("! String didn't end"); loc=limit; break;
+@.String didn't end@>
+ }
+ if(get_line()==0) {
+ err_print("! Input ended in middle of string"); loc=buffer; break;
+@.Input ended in middle of string@>
+ }
+ }
+ if ((c=*loc++)==delim) {
+ if (++id_loc<=mod_text_end) *id_loc=c;
+ break;
+ }
+ if (c=='\\') if (loc>=limit) continue;
+ else if (++id_loc<=mod_text_end) {
+ *id_loc = '\\'; c=*loc++;
+ }
+ if (++id_loc<=mod_text_end) *id_loc=c;
+ }
+ if (id_loc>=mod_text_end) {
+ printf("\n! String too long: ");
+@.String too long@>
+ ASCII_write(mod_text+1,25);
+ printf("..."); mark_error;
+ }
+ id_loc++;
+ return(string);
+}
+
+@ After an \.{@@} sign has been scanned, the next character tells us
+whether there is more work to do.
+
+@<Get control code and possible module name@>= {
+ c=*loc++;
+ switch(ccode[c]) {
+ case underline: xref_switch=def_flag; continue;
+ case switch_math_flag: math_flag=!math_flag; continue;
+#ifdef DEBUG
+ case trace: tracing=c-'0'; continue;
+#endif DEBUG
+ case xref_roman: case xref_wildcard: case xref_typewriter:
+ case TeX_string:
+ @<Scan to the next \.{@@>}@>@;
+ case module_name:
+ @<Scan the module name and make |cur_module| point to it@>@;
+ case verbatim: @<Scan a verbatim string@>@;
+ case ascii_constant: /* fake into looking like quoted char */
+ @<Get a string@>;
+ case octal: @<Get an octal constant@>;
+ case hex: @<Get a hex constant@>;
+ default: return(ccode[c]);
+ }
+}
+
+@ The occurrence of a module name sets |xref_switch| to zero,
+because the module name might (for example) follow \&{int}.
+
+@<Scan the module name...@>= {
+ ASCII *k; /* pointer into |mod_text| */
+ cur_module_char=c; /* remember |'<'| or |'('| */
+ @<Put module name into |mod_text|@>;
+ if (k-mod_text>3 && strncmp(k-2,"...",3)==0) cur_module=prefix_lookup(mod_text+1,k-3);
+ else cur_module=mod_lookup(mod_text+1,k);
+ xref_switch=0; return(module_name);
+}
+
+@ @<Global...@>=ASCII cur_module_char;
+
+@ Module names are placed into the |mod_text| array with consecutive spaces,
+tabs, and carriage-returns replaced by single spaces. There will be no
+spaces at the beginning or the end. (We set |mod_text[0]=' '| to facilitate
+this, since the |mod_lookup| routine uses |mod_text[1]| as the first
+character of the name.)
+
+@<Set init...@>=mod_text[0]=' ';
+
+@ @<Put module name...@>=
+k=mod_text;
+while (1) {
+ if (loc>limit && get_line()==0) {
+ err_print("! Input ended in section name");
+@.Input ended in section name@>
+ loc=buffer+1; break;
+ }
+ c=*loc;
+ @<If end of name, |break|@>;
+ loc++; if (k<mod_text_end) k++;
+ if (c==' ' || c==tab_mark) {
+ c=' '; if (*(k-1)==' ') k--;
+ }
+*k=c;
+}
+if (k>=mod_text_end) {
+ printf("\n! Section name too long: ");
+@.Section name too long@>
+ ASCII_write(mod_text+1,25);
+ printf("..."); mark_harmless;
+}
+if (*k==' ' && k>mod_text) k--;
+
+@ @<If end of name,...@>=
+if (c==at_sign) {
+ c=*(loc+1);
+ if (c=='>') {
+ loc+=2; break;
+ }
+ if (ccode[c]==new_module) {
+ err_print("! Section name didn't end"); break;
+@.Section name didn't end@>
+ }
+ *(++k)=at_sign; loc++; /* now |c==*loc| again */
+}
+
+@ @<Scan to the next...@>= {
+ c=ccode[*(loc-1)]; id_first=loc; *(limit+1)=at_sign;
+ while (*loc!=at_sign) loc++;
+ id_loc=loc;
+ if (loc++>limit) {
+ err_print("! Control text didn't end"); loc=limit; return(c);
+@.Control text didn't end@>
+ }
+ if (*loc++!='>') err_print("! Control codes are forbidden in control text");
+@.Control codes are forbidden...@>
+ return(c);
+}
+
+@ At the present point in the program we
+have |*(loc-1)=verbatim|; we set |id_first| to the beginning
+of the string itself, and |id_loc| to its ending-plus-one location in the
+buffer. We also set |loc| to the position just after the ending delimiter.
+
+@<Scan a verbatim string@>= {
+ id_first=loc++; *(limit+1)=at_sign; *(limit+2)='>';
+ while (*loc!=at_sign || *(loc+1)!='>') loc++;
+ if (loc>=limit) err_print("! Verbatim string didn't end");
+@.Verbatim string didn't end@>
+ id_loc=loc; loc+=2;
+ return (verbatim);
+}
+
+@* Phase one processing.
+We now have accumulated enough subroutines to make it possible to carry out
+\.{WEAVE}'s first pass over the source file. If everything works right,
+both phase one and phase two of \.{WEAVE} will assign the same numbers to
+modules, and these numbers will agree with what \.{TANGLE} does.
+
+The global variable |next_control| often contains the most recent output of
+|get_next|; in interesting cases, this will be the control code that
+ended a module or part of a module.
+
+@<Global...@>=
+eight_bits next_control; /* control code waiting to be acting upon */
+
+@ The overall processing strategy in phase one has the following
+straightforward outline.
+
+@u phase_one() {
+phase=1; reset_input(); module_count=0;
+skip_limbo(); change_exists=0;
+while (!input_has_ended)
+ @<Store cross-reference data for the current module@>;
+changed_module[module_count]=change_exists;
+ /* the index changes if anything does */
+phase=2; /* prepare for second phase */
+@<Print error messages about unused or undefined module names@>;
+}
+
+@ @<Store cross-reference data...@>=
+{
+ if (++module_count==max_modules) stat_overflow("section number");
+ changed_module[module_count]=0; /* it will become 1 if any line changes */
+ if (*(loc-1)=='*') {
+ printf("*%d",module_count);
+ update_terminal; /* print a progress report */
+ }
+ @<Store cross-references in the \TeX\ part of a module@>;
+ @<Store cross-references in the definition part of a module@>;
+ @<Store cross-references in the \cee\ part of a module@>;
+ if (changed_module[module_count]) change_exists=1;
+}
+
+@ The |C_xref| subroutine stores references to identifiers in
+\cee\ text material beginning with the current value of |next_control|
+and continuing until |next_control| is `\.\{' or `\v', or until the next
+``milestone'' is passed (i.e., |next_control>=format|). If
+|next_control>=format| when |C_xref| is called, nothing will happen;
+but if |next_control="|"| upon entry, the procedure assumes that this is
+the `\v' preceding \cee\ text that is to be processed.
+
+The program uses the fact that our internal code numbers satisfy
+the relations |xref_roman=identifier+roman| and |xref_wildcard=identifier
++wildcard| and |xref_typewriter=identifier+typewriter| and |normal=0|.
+
+@u C_xref(see_v) /* makes cross-references for \cee\ identifiers */
+ char see_v;
+{
+ name_pointer p; /* a referenced name */
+ while (next_control<format) {
+ if (next_control>=identifier && next_control<=xref_typewriter) {
+ p=id_lookup(id_first, id_loc,next_control-identifier); new_xref(p);
+ }
+ next_control=get_next(see_v);
+ if (next_control==vertical_bar || next_control==begin_comment) return;
+ }
+}
+
+@ The |outer_xref| subroutine is like |C_xref| but it begins
+with |next_control!=vertical_bar| and ends with |next_control>=format|. Thus, it
+handles \cee\ text with embedded comments.
+
+@u outer_xref() /* extension of |C_xref| */
+{
+ int bal; /* brace level in comment */
+ while (next_control<format)
+ if (next_control!=begin_comment) C_xref(0);
+ else {
+ bal=copy_comment(1); next_control=vertical_bar;
+ while (bal>0) {
+ C_xref(1);
+ if (next_control==vertical_bar) bal=copy_comment(bal);
+ else bal=0; /* an error message will occur in phase two */
+ }
+ }
+}
+
+@ In the \TeX\ part of a module, cross-reference entries are made only for
+the identifiers in \cee\ texts enclosed in \pb, or for control texts
+enclosed in \.{@@\^}$\,\ldots\,$\.{@@>} or \.{@@.}$\,\ldots\,$\.{@@>}
+or \.{@@:}$\,\ldots\,$\.{@@>}.
+
+@<Store cross-references in the \T...@>=
+while (1) {
+ switch (next_control=skip_TeX()) {
+ case underline: xref_switch=def_flag; continue;
+#ifdef DEBUG
+ case trace: tracing=next_control-'0'; continue;
+#endif DEBUG
+ case vertical_bar: C_xref(1); break;
+ case xref_roman: case xref_wildcard:
+ case xref_typewriter: case module_name:
+ loc-=2; next_control=get_next(1); /* scan to \.{@@>} */
+ if (next_control!=module_name) {
+/* |printf ("\nweave debugging: new xref: ");| */
+/* |{char *p; for (p=id_first;p<id_loc;p++) putchar(*p);}| */
+/* |putchar('\n');|
+ */
+ new_xref(id_lookup(id_first, id_loc,next_control-identifier));
+ }
+ break;
+ }
+ if (next_control>=format) break;
+}
+
+@ During the definition and \cee\ parts of a module, cross-references
+are made for all identifiers except reserved words; however, the
+identifiers in a format definition are referenced even if they are
+reserved. The \TeX\ code in comments is, of course, ignored, except for
+\cee\ portions enclosed in \pb; the text of a module name is skipped
+entirely, even if it contains \pb\ constructions.
+
+The variables |lhs| and |rhs| point to the respective identifiers involved
+in a format definition.
+
+@<Global...@>=
+name_pointer lhs, rhs; /* pointers to |byte_start| for format identifiers */
+
+@ When we get to the following code we have |next_control>=format|.
+
+@<Store cross-references in the d...@>=
+while (next_control<=definition) { /* |format| or |definition| */
+ xref_switch=def_flag; /* implied \.{@@!} */
+ if (next_control==definition) next_control=get_next(1);
+ else @<Process a format definition@>;
+ outer_xref();
+}
+
+@ Error messages for improper format definitions will be issued in phase
+two. Our job in phase one is to define the |ilk| of a properly formatted
+identifier, and to fool the |new_xref| routine into thinking that the
+identifier on the right-hand side of the format definition is not a
+reserved word.
+
+@<Process a form...@>= {
+ next_control=get_next(1);
+ if (next_control==identifier) {
+ lhs=id_lookup(id_first, id_loc,normal); lhs->ilk=normal; new_xref(lhs);
+ next_control=get_next(1);
+ if (next_control==identifier) {
+ rhs=id_lookup(id_first, id_loc,normal);
+ lhs->ilk=rhs->ilk; rhs->ilk=normal; new_xref(rhs);
+ rhs->ilk=lhs->ilk; next_control=get_next(1);
+ }
+ }
+}
+
+@ Finally, when the \TeX\ and definition parts have been treated, we have
+|next_control>=begin_unnamed|.
+
+@<Store cross-references in the \cee...@>=
+if (next_control<=module_name) { /* |begin_unnamed| or |module_name| */
+ if (next_control==begin_unnamed) mod_xref_switch=0;
+ else mod_xref_switch=(cur_module_char=='<' ? def_flag: file_flag);
+ do {
+ if (next_control==module_name && cur_module!=NULL) new_mod_xref(cur_module);
+ next_control=get_next(1); outer_xref();
+ } while ( next_control<=module_name);
+}
+
+@ After phase one has looked at everything, we want to check that each
+module name was both defined and used. The variable |cur_xref| will point
+to cross-references for the current module name of interest.
+
+@<Global...@>=
+xref_pointer cur_xref; /* temporary cross-reference pointer */
+
+@ The following recursive procedure
+walks through the tree of module names and prints out anomalies.
+@^recursion@>
+
+@u mod_check(p) name_pointer p; /* print anomalies in subtree |p| */
+{
+ int level; /* 0: use 1: definition 2: file definition */
+ if (p) {
+ mod_check(p->llink);
+ cur_xref=(xref_pointer)p->xref;
+ level=(cur_xref->num)/def_flag;
+ if (level==0) {
+ printf("\n! Never defined: <"); print_id(p); putchar('>'); mark_harmless;
+@.Never defined: <section name>@>
+ }
+ while (cur_xref->num >=def_flag) {
+ if ((cur_xref->num)/def_flag != level) {
+ printf("\n! You can't use <"); print_id(p);
+ printf("> both as a file and as a named module"); mark_harmless;
+@.You can't use <section name> both as a file...@>
+ }
+ cur_xref=cur_xref->xlink;
+ }
+ if (cur_xref==xmem && level<2) {
+ printf("\n! Never used: <"); print_id(p); putchar('>'); mark_harmless;
+@.Never used: <section name>@>
+ }
+ else if (cur_xref!=xmem && level==2) {
+ printf("\n! You can't use file module ("); print_id(p);
+ putchar(')'); mark_harmless;
+@.You can't use file module (file name)@>
+ }
+ mod_check(p->rlink);
+ }
+}
+
+@ @<Print error messages about un...@>=mod_check(root)
+
+@* Low-level output routines.
+The \TeX\ output is supposed to appear in lines at most |line_length|
+characters long, so we place it into an output buffer. During the output
+process, |out_line| will hold the current line number of the line about to
+be output.
+
+@<Global...@>=
+ASCII out_buf[line_length+1]; /* assembled characters */
+ASCII *out_ptr; /* just after last character in |out_buf| */
+ASCII *out_buf_end = out_buf+line_length; /* end of |out_buf| */
+int out_line; /* number of next line to be output */
+
+@ The |flush_buffer| routine empties the buffer up to a given breakpoint,
+and moves any remaining characters to the beginning of the next line.
+If the |per_cent| parameter is 1 a |'%'| is appended to the line
+that is being output; in this case the breakpoint |b| should be strictly
+less than |out_buf_end|. If the |per_cent| parameter is |0|,
+trailing blanks are suppressed.
+The characters emptied from the buffer form a new line of output.
+
+The same caveat that applies to |ASCII_write| applies to |c_line_write|.
+
+@d c_line_write(c) = fflush(tex_file),write(fileno(tex_file),out_buf+1,c)@;
+@d tex_putxchar(c) = putc(xchr[c],tex_file)@;
+@d tex_new_line = putc('\n',tex_file)@;
+@d tex_printf(c) = fprintf(tex_file,c)@;
+
+@u flush_buffer(b,per_cent)
+ASCII *b;
+boolean per_cent; /* outputs from |out_buf+1| to |b|,where |b<=out_ptr| */
+{
+ ASCII *j; j=b; /* pointer into |out_buffer| */
+ if (! per_cent) /* remove trailing blanks */
+ while (j>out_buf && *j==' ') j--;
+ c_line_write(j-out_buf);
+ if (per_cent) tex_putxchar('%');
+ tex_new_line; out_line++;
+ if (b<out_ptr) strncpy(out_buf+1,b+1,out_ptr-b);
+ out_ptr-=b-out_buf;
+}
+
+@ When we are copying \TeX\ source material, we retain line breaks
+that occur in the input, except that an empty line is not
+output when the \TeX\ source line was nonempty. For example, a line
+of the \TeX\ file that contains only an index cross-reference entry
+will not be copied. The |finish_line| routine is called just before
+|get_line| inputs a new line, and just after a line break token has
+been emitted during the output of translated \cee\ text.
+
+@u finish_line() /* do this at the end of a line */
+{
+ ASCII *k; /* pointer into |buffer| */
+ if (out_ptr>out_buf) flush_buffer(out_ptr,0);
+ else {
+ for (k=buffer; k<=limit; k++)
+ if (*k!=' ' && *k!=tab_mark) return;
+ flush_buffer(out_buf,0);
+ }
+}
+
+@ In particular, the |finish_line| procedure is called near the very
+beginning of phase two. We initialize the output variables in a slightly
+tricky way so that the first line of the output file will be a command
+to read in the macro file.
+
+@<Set init...@>=
+out_ptr=out_buf+1; out_line=1;
+@<Set |out_ptr| and do a |tex_printf| to read the macros@>
+
+@ When we wish to append one character |c| to the output buffer, we write
+`|out(c)|'; this will cause the buffer to be emptied if it was already
+full. If we want to append more than one character at once, we say
+|out_str(s)|, where |s| is a string containing the characters,
+or |out_str_del(s,t)|, where |s| and |t| point to the same array of
+characters; characters from |s| to |t-1|, inclusive, are output.
+
+A line break will occur at a space or after a single-nonletter
+\TeX\ control sequence.
+
+@d out(c) = {if (out_ptr>=out_buf_end) break_out(); *(++out_ptr)=c;}
+
+@u out_str_del(s,t) /* output characters from |s| to |t-1| */
+ASCII *s, *t;
+{
+ while (s<t) out(*s++);
+}
+
+out_str(s) /* output characters from |s| to end of string */
+ASCII *s;
+{
+ while (*s) out(*s++);
+}
+
+@ The |break_out| routine is called just before the output buffer is about
+to overflow. To make this routine a little faster, we initialize position
+0 of the output buffer to `\.\\'; this character isn't really output.
+
+@<Set init...@>=
+out_buf[0]='\\';
+
+@ A long line is broken at a blank space or just before a backslash that isn't
+preceded by another backslash. In the latter case, a |'%'| is output at
+the break.
+
+@u break_out() /* finds a way to break the output line */
+{
+ ASCII *k=out_ptr; /* pointer into |out_buf| */
+ while (1) {
+ if (k==out_buf) @<Print warning message, break the line, |return|@>;
+ if (*k==' ') {
+ flush_buffer(k,0); return;
+ }
+ if (*(k--)=='\\' && *k!='\\') { /* we've decreased |k| */
+ flush_buffer(k,1); return;
+ }
+ }
+}
+
+@ We get to this module only in unusual cases that the entire output line
+consists of a string of backslashes followed by a string of nonblank
+non-backslashes. In such cases it is almost always safe to break the
+line by putting a |'%'| just before the last character.
+
+@<Print warning message...@>=
+{
+ printf("\n! Line had to be broken (output l. %d):\n",out_line);
+@.Line had to be broken@>
+ ASCII_write(out_buf+1, out_ptr-out_buf-1);
+ new_line; mark_harmless;
+ flush_buffer(out_ptr-1,1); return;
+}
+
+@ Here is a macro that outputs a module number in decimal notation.
+The number to be converted by |out_mod| is known to be less than
+|def_flag|, so it cannot have more than five decimal digits. If
+the module is changed, we output `\.{\\*}' just after the number.
+
+@u out_mod(n) sixteen_bits n;
+{
+ ASCII s[6];
+ sprintf(s,"%d",n); out_str(s);
+ if(changed_module[n]) out_str ("\\*");
+}
+
+@ The |out_name| procedure is used to output an identifier or index
+entry, enclosing it in braces.
+
+@u out_name(p) name_pointer p; {
+ ASCII *k, *k_end=(p+1)->byte_start; /* pointers into |byte_mem| */
+ out('{');
+ for (k=p->byte_start; k<k_end; k++) {
+ if (*k=='$') {out('\\'); out('D'); out('O'); out(' ');}
+ else if (*k=='&') {out('\\'); out('a'); out('m'); out('p');}
+ else {
+ if (*k=='_' || *k=='%' || *k=='#' || *k=='^' || *k=='{' || *k=='}')
+ out('\\');
+ out(*k);
+ }
+ }
+ out('}');
+}
+
+@* Routines that copy \TeX\ material.
+During phase two, we use the subroutines |copy_limbo|, |copy_TeX|, and
+|copy_comment| in place of the analogous |skip_limbo|, |skip_TeX|, and
+|skip_comment| that were used in phase one.
+
+The |copy_limbo| routine, for example, takes \TeX\ material that is not
+part of any module and transcribes it almost verbatim to the output file.
+No `\.{@@}' signs should occur in such material except in `\.{@@@@}'
+pairs; such pairs are replaced by singletons.
+
+@u copy_limbo()
+{
+ ASCII c;
+ while (1) {
+ if (loc>limit && (finish_line(), get_line()==0)) return;
+ *(limit+1)=at_sign;
+ while (*loc!=at_sign) out(*(loc++));
+ if (loc++<=limit) {
+ c=*loc++;
+ if (ccode[c]==new_module) break;
+ if (c!='z' && c!='Z') {
+ out(at_sign);
+ if (c!=at_sign) err_print("! Double @@ required outside of sections");
+@.Double \AT! required...@>
+ }
+ }
+ }
+}
+
+
+@ The |copy_TeX| routine processes the \TeX\ code at the beginning of a
+module; for example, the words you are now reading were copied in this
+way. It returns the next control code or `\v' found in the input.
+We don't copy spaces or tab marks into the beginning of a line. This
+makes the test for empty lines in |finish_line| work.
+
+@<Global...@>= eight_bits next_control; /* control code found */
+
+@ @u eight_bits copy_TeX()
+{
+ ASCII c; /* current character being copied */
+ while (1) {
+ if (loc>limit && (finish_line(), get_line()==0)) return(new_module);
+ *(limit+1)=at_sign;
+ while ((c=*(loc++))!=vertical_char && c!=at_sign) {
+ out(c);
+ if (out_ptr==out_buf+1 && (c==' ' || c==tab_mark)) out_ptr--;
+ }
+ if (c==vertical_char) return(vertical_bar);
+ if (loc<=limit) return(ccode[*(loc++)]);
+ }
+}
+
+@ The |copy_comment| function issues a warning if more braces are opened than
+closed, and in the case of a more serious error it supplies enough
+braces to keep \TeX\ from complaining about unbalanced braces.
+Instead of copying the \TeX\ material
+into the output buffer, this function copies it into the token memory.
+The abbreviation |app_tok(t)| is used to append token |t| to the current
+token list, and it also makes sure that it is possible to append at least
+one further token without overflow.
+
+Copies to end and then follows end of comment with a right brace.
+
+@d app_tok(c) = {if (tok_ptr+2>tok_mem_end) stat_overflow("token"); *(tok_ptr++)=c;}
+
+@u
+copy_comment(bal) /* copies \TeX\ code in comments */
+int bal; /* brace balance */
+{
+ ASCII c; /* current character being copied */
+ while (1) {
+ if (loc>limit)
+ if (comments_end_with_newline) {
+ loc++; if(bal==1) {if (phase==2) app_tok('}'); return(0);}
+ else {
+ err_print("! Braces don't balance in comment");
+@.Braces don't balance in comment@>
+ @<Clear |bal| and |return|@>;
+ }
+ } else {
+ if (get_line()==0) {
+ err_print("! Input ended in mid-comment");
+@.Input ended in mid-comment@>
+ loc=buffer+1; @<Clear |bal| and |return|@>;
+ }
+ }
+
+ c=*(loc++);
+ if (c==vertical_char) return(bal);
+ @<Check for end of comment@>;
+ if (phase==2) app_tok(c);
+ @<Copy special things when |c==at_sign, '\\', '{', '}'|; |return| at end@>;
+ }
+}
+
+
+
+@ @<Copy special things when |c==at_sign...@>=
+if (c==at_sign) {
+ if (*(loc++)!=at_sign) {
+ err_print("! Illegal use of @@ in comment");
+@.Illegal use of \AT!...@>
+ loc-=2; if (phase==2) tok_ptr--; @<Clear |bal|...@>;
+ }
+}
+else if (c=='\\' && *loc!=at_sign && phase==2) app_tok(*(loc++))@;
+else if (c=='{') bal++;
+else if (c=='}') bal--;
+
+@ When the comment has terminated abruptly due to an error, we output
+enough right braces to keep \TeX\ happy.
+
+@<Clear |bal|...@>=
+app_tok(' '); /* this is done in case the previous character was `\.\\' */
+while (bal-- >0) app_tok('}');
+/* |if (see_end_of_line) next_control=end_of_line;| */
+return(0);
+
+@* Parsing.
+The most intricate part of \.{WEAVE} is its mechanism for converting
+\cee-like code into \TeX\ code, and we might as well plunge into this
+aspect of the program now. A ``bottom up'' approach is used to parse the
+\cee-like material, since \.{WEAVE} must deal with fragmentary
+constructions whose overall ``part of speech'' is not known.
+
+At the lowest level, the input is represented as a sequence of entities
+that we shall call {\it scraps}, where each scrap of information consists
+of two parts, its {\it category} and its {\it translation}. The category
+is essentially a syntactic class, and the translation is a token list that
+represents \TeX\ code. Rules of syntax and semantics tell us how to
+combine adjacent scraps into larger ones, and if we are lucky an entire
+\cee\ text that starts out as hundreds of small scraps will join
+together into one gigantic scrap whose translation is the desired \TeX\
+code. If we are unlucky, we will be left with several scraps that don't
+combine; their translations will simply be output, one by one.
+
+The combination rules are given as context-sensitive productions that are
+applied from left to right. Suppose that we are currently working on the
+sequence of scraps $s_1\,s_2\ldots s_n$. We try first to find the longest
+production that applies to an initial substring $s_1\,s_2\ldots\,$; but if
+no such productions exist, we find to find the longest production
+applicable to the next substring $s_2\,s_3\ldots\,$; and if that fails, we
+try to match $s_3\,s_4\ldots\,$, etc.
+
+A production applies if the category codes have a given pattern. For
+example, one of the productions is
+$$open\ math\ semi\ \RA\ open\ math$$
+and it means that three consecutive scraps whose respective categories are
+|open|, |math|, and |semi| are con\-verted to two scraps whose categories
+are |open| and |math|. This production also has an associated rule that
+tells how to combine the translation parts:
+$$\eqalign{O_2&=O_1\cr
+M_2&=M_1\,S\,\.{\\,}\,\hbox{|opt|\thinspace\tt5}\cr}$$
+This means that the |open| scrap has not changed, while the new |math| scrap
+has a translation $M_2$ composed of the translation $M_1$ of the original
+|math| scrap followed by the translation |S| of the |semi| scrap followed
+by `\.{\\,}' followed by `|opt|' followed by `\.5'. (In the \TeX\ file,
+this will specify an additional thin space after the semicolon, followed
+by an optional line break with penalty 50.) Translation rules use subscripts
+to distinguish between translations of scraps whose categories have the
+same initial letter; these subscripts are assigned from left to right.
+
+$\.{WEAVE}$ also has the production rule
+$$\hbox{|semi|$\;\RA\;$|terminator|}$$
+(meaning that a semicolon can terminate a \cee\ statement). Since
+productions are applied from left to right, this rule will be activated
+only if the |semi| is not preceded by scraps that match other productions;
+in particular, a |semi| that is preceded by `|open| |math|' will have
+disappeared because of the production above, and such semicolons do not
+act as statement terminators.
+
+The translation rule corresponding to $\hbox{|semi|$\;\RA\;$|terminator|}$ is
+$$T=S$$
+but we shall not mention translation rules in the common case that the
+translation of the new scrap on the right-hand side is simply the
+concatenation of the disappearing scraps on the left-hand side.
+
+
+
+@ The token lists for translated \TeX\ output contain some special control
+symbols as well as ordinary characters. These control symbols are
+interpreted by \.{WEAVE} before they are written to the output file.
+
+\yskip\hang |break_space| denotes an optional line break or an en space;
+
+\yskip\hang |force| denotes a line break;
+
+\yskip\hang |big_force| denotes a line break with additional vertical space;
+
+\yskip\hang |opt| denotes an optional line break (with the continuation
+line indented two ems with respect to the normal starting position)---this
+code is followed by an integer |n|, and the break will occur with penalty
+$10n$;
+
+\yskip\hang |backup| denotes a backspace of one em;
+
+\yskip\hang |cancel| obliterates any |break_space| or |force| or |big_force|
+tokens that immediately precede or follow it and also cancels any
+|backup| tokens that follow it;
+
+\yskip\hang |indent| causes future lines to be indented one more em;
+
+\yskip\hang |outdent| causes future lines to be indented one less em.
+
+\yskip\noindent All of these tokens are removed from the \TeX\ output that
+comes from \cee\ text between \pb\ signs; |break_space| and |force| and
+|big_force| become single spaces in this mode. The translation of other
+\cee\ texts results in \TeX\ control sequences \.{\\1}, \.{\\2},
+\.{\\3}, \.{\\4}, \.{\\5}, \.{\\6}, \.{\\7} corresponding respectively to
+|indent|, |outdent|, |opt|, |backup|, |break_space|, |force|, and
+|big_force|. However, a sequence of consecutive `\.\ ', |break_space|,
+|force|, and/or |big_force| tokens is first replaced by a single token
+(the maximum of the given ones).
+
+The tokens |math_rel| and |math_bin| will be translated into
+\.{\\mathrel\{} and \.{\\mathbin\{}, respectively.
+Also |math_op| to \.{\\mathop\{}.
+Other control sequences in the \TeX\ output will be `\.{\\\\\{}$\,\ldots\,$\.\}'
+surrounding identifiers, `\.{\\\&\{}$\,\ldots\,$\.\}' surrounding
+reserved words, `\.{\\.\{}$\,\ldots\,$\.\}' surrounding strings,
+`\.{\\cee\{}$\,\ldots\,$\.\}$\,$|force|' surrounding comments, and
+`\.{\\X$n$:}$\,\ldots\,$\.{\\X}' surrounding module names, where
+|n| is the module number.
+
+@d math_bin = @'205 /* should these be octal or decimal? */
+@d math_rel = @'206
+@d math_op = @'207
+@d big_cancel = @'210 /* like |cancel|, also overrides spaces */
+@d cancel = @'211 /* overrides |backup|, |break_space|, |force|, |big_force| */
+@d indent = cancel+1 /* one more tab (\.{\\1}) */
+@d outdent = cancel+2 /* one less tab (\.{\\2}) */
+@d opt = cancel+3 /* optional break in mid-statement (\.{\\3}) */
+@d backup = cancel+4 /* stick out one unit to the left (\.{\\4}) */
+@d break_space = cancel+5 /* optional break between statements (\.{\\5}) */
+@d force = cancel+6 /* forced break between statements (\.{\\6}) */
+@d big_force = cancel+7 /* forced break with additional space (\.{\\7}) */
+@d end_translation = big_force+1 /* special sentinel token at end of list */
+
+@ Here is a table of all the productions. The reader can best get a feel for
+@^productions, table of@>
+how they work by trying them out by hand on small examples; no amount of
+explanation will be as effective as watching the rules in action.
+Parsing can also be watched by debugging with `\.{@@2}'.
+
+@i grammar.web
+
+@* Implementing the productions.
+More specifically, a scrap is a structure consisting of a category
+|cat| and a |text_pointer| |trans|, which points to the translation in
+|tok_start|. When \cee\ text is to be processed with the grammar above,
+we form an array |scrap_info| containing the initial scraps.
+Our production rules have the nice property that the right-hand side is never
+longer than the left-hand side. Therefore it is convenient to use sequential
+allocation for the current sequence of scraps. Five pointers are used to
+manage the parsing:
+
+\yskip\hang |pp| is a pointer into |scrap_info|. We will try to match
+the category codes |pp->cat@,(pp+1)->cat|$\,\ldots\,$ to the left-hand sides
+of productions.
+
+\yskip\hang |scrap_base|, |lo_ptr|, |hi_ptr|, and |scrap_ptr| are such that
+the current sequence of scraps appears in positions |scrap_base| through
+|lo_ptr| and |hi_ptr| through |scrap_ptr|, inclusive, in the |cat| and
+|trans| arrays. Scraps located between |scrap_base| and |lo_ptr| have
+been examined, while those in positions |>=hi_ptr| have not yet been
+looked at by the parsing process.
+
+\yskip\noindent Initially |scrap_ptr| is set to the position of the final
+scrap to be parsed, and it doesn't change its value. The parsing process
+makes sure that |lo_ptr>=pp+3|, since productions have as many as four terms,
+by moving scraps from |hi_ptr| to |lo_ptr|. If there are
+fewer than |pp+3| scraps left, the positions up to |pp+3| are filled with
+blanks that will not match in any productions. Parsing stops when
+|pp=lo_ptr+1| and |hi_ptr=scrap_ptr+1|.
+
+Since the |scrap| structure will later be used for other purposes, we
+declare its second element as unions.
+
+@<Type...@>=
+typedef struct {
+ eight_bits cat;
+ eight_bits mathness;
+ union {
+ text_pointer Trans;
+ ===> @<Rest of |trans_plus| union@>@;
+ } trans_plus;
+} scrap;
+typedef scrap *scrap_pointer;
+
+@ @d trans = trans_plus.Trans /* translation texts of scraps */
+@d no_math = 2
+@d yes_math = 1
+@d maybe_math = 0
+@d left_math(A) = ((A)->mathness %4)
+@d right_math(A) = (((A)->mathness/4)%4)
+@d make_math(LM,RM) = ((eight_bits) (LM+4*(RM)))
+
+
+@<Global...@>=
+scrap scrap_info[max_scraps]; /* memory array for scraps */
+scrap_pointer scrap_info_end=scrap_info+max_scraps -1; /* end of |scrap_info| */
+scrap_pointer pp; /* current position for reducing productions */
+scrap_pointer scrap_base; /* beginning of the current scrap sequence */
+scrap_pointer scrap_ptr; /* ending of the current scrap sequence */
+scrap_pointer lo_ptr; /* last scrap that has been examined */
+scrap_pointer hi_ptr; /* first scrap that has not been examined */
+#ifdef STAT
+scrap_pointer max_scr_ptr; /* largest value assumed by |scrap_ptr| */
+#endif STAT
+
+@ @<Set init...@>=
+scrap_base=scrap_info+1;
+#ifdef STAT
+max_scr_ptr=
+#endif STAT
+scrap_ptr=scrap_info;
+
+@ Token lists in |@!tok_mem| are composed of the following kinds of
+items for \TeX\ output.
+
+\yskip\item{$\bullet$}ASCII codes and special codes like |force| and
+|math_rel| represent themselves;
+
+\item{$\bullet$}|id_flag+p| represents \.{\\\\\{{\rm identifier $p$}\}};
+
+\item{$\bullet$}|res_flag+p| represents \.{\\\&\{{\rm identifier $p$}\}};
+
+\item{$\bullet$}|mod_flag+p| represents module name |p|;
+
+\item{$\bullet$}|tok_flag+p| represents token list number |p|;
+
+\item{$\bullet$}|inner_tok_flag+p| represents token list number |p|, to be
+translated without line-break controls.
+
+@d id_flag = 10240 /* signifies an identifier */
+@d res_flag = 2*id_flag /* signifies a reserved word */
+@d mod_flag = 3*id_flag /* signifies a module name */
+@d tok_flag = 4*id_flag /* signifies a token list */
+@d inner_tok_flag = 5*id_flag /* signifies a token list in `\pb' */
+
+@u
+#ifdef DEBUG
+print_text(p) /* prints a token list */
+text_pointer p;
+{
+ token_pointer j; /* index into |tok_mem| */
+ sixteen_bits r; /* remainder of token after the flag has been stripped off */
+ if (p>=text_ptr) printf("BAD");
+ else for (j=*p; j<*(p+1); j++) {
+ r=*j%id_flag;
+ switch (*j/id_flag) {
+ case 1: printf("\\{"); print_id((name_dir+r)); printf("}"); break;
+ /* |id_flag| */
+ case 2: printf("\\&{"); print_id((name_dir+r)); printf("}"); break;
+ /* |res_flag| */
+ case 3: printf("<"); print_id((name_dir+r)); printf(">"); break;
+ /* |mod_flag| */
+ case 4: printf("[[%d]]",r); break; /* |tok_flag| */
+ case 5: printf("|[[%d]]|",r); break; /* |inner_tok_flag| */
+ default: @<Print token |r| in symbolic form@>;
+ }
+ }
+}
+#endif DEBUG
+
+@ @<Print token |r|...@>=
+switch (r) {
+ case math_bin: printf("\\mathbin{"); break;
+ case math_op: printf("\\mathop{"); break;
+ case math_rel: printf("\\mathrel{"); break;
+ case big_cancel: printf("[ccancel]"); break;
+ case cancel: printf("[cancel]"); break;
+ case indent: printf("[indent]"); break;
+ case outdent: printf("[outdent]"); break;
+ case backup: printf("[backup]"); break;
+ case opt: printf("[opt]"); break;
+ case break_space: printf("[break]"); break;
+ case force: printf("[force]"); break;
+ case big_force: printf("[fforce]"); break;
+ case end_translation: printf("[quit]"); break;
+ default: putxchar(r);
+}
+
+@ The production rules listed above are embedded directly into the \.{WEAVE}
+program, since it is easier to do this than to write an interpretive system
+that would handle production systems in general. Several macros are defined
+here so that the program for each production is fairly short.
+
+All of our productions conform to the general notion that some |k|
+consecutive scraps starting at some position |j| are to be replaced by a
+single scrap of some category |c| whose translations is composed from the
+translations of the disappearing scraps. After this production has been
+applied, the production pointer |pp| should change by an amount |d|. Such
+a production can be represented by the quadruple |(j,k,c,d)|. For example,
+the production `|simp@,math| $\RA$ |math|' would be represented by
+`|(pp,2,math,-1)|'; in this case the pointer |pp| should decrease by 1
+after the production has been applied, because some productions with
+|math| in their second positions might now match, but no productions have
+|math| in the third or fourth position of their left-hand sides. Note that
+the value of |d| is determined by the whole collection of productions, not
+by an individual one. Consider the further example
+`|var_head@,math@,colon| $\RA$ |var_head@,intro|', which is represented by
+`|(pp+1,2,intro,+1)|'; the $+1$ here is deduced by looking at the
+grammar and seeing that no matches could possibly occur at positions |<=pp|
+after this production has been applied. The determination of |d| has been
+done by hand in each case, based on the full set of productions but not on
+the grammar of \cee\ or on the rules for constructing the initial
+scraps.
+
+We also attach a serial number of each production, so that additional
+information is available when debugging. For example, the program below
+contains the statement `|reduce(pp+1,2,intro,+1,52)|' when it implements
+the production just mentioned.
+
+Before calling |reduce|, the program should have appended the tokens of
+the new translation to the |tok_mem| array. We commonly want to append
+copies of several existing translations, and macros are defined to
+simplify these common cases. For example, |small_app2(pp)| will append the
+translations of two consecutive scraps, |trans[pp]| and |trans[pp+1]|, to
+the current token list. If the entire new translation is formed in this
+way, we write `|squash(j,k,c,d)|' instead of `|reduce(j,k,c,d)|'. For
+example, `|squash(pp,2,math,-1)|' is an abbreviation for `|small_app2(pp);
+reduce(pp,2,math,-1)|'.
+
+The code below is an exact translation of the production rules into
+\cee, using such macros, and the reader should have no difficulty
+understanding the format by comparing the code with the symbolic
+productions as they were listed earlier.
+
+@d app2(a) = app1(a);app1(a+1)@;
+@d app3(a) = app2(a);app1(a+2)@;
+@d app4(a) = app3(a);app1(a+3)@;
+@d small_app(a) = *(tok_ptr++)=a@;
+@d small_app1(a) = *(tok_ptr++)=tok_flag+(a)->trans-tok_start@;
+
+@<Global...@>=
+int init_mathness, last_mathness;
+
+@ @u app_str(s)
+ASCII *s;
+{
+ while (*s) small_app(*(s++));
+}
+
+app(a)
+token a;
+{
+ if (a==' ' || a>=big_cancel && a<=big_force) /* non-math token */ {
+ if (last_mathness==maybe_math) init_mathness=no_math;
+ else if (last_mathness==yes_math) small_app('$');
+ last_mathness=no_math;
+ }
+ else {
+ if (last_mathness==maybe_math) init_mathness=yes_math;
+ else if (last_mathness==no_math) small_app('$');
+ last_mathness=last_mathness=yes_math;
+ }
+ small_app(a);
+}
+app1(a)
+scrap_pointer a;
+{
+ switch (left_math(a)) { /* left boundary */
+ case (no_math):
+ if (last_mathness==maybe_math) init_mathness=no_math;
+ if (last_mathness==yes_math) small_app('$');
+ last_mathness = right_math(a); /* right boundary */
+ break;
+ case (yes_math):
+ if (last_mathness==maybe_math) init_mathness=yes_math;
+ else if (last_mathness==no_math) small_app('$');
+ last_mathness = right_math(a); /* right boundary */
+ break;
+ case (maybe_math): /* no changes */
+ break;
+ }
+ small_app(tok_flag+(a)->trans-tok_start);
+}
+
+@ Let us consider the big switch for productions now, before looking
+at its context. We want to design the program so that this switch
+works, so we might as well not keep ourselves in suspense about exactly what
+code needs to be provided with a proper environment.
+
+@<Match a production at |pp|, or increase |pp| if there is no match@>= {
+ /* |ignore_scrap| becomes part of the grammar */
+ @<Test for all of the productions@>@;
+ pp++; /* if no match was found, we move to the right */
+}
+
+@ It may be that during phase two we discover from some arrangement
+of the scraps that an identifier should be treated as a defining instance,
+meaning its index entry should be underlined.
+Since we're in phase two, the identifier is buried inside some scrap,
+which may contain other things as well.
+Using Spider to {\em star} a scrap causes the first identifier in that
+scrap's translation to get an underlined index entry.
+The starring generates a call to |make_underlined|, which
+finds the first identifier with |first_id| and then underlines it
+with |underline_xref|.
+@u
+@<Definition of |first_id|@>@;
+make_underlined(p)
+ /* underline the entry for the first identifier in |p->trans| */
+scrap_pointer p;
+{
+ sixteen_bits tok_value; /* a token:
+ the name of this identifier, plus its flag */
+ /* Assume |p->trans < text_ptr| */
+
+ /* attempt to set |tok_value| to the first identifier in |p->trans| */
+ tok_value = first_id(p->trans);
+ if (tok_value==0) {
+#ifdef DEBUG
+ if (tracing>0) {
+ printf("\n! I couldn't find an identifier to underline.");
+ mark_harmless;
+ }
+#endif DEBUG
+ return;
+ }
+ if (tok_value<id_flag || tok_value>=res_flag)
+ fatal("", "! Internal error in first_id");
+@.Internal error in first_id@>
+ /* don't underline identifiers of length 1, even if starred --- force
+ the user to use |"@@!"| */
+ if (length(tok_value-id_flag+name_dir)>1)
+ underline_xref(tok_value-id_flag+name_dir);
+}
+
+@ |first_id| finds the first identifier in a translation.
+It is indefatigable.
+It returns a |token| value, or zero if it can't find an identifier.
+@<Definition of |first_id|@>=
+
+sixteen_bits first_id(p)
+ text_pointer p;
+{
+ token_pointer tp; /* used to search for the first identifier */
+ sixteen_bits r; /* remainder after modding out by |id_flag| */
+ sixteen_bits the_id; /* the id we find, or zero otherwise */
+
+ for (tp=*p; tp<*(p+1); tp++) {
+ r=*tp%id_flag;
+ switch (*tp/id_flag) {
+ case 1: /* |id_flag| --- found it */
+ return *tp;
+ break;
+ case 2: /* |res_flag| */
+ case 3: /* |mod_flag| */
+ goto next;
+ break;
+ case 4: /* |tok_flag| */
+ case 5: /* |inner_tok_flag| */
+ /* search the inner list */
+ if ((the_id = first_id(tok_start+r))!=0) return the_id;
+ goto next;
+ break;
+ default:
+ goto next;
+ break;
+ }
+ next: continue;
+ }
+ return 0;
+}
+
+@ We cannot use |new_xref| to underline a cross-reference at this point
+because this would just make a new cross-reference at the end of the list.
+We actually have to search through the list for the existing
+cross-reference.
+
+@u underline_xref(p)
+name_pointer p;
+{
+ xref_pointer q=(xref_pointer)p->xref;
+ /* pointer to cross-reference being examined */
+ xref_pointer r; /* temporary pointer for permuting cross-references */
+ sixteen_bits m; /* cross-reference value to be installed */
+ sixteen_bits n; /* cross-reference value being examined */
+ if (no_xref) return;
+ xref_switch=def_flag;
+ m=module_count+xref_switch;
+ while (q != xmem) {
+ n=q->num;
+ if (n==m) return;
+ else if (m==n+def_flag) {
+ q->num=m; return;
+ }
+ else if (n>=def_flag && n<m) break;
+ q=q->xlink;
+ }
+ @<Insert new cross-reference at |q|, not at beginning of list@>;
+}
+
+@ We get to this module only when the identifier is one letter long,
+so it didn't get a non-underlined entry during phase one. But it may
+have got some explicitly underlined entries in later modules, so in order
+to preserve the numerical order of the entries in the index, we have
+to insert the new cross-reference not at the beginning of the list
+(namely, at |p->xref|), but rather right before |q|.
+
+@<Insert new cross-reference at |q|...@>=
+ append_xref(0); /* this number doesn't matter */
+ xref_ptr->xlink=(xref_pointer)p->xref;
+ p->xref=(ASCII*)xref_ptr;
+ r=xref_ptr;
+ while (r->xlink!=q) {r->num=r->xlink->num; r=r->xlink;}
+ r->num=m; /* everything from |q| on is left undisturbed */
+
+
+
+@ The `|freeze_text|' macro is used to give official status to a token list.
+Before saying |freeze_text|, items are appended to the current token list,
+and we know that the eventual number of this token list will be the current
+value of |text_ptr|. But no list of that number really exists as yet,
+because no ending point for the current list has been
+stored in the |tok_start| array. After saying |freeze_text|, the
+old current token list becomes legitimate, and its number is the current
+value of |text_ptr-1| since |text_ptr| has been increased. The new
+current token list is empty and ready to be appended to.
+Note that |freeze_text| does not check to see that |text_ptr| hasn't gotten
+too large, since it is assumed that this test was done beforehand.
+
+@d freeze_text = *(++text_ptr)=tok_ptr@;
+
+@ @u reduce(j,k,c,d,n)
+scrap_pointer j;
+eight_bits c;
+short k, d, n;
+{
+ scrap_pointer i, i1; /* pointers into scrap memory */
+ j->cat=c; j->trans=text_ptr;
+ j->mathness=make_math(init_mathness,last_mathness);
+ freeze_text;
+ if (k>1) {
+ for (i=j+k, i1=j+1; i<=lo_ptr; i++, i1++) {
+ i1->cat=i->cat; i1->trans=i->trans;
+ i1->mathness=i->mathness;
+ }
+ lo_ptr=lo_ptr-k+1;
+ }
+ @<Change |pp| to $\max(|scrap_base|,|pp+d|)$@>;
+#ifdef DEBUG
+ @<Print a snapshot of the scrap list if debugging @>;
+#endif DEBUG
+ pp--; /* we next say |pp++| */
+}
+
+@ @<Change |pp| to $\max...@>=
+if (pp+d>=scrap_base) pp=pp+d;
+else pp=scrap_base;
+
+@ The `|squash|'
+procedure takes advantage of the simplification that occurs when |k=1|.
+{\bf `|squash|' isn't used in Spidery \.{WEB}.}
+@u squash(j,k,c,d,n)
+scrap_pointer j;
+eight_bits c;
+short k, d, n;
+{
+ scrap_pointer i; /* pointers into scrap memory */
+ if (k==1) {
+ j->cat=c; @<Change |pp|...@>;
+#ifdef DEBUG
+ @<Print a snapshot...@>;
+#endif DEBUG
+ pp--; /* we next say |pp++| */
+ return;
+ }
+ for (i=j; i<j+k; i++) app1(i);
+ reduce(j,k,c,d,n);
+}
+
+@ Here now is the code that applies productions as long as possible. It
+requires two local labels (|found| and |done|), as well as a local
+variable (|i|).
+
+@<Reduce the scraps using the productions until no more rules apply@>=
+while (1) {
+ @<Make sure the entries |pp| through |pp+highestposoverall-1|
+ of |cat| are defined@>;
+ if (tok_ptr+8>tok_mem_end || text_ptr+4>tok_start_end) {
+#ifdef STAT
+ if (tok_ptr>max_tok_ptr) max_tok_ptr=tok_ptr;
+ if (text_ptr>max_text_ptr) max_text_ptr=text_ptr;
+#endif STAT
+ stat_overflow("token/text");
+ }
+ if (pp>lo_ptr) break;
+ init_mathness=last_mathness=maybe_math;
+ @<Match a production...@>;
+}
+
+@ If we get to the end of the scrap list, category codes equal to zero are
+stored, since zero does not match anything in a production.
+
+@<Make sure the entries...@>=
+if (lo_ptr<pp+highestposoverall-1) {
+ while (hi_ptr<=scrap_ptr && lo_ptr!=pp+highestposoverall-1) {
+ (++lo_ptr)->cat=hi_ptr->cat; lo_ptr->mathness=(hi_ptr)->mathness;
+ lo_ptr->trans=(hi_ptr++)->trans;
+ }
+ for (i=lo_ptr+1;i<=pp+highestposoverall-1;i++) i->cat=0;
+}
+
+@ If \.{WEAVE} is being run in debugging mode, the production numbers and
+current stack categories will be printed out when |tracing| is set to 2;
+a sequence of two or more irreducible scraps will be printed out when
+|tracing| is set to 1.
+
+@<Global...@>=
+#ifdef DEBUG
+int tracing; /* can be used to show parsing details */
+#endif DEBUG
+
+@ @<Print a snapshot...@>= {
+ scrap_pointer k; /* pointer into |scrap_info| */
+ if (tracing==2) {
+ printf("\n%d:",n);
+ for (k=scrap_base; k<=lo_ptr; k++) {
+ if (k==pp) putxchar('*'); else putxchar(' ');
+ if (left_math(k) == yes_math) putchar('+');
+ else if (left_math(k) == no_math) putchar('-');
+ print_cat(k->cat);
+ if (right_math(k)== yes_math) putchar('+');
+ else if (right_math(k) == no_math) putchar('-');
+ }
+ if (hi_ptr<=scrap_ptr) printf("..."); /* indicate that more is coming */
+ }
+}
+
+@ The |translate| function assumes that scraps have been stored in
+positions |scrap_base| through |scrap_ptr| of |cat| and |trans|. It
+appends a |terminator| scrap and begins to apply productions as much as
+possible. The result is a token list containing the translation of
+the given sequence of scraps.
+
+After calling |translate|, we will have |text_ptr+3<=max_texts| and
+|tok_ptr+6<=max_toks|, so it will be possible to create up to three token
+lists with up to six tokens without checking for overflow. Before calling
+|translate|, we should have |text_ptr<max_texts| and |scrap_ptr<max_scraps|,
+since |translate| might add a new text and a new scrap before it checks
+for overflow.
+
+@u text_pointer translate() /* converts a sequence of scraps */
+{
+ scrap_pointer i, /* index into |cat| */
+ j; /* runs through final scraps */
+ pp=scrap_base; lo_ptr=pp-1; hi_ptr=pp;
+ @<If tracing, print an indication of where we are@>;
+ @<Reduce the scraps...@>;
+ @<Combine the irreducible scraps that remain@>;
+}
+
+@ If the initial sequence of scraps does not reduce to a single scrap,
+we concatenate the translations of all remaining scraps, separated by
+blank spaces, with dollar signs
+placed according to the |mathness| of the scraps.
+
+@<Combine the irreducible...@>= {
+ @<If semi-tracing, show the irreducible scraps@>;
+ for (j=scrap_base; j<=lo_ptr; j++) {
+ if (j!=scrap_base) small_app(' ');
+ if ((left_math(j) == yes_math) && math_flag==0) small_app('$');
+ if ((left_math(j) == no_math) && math_flag==1) {
+ small_app(' '); small_app('$');}
+ small_app1(j);
+ if ((right_math(j) == yes_math) && math_flag==0) small_app('$');
+ if ((right_math(j) == no_math) && math_flag==1) {small_app('$');
+ small_app(' ');}
+ if (tok_ptr+6>tok_mem_end) stat_overflow("token");
+ }
+ freeze_text; return(text_ptr-1);
+}
+
+@ @<If semi-tracing, show the irreducible scraps@>=
+#ifdef DEBUG
+if (lo_ptr>scrap_base && tracing==1) {
+ printf("\nIrreducible scrap sequence in section %d:",module_count);
+ mark_harmless;
+ for (j=scrap_base; j<=lo_ptr; j++) {
+ printf(" "); print_cat(j->cat);
+ }
+}
+#endif DEBUG
+
+@ @<If tracing,...@>=
+#ifdef DEBUG
+if (tracing==2) {
+ printf("\nTracing after l. %d:\n",cur_line); mark_harmless;
+ if (loc>buffer+50) {
+ printf("...");
+ ASCII_write(loc-51,51);
+ }
+ else ASCII_write(buffer+1,loc-buffer);
+}
+#endif DEBUG
+
+@* Initializing the scraps.
+If we are going to use the powerful production mechanism just developed, we
+must get the scraps set up in the first place, given a \cee\ text.
+The raw input is converted into scraps according to the following table,
+which gives category codes followed by the translations. Sometimes a single
+item of input produces more than one scrap.
+\def\stars {\.{---}}%
+
+A comment in the input will be combined with the preceding
+|omega| or |semi| scrap, or with the following |terminator| scrap, if
+possible; otherwise it will be inserted as a separate |terminator| scrap.
+An additional ``comment'' is effectively appended at the end of the
+\PASCAL\ text, just before translation begins; this consists of a |cancel|
+token in the case of \PASCAL\ text in \pb, otherwise it consists of a
+|force| token.
+
+From this table it is evident that \.{WEAVE} will parse a lot of non-\PASCAL\
+programs. For example, the reserved words `\.{for}' and `\.{array}' are
+treated in an identical way by \.{WEAVE} from a syntactic standpoint,
+and semantically they are equivalent except that a forced line break occurs
+just before `\&{for}'; \PASCAL\ programmers may well be surprised at this
+similarity. The idea is to keep \.{WEAVE}'s rules as simple as possible,
+consistent with doing a reasonable job on syntactically correct \PASCAL\
+programs. The production rules below have been formulated in the same
+spirit of ``almost anything goes.''
+
+A table
+of the initial scraps corresponding to \cee\ tokens appeared above in the
+section on parsing; our goal now is to implement that table. We shall do this
+by implementing a subroutine called |C_parse| that is analogous to the
+|C_xref| routine used during phase one.
+
+Like |C_xref|, the |C_parse| procedure starts with the current
+value of |next_control| and it uses the operation |next_control=get_next|
+repeatedly to read \cee\ text until encountering the next `\v' or
+`\.\{' (begin comment symbol) , or until |next_control>=format|. The
+scraps corresponding to what
+it reads are appended into the |cat| and |trans| arrays, and |scrap_ptr|
+is advanced.
+
+|C_parse| should never be called with |next_control| equal to
+|begin_comment|, because the
+upper routines should be screening those out.
+
+@u C_parse(see_v) /* creates scraps from \cee\ tokens */
+ char see_v;
+{
+ name_pointer p; /* identifier designator */
+ while (next_control<format) {
+ @<Append the scrap appropriate to |next_control|@>;
+ next_control=get_next(see_v);
+ if (next_control==vertical_bar || next_control==begin_comment) return;
+ }
+}
+
+@ The following macro is used to append a scrap whose tokens have just
+been appended:
+
+@d app_scrap(c,M) = (++scrap_ptr)->cat=c; scrap_ptr->trans=text_ptr;
+scrap_ptr->mathness=make_math(M,M);
+freeze_text;
+
+@ @<Append the scr...@>=
+@<Make sure that there is room for at least four more scraps, six more
+tokens, and four more texts@>;
+switch (next_control) {
+ @<Cases for ordinary tokens@>@;
+ case string: case constant: case verbatim: @<Append a string or constant@>;
+ break;
+ case @`\n': @<Append a newline scrap@>; break;
+ case identifier: @<Append an identifier scrap@>; break;
+ case TeX_string: @<Append a \TeX\ string scrap@>; break;
+ case ignore: case vertical_bar:
+ break;
+case xref_roman: case xref_wildcard: case xref_typewriter:
+ break;
+ case thin_space: app_str("\\,"); app_scrap(SP_ignore_scrap,yes_math); break;
+ case math_break:
+ small_app(opt); app_str("0"); app_scrap(SP_ignore_scrap,yes_math); break;
+ case line_break:
+ app_str("\\0"); app_scrap(SP_ignore_scrap,yes_math); break;
+ case line_force:
+ small_app(force); app_scrap(SP_ignore_scrap,no_math); break;
+ case big_line_break:
+ small_app(big_force); app_scrap(SP_ignore_scrap,no_math); break;
+ case no_line_break:
+ small_app(big_cancel); small_app(' '); small_app(big_cancel);
+ app_scrap(SP_ignore_scrap,no_math); break;
+ case pseudo_semi:
+@<Append a |pseudo_semi| scrap@>
+break;
+ case join: app_str("\\J"); app_scrap(SP_ignore_scrap,no_math); break;
+ default: small_app(next_control); app_scrap(SP_ignore_scrap,no_math); break;
+}
+
+@ Since we haven't yet figured out how to compute the room required
+by looking at the productions, let's be paranoid.
+@d SCRAP_SLACK = 50
+@d TOK_SLACK = 50
+@d TEXT_SLACK = 50
+@<Make sure that there is room for at least four...@>=
+if (scrap_ptr+SCRAP_SLACK>scrap_info_end || tok_ptr+TOK_SLACK>tok_mem_end ||
+ text_ptr+TEXT_SLACK>tok_start_end) {
+#ifdef STAT
+ if (scrap_ptr>max_scr_ptr) max_scr_ptr=scrap_ptr;
+ if (tok_ptr>max_tok_ptr) max_tok_ptr=tok_ptr;
+ if (text_ptr>max_text_ptr) max_text_ptr=text_ptr;
+#endif STAT
+ stat_overflow("scrap/token/text");
+}
+
+@ Some nonstandard ASCII characters may have entered \.{WEAVE} by means of
+standard ones. They are converted to \TeX\ control sequences so that it is
+possible to keep \.{WEAVE} from stepping beyond standard ASCII.
+
+@ The following code must use |app_tok| instead of |small_app| in order to
+protect against overflow. Note that |tok_ptr+1<=max_toks| after |app_tok|
+has been used, so another |small_app| is legitimate before testing again.
+
+Many of the special characters in a string must be prefixed by `\.\\' so that
+\TeX\ will print them properly.
+@^special string characters@>
+
+@<Append a string or...@>=
+if (next_control==constant) app_str("\\O{");
+@.\\O@>
+else if (next_control==string) app_str("\\.{");
+@.\\.@>
+else app_str("\\={");
+@.\\=@>
+while (id_first<id_loc) {
+ if (*id_first==at_sign) {
+ if (*(id_first+1)==at_sign) id_first++;
+ else err_print("! Double at_sign should be used in strings");
+ }
+@.Double at_sign should be used...@>
+ @<Cause \TeX's special characters to be preceded with |'\\'|@>@;
+ app_tok(*id_first++);
+}
+small_app('}');
+@<Do the |app_scrap| for a string or constant@>@;
+
+@ @<Cause \TeX's special characters to be preceded with |'\\'|@>=
+switch (*id_first) {
+ case ' ':case '\\':
+ case '%':case '$': case '^':case '`':
+ case '#':
+ case '{': case '}': case '~': case '&': case '_':
+ small_app('\\'); break;
+
+ }
+
+@ @<Append a \TeX\ string scrap@>=
+app_str("\\hbox{"); while (id_first<id_loc) app_tok(*id_first++);
+small_app('}');
+@<Do the |app_scrap| for a string or constant@>@;
+
+
+@ When the `\v' that introduces \cee\ text is sensed, a call on
+|C_translate| will return a pointer to the \TeX\ translation of
+that text. If scraps exist in |scrap_info|, they are
+unaffected by this translation process.
+
+@u text_pointer C_translate()
+{
+ text_pointer p; /* points to the translation */
+ scrap_pointer save_base; /* holds original value of |scrap_base| */
+ save_base=scrap_base; scrap_base=scrap_ptr+1;
+ C_parse(1); /* get the scraps together */
+ if (next_control!=vertical_bar) err_print("! Missing vertical_bar after C text");
+@.Missing vertical_bar...@>
+ app_tok(cancel); app_scrap(SP_ignore_scrap,no_math);
+ /* place a |cancel| token as a final ``comment'' */
+ p=translate(); /* make the translation */
+#ifdef STAT
+ if (scrap_ptr>max_scr_ptr) max_scr_ptr=scrap_ptr;
+#endif STAT
+ scrap_ptr=scrap_base-1; scrap_base=save_base; /* scrap the scraps */
+ return(p);
+}
+
+@ The |outer_parse| routine is to |C_parse| as |outer_xref|
+is to |C_xref|: it constructs a sequence of scraps for \cee\ text
+until |next_control>=format|. Thus, it takes care of embedded comments.
+It will also do annotation duty.
+
+
+@u outer_parse() /* makes scraps from \cee\ tokens and comments */
+{
+ int bal; /* brace level in comment */
+ text_pointer p, q; /* partial comments */
+ while (next_control<format) {
+ if (next_control==begin_comment) {
+ @<Make sure that there is room for at least seven more
+ tokens, three more texts, and one more scrap@>; /* spider */
+ @<Copy comment, including embedded program text@>;
+ }
+ else {
+ C_parse(0);
+ }
+}
+}
+
+@ @<Copy comment, including embedded program text@>=
+ small_app(break_space); app_str("\\C{");
+@.\\cee@>
+ bal=copy_comment(1); next_control=vertical_bar;
+ while (bal>0) {
+ p=text_ptr; freeze_text; q=C_translate();
+ /* at this point we have |tok_ptr+6<=max_toks| */ /* spider */
+ small_app(tok_flag+p-tok_start); small_app(inner_tok_flag+q-tok_start);
+ if (next_control==vertical_bar) bal=copy_comment(bal);
+ else bal=0; /* an error has been reported */
+ }
+ small_app(force);
+ app_scrap(SP_ignore_scrap,no_math);
+ /* the full comment becomes a scrap */
+
+
+@ @<Make sure that there is room for at least seven more...@>=
+if (tok_ptr+TOK_SLACK>tok_mem_end || text_ptr+TEXT_SLACK>tok_start_end
+ || scrap_ptr+SCRAP_SLACK>scrap_info_end) {
+#ifdef STAT
+ if (scrap_ptr>max_scr_ptr) max_scr_ptr=scrap_ptr;
+ if (tok_ptr>max_tok_ptr) max_tok_ptr=tok_ptr;
+ if (text_ptr>max_text_ptr) max_text_ptr=text_ptr;
+#endif STAT
+ stat_overflow("token/text/scrap");
+}
+
+@i scraps.web
+
+@* Output of tokens.
+So far our programs have only built up multi-layered token lists in
+\.{WEAVE}'s internal memory; we have to figure out how to get them into
+the desired final form. The job of converting token lists to characters in
+the \TeX\ output file is not difficult, although it is an implicitly
+recursive process. Three main considerations had to be kept in mind when
+this part of \.{WEAVE} was designed: (a) There are two modes of output,
+|outer| mode that translates tokens like |force| into line-breaking
+control sequences, and |inner| mode that ignores them except that blank
+spaces take the place of line breaks. (b) The |cancel| instruction applies
+to adjacent token or tokens that are output, and this cuts across levels
+of recursion since `|cancel|' occurs at the beginning or end of a token
+list on one level. (c) The \TeX\ output file will be semi-readable if line
+breaks are inserted after the result of tokens like |break_space| and
+|force|. (d) The final line break should be suppressed, and there should
+be no |force| token output immediately after `\.{\\Y\\P}'.
+
+@ The output process uses a stack to keep track of what is going on at
+different ``levels'' as the token lists are being written out. Entries on
+this stack have three parts:
+
+\yskip\hang |end_field| is the |tok_mem| location where the token list of a
+particular level will end;
+
+\yskip\hang |tok_field| is the |tok_mem| location from which the next token
+on a particular level will be read;
+
+\yskip\hang |mode_field| is the current mode, either |inner| or |outer|.
+
+\yskip\noindent The current values of these quantities are referred to
+quite frequently, so they are stored in a separate place instead of in the
+|stack| array. We call the current values |cur_end|, |cur_tok|, and
+|cur_mode|.
+
+The global variable |stack_ptr| tells how many levels of output are
+currently in progress. The end of output occurs when an |end_translation|
+token is found, so the stack is never empty except when we first begin the
+output process.
+
+@d inner = 0 /* value of |mode| for \cee\ texts within \TeX\ texts */
+@d outer = 1 /* value of |mode| for \cee\ texts in modules */
+
+@<Typed...@>= typedef int mode;
+typedef struct {
+ token_pointer end_field; /* ending location of token list */
+ token_pointer tok_field; /* present location within token list */
+ boolean mode_field; /* interpretation of control tokens */
+} output_state;
+typedef output_state *stack_pointer;
+
+@ @d cur_end = cur_state.end_field /* current ending location in |tok_mem| */
+@d cur_tok = cur_state.tok_field /* location of next output token in |tok_mem| */
+@d cur_mode = cur_state.mode_field /* current mode of interpretation */
+@d init_stack = stack_ptr=stack;cur_mode=outer /* initialize the stack */
+
+@<Global...@>=
+output_state cur_state; /* |cur_end|, |cur_tok|, |cur_mode| */
+output_state stack[stack_size]; /* info for non-current levels */
+stack_pointer stack_ptr; /* first unused location in the output state stack */
+stack_pointer stack_end=stack+stack_size-1; /* end of |stack| */
+#ifdef STAT
+stack_pointer max_stack_ptr; /* largest value assumed by |stack_ptr| */
+#endif STAT
+
+@ @<Set init...@>=
+#ifdef STAT
+max_stack_ptr=stack;
+#endif STAT
+
+@ To insert token-list |p| into the output, the |push_level| subroutine
+is called; it saves the old level of output and gets a new one going.
+The value of |cur_mode| is not changed.
+
+@u push_level(p) /* suspends the current level */
+text_pointer p;
+{
+ if (stack_ptr==stack_end) stat_overflow("stack");
+ if (stack_ptr>stack) { /* save current state */
+ stack_ptr->end_field=cur_end;
+ stack_ptr->tok_field=cur_tok;
+ stack_ptr->mode_field=cur_mode;
+ }
+ stack_ptr++;
+#ifdef STAT
+ if (stack_ptr>max_stack_ptr) max_stack_ptr=stack_ptr;
+#endif STAT
+ cur_tok=*p; cur_end=*(p+1);
+}
+
+@ Conversely, the |pop_level| routine restores the conditions that were in
+force when the current level was begun. This subroutine will never be
+called when |stack_ptr=1|.
+
+@u pop_level()
+{
+ cur_end=(--stack_ptr)->end_field;
+ cur_tok=stack_ptr->tok_field; cur_mode=stack_ptr->mode_field;
+}
+
+@ The |get_output| function returns the next byte of output that is not a
+reference to a token list. It returns the values |identifier| or |res_word|
+or |mod_name| if the next token is to be an identifier (typeset in
+italics), a reserved word (typeset in boldface) or a module name (typeset
+by a complex routine that might generate additional levels of output).
+In these cases |cur_name| points to the identifier or module name in
+question.
+
+@<Global...@>=
+name_pointer cur_name;
+
+@ @d res_word = 0201 /* returned by |get_output| for reserved words */
+@d mod_name = 0200 /* returned by |get_output| for module names */
+
+@u eight_bits get_output() /* returns the next token of output */
+{
+ sixteen_bits a; /* current item read from |tok_mem| */
+ restart: while (cur_tok==cur_end) pop_level();
+ a=*(cur_tok++);
+ if (a>=0400) {
+ cur_name=a % id_flag + name_dir;
+ switch (a / id_flag) {
+ case 2: return(res_word); /* |a==res_flag+cur_name| */
+ case 3: return(mod_name); /* |a==mod_flag+cur_name| */
+ case 4: push_level(a % id_flag + tok_start); goto restart;
+ /* |a==tok_flag+cur_name| */
+ case 5: push_level(a % id_flag + tok_start); cur_mode=inner; goto restart;
+ /* |a==inner_tok_flag+cur_name| */
+ default: return(identifier); /* |a==id_flag+cur_name| */
+ }
+ }
+ return(a);
+}
+
+@ The real work associated with token output is done by |make_output|.
+This procedure appends an |end_translation| token to the current token list,
+and then it repeatedly calls |get_output| and feeds characters to the output
+buffer until reaching the |end_translation| sentinel. It is possible for
+|make_output| to be called recursively, since a module name may include
+embedded \cee\ text; however, the depth of recursion never exceeds one
+level, since module names cannot be inside of module names.
+
+A procedure called |output_C| does the scanning, translation, and
+output of \cee\ text within `\pb' brackets, and this procedure uses
+|make_output| to output the current token list. Thus, the recursive call
+of |make_output| actually occurs when |make_output| calls |output_C|
+while outputting the name of a module.
+@^recursion@>
+
+@u
+output_C() /* outputs the current token list */
+{
+ token_pointer save_tok_ptr;
+ text_pointer save_text_ptr;
+ sixteen_bits save_next_control; /* values to be restored */
+ text_pointer p; /* translation of the \cee\ text */
+ save_tok_ptr=tok_ptr; save_text_ptr=text_ptr;
+ save_next_control=next_control; next_control=vertical_bar; p=C_translate();
+ small_app(p-tok_start+inner_tok_flag);
+ make_output(); /* output the list */
+#ifdef STAT
+ if (text_ptr>max_text_ptr) max_text_ptr=text_ptr;
+ if (tok_ptr>max_tok_ptr) max_tok_ptr=tok_ptr;
+#endif STAT
+ text_ptr=save_text_ptr; tok_ptr=save_tok_ptr; /* forget the tokens */
+ next_control=save_next_control; /* restore |next_control| to original state */
+}
+
+@ Here is \.{WEAVE}'s major output handler.
+
+@u make_output() /* outputs the equivalents of tokens */
+{
+ eight_bits a, /* current output byte */
+ b; /* next output byte */
+ int c; /* count of |indent| and |outdent| tokens */
+ ASCII *k, *k_limit; /* indices into |byte_mem| */
+ ASCII *j; /* index into |buffer| */
+ ASCII delim; /* first and last character of string being copied */
+ ASCII *save_loc, *save_limit; /* |loc| and |limit| to be restored */
+ name_pointer cur_mod_name; /* name of module being output */
+ boolean save_mode; /* value of |cur_mode| before a sequence of breaks */
+ small_app(end_translation); /* append a sentinel */
+ freeze_text; push_level(text_ptr-1);
+ while (1) {
+ a=get_output();
+ reswitch: switch(a) {
+ case end_translation: return;
+ case identifier: case res_word: @<Output an identifier@>; break;
+ case mod_name: @<Output a module name@>; break;
+ case math_bin: case math_rel: case math_op:
+ @<Output a \.{\\math} operator@>; break;
+ case cancel: c=0; while ((a=get_output())>=indent && a<=big_force) {
+ if (a==indent) c++; if (a==outdent) c--;
+ }
+ @<Output saved |indent| or |outdent| tokens@>;
+ goto reswitch;
+ case big_cancel: c=0;
+ while (((a=get_output())>=indent || a==' ') && a<=big_force) {
+ if (a==indent) c++; if (a==outdent) c--;
+ }
+ @<Output saved...@>;
+ goto reswitch;
+ case indent: case outdent: case opt: case backup: case break_space:
+ case force: case big_force: @<Output a control,
+ look ahead in case of line breaks, possibly |goto reswitch|@>; break;
+ default: out(a); /* otherwise |a| is an ASCII character */
+ }
+ }
+}
+
+@ An identifier of length one does not have to be enclosed in braces, and it
+looks slightly better if set in a math-italic font instead of a (slightly
+narrower) text-italic font. Thus we output `\.{\\\char'174a}' but
+`\.{\\\\\{aa\}}'.
+
+BUG FIX: use |out_name| even for identifiers of length 1, so that
+the single-character identifier |_| is properly escaped.
+@<Output an identifier@>=
+out('\\');
+if (a==identifier)
+ if (length(cur_name)==1) out('|')@;
+@.\\|@>
+ else out('\\')@;
+@.\\\\@>
+else out('&')@; /* |a==res_word| */
+@.\\\&@>
+out_name(cur_name);
+
+@ @<Output a \....@>=
+if (a==math_bin) out_str("\\mathbin{");
+else if (a==math_rel) out_str("\\mathrel{");
+else out_str("\\mathop{");
+
+@ The current mode does not affect the behavior of \.{WEAVE}'s output routine
+except when we are outputting control tokens.
+
+@<Output a control...@>=
+if (a<break_space) {
+ if (cur_mode==outer) {
+ out('\\'); out(a-cancel+'0');
+ if (a==opt) out(get_output()); /* |opt| is followed by a digit */
+ }
+ else if (a==opt) b=get_output(); /* ignore digit following |opt| */
+ }
+else @<Look ahead for strongest line break, |goto reswitch|@>@;
+
+@ If several of the tokens |break_space|, |force|, |big_force| occur in a
+row, possibly mixed with blank spaces (which are ignored),
+the largest one is used. A line break also occurs in the output file,
+except at the very end of the translation. The very first line break
+is suppressed (i.e., a line break that follows `\.{\\Y\\P}').
+
+@<Look ahead for st...@>= {
+ b=a; save_mode=cur_mode; c=0;
+ while (1) {
+ a=get_output();
+ if (a==cancel || a==big_cancel) {
+ @<Output saved |indent| or |outdent| tokens@>;
+ goto reswitch; /* |cancel| overrides everything */
+ }
+ if ((a!=' ' && a<indent) || a==backup || a>big_force) {
+ if (save_mode==outer) {
+ if (out_ptr>out_buf+3 && strncmp(out_ptr-3,"\\Y\\P",4)==0)
+ goto reswitch;
+ @<Output saved |indent| or |outdent| tokens@>;
+ out('\\'); out(b-cancel+'0');
+ if (a!=end_translation) finish_line();
+ }
+ else if (a!=end_translation && cur_mode==inner) out(' ');
+ goto reswitch;
+ }
+ if (a==indent) c++;
+ else if (a==outdent) c--;
+ else if (a>b) b=a; /* if |a==' '| we have |a<b| */
+ }
+}
+
+@ @<Output saved...@>=
+ for (;c>0;c--) out_str("\\1");
+ for (;c<0;c++) out_str("\\2");
+
+@ The remaining part of |make_output| is somewhat more complicated. When we
+output a module name, we may need to enter the parsing and translation
+routines, since the name may contain \cee\ code embedded in
+\pb\ constructions. This \cee\ code is placed at the end of the active
+input buffer and the translation process uses the end of the active
+|tok_mem| area.
+
+@<Output a module name@>= {
+ boolean is_file;
+ cur_xref=(xref_pointer)cur_name->xref;
+ is_file = cur_xref->num >= file_flag;
+
+ out_str((is_file? "\\XF":"\\X"));
+@.\\X@>
+ if (cur_xref->num>=def_flag) {
+ out_mod(cur_xref->num-(is_file ? file_flag : def_flag));
+ if (phase==3) {
+ cur_xref=cur_xref->xlink;
+ while (cur_xref->num>=def_flag) {
+ out_str(", ");
+ out_mod(cur_xref->num-(is_file ? file_flag : def_flag));
+ cur_xref=cur_xref->xlink;
+ }
+ }
+ }
+ else out('0'); /* output the module number, or zero if it was undefined */
+ out(':'); @<Output the text of the module name@>;
+ out_str((is_file? "\\XF":"\\X"));
+}
+
+@ @<Output the text...@>=
+k=cur_name->byte_start; k_limit=(cur_name+1)->byte_start;
+cur_mod_name=cur_name;
+while (k<k_limit) {
+ b=*(k++);
+ if (b==at_sign) @<Skip next character, give error if not `\.{@@}'@>@;
+ if (b!=vertical_char) out(b)@;
+ else {
+ @<Copy the \cee\ text into the |buffer| array@>@;
+ save_loc=loc; save_limit=limit; loc=limit+2; limit=j+1;
+ *limit=vertical_char; output_C();
+ loc=save_loc; limit=save_limit;
+ }
+}
+
+@ @<Skip next char...@>=
+if (*k++!=at_sign) {
+ printf("\n! Illegal control code in section name: <");
+@.Illegal control code...@>
+ print_id(cur_mod_name); printf("> "); mark_error;
+}
+
+@ The \cee\ text enclosed in \pb\ should not contain `\v' characters,
+except within strings. We put a `\v' at the front of the buffer, so that an
+error message that displays the whole buffer will look a little bit sensible.
+The variable |delim| is zero outside of strings, otherwise it
+equals the delimiter that began the string being copied.
+
+@<Copy the \cee\ text into...@>=
+j=limit+1; *j=vertical_char; delim=0;
+while (1) {
+ if (k>=k_limit) {
+ printf("\n! C text in section name didn't end: <");
+@.C text...didn't end@>
+ print_id(cur_mod_name); printf("> "); mark_error; break;
+ }
+ b=*(k++);
+ if (b==at_sign) @<Copy a control code into the buffer@>@;
+ else {
+ if (b=='\'' || b=='"')
+ if (delim==0) delim=b;
+ else if (delim==b) delim=0;
+ if (b!=vertical_char || delim!=0) {
+ if (j>buffer+long_buf_size-3) stat_overflow("buffer");
+ *(++j)=b;
+ }
+ else break;
+ }
+}
+
+@ @<Copy a control code into the buffer@>= {
+ if (j>buffer+long_buf_size-4) stat_overflow("buffer");
+ *(++j)=at_sign; *(++j)=*(k++);
+}
+
+@* Phase two processing.
+We have assembled enough pieces of the puzzle in order to be ready to specify
+the processing in \.{WEAVE}'s main pass over the source file. Phase two
+is analogous to phase one, except that more work is involved because we must
+actually output the \TeX\ material instead of merely looking at the
+\.{WEB} specifications.
+
+@u phase_two() {
+reset_input(); printf("\nWriting the output file...");
+module_count=0; copy_limbo();
+math_flag=0;
+finish_line(); flush_buffer(out_buf,0); /* insert a blank line, it looks nice */
+while (!input_has_ended) @<Translate the current module@>;
+}
+
+@ The output file will contain the control sequence \.{\\Y} between non-null
+sections of a module, e.g., between the \TeX\ and definition parts if both
+are nonempty. This puts a little white space between the parts when they are
+printed. However, we don't want \.{\\Y} to occur between two definitions
+within a single module. The variables |out_line| or |out_ptr| will
+change if a section is non-null, so the following macros `|save_position|'
+and `|emit_space_if_needed|' are able to handle the situation:
+
+@d save_position = save_line=out_line; save_place=out_ptr@;
+@d emit_space_if_needed = if (save_line!=out_line || save_place!=out_ptr)
+ out_str("\\Y");
+@.\\Y@>
+
+@<Global...@>=
+int save_line; /* former value of |out_line| */
+ASCII *save_place; /* former value of |out_ptr| */
+
+@ @<Translate the current module@>= {
+ module_count++;
+ @<Output the code for the beginning of a new module@>;
+ save_position;
+ @<Translate the \TeX\ part of the current module@>;
+ @<Translate the definition part of the current module@>;
+ @<Translate the \cee\ part of the current module@>;
+ @<Show cross-references to this module@>;
+ @<Output the code for the end of a module@>;
+}
+
+@ Modules beginning with the \.{WEB} control sequence `\.{@@\ }' start in the
+output with the \TeX\ control sequence `\.{\\M}', followed by the module
+number. Similarly, `\.{@@*}' modules lead to the control sequence `\.{\\N}'.
+If this is a changed module, we put \.{*} just before the module number.
+
+@<Output the code for the beginning...@>=
+if (*(loc-1)!='*') out_str("\\M");
+@.\\M@>
+else {
+ out_str("\\N");
+@.\\N@>
+ printf("*%d",module_count); update_terminal; /* print a progress report */
+}
+out_mod(module_count); out_str(". ");
+
+@ In the \TeX\ part of a module, we simply copy the source text, except that
+index entries are not copied and \cee\ text within \pb\ is translated.
+
+@<Translate the \T...@>= do {
+ next_control=copy_TeX();
+ switch (next_control) {
+ case vertical_bar: /* surround vertical bar with \.{\\CD...\\DC} */
+ out_str("\\CD{}");
+ init_stack; output_C();
+ out_str("\\DC{}");
+ break;
+ case at_sign: out(at_sign); break;
+ case octal: @<Translate an octal constant appearing in \TeX\ text@>; break;
+ case hex: @<Translate a hex constant appearing in \TeX\ text@>; break;
+ case TeX_string: case xref_roman: case xref_wildcard: case xref_typewriter:
+ case module_name: loc-=2; next_control=get_next(1); /* skip to \.{@@>} */
+ if (next_control==TeX_string)
+ err_print("! TeX string should be in C text only"); break;
+@.TeX string should be...@>
+ case thin_space: case math_break:
+ case line_break: case big_line_break: case no_line_break: case join:
+ case pseudo_semi: err_print("! You can't do that in TeX text"); break;
+@.You can't do that...@>
+ }
+} while (next_control<format);
+
+@ @<Translate an octal constant appearing in \TeX\ text@>= {
+out_str("\\O{\\~");
+ while ('0'<=*loc && *loc<'8') out(*loc++);
+out('}');
+}
+
+@ @<Translate a hex constant appearing in \TeX\ text@>= {
+out_str("\\O{\\^");
+ while (isxdigit(*loc)) {
+ out(islower(*loc) ? toupper(*loc):*loc);
+ loc++;
+ }
+out('}');
+}
+
+
+
+@ When we get to the following code we have |next_control>=format|, and
+the token memory is in its initial empty state.
+
+@<Translate the d...@>=
+if (next_control<=definition) { /* definition part non-empty */
+ emit_space_if_needed; save_position;
+}
+while (next_control<=definition) { /* |format| or |definition| */
+ init_stack;
+ if (next_control==definition) @<Start a macro definition@>@;
+ else @<Start a format definition@>;
+ outer_parse(); finish_C();
+}
+
+@ The |finish_C| procedure outputs the translation of the current
+scraps, preceded by the control sequence `\.{\\P}' and followed by the
+control sequence `\.{\\par}'. It also restores the token and scrap
+memories to their initial empty state.
+
+A |force| token is appended to the current scraps before translation
+takes place, so that the translation will normally end with \.{\\6} or
+\.{\\7} (the \TeX\ macros for |force| and |big_force|). This \.{\\6} or
+\.{\\7} is replaced by the concluding \.{\\par} or by \.{\\Y\\par}.
+
+@u finish_C() /* finishes a definition or a \cee\ part */
+{
+ text_pointer p; /* translation of the scraps */
+ out_str("\\P"); app_tok(force); app_scrap(SP_ignore_scrap,no_math);
+ p=translate();
+@.\\P@>
+ small_app(p-tok_start+tok_flag); make_output(); /* output the list */
+ if (out_ptr>out_buf+1)
+ if (*(out_ptr-1)=='\\')
+@.\\6@>
+@.\\7@>
+@.\\Y@>
+ if (*out_ptr=='6') out_ptr-=2; /* suppress ordinary force?! */
+ else if (*out_ptr=='7') *out_ptr='Y';
+ out_str("\\par"); finish_line();
+#ifdef STAT
+ if (text_ptr>max_text_ptr) max_text_ptr=text_ptr;
+ if (tok_ptr>max_tok_ptr) max_tok_ptr=tok_ptr;
+ if (scrap_ptr>max_scr_ptr) max_scr_ptr=scrap_ptr;
+#endif STAT
+ tok_ptr=tok_mem+1; text_ptr=tok_start+1; scrap_ptr=scrap_info;
+ /* forget the tokens and the scraps */
+}
+
+@
+@<Start a macro...@>= {
+ small_app(backup); app_str("\\D"); /* this will produce `\&{define}' */
+@.\\D@>
+@<Set |next_control| to the first non-newline token@>@;
+ if (next_control!=identifier)
+ err_print("! Improper macro definition");
+@.Improper macro definition@>
+ else {
+ small_app('$');
+ small_app(id_flag+id_lookup(id_first, id_loc,normal)-name_dir);
+ @<Scan the parameter list (if any),
+ and set |next_control| to the non-newline
+ token following the parameter list@>;
+ if (next_control==@`=') {
+ small_app('\\'); small_app('S'); /* equivalence sign */
+ @<Set |next_control| to the first non-newline token@>@;
+ } else {
+ err_print ("! Equals sign required in macro definition");
+@.Equals sign required...@>
+ }
+punt_the_definition:
+ small_app('$'); small_app(break_space);
+ app_scrap(SP_ignore_scrap,no_math);
+ /* scrap won't take part in the parsing */
+ }
+}
+
+@ @<Quit scanning the macro definition@>=goto punt_the_definition;
+
+@ @<Scan the parameter list (if any),
+ and set |next_control| to the non-newline
+ token following the parameter list@>=
+@<Set |next_control| to the first non-newline token@>@;
+if (next_control==@`(') {
+ small_app(@`(');
+ do {
+ @<Set |next_control| to the first non-newline token@>@;
+ if (next_control==identifier) {
+ small_app(id_flag+id_lookup(id_first, id_loc,normal)-name_dir);
+ @<Set |next_control| to the first non-newline token@>@;
+ } else {
+ err_print("! Improper macro definition");
+ @<Quit scanning the macro definition@>;
+ }
+ if (next_control==@`,' || next_control==@`)')
+ small_app(next_control);
+ } while (next_control==@`,');
+ if (next_control != @`)') {
+ err_print("! Macro parameter list must end with )");
+ @<Quit scanning the macro definition@>;
+ }
+ @<Set |next_control| to the first non-newline token@>@;
+ /* first token following parameter list */
+}
+
+
+
+
+@ @<Start a format...@>= {
+ app_str("\\F"); app_scrap(SP_ignore_scrap,no_math);
+ /* this will produce `\&{format}' */
+@.\\F@>
+@<Set |next_control| to the first non-newline token@>@;
+/* claim at this point |scrap_ptr==scrap_info+1| */
+ if (scrap_ptr!=scrap_info+1) {
+ err_print("! This can't happen -- bad scrap_ptr in format definition");
+ printf("\n\tscrap_ptr-scrap_info==%d\n",scrap_ptr-scrap_info);
+ }
+ if (next_control==identifier) {
+ small_app(id_flag+id_lookup(id_first, id_loc,normal)-name_dir);
+ app_str(" ");
+ app_scrap(SP_ignore_scrap,no_math); /*spider*/
+ /* this is syntactically separate from what follows */
+ @<Set |next_control| to the first non-newline token@>@;
+ if (next_control==identifier) {
+ small_app(id_flag+id_lookup(id_first, id_loc,normal)-name_dir);
+ small_app(@`\n');
+ app_scrap(SP_ignore_scrap,no_math);
+ @<Set |next_control| to the first non-newline token@>@;
+ }
+ }
+ /* if everything went well, we appended two scraps */
+ if (scrap_ptr!=scrap_info+3) err_print("! Improper format definition");
+@.Improper format definition@>
+}
+
+@ Finally, when the \TeX\ and definition parts have been treated, we have
+|next_control>=begin_unnamed|. We will make the global variable |this_module|
+point to the current module name, if it has a name.
+
+@<Global...@>=
+name_pointer this_module; /* the current module name, or zero */
+
+@ @<Translate the \cee...@>=
+this_module=name_dir;
+if (next_control<=module_name) {
+ emit_space_if_needed; init_stack;
+ if (next_control==begin_unnamed) next_control=get_next(0);
+ else {
+ this_module=cur_module;
+ @<Check that |=| follows this module name, and
+ emit the scraps to start the module definition@>;
+ }
+ while (next_control<=module_name) {
+ outer_parse();
+ @<Emit the scrap for a module name if present@>;
+ }
+ finish_C();
+}
+
+@ @<Check that |=|...@>=
+do next_control=get_next(0);
+ while (next_control=='+'); /* allow optional `\.{+=}' */
+if (next_control!='=')
+ err_print("! You need an = sign after the section name");
+@.You need an = sign...@>
+ else next_control=get_next(0);
+if (out_ptr>out_buf+1 && *out_ptr=='Y' && *(out_ptr-1)=='\\') small_app(backup);
+ /* the module name will be flush left */
+@.\\Y@>
+small_app(mod_flag+this_module-name_dir);
+cur_xref=(xref_pointer)this_module->xref;
+app_str("${}");
+if (cur_xref->num%def_flag!=module_count) {
+ app_str("+"); /*module name is multiply defined*/
+ this_module=name_dir; /*so we won't give cross-reference info here*/
+}
+app_str("\\S"); /* output an equivalence sign */
+@.\\S@>
+app_str("{}$");
+small_app(force);
+@<Call |app_scrap| for a module definition@>
+/* this forces a line break unless `\.{@@+}' follows */
+
+@ @<Emit the scrap...@>=
+if (next_control<module_name) {
+ err_print("! You can't do that in C text");
+@.You can"t do that...@>
+ next_control=get_next(1);
+}
+else if (next_control==module_name) {
+ if (cur_module_char!='<') {
+ err_print("! You can't use a file like a module");
+@.You can't use a file like a module@>
+ next_control=get_next(1);
+ } else {
+ small_app(mod_flag+cur_module-name_dir);
+ @<Call |app_scrap| for a module use@>
+ next_control=get_next(1);
+ }
+}
+
+@ Cross references relating to a named module are given after the module ends.
+
+@<Show cross...@>=
+if (this_module>name_dir) {
+ @<Rearrange the list pointed to by |cur_xref|@>;
+ footnote(((((xref_pointer)this_module->xref)->num >= file_flag)
+ ? file_flag : def_flag));
+ footnote(0);
+}
+
+@ To rearrange the order of the linked list of cross-references, we need
+four more variables that point to cross-reference entries. We'll end up
+with a list pointed to by |cur_xref|.
+
+@<Global...@>=
+xref_pointer next_xref, this_xref, first_xref, mid_xref;
+ /* pointer variables for rearranging a list */
+
+@ We want to rearrange the cross-reference list so that all the entries with
+|def_flag| come first, in ascending order; then come all the other
+entries, in ascending order. There may be no entries in either one or both
+of these categories.
+
+@<Rearrange the list...@>=
+ first_xref=(xref_pointer)this_module->xref;
+ this_xref=first_xref->xlink; /* bypass current module number */
+ if (this_xref->num>def_flag) {
+ mid_xref=this_xref; cur_xref=0; /* this value doesn't matter */
+ do {
+ next_xref=this_xref->xlink; this_xref->xlink=cur_xref;
+ cur_xref=this_xref; this_xref=next_xref;
+ } while (this_xref->num>def_flag);
+ first_xref->xlink=cur_xref;
+}
+else mid_xref=xmem; /* first list null */
+cur_xref=xmem;
+while (this_xref!=xmem) {
+ next_xref=this_xref->xlink; this_xref->xlink=cur_xref;
+ cur_xref=this_xref; this_xref=next_xref;
+}
+if (mid_xref>xmem) mid_xref->xlink=cur_xref;
+else first_xref->xlink=cur_xref;
+cur_xref=first_xref->xlink;
+
+@ The |footnote| procedure gives cross-reference information about
+multiply defined module names (if the |flag| parameter is |def_flag|), or about
+the uses of a module name (if the |flag| parameter is zero). It assumes that
+|cur_xref| points to the first cross-reference entry of interest, and it
+leaves |cur_xref| pointing to the first element not printed. Typical outputs:
+`\.{\\A\ section 101.}'; `\.{\\U\ sections 370 and 1009.}';
+`\.{\\A\ sections 8, 27\\*, and 64.}'.
+
+@u footnote(flag) /* outputs module cross-references */
+sixteen_bits flag;
+{
+ xref_pointer q; /* cross-reference pointer variable */
+ if (cur_xref->num<=flag) return;
+ finish_line(); out('\\');
+@.\\A@>
+@.\\U@>
+ if (flag==0) out('U')@;@+else out('A');
+ out_str(" section");
+ @<Output all the module numbers on the reference list |cur_xref|@>;
+ out('.');
+}
+
+@ The following code distinguishes three cases, according as the number
+of cross-references is one, two, or more than two. Variable |q| points
+to the first cross-reference, and the last link is a zero.
+
+@<Output all the module numbers...@>=
+q=cur_xref; if (q->xlink->num>flag) out('s'); /* plural */
+out('~');
+while (1) {
+ out_mod(cur_xref->num-flag);
+ cur_xref=cur_xref->xlink; /* point to the next cross-reference to output */
+ if (cur_xref->num<=flag) break;
+ if (cur_xref->xlink->num>flag || cur_xref!=q->xlink) out(',');
+ /* not the last of two */
+ out(' ');
+ if (cur_xref->xlink->num<=flag) out_str("and~"); /* the last */
+}
+
+@ @<Output the code for the end of a module@>=
+out_str("\\fi"); finish_line();
+@.\\fi@>
+flush_buffer(out_buf,0); /* insert a blank line, it looks nice */
+
+@* Phase three processing.
+We are nearly finished! \.{WEAVE}'s only remaining task is to write out the
+index, after sorting the identifiers and index entries.
+
+If the user has set the |no_xref| flag (the |-x| option on the command line),
+just finish off the page, omitting the index, module name list, and table of
+contents.
+
+@<Glob...@>=
+extern int no_xref;
+
+@ @u phase_three() {
+if (no_xref) {
+ finish_line();
+ out_str("\\vfill\\end");
+ finish_line();
+}
+else {
+ phase=3; printf("\nWriting the index...");
+ if (change_exists) {
+ finish_line(); @<Tell about changed modules@>;
+ }
+ finish_line(); out_str("\\inx"); finish_line();
+@.\\inx@>
+ @<Do the first pass of sorting@>;
+ @<Sort and output the index@>;
+ out_str("\\fin"); finish_line();
+@.\\fin@>
+ @<Output all the module names@>;
+ out_str("\\con"); finish_line();
+@.\\con@>
+}
+printf("Done.");
+check_complete(); /* was all of the change file used? */
+}
+
+@ Just before the index comes a list of all the changed modules, including
+the index module itself.
+
+@<Global...@>=
+sixteen_bits k_module; /* runs through the modules */
+
+@ @<Tell about changed modules@>= {
+ /* remember that the index is already marked as changed */
+ k_module=0;
+ while (!changed_module[++k_module]);
+ out_str("\\ch ");
+ out_mod(k_module);
+ while (1) {
+ while (!changed_module[++k_module]);
+ out_str(", "); out_mod(k_module);
+ if (k_module==module_count) break;
+ }
+ out('.');
+}
+
+@ A left-to-right radix sorting method is used, since this makes it easy to
+adjust the collating sequence and since the running time will be at worst
+proportional to the total length of all entries in the index. We put the
+identifiers into 102 different lists based on their first characters.
+(Uppercase letters are put into the same list as the corresponding lowercase
+letters, since we want to have `$t<\\{TeX}<\&{to}$'.) The
+list for character |c| begins at location |bucket[c]| and continues through
+the |blink| array.
+
+@<Global...@>=
+name_pointer bucket[128];
+name_pointer next_name; /* successor of |cur_name| when sorting */
+hash_pointer h; /* index into |hash| */
+name_pointer blink[max_names]; /* links in the buckets */
+
+@ To begin the sorting, we go through all the hash lists and put each entry
+having a nonempty cross-reference list into the proper bucket.
+
+@<Do the first pass...@>= {
+int c;
+for (c=0; c<=127; c++) bucket[c]=NULL;
+for (h=hash; h<=hash_end; h++) {
+ next_name=*h;
+ while (next_name) {
+ cur_name=next_name; next_name=cur_name->link;
+ if (((xref_pointer)cur_name->xref)!=xmem) {
+ c=(cur_name->byte_start)[0];
+ if (c<='Z' && c>='A') c=c+040;
+ blink[cur_name-name_dir]=bucket[c]; bucket[c]=cur_name;
+ }
+ }
+}
+}
+
+@ During the sorting phase we shall use the |cat| and |trans| arrays from
+\.{WEAVE}'s parsing algorithm and rename them |depth| and |head|. They now
+represent a stack of identifier lists for all the index entries that have
+not yet been output. The variable |sort_ptr| tells how many such lists are
+present; the lists are output in reverse order (first |sort_ptr|, then
+|sort_ptr-1|, etc.). The |j|th list starts at |head[j]|, and if the first
+|k| characters of all entries on this list are known to be equal we have
+|depth[j]=k|.
+
+@ @<Rest of |trans_plus| union@>=
+name_pointer Head;
+
+@
+@d depth = cat /* reclaims memory that is no longer needed for parsing */
+@d head = trans_plus.Head /* ditto */
+@d sort_pointer = scrap_pointer /* ditto */
+@d sort_ptr = scrap_ptr /* ditto */
+@d max_sorts = max_scraps /* ditto */
+
+@<Global...@>=
+eight_bits cur_depth; /* depth of current buckets */
+ASCII *cur_byte; /* index into |byte_mem| */
+sixteen_bits cur_val; /* current cross-reference number */
+#ifdef STAT
+sort_pointer max_sort_ptr; /* largest value of |sort_ptr| */
+#endif STAT
+
+@ @<Set init...@>=
+#ifdef STAT
+max_sort_ptr=scrap_info;
+#endif STAT
+
+
+@ The desired alphabetic order is specified by the |collate| array; namely,
+|collate[0]<collate[1]<@t$\cdots$@><collate[100]|.
+
+@<Global...@>=
+ASCII collate[102]; /* collation order */
+
+@ We use the order $\hbox{null}<\.\ <\hbox{other characters}<\.\_<
+\.A=\.a<\cdots<\.Z=\.z<\.0<\cdots<\.9.$
+
+@<Set init...@>=
+collate[0]=0; strcpy(collate+1," \1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\
+\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37\
+!\42#$%&'()*+,-./:;<=>?@@[\\]^`{|}~_\
+abcdefghijklmnopqrstuvwxyz0123456789");
+
+@ Procedure |unbucket| goes through the buckets and adds nonempty lists
+to the stack, using the collating sequence specified in the |collate| array.
+The parameter to |unbucket| tells the current depth in the buckets.
+Any two sequences that agree in their first 255 character positions are
+regarded as identical.
+
+@d infinity = 255 /* $\infty$ (approximately) */
+
+@u unbucket(d) /* empties buckets having depth |d| */
+eight_bits d;
+{
+ ASCII c; /* index into |bucket| */
+ for (c=100; c>= 0; c--) if (bucket[collate[c]]) {
+ if (sort_ptr>=scrap_info_end) stat_overflow("sorting");
+ sort_ptr++;
+#ifdef STAT
+ if (sort_ptr>max_sort_ptr) max_sort_ptr=sort_ptr;
+#endif STAT
+ if (c==0) sort_ptr->depth=infinity;
+ else sort_ptr->depth=d;
+ sort_ptr->head=bucket[collate[c]]; bucket[collate[c]]=NULL;
+ }
+}
+
+@ @<Sort and output...@>=
+sort_ptr=scrap_info; unbucket(1);
+while (sort_ptr>scrap_info) {
+ cur_depth=sort_ptr->depth;
+ if (blink[sort_ptr->head-name_dir]==0 || cur_depth==infinity)
+ @<Output index entries for the list at |sort_ptr|@>@;
+ else @<Split the list at |sort_ptr| into further lists@>;
+}
+
+@ @<Split the list...@>= {
+ ASCII c;
+ next_name=sort_ptr->head;
+ do {
+ cur_name=next_name; next_name=blink[cur_name-name_dir];
+ cur_byte=cur_name->byte_start+cur_depth;
+ if (cur_byte==(cur_name+1)->byte_start) c=0; /* hit end of the name */
+ else {
+ c=*cur_byte;
+ if (c<='Z' && c>='A') c=c+040;
+ }
+ blink[cur_name-name_dir]=bucket[c]; bucket[c]=cur_name;
+ } while (next_name);
+ --sort_ptr; unbucket(cur_depth+1);
+}
+
+@ @<Output index...@>= {
+ cur_name=sort_ptr->head;
+ do {
+ out_str("\\:");
+@.\\:@>
+ @<Output the name at |cur_name|@>;
+ @<Output the cross-references at |cur_name|@>;
+ cur_name=blink[cur_name-name_dir];
+ } while (cur_name);
+ --sort_ptr;
+}
+
+@ @<Output the name...@>=
+switch (cur_name->ilk) {
+ case normal: if (length(cur_name)==1) out_str("\\|");
+ else out_str("\\\\"); break;
+@.\\|@>
+@.\\\\@>
+ case roman: break;
+ case wildcard: out_str("\\9"); break;
+@.\\9@>
+ case typewriter: out_str("\\."); break;
+@.\\.@>
+ default: out_str("\\&");
+@.\\\&@>
+}
+out_name(cur_name);
+
+@ Section numbers that are to be underlined are enclosed in
+`\.{\\[}$\,\ldots\,$\.]'.
+
+@<Output the cross-references...@>=
+@<Invert the cross-reference list at |cur_name|, making |cur_xref| the head@>;
+do {
+ out_str(", "); cur_val=cur_xref->num;
+ if (cur_val<def_flag) out_mod(cur_val);
+ else {out_str("\\["); out_mod(cur_val%def_flag); out(']');}
+@.\\[@>
+ cur_xref=cur_xref->xlink;
+} while (cur_xref!=xmem);
+out('.'); finish_line();
+
+@ List inversion is best thought of as popping elements off one stack and
+pushing them onto another. In this case |cur_xref| will be the head of
+the stack that we push things onto.
+
+@<Invert the cross-reference list at |cur_name|, making |cur_xref| the head@>=
+this_xref=(xref_pointer)cur_name->xref; cur_xref=xmem;
+do {
+ next_xref=this_xref->xlink; this_xref->xlink=cur_xref;
+ cur_xref=this_xref; this_xref=next_xref;
+} while (this_xref!=xmem);
+
+@ The following recursive procedure walks through the tree of module names and
+prints them.
+@^recursion@>
+
+@u mod_print(p) /* print all module names in subtree |p| */
+name_pointer p;
+{
+ boolean is_file;
+ if (p) {
+ mod_print(p->llink);
+ cur_xref=(xref_pointer)p->xref;
+ is_file=((cur_xref->num)>=file_flag);
+ if ((is_file && do_file)||(!is_file && !do_file)) { /* C has no xor */
+ out_str("\\:");
+@.\\:@>
+ tok_ptr=tok_mem+1; text_ptr=tok_start+1; scrap_ptr=scrap_info; init_stack;
+ small_app(p-name_dir+mod_flag); make_output();
+ footnote(0); /* |cur_xref| was set by |make_output| */
+ finish_line();
+ }
+ mod_print(p->rlink);
+ }
+}
+
+@ Here we list files, then modules.
+@<Global...@>=boolean do_file;
+@ @<Output all the module names@>=
+do_file=(1==1);
+mod_print(root);
+do_file=(1==0);
+mod_print(root);
+
+
+
+@ @<Print statistics about memory usage@>=
+printf(
+"\nMemory usage statistics: %d of %d names, %d of %d cross-references,\n",
+ name_ptr-name_dir, name_dir_end-name_dir,
+ xref_ptr-xmem, xmem_end-xmem);
+printf("\t %d of %d bytes;",byte_ptr-byte_mem,byte_mem_end-byte_mem);
+printf("\nParsing required %d of %d(%d) scraps, %d of %d(%d) texts,\n",
+ max_scr_ptr-scrap_info, max_scraps, max_scraps-SCRAP_SLACK,
+ max_text_ptr-tok_start, max_texts, max_texts-TEXT_SLACK
+ );
+printf("\t %d of %d(%d) tokens, %d of %d levels;\n",
+ max_tok_ptr-tok_mem, max_toks, max_toks-TOK_SLACK,
+ max_stack_ptr-stack, stack_end-stack
+ );
+printf("\nSorting required %d levels\n", max_sort_ptr-scrap_info);
+
+@ @u
+stat_overflow(s)
+ char *s;
+{
+ printf("\n! Sorry, capacity exceeded: %s",s);
+#ifdef STAT
+ @<Print statistics about memory usage@>;
+#endif STAT
+ history=fatal_message; wrap_up();
+}
+
+@* Index.
+If you have read and understood the code for Phase III above, you know what
+is in this index and how it got here. All modules in which an identifier is
+used are listed with that identifier, except that reserved words are
+indexed only when they appear in format definitions, and the appearances
+of identifiers in module names are not indexed. Underlined entries
+correspond to where the identifier was declared. Error messages, control
+sequences put into the output, and a few
+other things like ``recursion'' are indexed here too.
+
+
diff --git a/web/spiderweb/src/master/webhead b/web/spiderweb/src/master/webhead
new file mode 100644
index 0000000000..3dfb208171
--- /dev/null
+++ b/web/spiderweb/src/master/webhead
@@ -0,0 +1,2 @@
+@*Example.
+@c
diff --git a/web/spiderweb/src/master/webtail b/web/spiderweb/src/master/webtail
new file mode 100644
index 0000000000..3749661008
--- /dev/null
+++ b/web/spiderweb/src/master/webtail
@@ -0,0 +1 @@
+@*Index.
diff --git a/web/spiderweb/src/nawk/make b/web/spiderweb/src/nawk/make
new file mode 100644
index 0000000000..2fa9260a45
--- /dev/null
+++ b/web/spiderweb/src/nawk/make
@@ -0,0 +1,2 @@
+/bin/make -f ../master/WebMakefile CPUTYPE=`cputype`\
+ THETANGLE=nawktangle THEWEAVE=nawkweave SPIDER=nawk.spider $*
diff --git a/web/spiderweb/src/nawk/nawk.spider b/web/spiderweb/src/nawk/nawk.spider
new file mode 100644
index 0000000000..45e2186bb9
--- /dev/null
+++ b/web/spiderweb/src/nawk/nawk.spider
@@ -0,0 +1,176 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+language NAWK extension awk
+
+at_sign #
+
+module definition stmt use stmt
+# use as stmt is unavoidable since tangle introduces line breaks
+
+comment begin <"##"> end newline
+macros begin
+\def\commentbegin{\#} % we don't want \#\#
+macros end
+
+line begin <"#line"> end <"">
+
+default translation <*> mathness yes
+
+token identifier category math mathness yes
+token number category math mathness yes
+token newline category newline translation <> mathness maybe
+token pseudo_semi category ignore_scrap mathness no translation <opt-0>
+
+token \ category backslash translation <> mathness maybe
+token + category unorbinop
+token - category unorbinop
+token * category binop
+token / category binop
+token < category binop
+token > category binop
+token >> category binop translation <"\\GG">
+token = category equals translation <"\\K">
+token ~ category binop translation <"\\TI">
+token !~ category binop translation <"\\not\\TI">
+token & category binop translation <"\\amp">
+token % translation <"\\%"> category binop
+token ( category open
+token [ category lsquare
+token ) category close
+token ] category close
+token { translation <"\\;\\{"-indent> category lbrace
+token } translation <"\\}\\"-space> category close
+token , category binop translation <",\\,"-opt-3>
+token ^ category exponent translation <>
+
+token ; category semi translation <";"-space-opt-2> mathness no
+# stuff with semi can be empty in for statements
+open semi --> open
+semi semi --> semi
+semi close --> close
+semi --> binop
+
+# token : category colon
+# token | category bar
+token != name not_eq translation <"\\I"> category binop
+token <= name lt_eq translation <"\\L"> category binop
+token >= name gt_eq translation <"\\G"> category binop
+token == name eq_eq translation <"\\S"> category binop
+token && name and_and translation <"\\W"> category binop
+token || name or_or translation <"\\V"> category binop
+# token -> name minus_gt translation <"\\MG"> category binop
+token ++ name gt_gt category unop translation <"\\uparrow">
+token -- name lt_lt category unop translation <"\\downarrow">
+# preunop is for unary operators that are prefix only
+token $ category preunop translation <"\\DO"> mathness yes
+
+default mathness yes translation <*>
+
+ilk pattern_like category math
+reserved BEGIN ilk pattern_like
+reserved END ilk pattern_like
+
+ilk if_like category if
+reserved if
+ilk else_like category else
+reserved else
+
+ilk print_like category math
+# math forces space between this and other math...
+reserved print ilk print_like
+reserved printf ilk print_like
+reserved return ilk print_like
+
+
+ilk functions category unop mathness yes
+reserved length ilk functions
+reserved substr ilk functions
+reserved index ilk functions
+reserved split ilk functions
+reserved sqrt ilk functions
+reserved log ilk functions
+reserved exp ilk functions
+reserved int ilk functions
+reserved sprintf ilk functions
+
+ilk variables category math mathness yes
+reserved NR ilk variables
+reserved NF ilk variables
+reserved FS ilk variables
+reserved RS ilk variables
+reserved OFS ilk variables
+reserved ORS ilk variables
+
+ilk for_like category for
+reserved for ilk for_like
+reserved while ilk for_like
+
+ilk in_like category binop translation <math_bin-*-"}"> mathness yes
+# translation <"\\"-space-*-"\\"-space>
+reserved in ilk in_like
+
+ilk stmt_like category math
+reserved break ilk stmt_like
+reserved continue ilk stmt_like
+reserved next ilk stmt_like
+reserved exit ilk stmt_like
+
+ilk function_like category math translation <big_force-*> mathness no
+reserved function ilk function_like
+
+
+backslash newline --> math
+# The following line must be changed to make a backslash
+backslash <"\\backslash"> --> math
+
+math (binop|unorbinop) math --> math
+<"\\buildrel"> (binop|unorbinop) <"\\over{"> equals <"}"> --> binop
+equals --> binop
+(unop|preunop|unorbinop) math --> math
+# unorbinop can only act like unary op as *prefix*, not postfix
+math unop --> math
+math <"\\"-space> math --> math
+# concatenation
+
+math newline --> stmt
+newline --> ignore_scrap
+
+stmt <force> stmt --> stmt
+
+(open|lsquare) math close --> math
+
+# make exponentials superscripts
+math <"^{"> exponent math <"}"> --> math
+
+math lbrace --> lbrace
+lbrace <force> stmt --> lbrace
+lbrace <outdent-force> close --> stmt
+
+if <"\\"-space> math --> ifmath
+ifmath lbrace --> ifbrace
+ifmath newline --> ifline
+ifbrace <force> stmt --> ifbrace
+ifbrace <outdent-force> close else <"\\"-space> if --> if
+ifbrace <outdent-force> close else lbrace --> ifbrace
+ifbrace <outdent-force> close else newline --> ifline
+ifbrace <outdent-force> close --> stmt
+(ifline|ifmath) <indent-force> stmt <outdent-force> else <"\\"-space> if --> if
+(ifline|ifmath) <indent-force> stmt <outdent-force> else lbrace --> ifbrace
+(ifline|ifmath) <indent-force> stmt <outdent-force> else newline --> ifline
+(ifline|ifmath) <indent-force> stmt <outdent-force> else --> ifmath
+(ifline|ifmath) <indent-force> stmt <outdent> --> stmt
+
+for <"\\"-space> math --> formath
+formath lbrace --> forbrace
+formath newline --> forline
+forbrace <force> stmt --> forbrace
+forbrace <outdent-force> close --> stmt
+(forline|formath) <indent-force> stmt <outdent> --> stmt
+
+
+
+? ignore_scrap --> #1
+
+
+
diff --git a/web/spiderweb/src/penelope/SpiderMakefile b/web/spiderweb/src/penelope/SpiderMakefile
new file mode 100644
index 0000000000..9242c3ff9d
--- /dev/null
+++ b/web/spiderweb/src/penelope/SpiderMakefile
@@ -0,0 +1,9 @@
+tangle: processed-a.spider
+weave: processed-a.spider
+processed-a.spider: a.spider scan_annotations.awk
+ awk -f scan_annotations.awk < a.spider > processed-a.spider
+ chmod -w processed-a.spider
+clean: # do nothing
+ echo spider files need no cleaning
+
+
diff --git a/web/spiderweb/src/penelope/a.spider b/web/spiderweb/src/penelope/a.spider
new file mode 100644
index 0000000000..86694573ca
--- /dev/null
+++ b/web/spiderweb/src/penelope/a.spider
@@ -0,0 +1,375 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+language Ada extension ada
+
+at_sign @
+
+module definition stmt use math
+
+comment begin <dash-dash-space> end newline
+macros begin
+\def\commentbegin{{\tt -- }}
+macros end
+
+line begin <dash-dash-"line"> end <"">
+
+default translation <*> mathness yes
+
+token identifier category math mathness maybe
+token number category math mathness yes
+token newline category nl translation <> mathness maybe
+# newline mathness must be no to work with busted_comment
+token pseudo_semi translation <> category semi mathness maybe
+
+macros begin
+\let\R\relax
+macros end
+
+# Delimiters
+token & category binop translation <"\\amp">
+token ( category open
+token ) category close
+token * category binop
+token + category unorbinop
+token , category binop translation <",\\,"-opt-3>
+token - category unorbinop
+token . category binop
+token / category binop
+token : category binop
+token ; category semi translation <";"-space-opt-2>
+token < category binop
+token = category binop
+token > category binop
+token | category binop translation <"\\mid">
+
+# Compound delimiters
+
+token => category arrow translation <"\\AR">
+token .. category binop translation <"\\.{..}">
+token ** category binop
+token := category binop translation <"\\mathbin{:=}">
+token /= translation <"\\I"> category binop
+token >= translation <"\\G"> category binop
+token <= translation <"\\L"> category binop
+token << translation <"\\LL"> category openlabel
+token >> translation <"\\GG"> category closelabel
+token <> translation <"\\LG"> category math
+
+# Hacks no ', and this becomes a binary op
+token ' category binop mathness no
+
+token # category math translation <"\\#">
+token -- category busted_comment mathness no translation <"\\C{">
+
+
+
+
+default mathness maybe translation <*>
+
+reserved abort ilk math_like
+reserved abs ilk unop_like
+reserved accept ilk proc_like
+reserved access ilk math_like
+reserved all ilk math_like
+reserved and ilk and_like
+reserved array ilk math_like
+reserved at ilk at_like
+reserved begin ilk begin_like
+reserved body ilk math_like
+reserved case ilk case_like
+reserved constant ilk math_like
+reserved declare ilk decl_like
+reserved delay ilk math_like
+reserved delta ilk math_like
+reserved digits ilk math_like
+reserved do ilk is_like
+reserved else ilk else_like
+reserved elsif ilk elsif_like
+reserved end ilk end_like
+reserved entry ilk proc_like
+reserved exception ilk ex_like
+reserved exit ilk math_like
+reserved for ilk math_like
+reserved function ilk proc_like
+reserved generic ilk gen_like
+reserved goto ilk math_like
+reserved if ilk if_like
+reserved in ilk unorbinop_like
+reserved is ilk is_like
+reserved limited ilk math_like
+reserved loop ilk loop_like
+reserved mod ilk binop_like
+reserved new ilk separate_like
+reserved not ilk unop_like
+reserved null ilk math_like
+reserved of ilk math_like
+reserved or ilk or_like
+reserved others ilk math_like
+reserved out ilk math_like
+reserved package ilk proc_like
+reserved pragma ilk math_like
+reserved private ilk private_like
+reserved procedure ilk proc_like
+reserved raise ilk math_like
+reserved range ilk math_like
+reserved record ilk record_like
+reserved rem ilk binop_like
+reserved renames ilk math_like
+reserved return ilk math_like
+reserved reverse ilk math_like
+reserved select ilk begin_like
+reserved separate ilk separate_like
+reserved subtype ilk math_like
+reserved task ilk proc_like
+reserved terminate ilk math_like
+reserved then ilk then_like
+reserved type ilk math_like
+reserved use ilk math_like
+reserved when ilk when_like
+reserved while ilk math_like
+reserved with ilk with_like
+reserved xor ilk binop_like
+
+ilk and_like translation <*> category and
+ilk at_like translation <*> category at
+ilk begin_like translation <*-indent> category beginning
+ilk binop_like translation <"\\"-space-*-"\\"-space> category binop
+ilk case_like translation <*> category case
+ilk decl_like translation <*-indent> category declaration
+ilk else_like translation <*> category else
+ilk elsif_like translation <*> category elsif
+ilk end_like translation <*> category close
+ilk ex_like translation <*> category exception
+ilk gen_like translation <*-indent> category generic
+ilk if_like translation <*> category if
+ilk is_like translation <*> category is mathness no
+ilk loop_like translation <*> category loop
+ilk math_like translation <*> category math
+ilk or_like translation <*> category or
+ilk private_like translation <*> category private
+ilk proc_like translation <*> category proc
+ilk record_like translation <*> category record
+ilk separate_like translation <*> category separate
+ilk then_like translation <*> category then
+ilk unop_like translation <*-"\\"-space> category unop
+ilk unorbinop_like translation <"\\"-space-*-"\\"-space> category resunorbinop
+ilk when_like translation <*> category when
+ilk where_like category where
+ilk with_like translation <*> category with
+
+
+# \MC means ``math close'' and sets \MS to ``math set''
+macros begin
+\def\MC{\ifmmode\global\let\MS$\else\global\let\MS\relax\fi\relax\MS}
+\def\LG{\mathord{<}\mathord{>}}
+\let\IG=\ignorespaces
+macros end
+
+
+
+busted_comment <"\\MC}\\MS\\R"-force> nl --> ignore_scrap
+busted_comment ? --> busted_comment
+
+beginning <outdent-force> continuation <outdent-force> ending --> stmt
+beginning <outdent-force> ending --> stmt
+beginning <force> (stmt|ignore_scrap) --> beginning
+
+case <"\\"-space> math <"\\"-space> is <indent-force> --> beginning
+
+close semi --> ending
+close <"\\"-space> ? semi --> ending
+close <"\\"-space> ? <"\\"-space> ? semi --> ending
+
+continuation <force> (stmt|ignore_scrap) --> continuation
+continuation <outdent-force> continuation --> continuation
+
+
+declaration <outdent-force> beginning <outdent-force> continuation <outdent-force> ending --> stmt
+declaration <outdent-force> beginning <outdent-force> ending --> stmt
+declaration <outdent-force> ending --> stmt
+declaration <force> (stmt|ignore_scrap) --> declaration
+
+else <indent-force> --> continuation
+elsif <"\\"-space> math <"\\"-space> then <indent-force> --> continuation
+
+exception <indent-force> --> continuation
+
+generic <outdent-force> declaration --> declaration
+generic <force> (stmt|ignore_scrap) --> generic
+
+if <"\\"-space> math <"\\"-space> then --> ifthen
+ifthen <indent-force> stmt --> beginning
+ifthen <indent-force> <"\\"-space> math <"\\"-space> <outdent-force> else --> ifthen
+ifthen <indent-force> <"\\"-space> math <"\\"-space> <outdent-force> close <"\\"-space> if --> math
+ifthen <indent-force> <"\\"-space> math <"\\"-space> <outdent-force> elsif --> if
+
+
+is --> math
+
+loop <indent-force> --> beginning
+
+math [ <"\\"-space> and <"\\"-space> then <"\\"-space> ] --> math binop
+math [ <"\\"-space> and <"\\"-space> ] --> math binop
+
+math (binop|unorbinop) math --> math
+math <"\\"-space> resunorbinop <"\\"-space> math --> math
+(unorbinop|unop) math --> math
+resunorbinop <"\\"-space> math --> math
+# This doesn't apply in Ada: math unop --> math
+
+math arrow --> math
+math binop <"\\"-space> exception --> math
+math <space> is --> math
+math <"\\"-space> loop --> loop
+math <"\\"-space> math --> math
+math [ <"\\"-space> or <"\\"-space> else <"\\"-space> ] --> math binop
+math [ <"\\"-space> or <"\\"-space> ] --> math binop
+math <"\\"-space> private --> math
+math <"\\"-space> separate --> math
+math <indent-force> stmt <outdent-force> --> stmt
+math terminator --> stmt
+
+open close --> math
+open math close --> math
+open [ math semi ] --> open math
+
+<force-backup> openlabel math closelabel <force> --> math
+
+or <indent-force> --> continuation
+
+private <indent-force> --> beginning
+
+proc <"\\"-space> math <space> is <"\\"-space> separate --> math
+proc <"\\"-space> math <space> is <indent-force> --> declaration
+proc <"\\"-space> math terminator --> stmt
+
+record <"\\"-space> at <"\\"-space> math terminator <indent-force> --> beginning
+record <indent-force> --> beginning
+
+semi --> terminator
+
+stmt <force> stmt --> stmt
+
+when <"\\"-space> math arrow <indent-force> --> whengroup
+[ when <"\\"-space> math ] terminator --> math terminator
+whengroup stmt <outdent-force> ending --> ending
+whengroup stmt <outdent-force> whengroup --> whengroup
+
+where <indent> --> beginning
+
+with <"\\"-space> math --> math
+with <"\\"-space> proc <"\\"-space> math --> math
+
+? ignore_scrap --> #1
+
+
+########################### Additional stuff for PolyAnna ##################
+
+# PolyAnna delimiters
+
+default mathness yes
+
+token --: category virtual translation <"\\R\\IG"> mathness no
+token --| category annotation translation <"\\R\\IG"> mathness no
+token <=> category arrow translation <"\\DA">
+token -> category binop translation <"\\RA">
+
+# We might use these guys for PolyAnna
+
+# token [ category open
+# token ] category close
+# token { translation <"\\{"> category open
+# token } translation <"\\}"> category close
+
+
+
+# Polyanna reserved words
+
+default mathness maybe translation <*>
+
+reserved based ilk math_like
+reserved bound ilk math_like
+reserved exists ilk math_like
+reserved forall ilk math_like
+reserved global ilk math_like
+reserved mathforall ilk forall_like
+reserved on ilk math_like
+reserved such ilk math_like
+reserved that ilk math_like
+reserved trait ilk math_like
+reserved virtual ilk separate_like
+reserved where ilk where_like
+
+ilk forall_like translation <"\\forall"> category math mathness yes
+
+
+
+# The line below will cause scan_annotations.awk to generate code for
+# scanning annotations and virtual text. The integer is the depth of nesting.
+# (sp is short for "suspend parse", and is created when annotations are
+# encountered in the midst of virtual text.
+#scan_annotations 10
+
+# recognize the end of a group of annotations
+[ <"\\AN{"> annotation !(nl|sp) nl <"\\MC}\\MS\\R"> ] !annotation --> annotation_group !annotation
+
+# recognize the end of some lines of virtual text
+[ <"\\VI{"> virtual !(nl|sp) nl <"\\MC}\\MS\\R"> ] !(virtual|annotation) --> virtual_group !(virtual|annotation)
+
+# ignore a group of annotations in the midst of virtual text
+<"\\MC}\\MS\\R"> sp <force> annotation_group <force-"\\VI{"> virtual --> ignore_scrap
+# if a virtual text terminates with a group of annotations, just turn the
+# suspended parse into a newline---this terminates the virtual text.
+[ sp ] annotation_group !virtual --> nl annotation_group !virtual
+
+
+# put annotations or virtual text in a block by itself, and ignore it
+# in other parsing.
+<force> (annotation_group|virtual_group) <force> --> ignore_scrap
+
+# ignore newlines except in the special situations listed above
+!(annotation|virtual|sp|busted_comment) nl --> #1
+
+
+
+
+
+
+
+macros begin
+\def\AN{\markpar{--|}}
+\def\VI{\markpar{\frenchspacing--:}}
+\let\AR=\Longrightarrow
+\let\RA=\rightarrow
+\let\DA=\Longleftrightarrow
+\let\AS\K
+\def\MG{\mathrel{\to}}
+
+\newbox\window
+\newbox\icon
+\newif\ifmarkdo
+\newdimen\markh\markh=.83333333\baselineskip
+\newdimen\saveindent
+\newcount\saveind
+
+\def\markpar#1#2{\setbox\icon=\hbox{\.{#1 }}%
+\saveindent=\hangindent
+\saveind=\ind
+\setbox\window=\vbox{\advance\hsize by -\wd\icon
+\advance\hsize by -\saveindent
+\global\ind=2\hangindent=\ind em
+\hbox{This line will get peeled}
+\noindent\kern\ind em\copy\bakk\ignorespaces#2}%
+\hangindent=\saveindent
+\global\ind=\saveind
+\vbox{
+\splittopskip=\markh\vbadness=10000\setbox0=\vsplit\window to\markh
+\loop \ifvoid\window\markdofalse\else\markdotrue\fi
+\ifmarkdo
+\hbox{\unhcopy\icon\vsplit\window to\markh}
+\repeat
+}}
+
+\input frames
+macros end
diff --git a/web/spiderweb/src/penelope/make b/web/spiderweb/src/penelope/make
new file mode 100644
index 0000000000..d20e6ce373
--- /dev/null
+++ b/web/spiderweb/src/penelope/make
@@ -0,0 +1,5 @@
+#!/bin/csh -f
+# awk -f scan_annotations.awk < a.spider > processed-a.spider
+/bin/make -f SpiderMakefile $*
+/bin/make -f ../master/WebMakefile \
+ THETANGLE=adatangle THEWEAVE=adaweave SPIDER=processed-a.spider $*
diff --git a/web/spiderweb/src/penelope/nesting.spider b/web/spiderweb/src/penelope/nesting.spider
new file mode 100644
index 0000000000..ddf65041c5
--- /dev/null
+++ b/web/spiderweb/src/penelope/nesting.spider
@@ -0,0 +1,21 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+annotation [ !(nl|sp) nl annotation ] --> annotation #2
+annotation !(nl|sp) [ !(nl|sp) nl annotation ] --> annotation !(nl|sp) #3
+annotation !(nl|sp) !(nl|sp) [ !(nl|sp) nl annotation ] --> annotation !(nl|sp) !(nl|sp) #4
+annotation !(nl|sp) !(nl|sp) !(nl|sp) [ !(nl|sp) nl annotation ] --> annotation !(nl|sp) !(nl|sp) !(nl|sp) #5
+
+
+# No nesting yet.
+
+virtual [ !(nl|sp) nl virtual ] --> virtual #2
+virtual !(nl|sp) [ !(nl|sp) nl virtual ] --> virtual !(nl|sp) #3
+virtual !(nl|sp) !(nl|sp) [ !(nl|sp) nl virtual ] --> virtual !(nl|sp) !(nl|sp) #4
+virtual !(nl|sp) !(nl|sp) !(nl|sp) [ !(nl|sp) nl virtual ] --> virtual !(nl|sp) !(nl|sp) !(nl|sp) #5
+
+virtual !(nl|sp) [ nl ] annotation --> virtual !(nl|sp) sp annotation
+virtual !(nl|sp) !(nl|sp) [ nl ] annotation --> virtual !(nl|sp) !(nl|sp) sp annotation
+virtual !(nl|sp) !(nl|sp) !(nl|sp) [ nl ] annotation --> virtual !(nl|sp) !(nl|sp) !(nl|sp) sp annotation
+virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) [ nl ] annotation --> virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) sp annotation
+
diff --git a/web/spiderweb/src/penelope/processed-a.spider b/web/spiderweb/src/penelope/processed-a.spider
new file mode 100644
index 0000000000..db6529bcbb
--- /dev/null
+++ b/web/spiderweb/src/penelope/processed-a.spider
@@ -0,0 +1,418 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+language Ada extension ada
+
+at_sign @
+
+module definition stmt use math
+
+comment begin <dash-dash-space> end newline
+macros begin
+\def\commentbegin{{\tt -- }}
+macros end
+
+line begin <dash-dash-"line"> end <"">
+
+default translation <*> mathness yes
+
+token identifier category math mathness maybe
+token number category math mathness yes
+token newline category nl translation <> mathness maybe
+# newline mathness must be no to work with busted_comment
+token pseudo_semi translation <> category semi mathness maybe
+
+macros begin
+\let\R\relax
+macros end
+
+# Delimiters
+token & category binop translation <"\\amp">
+token ( category open
+token ) category close
+token * category binop
+token + category unorbinop
+token , category binop translation <",\\,"-opt-3>
+token - category unorbinop
+token . category binop
+token / category binop
+token : category binop
+token ; category semi translation <";"-space-opt-2>
+token < category binop
+token = category binop
+token > category binop
+token | category binop translation <"\\mid">
+
+# Compound delimiters
+
+token => category arrow translation <"\\AR">
+token .. category binop translation <"\\.{..}">
+token ** category binop
+token := category binop translation <"\\mathbin{:=}">
+token /= translation <"\\I"> category binop
+token >= translation <"\\G"> category binop
+token <= translation <"\\L"> category binop
+token << translation <"\\LL"> category openlabel
+token >> translation <"\\GG"> category closelabel
+token <> translation <"\\LG"> category math
+
+# Hacks no ', and this becomes a binary op
+token ' category binop mathness no
+
+token # category math translation <"\\#">
+token -- category busted_comment mathness no translation <"\\C{">
+
+
+
+
+default mathness maybe translation <*>
+
+reserved abort ilk math_like
+reserved abs ilk unop_like
+reserved accept ilk proc_like
+reserved access ilk math_like
+reserved all ilk math_like
+reserved and ilk and_like
+reserved array ilk math_like
+reserved at ilk at_like
+reserved begin ilk begin_like
+reserved body ilk math_like
+reserved case ilk case_like
+reserved constant ilk math_like
+reserved declare ilk decl_like
+reserved delay ilk math_like
+reserved delta ilk math_like
+reserved digits ilk math_like
+reserved do ilk is_like
+reserved else ilk else_like
+reserved elsif ilk elsif_like
+reserved end ilk end_like
+reserved entry ilk proc_like
+reserved exception ilk ex_like
+reserved exit ilk math_like
+reserved for ilk math_like
+reserved function ilk proc_like
+reserved generic ilk gen_like
+reserved goto ilk math_like
+reserved if ilk if_like
+reserved in ilk unorbinop_like
+reserved is ilk is_like
+reserved limited ilk math_like
+reserved loop ilk loop_like
+reserved mod ilk binop_like
+reserved new ilk separate_like
+reserved not ilk unop_like
+reserved null ilk math_like
+reserved of ilk math_like
+reserved or ilk or_like
+reserved others ilk math_like
+reserved out ilk math_like
+reserved package ilk proc_like
+reserved pragma ilk math_like
+reserved private ilk private_like
+reserved procedure ilk proc_like
+reserved raise ilk math_like
+reserved range ilk math_like
+reserved record ilk record_like
+reserved rem ilk binop_like
+reserved renames ilk math_like
+reserved return ilk math_like
+reserved reverse ilk math_like
+reserved select ilk begin_like
+reserved separate ilk separate_like
+reserved subtype ilk math_like
+reserved task ilk proc_like
+reserved terminate ilk math_like
+reserved then ilk then_like
+reserved type ilk math_like
+reserved use ilk math_like
+reserved when ilk when_like
+reserved while ilk math_like
+reserved with ilk with_like
+reserved xor ilk binop_like
+
+ilk and_like translation <*> category and
+ilk at_like translation <*> category at
+ilk begin_like translation <*-indent> category beginning
+ilk binop_like translation <"\\"-space-*-"\\"-space> category binop
+ilk case_like translation <*> category case
+ilk decl_like translation <*-indent> category declaration
+ilk else_like translation <*> category else
+ilk elsif_like translation <*> category elsif
+ilk end_like translation <*> category close
+ilk ex_like translation <*> category exception
+ilk gen_like translation <*-indent> category generic
+ilk if_like translation <*> category if
+ilk is_like translation <*> category is mathness no
+ilk loop_like translation <*> category loop
+ilk math_like translation <*> category math
+ilk or_like translation <*> category or
+ilk private_like translation <*> category private
+ilk proc_like translation <*> category proc
+ilk record_like translation <*> category record
+ilk separate_like translation <*> category separate
+ilk then_like translation <*> category then
+ilk unop_like translation <*-"\\"-space> category unop
+ilk unorbinop_like translation <"\\"-space-*-"\\"-space> category resunorbinop
+ilk when_like translation <*> category when
+ilk where_like category where
+ilk with_like translation <*> category with
+
+
+# \MC means ``math close'' and sets \MS to ``math set''
+macros begin
+\def\MC{\ifmmode\global\let\MS$\else\global\let\MS\relax\fi\relax\MS}
+\def\LG{\mathord{<}\mathord{>}}
+\let\IG=\ignorespaces
+macros end
+
+
+
+busted_comment <"\\MC}\\MS\\R"-force> nl --> ignore_scrap
+busted_comment ? --> busted_comment
+
+beginning <outdent-force> continuation <outdent-force> ending --> stmt
+beginning <outdent-force> ending --> stmt
+beginning <force> (stmt|ignore_scrap) --> beginning
+
+case <"\\"-space> math <"\\"-space> is <indent-force> --> beginning
+
+close semi --> ending
+close <"\\"-space> ? semi --> ending
+close <"\\"-space> ? <"\\"-space> ? semi --> ending
+
+continuation <force> (stmt|ignore_scrap) --> continuation
+continuation <outdent-force> continuation --> continuation
+
+
+declaration <outdent-force> beginning <outdent-force> continuation <outdent-force> ending --> stmt
+declaration <outdent-force> beginning <outdent-force> ending --> stmt
+declaration <outdent-force> ending --> stmt
+declaration <force> (stmt|ignore_scrap) --> declaration
+
+else <indent-force> --> continuation
+elsif <"\\"-space> math <"\\"-space> then <indent-force> --> continuation
+
+exception <indent-force> --> continuation
+
+generic <outdent-force> declaration --> declaration
+generic <force> (stmt|ignore_scrap) --> generic
+
+if <"\\"-space> math <"\\"-space> then --> ifthen
+ifthen <indent-force> stmt --> beginning
+ifthen <indent-force> <"\\"-space> math <"\\"-space> <outdent-force> else --> ifthen
+ifthen <indent-force> <"\\"-space> math <"\\"-space> <outdent-force> close <"\\"-space> if --> math
+ifthen <indent-force> <"\\"-space> math <"\\"-space> <outdent-force> elsif --> if
+
+
+is --> math
+
+loop <indent-force> --> beginning
+
+math [ <"\\"-space> and <"\\"-space> then <"\\"-space> ] --> math binop
+math [ <"\\"-space> and <"\\"-space> ] --> math binop
+
+math (binop|unorbinop) math --> math
+math <"\\"-space> resunorbinop <"\\"-space> math --> math
+(unorbinop|unop) math --> math
+resunorbinop <"\\"-space> math --> math
+# This doesn't apply in Ada: math unop --> math
+
+math arrow --> math
+math binop <"\\"-space> exception --> math
+math <space> is --> math
+math <"\\"-space> loop --> loop
+math <"\\"-space> math --> math
+math [ <"\\"-space> or <"\\"-space> else <"\\"-space> ] --> math binop
+math [ <"\\"-space> or <"\\"-space> ] --> math binop
+math <"\\"-space> private --> math
+math <"\\"-space> separate --> math
+math <indent-force> stmt <outdent-force> --> stmt
+math terminator --> stmt
+
+open close --> math
+open math close --> math
+open [ math semi ] --> open math
+
+<force-backup> openlabel math closelabel <force> --> math
+
+or <indent-force> --> continuation
+
+private <indent-force> --> beginning
+
+proc <"\\"-space> math <space> is <"\\"-space> separate --> math
+proc <"\\"-space> math <space> is <indent-force> --> declaration
+proc <"\\"-space> math terminator --> stmt
+
+record <"\\"-space> at <"\\"-space> math terminator <indent-force> --> beginning
+record <indent-force> --> beginning
+
+semi --> terminator
+
+stmt <force> stmt --> stmt
+
+when <"\\"-space> math arrow <indent-force> --> whengroup
+[ when <"\\"-space> math ] terminator --> math terminator
+whengroup stmt <outdent-force> ending --> ending
+whengroup stmt <outdent-force> whengroup --> whengroup
+
+where <indent> --> beginning
+
+with <"\\"-space> math --> math
+with <"\\"-space> proc <"\\"-space> math --> math
+
+? ignore_scrap --> #1
+
+
+########################### Additional stuff for PolyAnna ##################
+
+# PolyAnna delimiters
+
+default mathness yes
+
+token --: category virtual translation <"\\R\\IG"> mathness no
+token --| category annotation translation <"\\R\\IG"> mathness no
+token <=> category arrow translation <"\\DA">
+token -> category binop translation <"\\RA">
+
+# We might use these guys for PolyAnna
+
+# token [ category open
+# token ] category close
+# token { translation <"\\{"> category open
+# token } translation <"\\}"> category close
+
+
+
+# Polyanna reserved words
+
+default mathness maybe translation <*>
+
+reserved based ilk math_like
+reserved bound ilk math_like
+reserved exists ilk math_like
+reserved forall ilk math_like
+reserved global ilk math_like
+reserved mathforall ilk forall_like
+reserved on ilk math_like
+reserved such ilk math_like
+reserved that ilk math_like
+reserved trait ilk math_like
+reserved virtual ilk separate_like
+reserved where ilk where_like
+
+ilk forall_like translation <"\\forall"> category math mathness yes
+
+
+
+# The line below will cause scan_annotations.awk to generate code for
+# scanning annotations and virtual text. The integer is the depth of nesting.
+# (sp is short for "suspend parse", and is created when annotations are
+# encountered in the midst of virtual text.
+#scan_annotations 10
+
+# automatically generating productions...
+
+
+# "annotation" expansion sequence
+
+annotation [ !(nl|sp) nl annotation ] --> annotation #2
+annotation !(nl|sp) [ !(nl|sp) nl annotation ] --> annotation !(nl|sp) #3
+annotation !(nl|sp) !(nl|sp) [ !(nl|sp) nl annotation ] --> annotation !(nl|sp) !(nl|sp) #4
+annotation !(nl|sp) !(nl|sp) !(nl|sp) [ !(nl|sp) nl annotation ] --> annotation !(nl|sp) !(nl|sp) !(nl|sp) #5
+annotation !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) [ !(nl|sp) nl annotation ] --> annotation !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) #6
+annotation !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) [ !(nl|sp) nl annotation ] --> annotation !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) #7
+annotation !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) [ !(nl|sp) nl annotation ] --> annotation !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) #8
+annotation !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) [ !(nl|sp) nl annotation ] --> annotation !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) #9
+annotation !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) [ !(nl|sp) nl annotation ] --> annotation !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) #10
+
+# "virtual" expansion sequence
+
+virtual [ !(nl|sp) nl virtual ] --> virtual #2
+virtual !(nl|sp) [ !(nl|sp) nl virtual ] --> virtual !(nl|sp) #3
+virtual !(nl|sp) !(nl|sp) [ !(nl|sp) nl virtual ] --> virtual !(nl|sp) !(nl|sp) #4
+virtual !(nl|sp) !(nl|sp) !(nl|sp) [ !(nl|sp) nl virtual ] --> virtual !(nl|sp) !(nl|sp) !(nl|sp) #5
+virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) [ !(nl|sp) nl virtual ] --> virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) #6
+virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) [ !(nl|sp) nl virtual ] --> virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) #7
+virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) [ !(nl|sp) nl virtual ] --> virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) #8
+virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) [ !(nl|sp) nl virtual ] --> virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) #9
+virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) [ !(nl|sp) nl virtual ] --> virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) #10
+
+# "virtual" -- "annotation" expansion sequence
+
+virtual !(nl|sp) [ nl ] annotation --> virtual !(nl|sp) sp annotation
+virtual !(nl|sp) !(nl|sp) [ nl ] annotation --> virtual !(nl|sp) !(nl|sp) sp annotation
+virtual !(nl|sp) !(nl|sp) !(nl|sp) [ nl ] annotation --> virtual !(nl|sp) !(nl|sp) !(nl|sp) sp annotation
+virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) [ nl ] annotation --> virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) sp annotation
+virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) [ nl ] annotation --> virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) sp annotation
+virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) [ nl ] annotation --> virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) sp annotation
+virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) [ nl ] annotation --> virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) sp annotation
+virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) [ nl ] annotation --> virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) sp annotation
+virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) [ nl ] annotation --> virtual !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) !(nl|sp) sp annotation
+
+
+# end of automatically generated productions
+
+
+# recognize the end of a group of annotations
+[ <"\\AN{"> annotation !(nl|sp) nl <"\\MC}\\MS\\R"> ] !annotation --> annotation_group !annotation
+
+# recognize the end of some lines of virtual text
+[ <"\\VI{"> virtual !(nl|sp) nl <"\\MC}\\MS\\R"> ] !(virtual|annotation) --> virtual_group !(virtual|annotation)
+
+# ignore a group of annotations in the midst of virtual text
+<"\\MC}\\MS\\R"> sp <force> annotation_group <force-"\\VI{"> virtual --> ignore_scrap
+# if a virtual text terminates with a group of annotations, just turn the
+# suspended parse into a newline---this terminates the virtual text.
+[ sp ] annotation_group !virtual --> nl annotation_group !virtual
+
+
+# put annotations or virtual text in a block by itself, and ignore it
+# in other parsing.
+<force> (annotation_group|virtual_group) <force> --> ignore_scrap
+
+# ignore newlines except in the special situations listed above
+!(annotation|virtual|sp|busted_comment) nl --> #1
+
+
+
+
+
+
+
+macros begin
+\def\AN{\markpar{--|}}
+\def\VI{\markpar{\frenchspacing--:}}
+\let\AR=\Longrightarrow
+\let\RA=\rightarrow
+\let\DA=\Longleftrightarrow
+\let\AS\K
+\def\MG{\mathrel{\to}}
+
+\newbox\window
+\newbox\icon
+\newif\ifmarkdo
+\newdimen\markh\markh=.83333333\baselineskip
+\newdimen\saveindent
+\newcount\saveind
+
+\def\markpar#1#2{\setbox\icon=\hbox{\.{#1 }}%
+\saveindent=\hangindent
+\saveind=\ind
+\setbox\window=\vbox{\advance\hsize by -\wd\icon
+\advance\hsize by -\saveindent
+\global\ind=2\hangindent=\ind em
+\hbox{This line will get peeled}
+\noindent\kern\ind em\copy\bakk\ignorespaces#2}%
+\hangindent=\saveindent
+\global\ind=\saveind
+\vbox{
+\splittopskip=\markh\vbadness=10000\setbox0=\vsplit\window to\markh
+\loop \ifvoid\window\markdofalse\else\markdotrue\fi
+\ifmarkdo
+\hbox{\unhcopy\icon\vsplit\window to\markh}
+\repeat
+}}
+
+\input frames
+macros end
diff --git a/web/spiderweb/src/penelope/scan_annotations.awk b/web/spiderweb/src/penelope/scan_annotations.awk
new file mode 100644
index 0000000000..a4b82ee8b3
--- /dev/null
+++ b/web/spiderweb/src/penelope/scan_annotations.awk
@@ -0,0 +1,81 @@
+# used to print the code that ignores <<nl annotation>> in annotations
+# and ignores <<nl virtual>> in virtual text
+# Assumes the following categories
+# nl == newline token (closes virtual text and annotations)
+# sp == suspend parse -- used to suspend parsing of virtual
+# text while we scan an annotation
+# virtual = --: (opens virtual text)
+# annotation = --| (opens annotations)
+#
+
+# copy everything
+{ print }
+
+# Announce ourselves
+
+/^#scan_annotations [0-9]*$/ {
+ print ""
+ print "# automatically generating productions..."
+ print ""
+ }
+
+#
+# ignore <<nl annotation>> in annotations
+#
+/^#scan_annotations [0-9]*$/ {
+ print ""
+ print "# \"annotation\" expansion sequence"
+ print ""
+ $nlsp = ""
+ for (i = 2; i <= $2; i++)
+ {
+ printf "annotation " $nlsp
+ printf "[ !(nl|sp) nl annotation ] --> annotation "
+ printf $nlsp "#" i
+ printf "\n"
+ $nlsp = $nlsp "!(nl|sp) "
+ }
+}
+#
+# ignore <<nl virtual>> in virtual text
+#
+/^#scan_annotations [0-9]*$/ {
+ print ""
+ print "# \"virtual\" expansion sequence"
+ print ""
+ $nlsp = ""
+ for (i = 2; i <= $2; i++)
+ {
+ printf "virtual " $nlsp
+ printf "[ !(nl|sp) nl virtual ] --> virtual "
+ printf $nlsp "#" i
+ printf "\n"
+ $nlsp = $nlsp "!(nl|sp) "
+ }
+}
+#
+# suspend parsing of virtual text when an annotation is encountered
+#
+/^#scan_annotations [0-9]*$/ {
+ print ""
+ print "# \"virtual\" -- \"annotation\" expansion sequence"
+ print ""
+ $nlsp = ""
+ for (i = 2; i <= $2; i++)
+ {
+ $nlsp = $nlsp "!(nl|sp) "
+ printf "virtual " $nlsp
+ printf "[ nl ] annotation --> virtual "
+ printf $nlsp "sp annotation"
+ printf "\n"
+ }
+ print ""
+}
+
+# Announce our passing
+
+/^#scan_annotations [0-9]*$/ {
+ print ""
+ print "# end of automatically generated productions"
+ print ""
+ }
diff --git a/web/spiderweb/src/penelope/stacks.web b/web/spiderweb/src/penelope/stacks.web
new file mode 100644
index 0000000000..c37c65b9d0
--- /dev/null
+++ b/web/spiderweb/src/penelope/stacks.web
@@ -0,0 +1,445 @@
+\message{OK, entering \string\batchmode...}
+\batchmode
+\overfullrule0pt
+%\magnification=\magstep2
+%\input awebmac
+\input enumerate.sty
+\def\VC#1#2{{\enumerate\item #1\endenumerate\par}{$>\!\!>$\ #2\par}}
+%\parindent=0pt\parskip=0.5\baselineskip
+\let\maps\rightarrow
+\def\title{A Generic Stack Package}
+
+@*Stacks.
+The idea is to implement, and to prove part of, a simple stack package.
+We write a Larch trait for the stacks,
+we use terms of that trait to specify our package.
+ In the package body we write down an explicit
+representation invariant |invar| and an explicit abstraction function
+|abstraction|, and we use them to prove the package \`a la Hoare.
+The package specification refers only to the abstract trait,
+and our software will automatically perform the translation required
+to introduce explicit invariants and abstraction functions in the
+package body.
+
+@*Theory of stacks.
+We use the following theory:
+%\input stacktrait.pretty
+
+
+@*Specification.
+We now use the |Stack_theory| trait to specify a package.
+The phrase
+|with trait Stack_theory|
+makes the |Stack_theory| trait visible and
+the phrase
+|based on stack|
+makes the sort |stack| from |Stack_theory| the abstract sort |stack'ABSTRACT|.
+We also use the |element| sort to represent the private type |element|.
+% ACK! What proof obligations does this give?
+
+In the package {\it specification}, all terms of type |stack| are
+specified with terms of type |Stacks_theory.stack|.
+In the package {\it body}, we will specify terms of type |stack| with
+terms of a sort corresponding to the private type of stack (in this
+instance, a record type).
+We will provide an abstraction function from terms of the record trait
+to terms of the stack trait, and an invariant function from terms of
+the record trait to |boolean|.
+@c@0
+generic
+ type element is private; --| based on element;
+ length: natural := 100;
+package stacks is
+ --| with trait Stack_theory;
+ type stack is private;
+@/ --| based on stack;
+ overflow, underflow: exception;
+@#
+ function empty_stack return stack;
+ --| where return new_stack; end where;
+
+@#
+ function pushit(s:stack; e:element) return stack;
+ --| where
+ --| return push(s,e);
+ --| raise overflow <=> size(s) = length;
+ --| end where;
+@#
+ function popit(s:stack) return stack;
+ --| where
+ --| return pop(s);
+ --| raise underflow <=> size(s) = 0;
+ --| end where;
+@#
+ function topit(s:stack) return element;
+ --| where
+ --| return top(s);
+ --| raise underflow <=> size(s) = 0;
+ --| end where;
+@#
+ function isEmpty(s:stack) return boolean;
+ --| where
+ --| return is_empty(s);
+ --| end where;
+
+private
+ subtype stack_range is natural range 0.. length - 1;
+ type stack_array is array(stack_range) of element;
+ type stack is
+ record
+ l: natural; -- length
+ a: stack_array; --stack
+ end record;
+
+end stacks;
+@*Implementation.
+We break the implementation into pieces so we can discuss them one at
+a time.
+
+Within the hidden part of the package, |stack| will stand for the
+concrete type (or sort), |stack'CONCRETE|.
+Outside, in the specification, |stack| will stand for the abstract
+type (or sort), |stack'ABSTRACT|.
+We use types in actual Ada code, and sorts in annotations and virtual
+functions.
+
+@c
+generic
+ type element is private;
+ length: natural := 100;
+package body stacks is
+@<Abstraction and invariants@>@;
+@<Implementation of |empty_stack|@>@;
+@<Implementation of |pushit|@>@;
+@<Implementation of |popit|@>@;
+@<Implementation of |topit|@>@;
+@<Implementation of |isEmpty|@>@;
+end stacks;
+@ Here we make explicit the representation invariant |invar| and the
+abstraction function |abstraction|.
+These are virtual functions, and templates for them will be generated
+automatically from the package specification.
+These functions will appear in the annotations for the operations of
+the package, which will also have been translated from the package
+specification.
+
+The invariant requires only that the length be within sensible bounds.
+(I have ignored the problem of definedness throughout the example.)
+The abstraction function works by peeling off the top element, and
+pushing it onto the abstraction of what's left.
+This works all the way down to |s.l=0|, for which the abstraction is
+|new_stack|.
+
+The templates for |invar| and |abstraction| are generated
+automatically.
+
+@<Abstraction...@>=
+--:function invar(s:stack) return boolean
+--| where
+--| return 0<=s.l<=length; -- |and| some definedness condition
+--| end where;
+--:is virtual;
+
+--:function abstraction(s:stack) return stack'ABSTRACT
+--| where
+--| in invar(s);
+--| return if s.l=0 then
+--| new_stack@;
+--| else
+--| push(abstraction(s[l=>l-1]),s.a(s.l))@;
+--| end if;
+--| end where;
+--:is virtual;
+
+@ To implement |empty_stack| we return a stack of length zero.
+
+@<Implementation of |empty_stack|@>=
+function empty_stack return stack
+--| where
+--| return s:stack such that
+--| invar(s) and
+--| abstraction(s)=new_stack;
+--| end where;
+is
+ empty: stack;
+begin
+ empty.l := 0;
+ return empty;
+end empty_stack;
+
+@*Proof of |empty_stack|.
+Here and elsewhere we will use the notation |@@return| to denote the return
+value.
+Predicate transformation of the postcondition leaves the following verification
+condition:
+\VC{|true|}{|invar(empty) and abstraction(empty)=new_stack|}
+
+We split and get
+\VC{|true|}{|invar(empty)|}
+and, expanding
+\VC{|true|}{|0<=empty.l and empty.l <= length|}
+and substituting for |empty.l| (on what basis?)
+\VC{|true|}{|0<=0 and 0 <= length|}
+from which
+\VC{|true|}{|true|}
+because of the property |0<=n| for any natural number |n|.
+
+The second verification condition is
+\VC{|true|}{|abstraction(empty)=new_stack|}
+We expand |abstraction|, spawning the new VC
+\VC{|true|}{|invar(empty)|}
+for which we can refer to the earlier proof.
+We are left with
+\VC{|true|}{|if empty.l=0 then new_stack else
+ push(abstraction(empty[l=>l-1]),empty.a(empty.l));
+ end if = new_stack;|}
+Which rewrites to
+\VC{|true|}{|new_stack=new_stack|}
+
+
+@ Here we have to check for overflow, but there are really no surprises.
+@<Implementation of |pushit|@>=
+function pushit(s:stack; e:element) return stack
+--| where
+--| in invar(s);
+--| return r:stack such that
+--| invar(r) and
+--| abstraction(r)=push(abstraction(s),e);
+--| end where;
+is
+ t: stack;
+begin
+ if s.l=length then raise overflow; end if;
+ t.l := s.l+1;
+ t.a := s.a;
+ t.a(t.l) := e;
+ return t;
+end empty_stack;
+
+@*Predicate transformation of |pushit|.
+Here we have ignored the possibility of abnormal termination.
+
+I've written intermediate conditions in between the statements to
+which they apply.
+The predicate transformation rules I've used are completely
+informal.
+
+
+@c
+function pushit(s:stack; e:element) return stack
+--| where
+--| in invar(s);
+--| return r:stack such that
+--| invar(r) and
+--| abstraction(r)=push(abstraction(s),e);
+--| raise overflow <=> size(abstraction(s)) = length;
+--| end where;
+is
+ t: stack;
+begin
+--| s.l /= length and
+--| invar(t[l=>s.l+1;a=>s.a;a(l)=>e]) and
+--| abstraction(t[l=>s.l+1;a=>s.a;a(l)=>e])=push(abstraction(s),e);
+ if s.l=length then raise overflow; end if;
+--| invar(t[l=>s.l+1;a=>s.a;a(l)=>e]) and
+--| abstraction(t[l=>s.l+1;a=>s.a;a(l)=>e])=push(abstraction(s),e);
+ t.l := s.l+1;
+--| invar(t[a=>s.a;a(l)=>e]) and
+--| abstraction(t[a=>s.a;a(l)=>e])=push(abstraction(s),e);
+ t.a := s.a;
+--| invar(t[a(l)=>e]) and
+--| abstraction(t[a(l)=>e])=push(abstraction(s),e);
+ t.a(t.l) := e;
+--| invar(t) and
+--| abstraction(t)=push(abstraction(s),e);
+ return t;
+--| invar(@@return) and
+--| abstraction(@@return)=push(abstraction(s),e);
+end empty_stack;
+
+@*Proof of |pushit|.
+We're going to make heavy use of a (nonexistent) theory of records.
+Record states are as in Anna;
+informally they behave just as you would think.
+
+We first rewrite the term involving |t| into a simpler and more useful
+form:
+$$\vbox{\noindent
+|t[l=>s.l+1;a=>s.a;a(l)=>e]| rewrites to
+|s[l=>l+1;a(l)=>e]|.
+}$$
+
+
+After this simplification we have this verification condition:
+\VC{|
+invar(s)|\item
+|not (size(abstraction(s)) = length)|}
+{|
+s.l /= length and
+invar(s[l=>l+1;a(l)=>e]) and
+abstraction(s[l=>l+1;a(l)=>e])=push(abstraction(s),e)
+|}
+We'll tackle one conjunct at a time.
+
+@ {\it First conjunct.}
+We begin by proving a lemma about |size|:
+\VC{|invar(s)|}
+{|size(abstraction(s))|$\simeq$|s.l|}
+The proof is by type induction on the predefined type |natural|.
+We omit it here.
+
+Once we have the |size| lemma we rewrite the VC for the first conjunct as:
+\VC{|
+invar(s)|\item
+|not (s.l = length)|}
+{|s.l /= length|}
+The proof is by the laws (not stated) for |=| and |/=|.
+
+@ {\it Second Conjunct.}
+Again we apply the |size| lemma.
+\VC{|
+invar(s)|\item
+|not (s.l = length)|}
+{|
+invar(s[l=>l+1;a(l)=>e])|}
+Expanding the definition of |invar| in the hypothesis and the conclusion yields
+\VC{|
+0<=s.l and s.l <= length|\item
+|not (s.l = length)|}
+{|
+0<=s[l=>l+1;a(l)=>e].l and
+s[l=>l+1;a(l)=>e].l<=length
+|}
+and we again exploit the theory of records to rewrite as
+\VC{|
+0<=s.l and s.l <= length|\item
+|not (s.l = length)|}
+{|
+0<=s.l+1 and
+s.l+1<=length
+|}
+And the proof follows by |and|-splitting hypotheses and conclusion and by
+applying the laws of arithmetic.
+
+@ {\it Third conjunct.}
+This is the interesting part.
+We expand the definition of |abstraction| on the left hand side of the
+conclusion.
+This spawns a VC showing that the argument to |abstraction| satisfies
+|invariant|, but we did that earlier.
+
+\VC{|
+invar(s)|\item
+|not (size(abstraction(s)) = length)|}
+{|
+if s[l=>l+1;a(l)=>e].l=0 then new_stack else
+push(abstraction(s[l=>l+1;a(l)=>e;l=>l-1]),
+s[l=>l+1;a(l)=>e].a(s[l=>l+1;a(l)=>e].l)) end if
+ =push(abstraction(s),e)
+|}
+and, rewriting according to the theory of records
+(especially
+|s[l=>l+1;a(l)=>e].a(s[l=>l+1;a(l)=>e].l)|
+rewrites to
+|s[l=>l+1;a(s.l+1)=>e].a(s.l+1)|
+which rewrites to |e|):
+\VC{|
+invar(s)|\item
+|not (size(abstraction(s)) = length)|}
+{|
+if s.l+1=0 then new_stack else
+push(abstraction(s[a(l+1)=>e]),e) end if
+ =push(abstraction(s),e)
+|}
+Applying the laws of natural numbers we have
+\VC{|
+invar(s)|\item
+|not (size(abstraction(s)) = length)|}
+{|
+push(abstraction(s[a(l+1)=>e]),e) = push(abstraction(s),e)
+|}
+
+
+And now we show by a lemma that
+\VC{|invar(s)|\item |s.l/=length|}
+{
+|abstraction(s[a(l+1)=>e])|$\simeq$|abstraction(s)|
+}
+which is sufficient.
+The proof of the lemma is by induction over |l| (type induction of the
+predefined type |natural|).
+
+
+
+
+@ @<Implementation of |popit|@>=
+function popit(s:stack) return stack
+--| where
+--| in invar(s);
+ --| return c:stack such that invar(c) and
+ --| abstraction(c)=pop(abstraction(s));
+ --| raise underflow <=> size(abstraction(s)) = 0;
+--| end where;
+is
+ t: stack;
+begin
+ if s.l=0 then raise underflow; end if;
+ t := s;
+ t.l := t.l-1;
+ return t;
+end popit;
+
+@ @<Implementation of |topit|@>=
+function topit (s:stack) return element
+--| where
+--| in invar(s);
+--| return top(abstraction(s));
+--| end where;
+is
+begin
+ if s.l=0 then raise underflow; end if;
+ return s.a(s.l);
+end topit;
+
+@ @<Implementation of |isEmpty|@>=
+ function isEmpty(s:stack) return boolean
+ --| where
+ --| in invariant(s);
+ --| return is_empty(abstraction(s));
+ --| end where;
+ is
+ begin
+ return s.l=0;
+ end isEmpty;
+@ Predicate transformation of isEmpty.
+@c
+ function isEmpty(s:stack) return boolean
+ --| where
+ --| in invariant(s);
+ --| return is_empty(abstraction(s));
+ --| end where;
+ is
+ begin
+ --| (s.l=0)=is_empty(abstraction(s))
+ return s.l=0;
+ --| @@return=is_empty(abstraction(s))
+ end isEmpty;
+
+@ Proof of isEmpty.
+\VC{|invariant(s)|}{|s.l=0 =is_empty(abstraction(s))|}
+Expanding |abstraction(s)|,
+\VC{|invariant(s)|}{|s.l=0 =is_empty(if s.l=0 then nil
+ else cons(abstraction(s[l=>l-1]),l.a(s.l-1)))|}
+Simplifying,
+\VC{|invariant(s)|}{|(s.l=0)=if s.l=0 then is_empty(nil)
+ else is_empty(cons(abstraction(s[l=>l-1]),l.a(s.l-1)))|}
+which we can rewrite as
+\VC{|invariant(s)|}{|(s.l=0)=if s.l=0 then true
+ else is_empty(cons(abstraction(s[l=>l-1]),l.a(s.l-1)))|}
+Simplifying,
+\VC{|invariant(s)|}{|true|}
+
+
+@*Index.
+This is an index of all the identifiers used in the program.
+The numbers are section numbers, not page numbers. \ No newline at end of file
diff --git a/web/spiderweb/src/postscript/README b/web/spiderweb/src/postscript/README
new file mode 100644
index 0000000000..ab9885866e
--- /dev/null
+++ b/web/spiderweb/src/postscript/README
@@ -0,0 +1,10 @@
+This is a Spider description and set of change files for a PostScript WEB
+done by Dave Love, love@daresbury.ac.uk. Originally done as practice --
+is it useful?
+
+You need to alter the master/WebMakefile to incorporate change files and
+not to zap them if you do `make clean'. My version is included here.
+
+outline.ps1 is a copy of the result of tangling outline.web, to be
+included in the example. The name was changed since dvitops will make
+me an outline.ps from the TeX.
diff --git a/web/spiderweb/src/postscript/WebMakefile.new b/web/spiderweb/src/postscript/WebMakefile.new
new file mode 100644
index 0000000000..2067064dda
--- /dev/null
+++ b/web/spiderweb/src/postscript/WebMakefile.new
@@ -0,0 +1,147 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+# Modified by Dave Love, Daresbury Lab for local setup and to incorporate
+# change files
+
+#HOME=/nfs/dlsa/usr10/fx# # Make no longer inherits environment vars
+# (it does inherit env vars on my system!)
+THETANGLE=tangle
+THEWEAVE=weave
+SPIDER=any.spider
+WEAVECHANGEFILES=
+TANGLECHANGEFILES=
+#
+DVI=dvi
+CFLAGS=-DDEBUG -g -DSTAT
+
+# CPUTYPE is a grim hack that attempts to solve the problem of multiple
+# cpus sharing a file system. In my environment I have to have different
+# copies of object and executable for vax, sun3, next, iris, and other
+# cpu types. If you will be using Spidery WEB in a homogenous processor
+# environment, you can just set CPUTYPE to a constant, or eliminate it
+# entirely.
+#
+# In my environment, the 'cputype' program returns a string that
+# describes the current processor. That means that the easiest thing
+# for you to do is to define a 'cputype' program that does something
+# sensible. A shell script that says 'echo "vax"' is fine.
+
+CPUTYPE=`cputype`
+
+# Change the following three directories to match your installation
+#
+# the odd placement of # is to prevent any trailing spaces from slipping in
+
+WEBROOT=$(HOME)/spiderweb# # root of the WEB source distribution
+DEST=$(HOME)/bin# # place where the executables go
+MACROS=$(HOME)/tex/inputs# # place where the macros go
+
+MASTER=$(WEBROOT)/master# # master source directory
+OBDIR=$(MASTER)/$(CPUTYPE)# # common object files
+
+TANGLESRC=tangle
+CTANGLE=ceetangle -I$(MASTER)
+CWEAVE=ceeweave -I$(MASTER)
+AWKTANGLE=awktangle -I$(MASTER)
+COMMONOBJS=$(OBDIR)/common.o $(OBDIR)/pathopen.o
+COMMONC=$(MASTER)/common.c $(MASTER)/pathopen.c
+COMMONSRC=$(COMMONC) $(MASTER)/spider.awk
+
+
+
+# Our purpose is to make tangle and weave
+
+web: tangle weave
+
+tangle: $(COMMONOBJS) $(TANGLESRC).o
+ cc $(CFLAGS) -o $(DEST)/$(THETANGLE) $(COMMONOBJS) $(TANGLESRC).o
+
+weave: $(COMMONOBJS) weave.o
+ cc $(CFLAGS) -o $(DEST)/$(THEWEAVE) $(COMMONOBJS) weave.o
+
+
+source: $(TANGLESRC).c $(COMMONSRC) # make tangle.c and common src, then clean
+ if [ -f WebMakefile ]; then exit 1; fi # don't clean the master!
+ if [ -f spiderman.tex ]; then exit 1; fi # don't clean the manual
+ -rm -f tangle.web weave.* common.* # remove links that may be obsolete
+ -rm -f *.unsorted *.list grammar.web outtoks.web scraps.web
+ -rm -f cycle.test spider.slog
+ -rm -f *.o *.tex *.toc *.dvi *.log *.makelog *~ *.wlog *.printlog
+
+# Here is how we make the common stuff
+
+$(MASTER)/common.c: $(MASTER)/common.web # no change file
+ $(CTANGLE) $(MASTER)/common
+
+$(OBDIR)/common.o: $(MASTER)/common.c
+ cc $(CFLAGS) -c $(MASTER)/common.c
+ mv common.o $(OBDIR)
+
+
+$(MASTER)/pathopen.c: $(MASTER)/pathopen.web # no change file
+ $(CTANGLE) $(MASTER)/pathopen
+ mv pathopen.h $(MASTER)
+
+$(OBDIR)/pathopen.o: $(MASTER)/pathopen.c
+ cc $(CFLAGS) -c $(MASTER)/pathopen.c
+ mv pathopen.o $(OBDIR)
+
+
+## Now we make the tangle and weave source locally
+
+$(TANGLESRC).c: $(MASTER)/$(TANGLESRC).web $(MASTER)/common.h grammar.web $(TANGLECHANGEFILES)
+ -/bin/rm -f $(TANGLESRC).web
+ ln $(MASTER)/$(TANGLESRC).web $(TANGLESRC).web
+# chmod -w $(TANGLESRC).web
+ $(CTANGLE) $(TANGLESRC) $(TANGLECHANGEFILES)
+
+weave.c: $(MASTER)/weave.web $(MASTER)/common.h grammar.web $(WEAVECHANGEFILES)
+ -/bin/rm -f weave.web
+ ln $(MASTER)/weave.web weave.web
+# chmod -w weave.web
+ $(CTANGLE) weave $(WEAVECHANGEFILES)
+
+## Here's where we run SPIDER to create the source
+
+grammar.web: $(MASTER)/cycle.awk $(MASTER)/spider.awk $(SPIDER)
+ echo "date" `date` | cat - $(SPIDER) | awk -f $(MASTER)/spider.awk
+ cat $(MASTER)/transcheck.list trans_keys.unsorted | awk -f $(MASTER)/transcheck.awk
+ awk -f $(MASTER)/cycle.awk < cycle.test
+ sort *.unsorted | awk -f $(MASTER)/nodups.awk
+# mv *web.tex $(MACROS)
+
+## We might have to make spider first.
+
+$(MASTER)/spider.awk: $(MASTER)/spider.web
+ $(AWKTANGLE) $(MASTER)/spider
+ mv cycle.awk nodups.awk transcheck.awk $(MASTER)
+ rm junk.list
+
+
+# $(MASTER)/cycle.awk: $(MASTER)/cycle.web # making spider also makes cycle
+# $(AWKTANGLE) $(MASTER)/cycle
+
+
+# This cleanup applies to every language
+
+clean:
+ if [ -f WebMakefile ]; then exit 1; fi # don't clean the master!
+ if [ -f spiderman.tex ]; then exit 1; fi # don't clean the manual
+ -rm -f tangle.web weave.web common.* # remove links that may be obsolete
+ -rm -f *.unsorted *.list grammar.web outtoks.web scraps.web
+ -rm -f cycle.test spider.slog
+ -rm -f *.c *.o *.tex *.toc *.dvi *.log *.makelog *~ *.wlog *.printlog
+
+
+
+# booting the new distribution
+boot:
+ cd ../master; rm -f *.o; for i in $(COMMONC); do \
+ cc $(CFLAGS) -c $$i; \
+ mv *.o $(OBDIR) ; \
+ done; cd ../c
+ cc $(CFLAGS) -c $(TANGLESRC).c; \
+ cc $(CFLAGS) -o $(DEST)/$(THETANGLE) $(COMMONOBJS) $(TANGLESRC).o
+
+
diff --git a/web/spiderweb/src/postscript/local.guide b/web/spiderweb/src/postscript/local.guide
new file mode 100644
index 0000000000..f5fb55995c
--- /dev/null
+++ b/web/spiderweb/src/postscript/local.guide
@@ -0,0 +1,72 @@
+%-*-TeX-*-
+% Copyright 1989, David Love, SERC Daresbury Laboratory
+\def\ps{{\sc PostScript}}
+\def\web{{\tt WEB}}
+\font\sc=cmcsc10
+\centerline{{\bf Local guide for PS}\web}
+\vskip5ex
+\centerline{David Love, SERC Daresbury Laboratory ({\tt
+love@daresbury.ac.uk})}
+\vskip5ex
+\noindent
+This note describes the restrictions on the \ps\ code imposed by
+this implementation of \web\ for \ps, the treatment of the \web\
+source by {\tt TANGLE} and {\tt WEAVE} and points out a useful piece
+of self-referential treatment of the code.
+
+\beginsection Restrictions on names
+
+There are restrictions on the characters allowed in names. Apart from
+alphamerics and underscores, only {\tt !\$\&*-} are allowed. These
+should allow some messing around defining silly-looking private names
+as well as allowing {\tt -} as a `word' separator.
+
+\beginsection {\tt WEAVE} treatment of code
+
+Only rather limited pretty-printing is possible as the semantics of a
+\ps\ expression are so difficult to establish. What is done
+is:\footnote{*}{This is like GNUEmacs' \ps\ grinding, I discover.}
+\item{$\bullet$} Newlines in the source are obeyed. Consecutive
+newlines are replaced by a `bigskip'---newline with extra vertical
+space.
+\item{$\bullet$} \ps\ names are printed in math, numbers in
+roman, strings in {\tt \char'134ttex}.
+\item{$\bullet$} The only keywords which are
+recognised and to which meaning is attached are {\it def}, {\it
+begin}, {\it end}. A literal name which is {\it def\/}ed has its
+index entry underlined.
+\item{$\bullet$} Blocks delimited by {\tt
+begin} $\ldots$ {\tt end}, {\tt \char'173} $\ldots$ {\tt \char'175},
+{\tt [} $\ldots$ {\tt ]}, {\tt <} $\ldots$ {\tt >} are indented.
+\item{$\bullet$} The indentation may be controlled using the special
+tokens {\tt =>} and {\tt <=} respectively to increase and decrease the
+indentation level by one. They tangle to nothing and are not valid
+names anyway under the rules above. They should be placed (anywhere)
+on the line {\it before} the one to be in/outdented. A typical use
+might be to indent conditional code. Maybe these frigs should be replaced
+by {\tt WEB} control codes at some stage, although you can always send
+the control sequences through using {\tt @t}.
+
+\beginsection Demonstration of procedure results
+
+Remember that the {\tt \char'134psfig} macro allows you to include
+\ps\ into \TeX\ documents (if you have a suitable {\tt DVI} to \ps\
+backend). Thus you can include the {\tt TANGLE}d {\tt WEB} into the
+{\tt WEAVE}d output to show example results of your code.
+
+\beginsection \ps\ file conventions
+
+The {\tt \%!}\ comment often required at the beginning of a \ps\ file
+is inserted automatically into the {\tt TANGLE}d output. There is no
+other built-in support for the conventional structure of \ps\ files.
+In particular, you may need to get a {\tt \%\%BoundingBox:}\ comment
+in the output near the start---if you're using {\tt \char'134psfig},
+for instance. This can be achieved by using the {\tt @=} control
+sequence.
+
+\beginsection Example
+
+An example of a literate re-write of a \ps\ exmaple is given in {\tt
+outline.web}. It demonstrates inclusion of the results in the
+documentation.
+\bye
diff --git a/web/spiderweb/src/postscript/make b/web/spiderweb/src/postscript/make
new file mode 100644
index 0000000000..709f7d30cc
--- /dev/null
+++ b/web/spiderweb/src/postscript/make
@@ -0,0 +1,5 @@
+#!/bin/csh -f
+/bin/make -f ../master/WebMakefile CPUTYPE=`cputype`\
+ THETANGLE=pstangle THEWEAVE=psweave SPIDER=ps.spider \
+ WEAVECHANGEFILES=weave.ch TANGLECHANGEFILES=tangle.ch \
+ HOME=$HOME CFLAGS='-DC_FLOATING_POINT' $*
diff --git a/web/spiderweb/src/postscript/outline.ps1 b/web/spiderweb/src/postscript/outline.ps1
new file mode 100644
index 0000000000..070d410dee
--- /dev/null
+++ b/web/spiderweb/src/postscript/outline.ps1
@@ -0,0 +1,212 @@
+%!
+%3:
+
+% 21 "bigtest.web"
+
+%%BoundingBox: 18 18 577 824
+
+%:3
+%4:
+
+% 25 "bigtest.web"
+
+% 26 "bigtest.web"
+ /makeoutlinedict 7 dict def
+
+%:4
+%5:
+
+% 34 "bigtest.web"
+
+% 35 "bigtest.web"
+ /MakeOutlineFont
+{makeoutlinedict begin
+%6:
+
+% 50 "bigtest.web"
+
+% 51 "bigtest.web"
+ /uniqueid exch def
+ /strokewidth exch def
+ /newfontname exch def
+ /basefontname exch def
+
+%:6
+
+% 37 "bigtest.web"
+
+%7:
+
+% 56 "bigtest.web"
+
+% 57 "bigtest.web"
+ /basefontdict basefontname findfont def
+
+%:7
+
+% 38 "bigtest.web"
+
+%8:
+
+% 59 "bigtest.web"
+
+% 60 "bigtest.web"
+ /numentries basefontdict maxlength 1 add def
+
+%:8
+
+% 39 "bigtest.web"
+
+%9:
+
+% 65 "bigtest.web"
+
+% 66 "bigtest.web"
+basefontdict /UniqueID known not
+{ /numentries numentries 1 add def}if
+
+%:9
+
+% 40 "bigtest.web"
+
+%10:
+
+% 69 "bigtest.web"
+
+% 70 "bigtest.web"
+ /outfontdict numentries dict def
+
+%:10
+
+% 41 "bigtest.web"
+
+%11:
+
+% 72 "bigtest.web"
+
+% 73 "bigtest.web"
+basefontdict
+{exch dup /FID ne
+{exch outfontdict 3 1 roll put}
+{pop pop}
+ifelse
+}forall
+
+%:11
+
+% 43 "bigtest.web"
+
+%12:
+
+% 85 "bigtest.web"
+
+% 86 "bigtest.web"
+outfontdict /FontName newfontname put
+outfontdict /PaintType 2 put
+outfontdict /StrokeWidth strokewidth put
+outfontdict /UniqueID uniqueid put
+
+%:12
+
+% 44 "bigtest.web"
+
+%13:
+
+% 93 "bigtest.web"
+
+% 94 "bigtest.web"
+newfontname outfontdict definefont pop
+
+%:13
+
+% 45 "bigtest.web"
+
+end
+}def
+
+%:5
+%14:
+
+% 100 "bigtest.web"
+
+% 101 "bigtest.web"
+ /Helvetica-Bold /Helvetica-Outline1%15:
+
+% 110 "bigtest.web"
+
+% 111 "bigtest.web"
+ 1000 54 div
+
+%:15
+
+% 101 "bigtest.web"
+
+%16:
+
+% 116 "bigtest.web"
+
+% 117 "bigtest.web"
+ /Helvetica-Bold findfont dup /UniqueID known
+{ /UniqueID get 1 add}
+{pop 1}
+ifelse
+%:16
+
+% 102 "bigtest.web"
+
+MakeOutlineFont
+
+%:14
+%17:
+
+% 122 "bigtest.web"
+
+% 123 "bigtest.web"
+ /Helvetica-Outline1 findfont 36 scalefont setfont
+72 504 moveto(outline)show
+ /Helvetica-Outline1 findfont 54 scalefont setfont
+(outline)show
+
+%:17
+%18:
+
+% 133 "bigtest.web"
+
+% 134 "bigtest.web"
+ /Helvetica-Bold /Helvetica-Outline2 1000 36 div
+%16:
+
+% 116 "bigtest.web"
+
+% 117 "bigtest.web"
+ /Helvetica-Bold findfont dup /UniqueID known
+{ /UniqueID get 1 add}
+{pop 1}
+ifelse
+%:16
+
+% 135 "bigtest.web"
+
+MakeOutlineFont
+
+%:18
+%19:
+
+% 139 "bigtest.web"
+
+% 140 "bigtest.web"
+ /Helvetica-Outline2 findfont 36 scalefont setfont
+72 444 moveto(outline)show
+ /Helvetica-Outline2 findfont 54 scalefont setfont
+(outline)show
+
+%:19
+%20:
+
+% 146 "bigtest.web"
+
+% 147 "bigtest.web"
+showpage
+
+%:20
+
diff --git a/web/spiderweb/src/postscript/outline.web b/web/spiderweb/src/postscript/outline.web
new file mode 100644
index 0000000000..b9f90b78ae
--- /dev/null
+++ b/web/spiderweb/src/postscript/outline.web
@@ -0,0 +1,162 @@
+% Copyright 1989, David Love, SERC Daresbury Laboratory under the same
+% conditions as the Spider distribution
+
+\def\title{PSWEB demonstration -- outline font}
+\def\ps{{\sc PostScript}}
+
+@*Introduction.
+As a simple example of the use of \ps\ \.{WEB} we'll do a
+literate re-write of {\sl Program 16 / Making an Outline Font} from the
+Adobe blue {\sl Cookbook}, p~199. Most of the text will be directly lifted
+from that example.
+Compare this with the original!
+The \ps\ convention of writing, for instance, |MakeOutlineFont| instead
+of the form |make_outline_font| has been carried over from the original
+example just this once, contrary to Knuthian lore and my preference.
+
+@*2Purpose.
+This program defines a general procedure to take one of the built-in
+fonts and convert it to an outline font.
+(This program will also work for downloadable fonts available from
+Adobe Systems, Inc.).
+
+@ We need to write out a suitable bounding box comment for \.{\\psfig}.
+@u
+@=%%BoundingBox: 18 18 577 824@>
+
+@ Local storage for the procedure |MakeOutlineFont|.
+@u
+/makeoutlinedict 7 dict def
+
+@*2Function definition and use.
+|MakeOutlineFont| takes one of the built-in filled fonts and makes an outlined
+font out of it.
+It takes four arguments: the name of the font on which to base the outline
+version, the new name for the outline font, a stroke width to use on the
+outline and a unique ID.
+@u
+/MakeOutlineFont =>% base\_name new\_name stroke\_width ID
+ { makeoutlinedict begin
+ @<stash the arguments@>
+ @<get dictionary of font on which outline version will be based@>
+ @<determine how large new font dictionary should be@>
+ @<make sure there is room for the unique ID field@>
+ @<create dictionary to hold description for outline font@>
+ @<copy entries in base font dictionary to outline dictionary, except
+ for the FID@>
+ @<miscellaneous inserts into the new dictionary@>
+ @<make new font@>
+ end
+} def
+
+@ Four arguments as described above.
+@<stash...@>=
+/uniqueid exch def
+/strokewidth exch def
+/newfontname exch def
+/basefontname exch def
+
+@ @<get dictionary...@>=
+/basefontdict basefontname findfont def
+
+@ @<determine how large...@>=
+/numentries basefontdict maxlength 1 add def
+
+@ (Not all fonts have unique ID fields initially.
+In particlular, the built-in fonts in \ps\ version 23.0 don't.)
+
+@<make sure there is room...@>=
+basefontdict /UniqueID known not =>
+ {/numentries numentries 1 add def} if
+
+@ @<create dictionary...@>=
+/outfontdict numentries dict def
+
+@ @<copy entries...@>=
+basefontdict =>
+ { exch dup /FID ne
+{exch outfontdict 3 1 roll put}
+{pop pop} % ignore the FID pair
+ifelse
+} forall
+
+@ We need to 1) insert the new name into the dictionary
+2) change the paint type to outline
+3) insert the stroke width into the dictionary
+4) insert the new unique ID
+
+@<miscellaneous inserts...@>=
+outfontdict /FontName newfontname put
+outfontdict /PaintType 2 put
+outfontdict /StrokeWidth strokewidth put
+outfontdict /UniqueID uniqueid put
+
+@ In making the outline dictionary into a \ps\ font we ignore the
+modified dictionary returned on the stack by |definefont|.
+@<make new font@>=
+newfontname outfontdict definefont pop
+
+@*Use of the procedure and determining new IDs.
+We'll make a new font |Helvetica-Outline1| derived from |Helvetica-Bold|.
+The results will appear below.
+
+@u
+/Helvetica-Bold @!/Helvetica-Outline1 @<define stroke width@>
+@<determine unique ID@>
+MakeOutlineFont
+
+@ The stroke width is always specified in the character coordinate system
+(1000 units).
+The value specified here will yield a one point wide outline when the font is
+scaled to 54 points in size.
+Note that this outline width changes with different point sizes.
+@^stroke width@>
+@<define stroke width@>=
+1000 54 div
+
+@ To determine the unique id:
+If the `base' font already contains a unique ID, add a unique constant to it,
+otherwise pick a unique integer and leave that value on the operand stack.
+@<determine unique ID@>=
+/Helvetica-Bold findfont dup /UniqueID known =>
+ {/UniqueID get 1 add}
+{pop 1}
+ifelse
+@ So here are two sizes with this stroke width.
+@u
+/Helvetica-Outline1 findfont 36 scalefont setfont =>
+72 504 moveto (outline) show <=
+/Helvetica-Outline1 findfont 54 scalefont setfont =>
+ (outline) show
+
+@ Now we'll do one with a different stroke width.
+The width of 1000/36 used now yields a one point wide outline when the font
+is scaled to 36 point in size.
+It yields a 1.5 point outline when the font is scaled to 54 points
+in size ($54/36=1.5$).@^stroke width@>
+@u
+/Helvetica-Bold @!/Helvetica-Outline2 1000 36 div
+@<determine unique ID@>
+MakeOutlineFont
+
+@ And use the different stroke width:
+@u
+/Helvetica-Outline2 findfont 36 scalefont setfont =>
+72 444 moveto (outline) show <=
+/Helvetica-Outline2 findfont 54 scalefont setfont =>
+ (outline) show
+
+@ Finish off the example:
+@u
+showpage
+
+@*1Results of the examples.
+The results of including the \.{TANGLE}d version of this \.{WEB} source
+into the \.{WEAVE} output using the \.{\\psfig} macro and a suitable
+\.{DVI} to \ps\ converter are given here. The example has been shrunken
+to get it on the page and may be faint on a write-white engine with the
+stroke widths defined above.@^stroke width@>@^write-white@>
+\input psfig.sty
+\centerline{\psfig{figure=outline.ps1,height=6in}}
+
+@*Index.
diff --git a/web/spiderweb/src/postscript/ps.spider b/web/spiderweb/src/postscript/ps.spider
new file mode 100644
index 0000000000..b4a095bed3
--- /dev/null
+++ b/web/spiderweb/src/postscript/ps.spider
@@ -0,0 +1,77 @@
+# Copyright 1989 by David Love, SERC Daresbury Laboratory
+# (love@daresbury.ac.uk)
+# under the same conditions as the SPIDER distribution.
+# For more information, see file COPYRIGHT in the parent directory
+
+language PostScript extension ps
+
+comment begin <"%"> end newline
+macros begin
+\def\commentbegin{\%}
+\let\&=\\ % don't want bold reserved words (only begin, end, def used anyway)
+\def\ps{\sc PostScript}
+macros end
+
+line begin <"%"> end <"">
+
+default translation <*> mathness yes
+
+module definition math use math
+
+token identifier category math mathness yes
+token number category number mathness yes
+token newline category newline translation <> mathness maybe
+token pseudo_semi category ignore_scrap mathness no translation <opt-0>
+
+token [ category open translation <break_space-*>
+token ] category close translation <break_space-*>
+token { translation <"\\{"> category open
+token } translation <"\\}"> category close
+token < category open translation <break_space-*>
+token > category close translation <break_space-*>
+token # category hash translation <"\\#">
+# use mathness no here to avoid extra space after /
+token / category slash tangleto <space-"/"> mathness no
+token = category math
+token == category math
+
+# a frig to allow user to indent/outdent as required
+# => and <= can't be used as PostScript names!
+# this would be better done with new WEB control sequences
+token => category dent translation <indent> tangleto <"">
+token <= category dent translation <outdent> tangleto <"">
+
+ilk def_like category def mathness yes
+reserved def ilk def_like
+ilk begin_like category begin mathness yes
+reserved begin ilk begin_like
+ilk end_like category end mathness yes
+reserved end ilk end_like
+
+# index def'd things with underline
+slashed_math <break_space> math --> slashed_math
+slashed_math* <break_space> def --> math
+[ slashed_math ] (close|end) --> math (close|end)
+
+<big_force> newline newline --> ignore_scrap
+<force> newline --> ignore_scrap
+
+# want indent inside open/close pairs
+open <indent> math <outdent> close --> math
+# could have empty procedure
+open close --> math
+
+slash math --> slashed_math
+
+number hash number --> math
+number --> math
+math <break_space> math --> math
+
+begin <indent> --> math
+<outdent> end --> math
+
+dent --> ignore_scrap
+
+ignore_scrap math --> math
+
+? ignore_scrap --> #1
diff --git a/web/spiderweb/src/reduce/INSTALL b/web/spiderweb/src/reduce/INSTALL
new file mode 100644
index 0000000000..52aa82a432
--- /dev/null
+++ b/web/spiderweb/src/reduce/INSTALL
@@ -0,0 +1,26 @@
+In this directory you can find the stuff necessary for building RWEB,
+the REDUCE version of SPIDERY WEB.
+
+Along with these files you need a version of SPIDERY WEB, which can be
+obtained by anonymous ftp from princeton.edu (128.112.128.1).
+
+After you have installed SPIDERY WEB you know what it means to put the
+files contained in this directory into a new directory $(WEBROOT)/reduce.
+Do it. You might as well want to change the variable HOME in
+$(WEBROOT)/reduce/Makefile (which is in fact an adapted version of
+$(MASTER)/WebMakefile).
+
+In order to make RWEB, go to $(WEBROOT)/reduce and type 'make weave',
+'make tangle' or 'make web', if you want to make rweave, rtangle or
+both. The documentation needed for using RWEB is
+$(WEBROOT)/doc/spiderwebman.tex.
+
+Have fun,
+
+Marcel Roelofs,
+University of Twente,
+Department of applied mathematics,
+P.O. Box 217,
+7500 AE Enschede,
+The Netherlands.
+E-mail: roelofs@math.utwente.nl
diff --git a/web/spiderweb/src/reduce/Makefile b/web/spiderweb/src/reduce/Makefile
new file mode 100644
index 0000000000..ec100b3bcb
--- /dev/null
+++ b/web/spiderweb/src/reduce/Makefile
@@ -0,0 +1,152 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates.
+# Not to be sold, but may be used freely for any purpose.
+# For more information, see file COPYRIGHT in the parent directory.
+
+HOME=/users/redusers# # Make no longer inherits environment vars
+
+THETANGLE=tangle
+THEWEAVE=weave
+SPIDER=any.spider
+#
+DVI=dvi
+CFLAGS=-DDEBUG -g -DSTAT
+
+# CPUTYPE is a grim hack that attempts to solve the problem of multiple
+# cpus sharing a file system. In my environment I have to have different
+# copies of object and executable for vax, sun3, next, iris, and other
+# cpu types. If you will be using Spidery WEB in a homogenous processor
+# environment, you can just set CPUTYPE to a constant, or eliminate it
+# entirely.
+#
+# In my environment, the 'cputype' program returns a string that
+# describes the current processor. That means that the easiest thing
+# for you to do is to define a 'cputype' program that does something
+# sensible. A shell script that says 'echo "vax"' is fine.
+
+CPUTYPE=`cputype`
+
+# Change the following three directories to match your installation
+#
+# the odd placement of # is to prevent any trailing spaces from slipping in
+
+WEBROOT=$(HOME)/spider# # root of the WEB source distribution
+DEST=$(HOME)/bin# # place where the executables go
+MACROS=$(HOME)/tex/inputs# # place where the macros go
+
+MASTER=$(WEBROOT)/master# # master source directory
+OBDIR=$(MASTER)/$(CPUTYPE)# #common object files
+
+TANGLESRC=tangle
+CTANGLE=ceetangle -I$(MASTER)
+CWEAVE=ceeweave -I$(MASTER)
+AWKTANGLE=awktangle -I$(MASTER)
+COMMONOBJS=$(OBDIR)/common.o $(OBDIR)/pathopen.o
+COMMONC=$(MASTER)/common.c $(MASTER)/pathopen.c
+COMMONSRC=$(COMMONC) $(MASTER)/spider.awk
+
+
+# Our purpose is to make tangle and weave
+
+web: tangle weave
+
+tangle: mktangle underscore
+
+mktangle: $(COMMONOBJS) $(TANGLESRC).o
+ $(CC) $(CFLAGS) -o $(DEST)/$(THETANGLE) $(COMMONOBJS) $(TANGLESRC).o
+
+weave: $(COMMONOBJS) weave.o
+ $(CC) $(CFLAGS) -o $(DEST)/$(THEWEAVE) $(COMMONOBJS) weave.o
+
+underscore: $(DEST)/underscore underscore.web
+
+$(DEST)/underscore:
+ $(CTANGLE) underscore.web
+ $(CC) $(CFLAGS) -o $(DEST)/underscore underscore.c
+ cp rtangle $(DEST)/rtangle
+
+source: $(TANGLESRC).c $(COMMONSRC) # make tangle.c and common src, then clean
+ if [ -f WebMakefile ]; then exit 1; fi # don't clean the master!
+ if [ -f spiderman.tex ]; then exit 1; fi # don't clean the manual
+ -rm -f tangle.web weave.* common.* # remove links that may be obsolete
+ -rm -f *.unsorted *.list grammar.web outtoks.web scraps.web
+ -rm -f cycle.test spider.slog
+ -rm -f *.o *.tex *.toc *.dvi *.log *.makelog *~ *.wlog *.printlog
+
+# Here is how we make the common stuff
+
+$(MASTER)/common.c: $(MASTER)/common.web # no change file
+ $(CTANGLE) $(MASTER)/common
+
+$(OBDIR)/common.o: $(MASTER)/common.c
+ $(CC) $(CFLAGS) -c $(MASTER)/common.c
+ mv common.o $(OBDIR)
+
+
+$(MASTER)/pathopen.c: $(MASTER)/pathopen.web # no change file
+ $(CTANGLE) $(MASTER)/pathopen
+ mv pathopen.h $(MASTER)
+
+$(OBDIR)/pathopen.o: $(MASTER)/pathopen.c
+ $(CC) $(CFLAGS) -c $(MASTER)/pathopen.c
+ mv pathopen.o $(OBDIR)
+
+$(OBDIR):
+ if /bin/test ! -d $(OBDIR) ; then mkdir $(OBDIR) ; fi
+
+## Now we make the tangle and weave source locally
+
+$(TANGLESRC).c: $(MASTER)/$(TANGLESRC).web $(MASTER)/common.h grammar.web rtangle.ch
+ -/bin/rm -f $(TANGLESRC).web
+ ln $(MASTER)/$(TANGLESRC).web $(TANGLESRC).web
+# chmod -w $(TANGLESRC).web
+ $(CTANGLE) $(TANGLESRC) rtangle.ch
+
+weave.c: $(MASTER)/weave.web $(MASTER)/common.h grammar.web rweave.ch
+ -/bin/rm -f weave.web
+ ln $(MASTER)/weave.web weave.web
+# chmod -w weave.web
+ $(CTANGLE) weave rweave.ch
+
+## Here's where we run SPIDER to create the source
+
+grammar.web: $(MASTER)/cycle.awk $(MASTER)/spider.awk $(SPIDER)
+ echo "date" `date` | cat - $(SPIDER) | awk -f $(MASTER)/spider.awk
+ cat $(MASTER)/transcheck.list trans_keys.unsorted | awk -f $(MASTER)/transcheck.awk
+ awk -f $(MASTER)/cycle.awk < cycle.test
+ sort *.unsorted | awk -f $(MASTER)/nodups.awk
+ mv *web.tex $(MACROS)
+
+## We might have to make spider first.
+
+$(MASTER)/spider.awk: $(MASTER)/spider.web
+ $(AWKTANGLE) $(MASTER)/spider
+ mv cycle.awk nodups.awk transcheck.awk $(MASTER)
+ rm junk.list
+
+
+# $(MASTER)/cycle.awk: $(MASTER)/cycle.web # making spider also makes cycle
+# $(AWKTANGLE) $(MASTER)/cycle
+
+
+# This cleanup applies to every language
+
+clean:
+ if [ -f WebMakefile ]; then exit 1; fi # don't clean the master!
+ if [ -f spiderman.tex ]; then exit 1; fi # don't clean the manual
+ -rm -f tangle.* weave.* common.* # remove links that may be obsolete
+ -rm -f *.unsorted *.list grammar.web outtoks.web scraps.web
+ -rm -f cycle.test spider.slog
+ -rm -f *.c *.o *.tex *.toc *.dvi *.log *.makelog *~ *.wlog *.printlog
+
+
+
+# booting the new distribution
+boot:
+ cd ../master; rm -f *.o; for i in $(COMMONC); do \
+ $(CC) $(CFLAGS) -c $$i; \
+ mv *.o $(OBDIR) ; \
+ done; cd ../c
+ $(CC) $(CFLAGS) -c $(TANGLESRC).c; \
+ $(CC) $(CFLAGS) -o $(DEST)/$(THETANGLE) $(COMMONOBJS) $(TANGLESRC).o
+
+
diff --git a/web/spiderweb/src/reduce/README b/web/spiderweb/src/reduce/README
new file mode 100644
index 0000000000..0545d0e17d
--- /dev/null
+++ b/web/spiderweb/src/reduce/README
@@ -0,0 +1,69 @@
+REDUCE is a lisp based system for symbolic computation by A. Hearn.
+The real lisp is hidden for the user by a pascal like language, called
+rlisp, which is parsed and converted to ordinary lisp, when read.
+Due to the nature of lisp any expression that returns a value may
+appear at almost any place, for instance
+
+b:=for i:=1:if x then y else z sum a(i)+if c then d else e+
+ while x do begin ...; return ...; ... end;
+
+is a perfectly correct rlisp expression. REDUCE itself and all
+available libraries are written in rlisp. Users can also write their
+own packages in rlisp, containing both low and high level REDUCE
+procedures.
+
+Besides the ordinary stuff available in almost any computer algebra
+program, there are user written packages available for differential
+geometry, determining symmetries of differential equations, lie
+algebras etc., possibly using non standard data structures based on
+lisp objects.
+
+It will be clear from the rlisp expression given above that one has to
+be very careful about what has to appear in math mode and what in text
+mode. Moreover some additional indentation for complicated expressions
+may be desirable.
+The second problem can be solved by carefully implementing the
+production rules, the first one we solved by putting everything in
+text mode except for the unary and binary operators like +, -, :=,
+etc., and applying some tricks to get spaces that cannot be removed by
+a cancel.
+
+Changes necessary to weave and tangle in order to parse rlisp source
+code correctly are the following:
+- rlisp only knows one kind of string, namely the one surrounded by double
+ quotes ", whereas a single quote ' is explicitly used as a 'quote'.
+ This means that the parsing of strings had to be adapted.
+- rlisp has an escape character '!', which means that an identifier
+ may contain any character if it is preceded by an exclamation mark
+ (in this way identifiers may even contain spaces), hence the parsing
+ of identifiers had to be altered.
+- we changed some things which seemed to be bugs: a) in the debug part of
+ the weave code we replaced "\\{" by "\\\\{" since our compiler
+ complained about it, b) "+\equiv" isn't TeX'ed in a very nice way so
+ we replaced it by a new TeX macro "\PS" to be used for multiply
+ defined modules.
+- a minor change: we like tangle also to print the newlines in macros, so
+ we #define'd NEWLINES_IN_MACROS.
+- rlisp doesn't allow underscores to occur in identifiers, unless
+ preceded by '!'. Therefore, we postprocess the tangled file in order
+ to remove the underscores. Indeed this can also be done by changing
+ tangle.web in the appropriate place, but I think it is more work to
+ find the exact place where the change has to be made, than writing a
+ C program that does a similar job. However, if you are more familiar
+ with tangle than we are and know exactly where to make the change,
+ feel free to do so (underscores preceded by '!' and in strings
+ should stay).
+
+Moreover, previewing the weaved & TeX'ed tangle I discovered what
+seems to be a bug in your set of production rules of ceeweave, namely
+'extern' followed by two simps seems to be missing a space, whereas
+'extern' followed by one simp gives no problem.
+
+I hope this 'blurb' about REDUCE and the necessary changes is
+satisfactory. I have put all necessary files tarred, compressed and
+uuencoded at the end of this mail. It is also available by anonymous
+ftp from utmfu0.math.utwente.nl (130.89.60.149).
+
+If you have comments or suggestions on our work, feel free to react.
+
+Marcel Roelofs.
diff --git a/web/spiderweb/src/reduce/make b/web/spiderweb/src/reduce/make
new file mode 100644
index 0000000000..73a59fa56a
--- /dev/null
+++ b/web/spiderweb/src/reduce/make
@@ -0,0 +1,3 @@
+#!/bin/csh -f
+/bin/make -f ../reduce/Makefile CPUTYPE=`cputype`\
+ THETANGLE=rtangle.exe THEWEAVE=rweave SPIDER=reduce.spider $*
diff --git a/web/spiderweb/src/reduce/reduce.spider b/web/spiderweb/src/reduce/reduce.spider
new file mode 100644
index 0000000000..3a6f407cf4
--- /dev/null
+++ b/web/spiderweb/src/reduce/reduce.spider
@@ -0,0 +1,283 @@
+# Copyright (c): Marcel Roelofs and Peter Gragert
+# University of Twente, Enschede, The Netherlands
+#
+# @(#) reduce.spider (91/03/11)
+
+language REDUCE extension r
+
+at_sign @
+
+comment begin <"%"> end <"%">
+
+default translation <*> mathness no
+
+line begin <"%line"> end <>
+
+token identifier category simp
+token number category simp
+token newline category newline translation <>
+token pseudo_semi category terminator translation <"\\rx">
+
+module definition stmt use module_scrap
+
+default translation <"\\ro"-*> mathness no
+
+token * category binop translation <"\\eo*">
+token / category binop translation <"\\eo/">
+token < category binop
+token > category binop
+token = category binop
+token . category binop tangleto <space-"."-space>
+
+token .^ category binop translation <"\\ro{.\\^}"> tangleto <space-".^"-space>
+token .* category binop translation <"\\ro{.*}"> tangleto <space-".*"-space>
+token .+ category binop translation <"\\ro{.+}"> tangleto <space-".+"-space>
+token ./ category binop translation <"\\ro{./}"> tangleto <space-"./"-space>
+token ^ category binop translation <"\\eo\\^">
+token ** category binop translation <"\\eo\\^">
+token := category binop translation <"\\ro\\leftarrow">
+token != category binop translation <"\\ro\\NEQ"> tangleto <space-"neq"-space>
+token <> category binop translation <"\\ro\\NEQ"> tangleto <space-"neq"-space>
+token <= category binop translation <"\\ro\\leq">
+token >= category binop translation <"\\ro\\geq">
+
+default translation <*> mathness no
+
+token + category unorbinop
+token - category unorbinop
+token ' category quote tangleto <space-"'">
+token '( category listopen translation <"'("> tangleto <space-"'(">
+token '[ category listopen translation <"'["> tangleto <space-"'[">
+token ( category open
+token ) category close
+token [ category simpopen
+token ] category close
+token { category simpopen translation <"$\\{$">
+token } category close translation <"$\\}$">
+token , category comma translation <"\\comma"-opt-1>
+token ; category terminator translation <";"-break_space>
+token $ category terminator translation <"\\$"-break_space>
+token : category colon
+token << category progn_begin translation <"\\LL"> tangleto <space-"<<">
+token >> category end translation <"\\RR"> tangleto <">>"-space>
+
+ilk bool_like category simp
+ilk goto_like category simp
+
+default translation <*-space>
+
+ilk begin_like category begin
+ilk if_like category if
+ilk then_like category then
+ilk else_like category else
+ilk for_like category for
+ilk do_like category do
+ilk step_like category step
+ilk repeat_like category repeat
+ilk until_like category until
+ilk on_like category switch
+ilk return_like category return
+ilk modedef_like category mode
+ilk procmode_like category procmode
+ilk proc_like category proc
+ilk where_like category where
+ilk decl_like category decl
+ilk clear_like category clear
+ilk end_like category end translation <*>
+
+ilk not_like category unop translation <"\\R">
+ilk neq_like category binop translation <"\\ro\\NEQ">
+ilk and_like category binop translation <"\\ro\\W">
+ilk or_like category binop translation <"\\ro\\V">
+
+reserved not ilk not_like
+reserved neq ilk neq_like
+reserved and ilk and_like
+reserved or ilk or_like
+
+reserved begin ilk begin_like
+reserved end ilk end_like
+
+reserved if ilk if_like
+reserved then ilk then_like
+reserved else ilk else_like
+
+reserved for ilk for_like
+reserved each ilk for_like
+reserved foreach ilk for_like
+reserved all ilk for_like
+reserved forall ilk for_like
+
+reserved do ilk do_like
+reserved sum ilk do_like
+reserved product ilk do_like
+reserved collect ilk do_like
+reserved conc ilk do_like
+reserved let ilk do_like
+
+reserved in ilk step_like
+reserved step ilk step_like
+reserved such ilk step_like
+reserved that ilk step_like
+
+reserved repeat ilk repeat_like
+reserved until ilk until_like
+
+reserved on ilk on_like
+reserved off ilk on_like
+
+reserved go ilk goto_like
+reserved to ilk goto_like
+reserved goto ilk goto_like
+
+reserved return ilk return_like
+reserved while ilk for_like
+
+reserved algebraic ilk modedef_like
+reserved symbolic ilk modedef_like
+reserved lisp ilk modedef_like
+
+reserved expr ilk procmode_like
+reserved fexpr ilk procmode_like
+reserved macro ilk procmode_like
+reserved smacro ilk procmode_like
+
+reserved procedure ilk proc_like
+
+reserved where ilk where_like
+
+reserved scalar ilk decl_like
+reserved integer ilk decl_like
+reserved real ilk decl_like
+reserved operator ilk decl_like
+reserved array ilk decl_like
+reserved matrix ilk decl_like
+reserved linear ilk decl_like
+reserved symmetric ilk decl_like
+reserved antisymmetric ilk decl_like
+reserved clear ilk clear_like
+
+reserved nil ilk bool_like
+reserved t ilk bool_like
+
+##################################
+# The production rules
+##################################
+
+# Emergency rules, WEAVE commands & comments
+newline ? --> #2
+<cancel-"\\rx"> ignore_scrap ? --> #2
+<cancel> ignore_scrap --> terminator
+terminator --> stmt
+end --> simp
+
+# Simple expressions
+simp <"\\Rs"-opt-3> simp --> simp
+simp binop simp --> simp
+simp <"\\bo"> unorbinop simp --> simp
+<"\\uo"> (unop|unorbinop) simp --> simp
+
+simp <"\\Rs"-indent-cancel> stmt <outdent> --> stmt
+simp binop <indent-cancel> stmt <outdent> --> stmt
+simp <"\\bo"> unorbinop <indent-cancel> stmt <outdent> --> stmt
+<"\\uo"> (unop|unorbinop) <indent-cancel> stmt <outdent> --> stmt
+
+quote <cancel> ? <cancel> --> simp
+simp comma simp --> simp
+simp terminator --> stmt
+stmt stmt --> stmt
+
+# Lists and vectors
+open <cancel> simp <cancel> close --> simp
+
+listopen simp [ open ] --> listopen simp simpopen
+listopen [ open ] --> listopen simpopen
+listopen <"$\\,$"> close --> simp
+listopen simp close --> simp
+
+simpopen <"$\\,$"> close --> simp
+simpopen <"\\Ri"-cancel> simp <cancel-"\\Ro"> close --> simp
+
+# Function calls
+simp open <"$\\,$"> close --> simp
+simp open <"\\Ri"-cancel> simp <cancel-"\\Ro"> close --> simp
+
+# Procedure definitions
+(mode|procmode) proc --> proc
+proc stmt* <force-indent> stmt <outdent-force> --> stmt
+(simp|stmt) <force> proc --> proc
+
+# Declarations
+mode <cancel> (terminator|open) --> #2
+mode stmt --> stmt
+proc stmt begin [ decl stmt* <force> ] --> proc stmt begin stmt
+(decl|clear|switch|do) stmt* <force> --> stmt
+
+# Blocks
+[ simp <break_space> ] end --> stmt end
+<force> begin <force> end --> simp
+<force> begin <opt-7> stmt <force> end terminator <force> --> stmt
+[ <force> begin <opt-7> stmt <force> end ] !terminator --> simp !terminator
+progn_begin end --> simp
+<force> progn_begin <indent-cancel> stmt <cancel-outdent> end terminator <force> --> stmt
+[ <force> progn_begin <indent-cancel> stmt <cancel-outdent> end ] !terminator --> simp !terminator
+
+# For statements in all flavours
+for for --> for
+for [ simp colon <opt-3> simp ] --> for simp
+for [ simp <"\\Rs"> (step|until|switch) <opt-3> simp ] --> for simp
+[ <force> for simp <"\\Rs"> do <opt-1-indent> simp <outdent> ] (comma|close|else|end) --> simp (comma|close|else|end)
+<force> for simp <"\\Rs"> do <opt-1-indent> simp terminator <outdent-force> --> stmt
+<force> for simp <"\\Rs"> do <opt-1-indent> stmt <outdent> --> stmt
+
+# If statements
+if simp <"\\Rs"> then <opt-1> --> ifthen
+ifthen <indent> simp <"\\Rs"-outdent-force> else <opt-1> --> ifelse
+[ <force> ifelse <indent> simp <outdent> ] (comma|close|else|end) --> simp (comma|close|else|end)
+[ <force> (if|ifthen) <indent> simp <outdent> ] (comma|close|end) --> simp (comma|close|end)
+<force> (ifthen|ifelse) <indent> simp terminator <outdent-force> --> stmt
+<force> (ifthen|ifelse) <indent> stmt <outdent> --> stmt
+
+# Where
+[ simp <"\\Rs"-opt-1> where simp ] (close|else|end) --> simp (close|else|end)
+simp <"\\Rs"-opt-1> where simp terminator <force> --> stmt
+
+# Return statement
+[ <force> return <indent> simp <outdent> ] (close|else|end) --> simp (close|else|end)
+<force> return <indent> simp terminator <outdent-force> --> stmt
+<force> return <indent> stmt <outdent> --> stmt
+
+# Repeat statements
+[ <force> repeat <"\\Rs"-opt-7-indent> simp <outdent-force> until <indent> simp <outdent> ] (comma|close|else|end) --> simp (comma|close|else|end)
+<force> repeat <"\\Rs"-opt-7-indent> simp <outdent-force> until <indent> simp terminator <outdent-force> --> stmt
+
+# Labels
+!for [ <force-backup> simp colon <"\\Rs"-cancel> (simp|end) ] --> !for #4
+
+# Module use
+stmt <force> module_scrap terminator <force> --> stmt
+module_scrap --> simp
+
+macros begin
+\def\commentbegin{\{}
+\def\commentend{\}}
+\def\comma{$,{}$}
+\def\uo#1{$#1$}
+\def\ro#1{${}\mathrel{#1}{}$}
+\def\bo#1{${}\mathbin{#1}{}$}
+\def\eo#1{$#1$}
+\def\NEQ{\hbox{$\ne$}}
+\def\LL{$\ll\,$}
+\def\RR{$\,\gg$}
+\def\PS{\joinrel{+\equiv}}
+\let\rx\relax
+\newcount\extraindent
+\def\Ri{\global\advance\extraindent by1}
+\def\Ro{\global\advance\extraindent by-1}
+\def\Rs{{ }}
+\def\startline{\noindent\count255=\ind
+ \ifnum\extraindent=0\advance\count255by-2\fi
+ \hskip\count255 em}
+\def\3#1{\hfil\ifnum#1=0\penalty-100\else\penalty#10\fi\hfilneg}
+macros end
+
diff --git a/web/spiderweb/src/reduce/rtangle b/web/spiderweb/src/reduce/rtangle
new file mode 100644
index 0000000000..6c32919c89
--- /dev/null
+++ b/web/spiderweb/src/reduce/rtangle
@@ -0,0 +1,10 @@
+#!/bin/ksh
+# Copyright (c): Marcel Roelofs and Peter Gragert
+# University of Twente, Enschede, The Netherlands
+#
+# @(#) rtangle (91/03/11)
+
+webfile=$1
+shift
+rtangle.exe ${webfile} $*
+underscore <${webfile}.r > ${webfile}.red
diff --git a/web/spiderweb/src/reduce/rtangle.ch b/web/spiderweb/src/reduce/rtangle.ch
new file mode 100644
index 0000000000..b6edbe8e19
--- /dev/null
+++ b/web/spiderweb/src/reduce/rtangle.ch
@@ -0,0 +1,135 @@
+% Copyright (c): Marcel Roelofs and Peter Gragert
+% University of Twente, Enschede, The Netherlands
+% @@(#) rtangle.ch (91/03/11)
+
+@x
+@u
+@<Include files@>@;
+@<Common code for \.{WEAVE} and \.{TANGLE}@>@;
+@<Typedef declarations@>@;
+@<Global variables@>@;
+@y
+@u
+#define NEWLINES_IN_MACROS
+@<Include files@>@;
+@<Common code for \.{WEAVE} and \.{TANGLE}@>@;
+@<Typedef declarations@>@;
+@<Global variables@>@;
+@z
+
+@x
+ if (isdigit(c) || c=='\\' || c=='.') @<Get a constant@>@;/*spider*/
+ else if (isalpha(c) || c=='_' || c=='$') @<Get an identifier@>@;/*spider*/
+ else if (c=='\'' || c=='\"') @<Get a string@>@;/*spider*/
+@y
+ if (isdigit(c)) @<Get a constant@>@;/*spider*/
+ else if (isalpha(c) || c=='_' || c=='!') @<Get an identifier@>@;/*spider*/
+ else if (c=='\"') @<Get a string@>@;/*spider*/
+@z
+
+@x
+@ @<Get an identifier@>= {/*spider*/
+ id_first=--loc;
+ while (isalpha(*++loc) || isdigit(*loc) || *loc=='_');
+ if (*loc=='$') while (isdigit(*++loc)||*loc=='$');
+ /* make room for \$\$ and \$nnn suffixes */
+ id_loc=loc; return(identifier);
+}
+@y
+@ @<Get an identifier@>= {/*spider*/
+ id_first=--loc;
+ if (c=='!') ++loc;
+ while (isalpha(*++loc) || isdigit(*loc) || *loc=='_' || *loc=='!')
+ if (*loc=='!') ++loc;
+ id_loc=loc; return(identifier);
+}
+@z
+
+@x
+@ \cee\ strings and character constants, delimited by double and single
+quotes, respectively, can contain newlines or instances of their own
+delimiters if they are protected by a backslash. We follow this
+convention, but do not allow the string to be longer than |longest_name|.
+
+@<Get a string@>= {/*spider*/
+ ASCII delim = c; /* what started the string */
+@#
+/* if it's not a single-character literal, it's a tick mark or an |at_sign| */
+ if (delim=='\'' && (loc+1>=limit ||
+ (*loc != '\\' && *loc!=at_sign && loc[1]!='\'') ||
+ (*loc=='\\' && (loc+2>=limit||loc[2]!='\'')) ||
+ (*loc==at_sign &&
+ (loc+2>=limit||loc[1]!=at_sign||loc[2]!='\''))
+ )) goto mistake;
+ id_first = mod_text+1;
+ id_loc = mod_text; *++id_loc=delim;
+ while (1) {
+ if (loc>=limit) {
+ if(*(limit-1)!='\\') {
+ err_print("! String didn't end"); loc=limit; break;
+@.String didn't end@>
+ }
+ if(get_line()==0) {
+ err_print("! Input ended in middle of string"); loc=buffer; break;
+@.Input ended in middle of string@>
+ }
+ else if (++id_loc<=mod_text_end) *id_loc=@`\n'; /* will print as
+ \.{"\\\\\\n"} */
+ }
+ if ((c=*loc++)==delim) {
+ if (++id_loc<=mod_text_end) *id_loc=c;
+ break;
+ }
+ if (c=='\\') {
+ if (loc>=limit) continue;
+ if (++id_loc<=mod_text_end) *id_loc = '\\';
+ c=*loc++;
+ }
+ if (++id_loc<=mod_text_end) *id_loc=c;
+ }
+ if (id_loc>=mod_text_end) {
+ printf("\n! String too long: ");
+@.String too long@>
+ ASCII_write(mod_text+1,25);
+ printf("..."); mark_error;
+ }
+ id_loc++;
+ return(string);
+}
+@y
+@ \cee\ strings are delimited by double quotes and must be restricted
+to one line. Double quotes in strings must be doubled and we allow no
+string to be longer than |longest_name|.
+
+@<Get a string@>= {/*spider*/
+ ASCII delim = c; /* what started the string */
+@#
+ id_first = mod_text+1;
+ id_loc = mod_text; *++id_loc=delim;
+ while (1) {
+ if (loc>=limit) {
+ err_print("! String didn't end"); loc=limit;
+@.String didn't end@>
+ if (get_line()==0) {
+ err_print("! Input ended in middle of string"); loc=buffer;
+@.Input ended in middle of string@>
+ }
+ break;
+ }
+ if ((c=*loc++)==delim) {
+ if (++id_loc<=mod_text_end) *id_loc=c;
+ if (*loc==delim) loc++;
+ else break;
+ }
+ if (++id_loc<=mod_text_end) *id_loc=c;
+ }
+ if (id_loc>=mod_text_end) {
+ printf("\n! String too long: ");
+@.String too long@>
+ ASCII_write(mod_text+1,25);
+ printf("..."); mark_error;
+ }
+ id_loc++;
+ return(string);
+}
+@z
diff --git a/web/spiderweb/src/reduce/rweave.ch b/web/spiderweb/src/reduce/rweave.ch
new file mode 100644
index 0000000000..857cfe2d41
--- /dev/null
+++ b/web/spiderweb/src/reduce/rweave.ch
@@ -0,0 +1,149 @@
+% Copyright (c): Marcel Roelofs and Peter Gragert
+% University of Twente, Enschede, The Netherlands
+% @@(#) rweave.ch (91/03/11)
+
+@x
+ if (isdigit(c)) @<Get a constant@>@; /*spider*/
+ else if (isalpha(c) || c=='_') @<Get an identifier@>@;/*spider*/
+ else if (c=='\'' || c=='"') @<Get a string@>@;/*spider*/
+@y
+ if (isdigit(c)) @<Get a constant@>@;/*spider*/
+ else if (isalpha(c) || c=='_' || c=='!') @<Get an identifier@>@;/*spider*/
+ else if (c=='\"') @<Get a string@>@;/*spider*/
+@z
+
+@x
+@ @<Get an identifier@>= {/*spider*/
+ id_first=--loc;
+ while (isalpha(*++loc) || isdigit(*loc) || *loc=='_');
+ id_loc=loc; return(identifier);
+}
+@y
+@ @<Get an identifier@>= {/*spider*/
+ id_first=--loc;
+ if (c=='!') ++loc;
+ while (isalpha(*++loc) || isdigit(*loc) || *loc=='_' || *loc=='!')
+ if (*loc=='!') ++loc;
+ id_loc=loc; return(identifier);
+}
+@z
+
+@x
+@ \cee\ strings and character constants, delimited by double and single
+quotes, respectively, can contain newlines or instances of their own
+delimiters if they are protected by a backslash. We follow this
+convention, but do not allow the string to be longer than |longest_name|.
+
+@<Get a string@>= {/*spider*/
+ ASCII delim = c; /* what started the string */
+ id_first = mod_text+1;
+ id_loc = mod_text;
+ if (delim=='`' && *(loc-2)==at_sign) {
+ /* make string begin with |"@@`"| */
+ *++id_loc=at_sign;
+ *++id_loc=at_sign;
+ }
+ /* this is hack for ascii constant */
+@#
+/* if it's not a single-character literal, it's a tick mark or an |at_sign| */
+ if ((delim=='\'' || delim == '`') &&
+ (loc+1>=limit ||
+ (*loc != '\\' && *loc!=at_sign && loc[1]!='\'') ||
+ (*loc=='\\' && (loc+2>=limit||loc[2]!='\'')) ||
+ (*loc==at_sign &&
+ (loc+2>=limit||loc[1]!=at_sign||loc[2]!='\''))
+ )
+ ) goto mistake;
+ *++id_loc=delim;
+ if (delim=='`') delim='\''; /* for |ascii_constant|s */
+ while (1) {
+ if (loc>=limit) {
+ if(*(limit-1)!='\\') {
+ err_print("! String didn't end"); loc=limit; break;
+@.String didn't end@>
+ }
+ if(get_line()==0) {
+ err_print("! Input ended in middle of string"); loc=buffer; break;
+@.Input ended in middle of string@>
+ }
+ }
+ if ((c=*loc++)==delim) {
+ if (++id_loc<=mod_text_end) *id_loc=c;
+ break;
+ }
+ if (c=='\\') if (loc>=limit) continue;
+ else if (++id_loc<=mod_text_end) {
+ *id_loc = '\\'; c=*loc++;
+ }
+ if (++id_loc<=mod_text_end) *id_loc=c;
+ }
+ if (id_loc>=mod_text_end) {
+ printf("\n! String too long: ");
+@.String too long@>
+ ASCII_write(mod_text+1,25);
+ printf("..."); mark_error;
+ }
+ id_loc++;
+ return(string);
+}
+@y
+@ \cee\ strings are delimited by double quotes and must be restricted
+to one line. Double quotes in strings must be doubled and we allow no
+string to be longer than |longest_name|.
+
+@<Get a string@>= {/*spider*/
+ ASCII delim = c; /* what started the string */
+@#
+ id_first = mod_text+1;
+ id_loc = mod_text; *++id_loc=delim;
+ while (1) {
+ if (loc>=limit) {
+ err_print("! String didn't end"); loc=limit;
+@.String didn't end@>
+ if (get_line()==0) {
+ err_print("! Input ended in middle of string"); loc=buffer;
+@.Input ended in middle of string@>
+ }
+ break;
+ }
+ if ((c=*loc++)==delim) {
+ if (++id_loc<=mod_text_end) *id_loc=c;
+ if (*loc==delim) loc++;
+ else break;
+ }
+ if (++id_loc<=mod_text_end) *id_loc=c;
+ }
+ if (id_loc>=mod_text_end) {
+ printf("\n! String too long: ");
+@.String too long@>
+ ASCII_write(mod_text+1,25);
+ printf("..."); mark_error;
+ }
+ id_loc++;
+ return(string);
+}
+@z
+
+@x
+ case 1: printf("\\{"); print_id((name_dir+r)); printf("}"); break;
+ /* |id_flag| */
+ case 2: printf("\&{"); print_id((name_dir+r)); printf("}"); break;
+@y
+ case 1: printf("\\\\{"); print_id((name_dir+r)); printf("}"); break;
+ /* |id_flag| */
+ case 2: printf("\\&{"); print_id((name_dir+r)); printf("}"); break;
+@z
+
+@x
+if (cur_xref->num%def_flag!=module_count) {
+ app_str("+"); /*module name is multiply defined*/
+ this_module=name_dir; /*so we won't give cross-reference info here*/
+}
+app_str("\\S"); /* output an equivalence sign */
+@y
+if (cur_xref->num%def_flag!=module_count) {
+ app_str("\\PS"); /*module name is multiply defined*/
+ this_module=name_dir; /*so we won't give cross-reference info here*/
+}
+else app_str("\\S"); /* output an equivalence sign */
+@z
diff --git a/web/spiderweb/src/reduce/underscore.web b/web/spiderweb/src/reduce/underscore.web
new file mode 100644
index 0000000000..310de4fdac
--- /dev/null
+++ b/web/spiderweb/src/reduce/underscore.web
@@ -0,0 +1,32 @@
+% Copyright (c): Marcel Roelofs and Peter Gragert
+% University of Twente, Enschede, The Netherlands
+% @@(#) underscore.web (91/03/11)
+
+@* Filter to remove underscores from REDUCE source. REDUCE does not
+allow sole underscores in identifiers. However, underscores preceded
+by an exclamation mark are allowed. Also REDUCE strings may contain
+underscores. The following C program is a filter that removes the
+forbidden underscores.
+
+@u
+#include <stdio.h>
+
+main (ac, av)
+char **av;
+{
+char c;
+while ((c=getc(stdin)) != EOF)
+ if (c=='!') {
+ putc(c,stdout);
+ c=getc(stdin);
+ putc(c,stdout);
+ }
+ else
+ if (c=='\"') {
+ while (putc(c,stdout), (c=getc(stdin)) != '\"') ;
+ putc(c,stdout);
+ }
+ else
+ if (c != '_') putc(c,stdout);
+}
+
diff --git a/web/spiderweb/src/sml/leavens.mail b/web/spiderweb/src/sml/leavens.mail
new file mode 100644
index 0000000000..9c91b69aa4
--- /dev/null
+++ b/web/spiderweb/src/sml/leavens.mail
@@ -0,0 +1,548 @@
+# This for weave
+token @ category binop translation <"\\ATSIGN">
+ From leavens@cs.iastate.edu Wed Mar 11 20:35:11 1992
+Received: from Princeton.EDU (Princeton.EDU.) by fs.Princeton.EDU (4.0/1.105)
+ id AA20432; Wed, 11 Mar 92 20:35:09 EST
+Received: from flash.cs.iastate.edu by Princeton.EDU (5.65b/2.86/princeton)
+ id AA26935; Wed, 11 Mar 92 20:34:59 -0500
+Received: from bambam.cs.iastate.edu by flash.cs.iastate.edu with SMTP
+ (16.7/16.2) id AA24210; Wed, 11 Mar 92 19:34:50 -0600
+Received: by bambam.cs.iastate.edu (4.1/SMI-4.1)
+ id AA29309; Wed, 11 Mar 92 19:34:49 CST
+Date: Wed, 11 Mar 92 19:34:49 CST
+From: leavens@cs.iastate.edu (Gary Leavens)
+Message-Id: <9203120134.AA29309@bambam.cs.iastate.edu>
+To: nr@Princeton.EDU
+In-Reply-To: Norman Ramsey's message of Wed, 11 Mar 92 18:12:19 -0500 <9203112312.AA02296@cs.Princeton.EDU>
+Subject: Literate programming for SML?
+Status: RO
+
+Norman,
+ I read your TOSE paper on noweb, and all I can say is: hooray!
+Really, for giving students an introduction to literate programming,
+and for getting started in a new language, etc., it seems like a great
+idea. I guess I'm just echoing the points you make in the paper, but I've
+been trying to think of how to make some literate programming stuff available
+to graduate students, and this seems like it has more of a chance of catching
+on than anything else.
+
+ As far as sml.spider goes, I had not planned on worrying about infix
+for a while... I haven't done a lot of programming in SML, do you find you
+use infix signficantly? Perhaps it's a personal style thing.
+
+ I'm very happy to send you the sml.spider file, which follows.
+The main problem I'm having with it at the moment is that in the formatting
+I don't get anything combined in a big math format, instead I get lots of
+little math shifts, which causes code to look pretty ugly. But I'm sure
+you would see many, many other problems. My basic approach, which may not
+be a good one, was to type in the grammar from the defintion of SML,
+making changes along the way to make it left recursive, and adding context
+and some formatting stuff. Clearly it needs work. So if you'd like to build
+on that base, please do so... Anyway, the file follows.
+ Gary
+
+# sml.spider
+# AUTHOR: Gary T. Leavens
+
+language SML extension sml version 1.4
+
+at_sign @
+
+comment begin <"(*"> end <"*)">
+
+line begin <"(*"-space-"line"> end <"*)">
+
+default mathness yes
+default translation <*>
+
+token identifier category id
+token number category scon
+token newline category ignore_scrap mathness maybe translation <>
+token pseudo_semi category semi mathness maybe translation <force>
+
+# web's idea of modules...
+module definition topdec use id
+
+
+# nonfix functions in standard basis
+ilk functions category unop
+
+reserved map ilk functions
+reserved rev ilk functions
+reserved not ilk functions
+token ~ category unop translation <"\\TI"> mathness yes
+reserved abs ilk functions
+reserved floor ilk functions
+reserved real ilk functions
+reserved sqrt ilk functions
+reserved sin ilk functions
+reserved cos ilk functions
+reserved arctan ilk functions
+reserved exp ilk functions
+reserved ln ilk functions
+reserved size ilk functions
+reserved chr ilk functions
+reserved ord ilk functions
+reserved explode ilk functions
+reserved implode ilk functions
+token ! category unop translation <*>
+reserved ref ilk functions
+
+# constants in the standard basis
+ilk constants category con
+
+reserved true ilk constants
+reserved false ilk constants
+reserved nil ilk constants
+
+# infix functions in the standard basis
+ilk infixfun category binop
+
+# precedence 7
+token / category binop
+reserved div ilk infixfun
+reserved mod ilk infixfun
+token * category star translation <"\\times">
+# precedence 6
+token + category binop
+token - category binop
+token ^ category binop
+# precedence 5
+token :: category binop
+token @ category binop
+# precedence 4
+token = category equals
+token <> category binop translation <"\\I">
+token < category binop
+token > category binop
+token <= category binop translation <"\\L">
+token >= category binop translation <"\\G">
+# precedence 3
+token := category binop translation <"\\leftarrow">
+ilk compose category binop translation <"\\circ">
+reserved o ilk compose
+
+default translation <*-"\\"-space>
+
+# core ilks
+ilk abstype_like category abstype
+ilk and_like category and
+ilk andalso_like category andalso
+ilk as_like category as
+ilk case_like category case
+ilk do_like category do
+ilk datatype_like category datatype
+ilk else_like category else
+ilk end_like category end
+ilk exception_like category exception
+ilk fn_like category fn
+ilk fun_like category fun
+ilk handle_like category handle
+ilk if_like category if
+ilk in_like category in
+ilk infix_like category infix
+ilk let_like category let
+ilk local_like category local
+ilk nonfix_like category nonfix
+ilk of_like category of
+ilk op_like category op
+ilk open_like category open
+ilk orelse_like category orelse
+ilk raise_like category raise
+ilk rec_like category rec
+ilk then_like category then
+ilk type_like category type
+ilk val_like category val
+ilk with_like category with
+ilk withtype_like category withtype
+ilk while_like category while
+
+# modules ilks
+ilk eqtype_like category eqtype
+ilk functor_like category functor
+ilk include_like category include
+ilk sharing_like category sharing
+ilk sig_like category sig
+ilk signature_like category signature
+ilk struct_like category struct
+ilk structure_like category structure
+ilk use_like category use
+
+default translation <*>
+
+# core reserved words
+reserved abstype ilk abstype_like
+reserved and ilk and_like
+reserved andalso ilk andalso_like
+reserved as ilk as_like
+reserved case ilk case_like
+reserved do ilk do_like
+reserved datatype ilk datatype_like
+reserved else ilk else_like
+reserved end ilk end_like
+reserved exception ilk exception_like
+reserved fn ilk fn_like
+# reserved fn translation <\\lambda>
+reserved fun ilk fun_like
+reserved handle ilk handle_like
+reserved if ilk if_like
+reserved in ilk in_like
+reserved infix ilk infix_like
+reserved infixr ilk infix_like
+reserved let ilk let_like
+reserved local ilk local_like
+reserved nonfix ilk nonfix_like
+reserved of ilk of_like
+reserved op ilk op_like
+reserved open ilk open_like
+reserved orelse ilk orelse_like
+reserved raise ilk raise_like
+reserved rec ilk rec_like
+reserved then ilk then_like
+reserved type ilk type_like
+reserved val ilk val_like
+reserved with ilk with_like
+reserved withtype ilk withtype_like
+reserved while ilk while_like
+
+# modules reserved words
+reserved eqtype ilk eqtype_like
+reserved functor ilk functor_like
+reserved include ilk include_like
+reserved sharing ilk sharing_like
+reserved sig ilk sig_like
+reserved signature ilk signature_like
+reserved struct ilk struct_like
+reserved structure ilk structure_like
+reserved use ilk use_like
+
+token ( category lparen
+token ) category rparen
+token [ category lsqbracket
+token ] category rsqbracket
+token { category lcurly translation <"\\{">
+token } category rcurly translation <"\\}">
+token , category comma translation <",\\,">
+token : category colon
+token ; category semi
+token ... category dotdotdot translation <"\\ldots">
+token | category vertbar
+token => category reducesto translation <"\\Rightarrow">
+token -> category arrow translation <"\\rightarrow">
+token # category sharp translation <"\\#">
+token . category dot
+token ' category prime
+
+
+#
+? ignore_scrap --> #1
+
+# lexical rules
+id --> longvar
+longvar dot id --> longvar
+longvar dot con --> longvar
+longvar prime --> longvar
+
+prime id --> tyvar
+prime tyvar --> tyvar
+
+# core language syntax
+scon --> atexp
+longvar --> atexp
+unop --> atexp
+op (longvar|binop|equals|star|unop) --> atexp
+lcurly exprow rcurly --> atexp
+sharp id --> atexp
+lparen rparen --> atexp
+lparen <indent> exptupling <outdent> rparen --> atexp
+lsqbracket rsqbracket --> atexp
+lsqbracket <indent> explist <outdent> rsqbracket --> atexp
+lparen expblock rparen --> atexp
+let dec in exp end --> atexp
+lparen exp rparen --> atexp
+
+exp comma <opt-9> exp --> exptupling
+exptupling comma <opt-9> exp --> exptupling
+
+exp semi <opt-1> exp --> expblock
+expblock semi <opt-1> exp --> expblock
+
+lsqbracket [ exp ] --> lsqbracket explist
+lsqbracket [ explist comma <opt-9> exp ] --> lsqbracket explist
+
+id equals exp --> exprow
+exprow comma <opt-8> id equals exp --> exprow
+
+atexp --> appexp
+appexp <"\\"-space> atexp --> appexp
+
+appexp --> infexp
+infexp (binop|equals|star) infexp --> infexp
+
+infexp --> exp
+exp colon ty --> exp
+exp andalso exp --> exp
+exp orelse exp --> exp
+exp handle <indent> match <outdent> --> exp
+raise exp --> exp
+if exp <opt-2> then <indent> exp <outdent-opt-1> else <indent> exp <outdent> --> exp
+while exp do <indent> exp <outdent> --> exp
+case exp of <indent> match <outdent> --> exp
+fn <indent> match <outdent> --> exp
+
+mrule --> match
+match vertbar mrule --> match
+
+pat reducesto exp --> mrule
+
+val valbind* --> dec
+fun fvalbind* --> dec
+type typbind* --> dec
+datatype datbind* --> dec
+datatype datbind* <force> withtype typbind --> dec
+abstype datbind* <force> with dec end --> dec
+abstype datbind* <force> withtype typbind <force> with dec end --> dec
+exception exbind* --> dec
+local <opt-1-indent> dec <outdent-opt-1> in <opt-1-indent> dec <outdent-opt-1> end --> dec
+open longvarlist --> dec
+dec <force> dec --> dec
+dec semi <force> dec --> dec
+infix scon idlist --> dec
+infix idlist --> dec
+nonfix idlist --> dec
+
+open [ longvar ] --> open longvarlist
+open [ longvarlist longvar ] --> open longvarlist
+
+(infix|nonfix|include) [ id ] --> (infix|nonfix|include) idlist
+(infix|nonfix|include) [ idlist id ] --> (infix|nonfix|include) idlist
+infix scon [ id ] --> infix scon idlist
+infix scon [ idlist id ] --> infix scon idlist
+
+pat* equals exp --> valbind
+valbind and pat* equals exp --> valbind
+rec valbind* --> valbind
+
+fun [ op id* atpatlist colon ty equals <opt-2-indent> exp <outdent> ] --> fun prefvalbind
+fun [ id* atpatlist colon ty equals <opt-2-indent> exp <outdent> ] --> fun prefvalbind
+fun [ prefvalbind vertbar op id atpatlist colon ty equals <opt-2-indent> exp <outdent> ] --> fun prefvalbind
+fun [ prefvalbind vertbar id atpatlist colon ty equals <opt-2-indent> exp <outdent> ] --> fun prefvalbind
+fvalbind and [ op id* atpatlist colon ty equals <opt-2-indent> exp <outdent> ] --> fvalbind and prefvalbind
+fvalbind and [ vertbar id* atpatlist colon ty equals <opt-2-indent> exp <outdent> ] --> fvalbind and prefvalbind
+fvalbind and [ prefvalbind vertbar op id atpatlist colon ty equals <opt-2-indent> exp <outdent> ] --> fvalbind and prefvalbind
+fvalbind and [ prefvalbind vertbar id atpatlist colon ty equals <opt-2-indent> exp <outdent> ] --> fvalbind and prefvalbind
+
+fun [ prefvalbind ] (and|semi) --> fun fvalbind (and|semi)
+fun [ fvalbind and prefvalbind ] --> fun fvalbind
+
+(fun|vertbar) op id [ atpat ] --> (fun|vertbar) op id atpatlist
+(fun|vertbar) op id [ atpatlist atpat ] --> (fun|vertbar) op id atpatlist
+(fun|vertbar) id [ atpat ] --> (fun|vertbar) id atpatlist
+(fun|vertbar) id [ atpatlist atpat ] --> (fun|vertbar) id atpatlist
+
+tyvarseq longvar* equals ty --> typbind
+typbind and tyvarseq longvar* equals ty --> typbind
+
+type [ tyvar ] --> type tyvarseq
+type [ ] --> type tyvarseq
+type lparen [ tyvarseq comma tyvar ] --> type lparen tyvarseq
+type [ lparen tyvarseq rparen ] --> type tyvarseq
+datatype [ tyvar ] --> datatype tyvarseq
+datatype [ ] --> datatype tyvarseq
+datatype lparen [ tyvarseq comma tyvar ] --> datatype lparen tyvarseq
+datatype [ lparen tyvarseq rparen ] --> datatype tyvarseq
+abstype [ tyvar ] --> abstype tyvarseq
+abstype [ ] --> abstype tyvarseq
+abstype lparen [ tyvarseq comma tyvar ] --> abstype lparen tyvarseq
+abstype [ lparen tyvarseq rparen ] --> abstype tyvarseq
+typbind and [ tyvar ] --> typbind and tyvarseq
+typbind and [ ] --> typbind and tyvarseq
+typbind and lparen [ tyvarseq comma tyvar ] --> typbind and lparen tyvarseq
+typbind and [ lparen tyvarseq rparen ] --> typbind and tyvarseq
+
+tyvarseq longvar* equals conbind --> datbind
+datbind and tyvarseq longvar* equals conbind --> datbind
+
+datatype tyvarseq id equals [ op id* of ty ] --> datatype tyvarseq id equals conbind
+datatype tyvarseq id equals [ op id* ] --> datatype tyvarseq id equals conbind
+datatype tyvarseq id equals [ id* of ty ] --> datatype tyvarseq id equals conbind
+datatype tyvarseq id equals [ id* ] --> datatype tyvarseq id equals conbind
+
+conbind and op id* of ty --> conbind
+conbind and op id* --> conbind
+conbind and id* of ty --> conbind
+conbind and id* --> conbind
+
+exception [ op id* of ty ] --> exception exbind
+exception [ op id* ] --> exception exbind
+exception [ id* of ty ] --> exception exbind
+exception [ id* ] --> exception exbind
+exception [ op id* equals op longvar ] --> exception exbind
+exception [ op id* equals longvar ] --> exception exbind
+exception [ id* equals op longvar ] --> exception exbind
+exception [ id* equals longvar ] --> exception exbind
+
+exbind and op id* of ty --> exbind
+exbind and op id* --> exbind
+exbind and id* of ty --> exbind
+exbind and id* --> exbind
+exbind and op id* equals op longvar --> exbind
+exbind and op id* equals longvar --> exbind
+exbind and id* equals op longvar --> exbind
+exbind and id* equals longvar --> exbind
+
+longvar --> atpat
+scon --> atpat
+op (longvar|unop) --> atpat
+lcurly patrow rcurly --> atpat
+lparen rparen --> atpat
+lparen pattupling rparen --> atpat
+lsqbracket rsqbracket --> atpat
+lparen pat rparen --> atpat
+
+pat comma pat --> pattupling
+pattupling comma pat --> pattupling
+
+lsqbracket [ pat ] --> lsqbracket patlist
+lsqbracket [ patlist comma pat ] --> lsqbracket patlist
+
+dotdotdot --> patrow
+id equals pat --> patrow
+id colon ty as pat --> patrow
+id as pat --> patrow
+id colon ty --> patrow
+patrow comma id equals pat --> patrow
+patrow comma id colon ty as pat --> patrow
+patrow comma id as pat --> patrow
+patrow comma id colon ty --> patrow
+
+atpat --> pat
+op longvar atpat --> pat
+longvar atpat --> pat
+pat (binop|equals|star) pat --> pat
+pat colon ty --> pat
+op id colon ty as pat --> pat
+op id as pat --> pat
+id colon ty as pat --> pat
+id as pat --> pat
+
+tyvar --> ty
+lcurly tyrow rcurly --> ty
+longvar --> ty
+lparen ty rparen longvar --> ty
+lparen tyseq rparen longvar --> ty
+tytuple --> ty
+ty arrow ty --> ty
+lparen ty rparen --> ty
+
+lparen [ ty comma ] --> lparen tyseq
+tyseq comma ty --> tyseq
+
+id colon ty --> tyrow
+tyrow comma id colon ty --> tyrow
+
+ty star ty --> tytuple
+tytuple star ty --> tytuple
+
+
+# modules, with permissive syntax
+#struct strdec end --> strexp
+struct <opt-1-indent> dec <outdent-opt-1> end --> exp
+
+# whereever the SML grammar has strdec, have to use dec too
+structure strbind --> dec
+
+structure [ id* colon sigexp equals <opt-1-indent> exp <outdent-opt-1> ] --> structure strbind
+structure [ id* colon id equals <opt-1-indent> exp <outdent-opt-1> ] --> structure strbind
+structure [ id* equals <opt-1-indent> exp <outdent-opt-1> ] --> structure strbind
+strbind <force> and id* colon sigexp equals <opt-1-indent> exp <outdent-opt-1> --> strbind
+strbind <force> and id* colon id equals <opt-1-indent> exp <outdent-opt-1> --> strbind
+strbind <force> and id* equals <opt-1-indent> exp <outdent-opt-1> --> strbind
+
+# whereever the SML grammar has sigexp, have to use id too
+sig <opt-1-indent> spec <outdent-opt-1> end --> sigexp
+
+signature sigbind --> sigdec
+sigdec <force> sigdec --> sigdec
+sigdec semi <force> sigdec --> sigdec
+
+signature [ id* equals <opt-1-indent> sigexp <outdent> ] --> signature sigbind
+signature [ id* equals id ] --> signature sigbind
+sigbind <force> and id* equals <opt-1-indent> sigexp <outdent> --> sigbind
+sigbind <force> and id* equals id --> sigbind
+
+val valdesc --> spec
+type typdesc --> spec
+eqtype typdesc --> spec
+datatype datdesc --> spec
+exception exdesc --> spec
+structure strdesc --> spec
+sharing shareq --> spec
+local spec in spec end --> spec
+open longvarlist --> spec
+include idlist --> spec
+sig [ ] end --> sig spec end
+spec <force> spec --> spec
+spec semi spec --> spec
+
+val [ id* colon ty ] --> val valdesc
+valdesc <opt-1> and id* colon ty --> valdesc
+
+type [ tyvarseq id* ] --> type typdesc
+typdesc <opt-1> and tyvarseq id* --> typdesc
+
+typdesc and [ tyvar ] --> typdesc and tyvarseq
+typdesc and [ ] --> typdesc and tyvarseq
+typdesc and lparen [ tyvarseq comma tyvar ] --> typdesc and lparen tyvarseq
+typdesc and [ lparen tyvarseq rparen ] --> typdesc and tyvarseq
+
+tyvarseq id* equals condesc --> datdesc
+datdesc <opt-1> and tyvarseq id* equals condesc --> datdesc
+
+datatype tyvarseq id equals [ id* of ty ] --> datatype tyvarseq id equals condesc
+datatype tyvarseq id equals [ id* ] --> datatype tyvarseq id equals condesc
+
+condesc <opt-1> and id* of ty --> condesc
+condesc <opt-1> and id* --> condesc
+
+exception [ id* of ty ] --> exception exdesc
+exception [ id* ] --> exception exdesc
+
+exdesc <opt-1> and id* of ty --> exdesc
+exdesc <opt-1> and id* --> exdesc
+
+structure [ id* colon sigexp ] --> structure strdesc
+structure [ id* colon id ] --> structure strdesc
+strdesc <opt-1> and id* colon sigexp --> strdesc
+strdesc <opt-1> and id* colon id --> strdesc
+
+sharing [ longvar equals longvar ] --> sharing shareq
+shareq equals longvar --> shareq
+sharing type [ longvar equals longvar ] --> sharing type shareq
+shareq equals longvar --> shareq
+shareq <opt-1> and longvar equals longvar --> shareq
+shareq <opt-1> and type longvar equals longvar --> shareq
+
+functor funbind --> fundec
+fundec <force> fundec --> fundec
+fundec semi fundec --> fundec
+
+functor [ id* lparen id colon sigexp rparen colon sigexp equals <force-indent> exp ] --> functor funbind
+functor [ id* lparen id colon sigexp rparen equals <force-indent> exp ] --> functor funbind
+funbind <opt-1> and id* lparen id colon sigexp rparen colon sigexp equals <force-indent> exp --> funbind
+funbind <opt-1> and id* lparen id colon sigexp rparen equals <force-indent> exp --> funbind
+
+sigdec --> topdec
+fundec --> topdec
+dec --> topdec
+use scon --> topdec
+
+
+topdec <force> topdec --> topdec
+topdec semi <force> topdec --> topdec
+
+macros begin
+\let\LN\langle
+\let\RN\rangle
+macros end
+
diff --git a/web/spiderweb/src/sml/make b/web/spiderweb/src/sml/make
new file mode 100644
index 0000000000..d376f72a64
--- /dev/null
+++ b/web/spiderweb/src/sml/make
@@ -0,0 +1,3 @@
+#!/bin/sh
+/bin/make -f ../master/WebMakefile CPUTYPE=`cputype`\
+ THETANGLE=smltangle THEWEAVE=smlweave SPIDER=sml.spider "$@"
diff --git a/web/spiderweb/src/sml/mason.mail b/web/spiderweb/src/sml/mason.mail
new file mode 100644
index 0000000000..081b209b6a
--- /dev/null
+++ b/web/spiderweb/src/sml/mason.mail
@@ -0,0 +1,1031 @@
+From dmason@plg.uwaterloo.ca Wed Aug 5 17:08:26 1992
+Received: from Princeton.EDU by fs.Princeton.EDU (4.1/1.105)
+ id AA10701; Wed, 5 Aug 92 17:08:21 EDT
+Received: from plg.uwaterloo.ca by Princeton.EDU (5.65b/2.93/princeton)
+ id AA23362; Wed, 5 Aug 92 17:07:44 -0400
+Received: by plg.uwaterloo.ca id <29115>; Wed, 5 Aug 1992 17:07:32 -0400
+From: Dave Mason <dmason@plg.uwaterloo.ca>
+To: Norman Ramsey <nr@Princeton.EDU>
+Subject: spiderweb
+Message-Id: <92Aug5.170732edt.29115@plg.uwaterloo.ca>
+Date: Wed, 5 Aug 1992 17:07:26 -0400
+Status: R
+
+I talked to you at PLDI about SML spiderweb. I haven't had any time to work
+on it, so I decided to send you what I had.
+
+Included is a diff of weave.web to treat _ as a non-identifier, and to treat
+' as part of an identifier if it immediately follows something that is
+already treated as an identifier.
+
+Also included is sml.spider. It isn't perfect, but it works fairly well.
+There are 3 special tokens: |: |= and |; that are useful to have different
+paragraphs be working on a common function or datatype. Sorry I don't have
+documentation, but I am not 100% happy with the system yet. BTW, the |;
+could be removed, and the grammar made *much* simpler if there were a
+special token for the END of a code block.
+
+Finally, I've included a web file for a denotational semantics that I wrote.
+It exhibits the three special tokens.
+
+Are you, or anyone else, working on moving spiderweb so it would work with
+LaTeX? I would *love* to be able to import small (or not so small) code
+segments into my latex documents (particularly for overheads).
+
+I'm off for vacation most of the rest of the month. I plan to do the LaTeX
+thing when I get back, if no-one else is working on it. I will also be
+doing a fair bit of sml hacking in the fall, and I'm likely to be using web,
+so the sml stuff will get cleaned up some.
+
+ ../Dave
+
+------------------------------------start of diff-------------------
+*** weave.web Sun Mar 29 02:54:59 1992
+--- weave.webO Wed Nov 13 19:48:26 1991
+***************
+*** 85,93 ****
+ @d max_refs = 20000 /* number of cross-references; must be less than 65536 */
+ @d max_toks = 20000 /* number of symbols in \cee\ texts being parsed;
+ must be less than 65536 */
+! @d max_texts = 4000 /* number of phrases in \cee\ texts being parsed;
+ must be less than 10240 */
+! @d max_scraps = 2000 /* number of tokens in \cee\ texts being parsed */
+ @d stack_size = 400 /* number of simultaneous output levels */
+
+ @i common.h
+--- 85,93 ----
+ @d max_refs = 20000 /* number of cross-references; must be less than 65536 */
+ @d max_toks = 20000 /* number of symbols in \cee\ texts being parsed;
+ must be less than 65536 */
+! @d max_texts = 2000 /* number of phrases in \cee\ texts being parsed;
+ must be less than 10240 */
+! @d max_scraps = 1000 /* number of tokens in \cee\ texts being parsed */
+ @d stack_size = 400 /* number of simultaneous output levels */
+
+ @i common.h
+***************
+*** 543,549 ****
+ }
+ }
+ if (isdigit(c)) @<Get a constant@>@; /*spider*/
+! else if (isalpha(c) || (c=='_' && (*loc=='_' || isalpha(*loc)))) @<Get an
+identifier@>@;/*spider*/
+ else if (c=='\'' || c=='"') @<Get a string@>@;/*spider*/
+ else if (c==at_sign) @<Get control code and possible module name@>@;
+ else if (c==' ' || c==tab_mark) continue; /* ignore spaces and tabs */
+--- 543,549 ----
+ }
+ }
+ if (isdigit(c)) @<Get a constant@>@; /*spider*/
+! else if (isalpha(c) || c=='_') @<Get an identifier@>@;/*spider*/
+ else if (c=='\'' || c=='"') @<Get a string@>@;/*spider*/
+ else if (c==at_sign) @<Get control code and possible module name@>@;
+ else if (c==' ' || c==tab_mark) continue; /* ignore spaces and tabs */
+***************
+*** 557,563 ****
+
+ @ @<Get an identifier@>= {/*spider*/
+ id_first=--loc;
+! while (isalpha(*++loc) || isdigit(*loc) || *loc=='_' || *loc=='\'');
+ id_loc=loc; return(identifier);
+ }
+
+--- 557,563 ----
+
+ @ @<Get an identifier@>= {/*spider*/
+ id_first=--loc;
+! while (isalpha(*++loc) || isdigit(*loc) || *loc=='_');
+ id_loc=loc; return(identifier);
+ }
+
+------------------------------------end of diff-------------------
+---------------------------------start of sml.spider-------------
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+language SML extension sml
+
+at_sign %
+
+module definition codedef use codeuse
+
+comment begin <"(*"> end <"*)">
+
+line begin <"(*line"> end <"*)">
+
+default translation <*> mathness yes
+
+token identifier category id mathness maybe
+token number category const mathness yes
+token newline category ignore_scrap translation <> mathness maybe
+token pseudo_semi translation <> category semi mathness maybe
+
+macros begin
+\let\R\relax
+\def\SS{\relax\ifmmode\>\else$\>$\fi}
+\def\UL{\relax\ifmmode\_\!\_\,\else$\_\!\_\,$\fi}
+\def\FL.#1#2#3(#4){\relax\ifmmode#4^{\rm{#2}}\else$#4^{\rm{#2}}$\fi}
+\def\SL#1{\relax\ifmmode{}_{#1}\else${}_{#1}$\fi}
+\def\LA{\relax\ifmmode\leftarrow\else$\leftarrow$\fi}
+\def\GK#1#2{\if#2a\alpha\else\if#2b\beta\else\if#2c\gamma\else\if#2d\delta\else\if#2e\varepsilon\else\if#2f\zeta\else\if#2g\eta\fi\fi\fi\fi\fi\fi\fi^{^{#1}}}
+\def\'#1#2#3{\relax\ifmmode\GK{#1}{#3}\else$\GK{#1}{#3}$\fi}
+\def\"#1#2{\relax\ifmmode\GK{=}{#2}\else$\GK{=}{#2}$\fi}
+\def\ST#1{\relax\ifmmode\times\else$\times$\fi}
+macros end
+
+# Delimiters
+#token & category binop translation <"\\amp">
+token ( category open
+token ) category close
+token [ category open
+token ] category close
+token { category ocurly translation <"\\{">
+token } category ccurly translation <"\\}">
+token [. category open tangleto <space-"sub("> translation <"\\SL{"> mathness maybe
+token .] category close tangleto <")"> translation <"}"> mathness maybe
+token [= category open tangleto <space-"assign("> translation <"\\SL{"> mathness maybe
+token =] category close tangleto <")"> translation <"}\\LA"> mathness maybe
+token * category star mathness maybe
+token + category binop
+token , category comma translation <",\\,"-opt-5>
+token - category binop
+token ^ category binop translation <"\\^">
+token ! category unop
+token ~ category unop
+token . category dot
+token @ category binop
+token # category unop translation <"\\FL.">
+token / category binop
+token : category tylook
+token ; category semi
+token < category binop
+token = category equal
+token > category binop
+token | category choice translation <"\\mid">
+token |: category datam translation <"\\mid"> tangleto <"|">
+token |= category fun translation <"\\mid"> tangleto <"|">
+token |; category semi translation <""> tangleto <""> mathness maybe
+token _ category underline translation <"\\UL"> mathness no
+token ' category tick tangleto <space-"'"> translation <"\\'{"> mathness maybe
+token '' category tick tangleto <space-"''"> translation <"\\'{="> mathness maybe
+token ... category labpat translation <"\\cdots"> mathness yes
+
+# Compound delimiters
+
+token := category binop translation <"\\mathbin{:=}">
+token :: category binop translation <"\\mathbin{::}">
+token => category arrow translation <"\\Rightarrow">
+token -> category fnarrow translation <"\\mapsto">
+#token /= translation <"\\I"> category binop
+token >= translation <"\\G"> category binop
+token <= translation <"\\L"> category binop
+#token << translation <"\\LL"> category openlabel
+#token >> translation <"\\GG"> category closelabel
+#token <> translation <"\\LG"> category math
+
+#token # category math translation <"\\#">
+
+token && category binop tangleto <space-"andalso"-space> mathness yes translation <"\\wedge">
+token || category binop tangleto <space-"orelse"-space> mathness yes translation <"\\vee">
+
+
+
+default mathness maybe translation <*>
+
+reserved abstraction ilk abstraction_like
+reserved abstype ilk abstype_like
+reserved and ilk and_like
+reserved andalso ilk andalso_like
+reserved array ilk math_like
+reserved as ilk as_like
+reserved case ilk case_like
+reserved datatype ilk datatype_like
+reserved do ilk do_like
+reserved else ilk else_like
+reserved end ilk end_like
+reserved eqtype ilk type_like
+reserved exception ilk ex_like
+reserved false ilk const_like
+reserved fn ilk fn_like
+reserved fun ilk fun_like
+reserved functor ilk functor_like
+reserved handle ilk handle_like
+reserved if ilk if_like
+reserved in ilk in_like
+reserved int ilk int_like
+#reserved infix ilk infix_like
+#reserved infixr ilk infix_like
+reserved let ilk let_like
+reserved list ilk list_like
+reserved local ilk local_like
+#reserved nonfix ilk infix_like
+reserved not ilk unop_like
+reserved nil ilk const_like
+reserved of ilk of_like
+#reserved op ilk op_like
+reserved open ilk open_like
+reserved orelse ilk orelse_like
+reserved overload ilk overload_like
+reserved raise ilk raise_like
+reserved rec ilk rec_like
+reserved ref ilk ref_like
+#reserved sharing ilk sharing_like
+reserved sig ilk sig_like
+reserved signature ilk signature_like
+reserved string ilk int_like
+reserved struct ilk struct_like
+reserved structure ilk structure_like
+reserved then ilk then_like
+reserved true ilk const_like
+reserved type ilk type_like
+reserved unit ilk int_like
+reserved val ilk val_like
+reserved while ilk while_like
+reserved with ilk with_like
+reserved withtype ilk withtype_like
+reserved orelse ilk binop_like
+
+ilk overload_like translation <*> category keyword
+ilk abstraction_like translation <*> category keyword
+
+ilk abstype_like translation <*> category abstype
+ilk and_like translation <*> category and
+ilk andalso_like category binop mathness yes translation <"\\wedge">
+ilk as_like translation <*> category id
+ilk binop_like translation <"\\"-space-*-"\\"-space> category binop
+ilk case_like translation <*> category case
+ilk const_like translation <*> category const
+ilk datatype_like translation <*> category datatype
+ilk do_like translation <*> category do
+ilk else_like translation <*> category else
+ilk end_like translation <*> category end
+ilk ex_like translation <*> category exception
+ilk fn_like category fn mathness yes translation <"\\lambda\\"-space>
+
+ilk fun_like translation <*> category fun
+ilk functor_like translation <*> category functor
+ilk handle_like translation <*> category handle
+ilk if_like translation <*> category if
+ilk in_like translation <*> category in
+ilk int_like translation <*> category ty
+ilk let_like translation <*> category let
+ilk list_like translation <*> category id
+ilk local_like translation <*> category local
+ilk math_like translation <*> category math
+ilk of_like translation <*> category of
+ilk open_like translation <*> category openop
+ilk orelse_like category binop mathness yes translation <"\\vee">
+ilk raise_like translation <*> category raise
+ilk rec_like translation <*> category rec
+ilk ref_like translation <*> category id
+ilk sig_like translation <*> category sig
+ilk signature_like translation <*> category signature
+ilk struct_like translation <*> category struct
+ilk structure_like translation <*> category val
+ilk then_like translation <*> category then
+ilk type_like translation <*> category type
+ilk unop_like translation <*-"\\"-space> category unop
+#ilk unorbinop_like translation <"\\"-space-*-"\\"-space> category resunorbinop
+ilk val_like translation <*> category val
+ilk while_like translation <*> category while
+ilk with_like translation <*> category with
+ilk withtype_like translation <*> category withtype
+
+
+# \MC means ``math close'' and sets \MS to ``math set''
+macros begin
+\def\MC{\ifmmode\global\let\MS$\else\global\let\MS\relax\fi\relax\MS}
+\def\LG{\mathord{<}\mathord{>}}
+\let\IG=\ignorespaces
+macros end
+
+codedef dec --> dec
+[ codedef (math|multimath) ] semi --> dec semi
+codeuse <force> codeuse --> codeuse
+codeuse semi --> codeuse
+!ignore_scrap [ codeuse ] !(codeuse|ignore_scrap|semi|val|fun|type|let|struct|openop|end|in) --> !ignore_scrap multimath !(codeuse|ignore_scrap|semi|val|fun|type|let|struct|openop|end|in)
+ [ codeuse ] (dec|end|in) --> dec (dec|end|in)
+ [ codeuse ] semi (dec|end|in) --> dec semi (dec|end|in)
+
+id dot id --> id
+ty dot id --> ty
+
+sig <indent-force> dec <outdent-force> end --> sig_body
+signature <"\\"-space> id* equal <indent-force> sig_body <outdent> --> dec
+functor [ <"\\"-space> id* ] --> functor funhead
+functor funhead pat equal <force-indent> struct_object <outdent> --> dec
+struct <force-indent> dec <force-outdent> end --> struct_object
+openop <"\\"-space> id --> dec
+
+exception <"\\"-space> --> exlook
+exlook eb --> dec
+exlook [ id* ] !(of|equal) --> exlook eb !(of|equal)
+exlook [ id* <"\\"-space> of <"\\"-space> ] --> exlook tylook
+exlook [ tylook <"\\"-space> ty ] --> exlook eb
+exlook [ id* equal id ] --> exlook eb
+eb and --> exlook
+
+(tylook|tyopen|tys|tya|datatop|datarest) [ id ] --> (tylook|tyopen|tys|tya|datatop|datarest) ty
+(tylook|tyopen|tys|tya|datatop|datarest) [ ty <"\\"-space> id ] --> (tylook|tyopen|tys|tya|datatop|datarest) ty
+(tylook|tyopen|tys|tya|datatop|datarest) [ ocurly labty ccurly ] --> (tylook|tyopen|tys|tya|datatop|datarest) ty
+(tylook|tyopen|tys|tya|datatop|datarest) ocurly [ id tylook ty ] !id --> (tylook|tyopen|tys|tya|datatop|datarest) ocurly labty !id
+(tylook|tyopen|tys|tya|datatop|datarest) [ ocurly labty comma ] --> (tylook|tyopen|tys|tya|datatop|datarest) ocurly
+(tylook|tyopen|tys|tya|datatop|datarest) [ open ] --> (tylook|tyopen|tys|tya|datatop|datarest) tyopen
+(tylook|tyopen|tys|tya|datatop|datarest) [ tyopen ty close ] --> (tylook|tyopen|tys|tya|datatop|datarest) ty
+(tylook|tyopen|tys|tya|datatop|datarest) [ tys ty close <"\\"-space> id ] --> (tylook|tyopen|tys|tya|datatop|datarest) ty
+tys ty comma --> tys
+tys ty <"\\ST"> star --> tys
+tys ty close --> ty
+(tylook|tyopen|tys|tya|datatop|datarest) [ tyopen ty comma ] --> (tylook|tyopen|tys|tya|datatop|datarest) tys
+(tylook|tyopen|tys|tya|datatop|datarest) [ tyopen ty <"\\ST"> star ] --> (tylook|tyopen|tys|tya|datatop|datarest) tys
+tick const <"}"> id --> ty
+tick <"}"> id --> ty
+(tylook|tyopen|tys|tya|datatop|datarest) [ ty fnarrow ] --> (tylook|tyopen|tys|tya|datatop|datarest) tya
+tya ty --> ty
+
+val <"\\"-space> rec --> val
+val [ <"\\"-space> pat* <"\\"-space> equal <"\\"-space-indent-opt-1> math <outdent> ] (semi|val|fun|type|let|struct|openop|and|end|close|in|val) --> val valbody (semi|val|fun|type|let|struct|openop|and|end|close|in|val)
+val [ <"\\"-space> pat* ] (semi|val|fun|type|let|struct|openop|and|end|close|in|val) --> val valbody (semi|val|fun|type|let|struct|openop|and|end|close|in|val)
+val [ <"\\"-space> pat* <"\\"-space> equal <indent-force> multimath <outdent> ] (semi|val|fun|type|let|struct|openop|and|end|close|in) --> val valbody (semi|val|fun|type|let|struct|openop|and|end|close|in)
+<force> val valbody <force> and --> val
+<force> val valbody --> dec
+datatop <"\\"-space-indent> codeuse <force> --> datahead
+datatop <"\\"-space> ty* <"\\"-space-indent> equal <force> --> datat
+datarest <"\\"-space> ty* <"\\"-space> equal <"\\"-space-indent-opt-2> id <"\\"-space> of <"\\"-space> --> datarest
+(datat|datam) <"\\"-space> id <"\\"-space> of <"\\"-space> --> datarest
+[ datat <"\\"-space> id* <"\\"-space-opt-1> choice ] id !of --> datat id !of
+[ datat <"\\"-space> id* <force> choice ] id of --> datam id of
+datam <"\\"-space> id* <force> choice --> datam
+[ datat <"\\"-space> ty ] comma --> datahead comma
+[ datat <"\\"-space> ty ] <"\\ST"> star --> datahead star
+[ datarest ty ] !(equal|ignore_scrap) --> datahead !(equal|ignore_scrap)
+datahead comma --> datarest
+datahead <"\\ST"> star --> datarest
+datahead <force> choice --> datam
+[ (datat|datam) <"\\"-space> id <outdent-outdent> ] (semi|val|fun|type|datatype|let|struct|openop|end|in) --> dec (semi|val|fun|type|datatype|let|struct|openop|end|in)
+[ datahead <outdent-outdent> ] (semi|val|fun|type|datatype|let|struct|openop|end|in) --> dec (semi|val|fun|type|datatype|let|struct|openop|end|in)
+datat <"\\"-space> id <outdent-force> (and|withtype) --> datatop
+datahead <outdent-force> (and|withtype) --> datatop
+datatype <indent> --> datatop
+abstype <indent> --> datatop
+datahead <outdent-outdent-force> with <indent-force> dec <outdent-force> end --> dec
+type <"\\"-space> ty --> type
+type pat [ equal ] --> type pat tylook
+[ type <"\\"-space> pat* tylook ty ] (semi|val|fun|type|datatype|let|struct|openop|end|in|with|withtype|and) --> dec (semi|val|fun|type|datatype|let|struct|openop|end|in|with|withtype|and)
+[ type <"\\"-space> pat* ] (semi|val|fun|type|datatype|let|struct|openop|end|in|with|withtype|and) --> dec (semi|val|fun|type|datatype|let|struct|openop|end|in|with|withtype|and)
+
+(equal|arrow) [ <cancel-"\\SS"-space> let ] --> (equal|arrow) letf
+!(ignore_scrap|equal|arrow) [ let ] --> !(ignore_scrap|equal|arrow) letf
+letf <indent-force> dec <outdent-force> in <indent-force> (math|multimath) <outdent-force> end --> multimath
+local <indent-force> dec <outdent-force> in <indent-force> dec <outdent-force> end --> dec
+
+dec <cancel> semi <force> --> dec
+[ (math|multimath) <cancel> semi ] dec --> dec dec
+[ (math|multimath) ] dec --> dec dec
+dec [ <force> (math|multimath) ] (semi|val|fun|type|datatype|let|struct|openop|end|in|with|withtype|and) --> dec dec (semi|val|fun|type|datatype|let|struct|openop|end|in|with|withtype|and)
+[ dec <force> dec ] !(semi|ignore_scrap) --> dec !(semi|ignore_scrap)
+
+[ case <"\\"-space> (math|multimath) <indent-force> of multimatch <outdent> ] (close|semi|val|fun|type|datatype|let|struct|openop|end|in|with|withtype|and) --> multimath (close|semi|val|fun|type|datatype|let|struct|openop|end|in|with|withtype|and)
+[ <indent-force> fn (multimatch|match) <outdent> ] (close|semi|val|fun|type|datatype|let|struct|openop|end|in|with|withtype|and) --> multimath (close|semi|val|fun|type|datatype|let|struct|openop|end|in|with|withtype|and)
+[ (math|multimath) <indent-indent-force> handle <indent-indent-indent> (multimatch|match) <outdent-outdent-outdent-outdent-outdent> ] (close|semi|val|fun|type|datatype|let|struct|openop|end|in|with|withtype|and) --> multimath (close|semi|val|fun|type|datatype|let|struct|openop|end|in|with|withtype|and)
+
+[ <"\\"-space> pat <"\\"-space> arrow <indent-indent-"\\"-space-opt-3> math <outdent-outdent-opt-1> ] (choice|semi|val|fun|type|datatype|let|struct|openop|end|close|in|with|withtype|and) --> match (choice|semi|val|fun|type|datatype|let|struct|openop|end|close|in|with|withtype|and)
+[ <"\\"-space> pat <"\\"-space> arrow <indent-indent-force> multimath <outdent-outdent> ] (choice|semi|val|fun|type|datatype|let|struct|openop|end|close|in|with|withtype|and) --> multimatch (choice|semi|val|fun|type|datatype|let|struct|openop|end|close|in|with|withtype|and)
+(match|multimatch) <force-"\\"-space> choice (match|multimatch) --> multimatch
+[ match ] (semi|val|fun|type|datatype|let|struct|openop|end|close|in|with|withtype|and) --> multimatch (semi|val|fun|type|datatype|let|struct|openop|end|close|in|with|withtype|and)
+
+fun [ <"\\"-space> id* ] --> fun funhead
+fun funbody <force-"\\"-space-"\\"-space> choice <"\\"-space> --> fun
+[ fun funbody ] (in|semi|val|fun|type|datatype|let|struct|openop|end) --> dec (in|semi|val|fun|type|datatype|let|struct|openop|end)
+fun funbody <force> and --> fun
+fun [ funhead <"\\"-space> pat <"\\"-space> equal <indent-indent-"\\"-space-opt-1> math <outdent-outdent> ] !(binop|handle|math|id|open|multimath|ignore_scrap) --> fun funbody !(binop|handle|math|id|open|multimath|ignore_scrap)
+fun [ funhead <"\\"-space> pat <"\\"-space> equal <indent-indent-force> multimath <outdent-outdent-force> ] !(binop|handle|math|id|open|multimath|ignore_scrap) --> fun funbody !(binop|handle|math|id|open|multimath|ignore_scrap)
+
+equal [ <force> multimath ] --> equal math
+[ if <"\\"-space> (math|multimath) <"\\"-space> then <indent-force> (math|multimath) <outdent-force> else <indent-force> (math|multimath) <outdent> ] (choice|semi|val|fun|type|datatype|let|struct|openop|end|close|in|with|withtype|and) --> multimath (choice|semi|val|fun|type|datatype|let|struct|openop|end|close|in|with|withtype|and)
+
+[ while <"\\"-space> (math|multimath) <"\\"-space> do <indent-force> <"\\"-space> (math|multimath) <outdent> ] (choice|semi|val|fun|type|datatype|let|struct|openop|end|close|in|with|withtype|and) --> multimath (choice|semi|val|fun|type|datatype|let|struct|openop|end|close|in|with|withtype|and)
+
+apat --> pat
+(choice|funhead|of|fn|handle|val|type) [ (pat|id) <"\\"-space> (apat|id) ] --> (choice|funhead|of|fn|handle|val|type) pat
+[ pat tylook ty ] !(fnarrow|id|dot|ignore_scrap) --> pat !(fnarrow|id|dot|ignore_scrap)
+pat (binop|star) (math|pat) --> pat
+pat <"\\"-space> pat --> pat
+
+underline --> apat
+(choice|funhead|of|fn|handle|val|type|opat|pat) [ id ] --> (choice|funhead|of|fn|handle|val|type|opat|pat) apat
+(choice|funhead|of|fn|handle|val|type|opat|pat) [ const ] --> (choice|funhead|of|fn|handle|val|type|opat|pat) apat
+(choice|funhead|of|fn|handle|val|type|opat|pat) [ open ] --> (choice|funhead|of|fn|handle|val|type|opat|pat) opat
+(choice|funhead|of|fn|handle|val|type|opat|pat) [ open <"\\,"> close ] --> (choice|funhead|of|fn|handle|val|type|opat|pat) apat
+opat close --> apat
+opat pat close --> apat
+opat pat comma --> opat
+[ open ] pat --> opat pat
+
+ocurly id equal math --> ocmath
+(ocurly|ocurlym) id equal multimath --> ocmulti
+ocmath comma --> ocurly
+ocmath ccurly --> math
+ocmulti comma --> ocurlym
+ocmulti ccurly --> multimath
+ocurly ccurly --> const
+(choice|funhead|of|fn|handle|val|type|opat|pat) [ ocurly labpat ccurly ] --> (choice|funhead|of|fn|handle|val|type|opat|pat) apat
+(choice|funhead|of|fn|handle|val|type|opat|pat) ocurly id [ equal ] --> (choice|funhead|of|fn|handle|val|type|opat|pat) ocurly id choice
+(choice|funhead|of|fn|handle|val|type|opat|pat) ocurly [ id choice pat ] --> (choice|funhead|of|fn|handle|val|type|opat|pat) ocurly labpat
+(choice|funhead|of|fn|handle|val|type|opat|pat) ocurly [ id ] !equal --> (choice|funhead|of|fn|handle|val|type|opat|pat) ocurly labpat !equal
+(choice|funhead|of|fn|handle|val|type|opat|pat) [ ocurly labpat comma ] --> (choice|funhead|of|fn|handle|val|type|opat|pat) ocurly
+
+raise <"\\"-space> math --> math
+math comma math --> math
+math (binop|star) math --> math
+unop math --> math
+(math|multimath) <cancel-space-force> comma <cancel> (multimath|math) --> multimath
+(math|multimath) (binop|star) (math|multimath) --> multimath
+unop (math|multimath) --> multimath
+math <"\\"-space> math --> math
+(math|multimath) <"\\"-space> (math|multimath) --> multimath
+
+open <"\\,"> close --> const
+[ open <indent> math <outdent> close <opt-1> ] !(ignore_scrap|close|semi|val|fun|type|datatype|let|struct|openop|in|with|withtype|end) --> math !(ignore_scrap|close|semi|val|fun|type|datatype|let|struct|openop|in|with|withtype|end)
+[ open <indent-opt-3> math <outdent> close ] (close|semi|val|fun|type|datatype|let|struct|openop|in|with|withtype|end) --> math (close|semi|val|fun|type|datatype|let|struct|openop|in|with|withtype|end)
+[ (math|multimath) <force-backup-"\\SS\\SS"> semi <"\\SS"> (math|multimath) ] (semi|val|fun|type|datatype|let|struct|openop|close|end) --> multimath (semi|val|fun|type|datatype|let|struct|openop|close|end)
+(then|semi|else|in|equal|arrow) [ open <indent-"\\"-space-"\\"-space> multimath <outdent-force-"\\SS\\SS"> close ] --> (then|semi|else|in|equal|arrow) multimath
+!(then|semi|else|in|equal|arrow) [ open <indent-indent-force> multimath <outdent-force-"\\"-space-"\\"-space> close <outdent> ] --> !(then|semi|else|in|equal|arrow) multimath
+
+math [ equal ] --> math binop
+[ math tylook ty ] !(ignore_scrap|id|dot|fnarrow) --> pat !(ignore_scrap|id|dot|fnarrow)
+id <"\\"-space> math --> math
+(multimath|semi|equal|dec|while|do|case|then|else|if|in|with|withtype|open|raise|arrow|comma|math|binop|star|unop) [ id ] !dot --> (multimath|semi|equal|dec|while|do|case|then|else|if|in|with|withtype|open|raise|arrow|comma|math|binop|star|unop) math !dot
+(multimath|semi|equal|dec|while|do|case|then|else|if|in|with|withtype|open|raise|arrow|comma|math|binop|star|unop) [ const ] --> (multimath|semi|equal|dec|while|do|case|then|else|if|in|with|withtype|open|raise|arrow|comma|math|binop|star|unop) math
+
+? ignore_scrap --> #1
+ignore_scrap ? --> #2
+
+macros begin
+\let\AR=\Longrightarrow
+macros end
+---------------------------------end of sml.spider-------------
+---------------------------------start of denote.web-------------
+\def\topofcontents{\relax\ifodd\pageno\else\null\vfill\eject\null\fi\titletrue\null\vfill
+ \centerline{\titlefont Denotional Semantics and}
+ \centerline{\titlefont an {\ttitlefont ML} Interpreter}
+ \centerline{\titlefont for a Functional Programming Language}
+ \vfill
+ \centerline{Table of Contents}
+}
+\def\botofcontents{\null\vfill
+ \centerline{\copyright\ 1991, Dave Mason {\tt <dmason@plg.uwaterloo.ca>}}
+}
+\let\contentspagenumber=\pageno
+
+\def\ME#1{{\ifmmode\lbrack\!\lbrack#1\rbrack\!\rbrack\else$\lbrack\!\lbrack$#1$\rbrack\!\rbrack$\fi}}
+\def\Me#1{{\bf Me}\ME{#1}}
+\def\St{\relax\ifmmode\sigma\else$\sigma$\fi}
+\def\Co{\relax\ifmmode\theta\else$\theta$\fi}
+\def\CO{\relax\ifmmode\Theta\else$\Theta$\fi}
+\def\IV{\relax\ifmmode\Xi\else$\Xi$\fi}
+\def\En{\relax\ifmmode\rho\else$\rho$\fi}
+\def\Ex{\relax\ifmmode\varepsilon\else$\varepsilon$\fi}
+\def\Sy{\relax\ifmmode\xi\else$\xi$\fi}
+\def\Nu{\relax\ifmmode\nu\else$\nu$\fi}
+\def\Lo{\relax\ifmmode\phi\else$\phi$\fi}
+\def\Tp#1#2{\langle{#1},{#2}\rangle}
+ %*Denotational Semantics. Denotational semantics is a formal method
+to specify the meaning of programming languages. We define an
+abstract syntax for the language (|Term|), a meaning function (|Me|),
+a polymorphic store (|store|) and a polymorphic environment (|env|).
+
+The code is laid out in this document in a logical form (rather than
+slavishly following the order the compiler wants), but we
+must force the \.{ML} code into the right order to make sure that
+things are defined before use.
+ %c
+ %<Type Definitions%>
+ %<Functions%>
+ %<Meaning Function%>;
+ %<Test Cases%>
+
+ % This is the type of possible declarations, along with the start of
+the definition of possible terms. They are mutually recursive
+definitions so they must be connected by an |and|. The actual
+declaration type are explained below in the definition of the semantic
+function for declarations.
+ %<Type Definitions%>=
+datatype Decl =
+ Var_Decl of string * Term
+ | Val_Decl of string * Term
+ | Rec_Decl of string * Term
+and
+ %<Term Definition%>;
+
+ %*|Term| and |Me|. We define the datatype for the abstract syntax
+tree and the meaning function in parallel. \.{Web} will worry about
+putting it all together in the right order.
+
+The meaning function has to have type:
+
+ |Me : Term -> (Value env) -> (Value continuation) -> (Value store) -> (Value * (Value store)) |.
+
+ That is, it maps abstract syntax trees, environments, continuations,
+and stores to a value,store pair.
+
+ % The denotational semantics are given in terms of the following:
+ \medskip
+ \itemitem {\bf Me} - this is the meaning function itself.
+ \itemitem {\IV} - is an invalid value
+ \itemitem {\Ex} - an expression
+ \itemitem {\Sy} - a symbol
+ \itemitem {\Nu} - a number
+ \itemitem {\En} - the environment (bindings from names to values)
+ \itemitem {\Co} - this is the continuation
+ \itemitem {\CO} - this is a null continuation that simply returns the value
+ \itemitem {\St} - this is the store of values
+ \itemitem {\Lo} - a location in the store
+ \itemitem {$x[e/v]$} - a substitution of the expression $e$ for the name
+(or whatever) $v$, where $x$ is usually \En\ or \St
+ \itemitem {$x\ME{v}$} - $v$ in the context of $x$, where $x$ is {\bf Me},
+\En, \St, {\bf O} or {\bf V}
+ \itemitem {$\Tp{x}{y}$} - the tuple composed of $x$ and $y$
+ \itemitem {$\{e\}$} - a continuation that evaluates $e$ in the current
+context
+ \medskip
+ \noindent When either of the environment or store are omitted, the
+environment or store from the enclosing environment is assumed.
+
+
+ % The first type of term is the name of a variable or constant. The
+meaning of a name is the value that the environment contains for that
+name. For variables, this value is the location in the store where
+the value may be found.
+ %<Term Definition%>=
+ Term = Var of string
+ % $\Me{\Sy}\En\Co\St=\Co\Tp{\En\ME{\Sy}}{\St}$
+ %<Meaning Function%>=
+ fun Me (Var x) e c s = c (lookup x e ,s)
+ |;
+
+ % Integer constants.
+ %<Term Definition%>=
+ |: Numeral of int
+ % $\Me{\Nu}\En\Co\St=\Co\Tp{{\bf V}\ME{\Nu}}{\St}$
+ %<Meaning Function%>=
+ |= Me (Numeral n) e c s = c (intValue n,s)
+ |;
+
+ %*Declarations.
+
+Declarations come in 3 flavours: {\tt val}, {\tt rec}, and {\tt
+var}. For all three, the declaration only holds for the evaluation of
+the expression with which it is composed. {\tt val} introduces a
+constant. {\tt rec} is similar but the symbol is introduced into the
+environment of the expression (which must be a function) to allow for
+recursive calls. {\tt var} introduces a variable.
+ %<Term Definition%>=
+ |: Decl of Decl * Term
+ % $\Me{{\tt var}~\Sy~{\tt =}~\Ex_1~{\tt ;}~\Ex_2}\En\Co\St=\Me{\Ex_2}\En[\Lo/\Sy]\Co\St[\Me{\Ex_1}\En\CO\St/\Lo]$
+ %<Meaning Function%>=
+ |= Me (Decl (Var_Decl (x,V),E)) e c s =
+ Me V e (fn (R,_) => let
+ val (S,L) = new s R;
+ val nE = bind x (lvalueValue L) e;
+ in Me E nE c S end) s
+ |;
+
+ % $\Me{{\tt val}~\Sy~{\tt =}~\Ex_1~{\tt ;}~\Ex_2}\En\Co\St=\Me{\Ex_2}\En[\Me{\Ex_1}\En\CO\St/\Sy]\Co\St$
+ %<Meaning Function%>=
+ |= Me (Decl (Val_Decl (x,V),E)) e c s =
+ Me V e (fn (R,_) => Me E (bind x R e) c s)s
+ |;
+
+ % The interpretation of the recursive declaration ($\Me{{\tt
+rec}~\Sy~{\tt =}~\Ex_1~{\tt ;}~\Ex_2}\En\Co\St$) is fairly difficult
+to describe, short of translating the ML code. There are a couple of
+ways of doing this, but the one I chose is to implement the Y
+combinator ({\tt fix}) in the language and then apply it to the
+functional we want to make recursive. To bootstrap the process, we
+put an entry for {\tt fix} into the environment as a var name with an
+initial binding to an invalid value, which we replace once we have a
+definition for the function proper. If we were looking for
+efficiency, we'd put these in the initial environment and store.
+ %<Meaning Function%>=
+ |= Me (Decl (Rec_Decl (x,V),E)) e c s = let
+ val fixpoint=Proc ("fix-f",
+ Proc ("fix-x", App (App (Var "fix-f",
+ App (Deref (Var "fix"),Var "fix-f"))
+ ,Var "fix-x")));
+ val (S,L) = new s invalidValue;
+ val nE = bind "fix" (lvalueValue L) e;
+ in
+ Me fixpoint nE (
+ fn (FIX,_) => Me (App (Deref (Var "fix"),Proc(x,V))) nE (
+ fn (funcValue R,S) => Me E (bind x (funcValue R) e) c S
+ |_=>raise NotFuncDecl) (update S L FIX)
+ ) S
+ end
+
+ |;
+
+ %*Function operations.
+
+ Function abstraction. Define a function of one parameter bound in
+the scope of the expression.
+ %<Term Definition%>=
+ |: Proc of string * Term
+ % $\Me{{\tt proc}~\Sy~{\tt =>}~\Ex}\En\Co\St=\Co\Tp{\lambda\Co'.\lambda\Tp{V}{\St'}.\Me{\Ex}\En[V/\Sy]\Co'\St'}{\St}$
+ %<Meaning Function%>=
+ |= Me (Proc (x,E)) e c s =
+ c (funcValue (fn C => fn (V,S) => Me E (bind x V e) C S ),s)
+ |;
+
+ % Function Application. Supply one parameter to the function and
+execute the function.
+ %<Term Definition%>=
+ |: App of Term * Term
+ % The interpretation of function application
+($\Me{\Ex_1{\tt(}\Ex_2{\tt)}}\En\Co\St$) is basically going to be a translation
+of the ML code.
+ %<Meaning Function%>=
+ |= Me (App (E1,E2)) e c s =
+ Me E1 e (fn (funcValue f,_) =>
+ Me E2 e (fn VS => f c VS) s
+ |_ =>raise NotFunc
+ ) s
+ |;
+
+ % Call the specified function passing our continuation as a
+functional parameter.
+ %<Term Definition%>=
+ |: Callcc of Term
+
+ % The interpretation of function application
+($\Me{{\tt callcc}~\Ex}\En\Co\St$) is basically going to be a translation
+of the ML code.
+ %<Meaning Function%>=
+ |= Me (Callcc E) e c s =
+ Me E e (fn (funcValue f,_) =>
+ f c (funcValue (fn (C:Value continuation) => c),s)
+ |_ =>raise NotFunc
+ )s
+ |;
+
+ %*Operations on Pairs.
+
+ Create a pair from the values of two expressions.
+ %<Term Definition%>=
+ |: Pair of Term * Term
+ % $\Me{{\tt <}\Ex_1{\tt ,}\Ex_2{\tt >}}\En\Co\St=\Co\Tp{\Me{\Ex_1}\En\CO\St}{\Me{\Ex_2}\En\CO\St}$
+ %<Meaning Function%>=
+ |= Me (Pair (E1,E2)) e c s =
+ Me E1 e (fn (V1,_) =>
+ Me E2 e (fn (V2,S) => c (pairValue (V1,V2),s)) s
+ ) s
+ |;
+
+ % Get the first element from a pair.
+ %<Term Definition%>=
+ |: Fst of Term
+ % $\Me{{\tt fst}~\Ex}\En\Co\St=\Co\Tp{\pi_1(\Me{\Ex}\En\CO\St)}{\St}$
+ %<Meaning Function%>=
+ |= Me (Fst T) e c s =
+ Me T e (fn
+ (pairValue (T1,T2),_) => c (T1,s)
+ | _ => raise NotPair) s
+ |;
+
+ % Get the second element from a pair.
+ %<Term Definition%>=
+ |: Snd of Term
+ % $\Me{{\tt snd}~\Ex}\En\Co\St=\Co\Tp{\pi_2(\Me{\Ex}\En\CO\St)}{\St}$
+ %<Meaning Function%>=
+ |= Me (Snd T) e c s =
+ Me T e (fn
+ (pairValue (T1,T2),_) => c (T2,s)
+ | _ => raise NotPair) s
+ |;
+
+ %*Flow of control.
+
+ Conditional execution. Only one of the then or else expressions
+will be executed.
+ %<Term Definition%>=
+ |: Cond of Term * Term * Term
+ % $\Me{{\tt if}~\Ex_1~{\tt then}~\Ex_2~{\tt else}~\Ex_3~{\tt
+fi}}\En\Co\St=
+(if~\Me{\Ex_1}\En\CO\St={\tt true}~then~\Me{\Ex_2}~else~\Me{\Ex_3})\En\Co\St$
+ %<Meaning Function%>=
+ |= Me (Cond (E1,E2,E3)) e c s =
+ Me E1 e (fn (boolValue true,_) => Me E2 e c s
+ |(boolValue false,_)=> Me E3 e c s
+ |_ => raise NotBool
+ ) s
+ |;
+
+ % Expression composition. Execute the expressions sequentially.
+ %<Term Definition%>=
+ |: Seq of Term * Term
+ % $\Me{\Ex_1{\tt ;}\Ex_2}\En\Co\St=\Me{\Ex_1}\En\{\Me{\Ex_2}\En\Co\}\St$
+ %<Meaning Function%>=
+ |= Me (Seq (E1,E2)) e c s =
+ Me E1 e (fn (V,S) => Me E2 e c S) s
+ |;
+
+ % Indefinite iteration. Execute the second expression as long as the
+first expression evaluates to {\tt true}.
+ %<Term Definition%>=
+ |: While of Term * Term
+ % $\Me{{\tt while}~\Ex_1~{\tt do}~\Ex_2~{\tt od}}\En\Co\St=(if~
+\Me{\Ex_1}\CO\St={\tt true}~then~\Me{\Ex_2}\En\{\Me{{\tt
+while}\ldots}\En\Co\}~else~\Co)\St$
+ %<Meaning Function%>=
+ |= Me (While (E1,E2)) e c s =
+ Me E1 e (fn (boolValue true,S) => Me E2 e (fn (V,S) =>
+ Me (While (E1,E2)) e c S
+ ) S
+ |(boolValue false,S)=> c (invalidValue,S)
+ |_ => raise NotBool
+ ) s
+ |;
+
+ %*Storage References and Updates.
+
+ Allocate storage for a value and return the location of the value
+in the store.
+ %<Term Definition%>=
+ |: Ref of Term
+ % $\Me{{\tt ref}~\Ex}\En\Co\St=\Co\Tp{\Lo}{\St[\Me{\Ex}\En\CO\St/\Lo]}$
+ %<Meaning Function%>=
+ |= Me (Ref E) e c s =
+ Me E e (fn (V,_) => let
+ val (nS,L) = new s V;
+ in
+ c (lvalueValue L,nS)
+ end
+ ) s
+ |;
+
+ % Given the location of a datum, get the value currently stored there.
+ %<Term Definition%>=
+ |: Deref of Term
+ % $\Me{{\tt .}\Ex}\En\Co\St=\Co\Tp{\St\ME{\Me{\Ex}\En\CO\St}}{\St}$
+ %<Meaning Function%>=
+ |= Me (Deref E) e c s =
+ Me E e (fn
+ (lvalueValue V,S) => c (access S V,s)
+ |_=>raise NotLValue) s
+ |;
+
+ % Modify the storage at the location specified by the first
+expression to have the value of the second expression.
+ %<Term Definition%>=
+ |: Assign of Term * Term
+ % $\Me{\Ex_1{\tt :=}\Ex_2}\En\Co\St=\Co\Tp{\Me{\Ex_2}\En\CO\St}{\St[\Me{\Ex_2}\En\CO\St/\Me{\Ex_1}\En\CO\St]}$
+ %<Meaning Function%>=
+ |= Me (Assign (E1,E2)) e c s =
+ Me E1 e (fn
+ (lvalueValue L,_) => Me E2 e (fn (V,_) =>
+ c (V,update s L V)) s
+ |_=>raise NotLValue
+
+ ) s
+ |;
+
+ %*Integer Operations.
+
+ Add two integers together.
+ %<Term Definition%>=
+ |: Add of Term * Term
+ % $\Me{\Ex_1{\tt +}\Ex_2}\En\Co\St=\Co\Tp{{\bf O}\ME{+}(\Me{\Ex_1}\En\CO\St,\Me{\Ex_2}\En\CO\St)}{\St}$
+ %<Meaning Function%>=
+ |= Me (Add (E1,E2)) e c s =
+ Me E1 e (fn (intValue V1,_) =>
+ Me E2 e (fn (intValue V2,_) => c (intValue (V1+V2),s)
+ |_ => raise NotInteger) s
+ |_ => raise NotInteger) s
+ |;
+
+ % Multiply two integers.
+ %<Term Definition%>=
+ |: Mult of Term * Term
+ % $\Me{\Ex_1{\tt *}\Ex_2}\En\Co\St=\Co\Tp{{\bf O}\ME{\times}(\Me{\Ex_1}\En\CO\St,\Me{\Ex_2}\En\CO\St)}{\St}$
+ %<Meaning Function%>=
+ |= Me (Mult (E1,E2)) e c s =
+ Me E1 e (fn (intValue V1,_) =>
+ Me E2 e (fn (intValue V2,_) => c (intValue (V1*V2),s)
+ |_ => raise NotInteger) s
+ |_ => raise NotInteger) s
+ |;
+
+ % Calculate the negative of an integer.
+ %<Term Definition%>=
+ |: Neg of Term
+ % $\Me{{\tt -}\Ex}\En\Co\St=\Co\Tp{-\Me{\Ex}\En\CO\St}{\St}$
+ %<Meaning Function%>=
+ |= Me (Neg E) e c s =
+ Me E e ( fn (intValue V,_) => c (intValue (0-V),s)
+ |_ => raise NotInteger) s
+ |;
+
+ %* Boolean Operations.
+Determine if the first integer expression is lower in value than
+the second. Return a boolean truth value.
+ %<Term Definition%>=
+ |: Less of Term * Term
+ % $\Me{\Ex_1{\tt <}\Ex_2}\En\Co\St=\Co\Tp{{\bf O}\ME{<}(\Me{\Ex_1}\En\CO\St,\Me{\Ex_2}\En\CO\St)}{\St}$
+ %<Meaning Function%>=
+ |= Me (Less (E1,E2)) e c s =
+ Me E1 e (fn (intValue V1,_) =>
+ Me E2 e (fn (intValue V2,_) => c (boolValue (V1<V2),s)
+ |_ => raise NotInteger) s
+ |_ => raise NotInteger) s
+ |;
+
+ % Calculate the boolean complement of the expression.
+ %<Term Definition%>=
+ |: Not of Term
+ % $\Me{\neg\Ex}\En\Co\St=\Co\Tp{\neg\Me{\Ex}\En\CO\St}{\St}$
+ %<Meaning Function%>=
+ |= Me (Not E) e c s =
+ Me E e ( fn (boolValue true,_) => c (boolValue false,s)
+ |(boolValue false,_) => c (boolValue true,s)
+ |_ => raise NotBool ) s
+ |;
+
+ %*Environments. An environment captures the bindings of names to
+values (in this case locations). This trivial implementation has
+dreadful performance, but it is at least fairly obviously correct.
+ %<Type Definitions%>=
+abstype 'a env = Env of string->'a with
+ exception unbound_variable of string;
+ val newenv = Env (fn x => raise unbound_variable x);
+ fun bind x t (Env f) = Env(fn y => if x=y then t else f y);
+ fun lookup x (Env f) = f x
+end;
+
+ %*Stores. A store binds locations to values. Once again, this is
+just about the most inefficient implementation you could come up with
+(although there actually was a bug in the first version). A store can
+be thought of as a mapping from locations to values, where new
+locations are created on demand.
+ %<Type Definitions%>=
+abstype 'a store = Store of int * (int->'a)
+and lvalue = lvalue of int
+with
+ exception segmentation_violation;
+ val newstore = Store (0, fn x => raise segmentation_violation);
+ fun new (Store (avail,f)) v =
+ (Store (avail+1, fn l=>if l=avail then v else f l), lvalue(avail));
+ fun access (Store (_,f)) (lvalue loc) = f loc;
+ fun update (Store (avail,f)) (lvalue loc) v =
+ Store (avail, fn l=>if l=loc then v else f l);
+ end;
+
+ %*Values and Miscellaneous Definitions. Define a continuation to be
+a mapping from a value,state pair to a resulting value,state.
+ %<Type Definitions%>=
+type 'a continuation = ('a * 'a store) -> ('a * 'a store);
+
+ % Values. These are the set of values that can result from a
+computation. Only the first 3 of these were in the original problem
+description. I added the others to make the language/interpreter more
+useful and to catch and report errors.
+ %<Type Definitions%>=
+datatype Value =
+ intValue of int
+ | lvalueValue of lvalue
+ | funcValue of Value continuation -> Value continuation
+ | boolValue of bool
+ | pairValue of Value*Value
+ | invalidValue
+ |Missing_Name of string
+ ;
+
+ % These are exceptions that are raised by the semantic function when
+values are inappropriate.
+ %<Type Definitions%>=
+ exception NotImplemented;
+ exception NotCorrect;
+ exception NotPair;
+ exception NotLValue;
+ exception NotBool;
+ exception NotInteger;
+ exception NotFunc;
+ exception NotFuncDecl;
+
+ % Here is an \.{ML} version of the Y fix point operator. We could use it
+for to implement recursion. It would only be a minor change to make
+the semantic function use this rather than use \.{ML}'s builtin recursion.
+ %<Functions%>=fun fix f x = f (fix f) x;
+
+ % The empty continuation.
+ %<Functions%>=fun nullContinuation x = x;
+
+ %*Test of the Machine. Testing is no substitute for correct
+implementation, but it is somewhat heartwarming to see such an
+abstract interpreter actually work.
+
+ First of all define a |test| function that will accept any program in
+the language and execute it, returning the result.
+ %<Test Cases%>=
+ fun test n = let
+ val (V,S) =Me n newenv nullContinuation newstore handle
+ unbound_variable x => (Missing_Name x,newstore);
+ in V end;
+ % A few dead simple tests to show that integers and pairs work
+properly.
+ %<Test Cases%>=
+ test (Numeral 3);
+ test (Neg (Add (Numeral 3,Numeral 39)));
+ test (Fst (Pair (Numeral 3,Numeral 4)));
+ test (Snd (Pair (Numeral 3,Numeral 4)));
+ test (Seq (Numeral 3,Numeral 4));
+
+ % Test binding names, both through value declarations and $\lambda$
+bindings. Also verify that function abstraction, function application,
+and call-with-current-continuation work.
+ %<Test Cases%>=
+ val X="x";val Y="y";val FIX="fix" and F="f";
+ test (Decl (Val_Decl (X,Numeral 29),Var X));
+ test (App (Proc (X,Numeral 17),Numeral 7));
+ test (App (Proc (X,Add (Var X,Numeral 1)),Numeral 7));
+ test (Decl (Val_Decl (X,Proc (Y,Var Y))
+ ,Add (Numeral 3,App (Var X,Numeral 55))));
+ test (Decl (Val_Decl (X,Proc (Y,
+ Seq (App (Var Y,Numeral 33),Numeral 44)))
+ ,Add (Numeral 3,Callcc (Var X))));
+ % Now for some real excitement: recursive functions. Surprise!
+Surprise! They actually work.
+ %<Test Cases%>=
+ val fact=Rec_Decl (X,Proc (Y,
+ Cond (Less (Var Y
+ ,Numeral 2)
+ ,Numeral 1
+ ,Mult (App (Var X
+ ,Add (Var Y
+ ,Neg (Numeral 1)
+ )
+ )
+ ,Var Y
+ )
+ )));
+ test (Decl (fact
+ ,App (Var X
+ ,Numeral 1)));
+ test (Decl (fact
+ ,App (Var X,Numeral 5)));
+ % Ok, so let's use some CPU time! Try fibonacci
+ %<Test Cases%>=
+ val fib=Rec_Decl (X,Proc (Y,
+ Cond (Less (Var Y
+ ,Numeral 2)
+ ,Numeral 1
+ ,Add (App (Var X
+ ,Add (Var Y
+ ,Neg (Numeral 1)
+ )
+ )
+ ,App (Var X
+ ,Add (Var Y
+ ,Neg (Numeral 2)
+ )
+ )
+ )
+ )));
+ test (Decl (fib
+ ,App (Var X
+ ,Numeral 1)));
+ test (Decl (fib
+ ,App (Var X,Numeral 5)));
+ test (Decl (fib
+ ,App (Var X,Numeral 10)));
+ test (Decl (fib
+ ,App (Var X,Numeral 15)));
+ test (Decl (fib
+ ,App (Var X,Numeral 20)));
+ test (Decl (fib
+ ,App (Var X,Numeral 25)));
+ test (Decl (fib
+ ,App (Var X,Numeral 28)));
+ % Finally test that reference bindings and iteration work properly.
+ %<Test Cases%>=
+ test (Assign (Ref (Numeral 2),Numeral 3));
+ test (Decl (Var_Decl (X,Numeral 1)
+ ,Deref (Var X)));
+ test (Decl (Var_Decl (X,Numeral 1)
+ ,Seq (Assign (Var X
+ ,Add (Numeral 22,Deref (Var X)))
+ ,Deref (Var X))));
+ test (Decl (Var_Decl (X,Numeral 1)
+ ,(Decl (Var_Decl (Y,Numeral 0)
+ ,Seq (While
+ (Less (Deref (Var X),Numeral 11)
+ ,Seq (Assign (Var Y
+ ,Add (Deref (Var Y),Deref (Var X)))
+ ,(Assign (Var X
+ ,Add (Numeral 1,Deref (Var X)))))
+ )
+ ,Deref (Var Y))
+ ))));
+
+ %*Index.
+---------------------------------end of denote.web-------------
+
diff --git a/web/spiderweb/src/ssl/make b/web/spiderweb/src/ssl/make
new file mode 100644
index 0000000000..115eb3d665
--- /dev/null
+++ b/web/spiderweb/src/ssl/make
@@ -0,0 +1,2 @@
+/bin/make -f ../master/WebMakefile CPUTYPE=`cputype` \
+ THETANGLE=stangle THEWEAVE=sweave SPIDER=s.spider $*
diff --git a/web/spiderweb/src/ssl/s.spider b/web/spiderweb/src/ssl/s.spider
new file mode 100644
index 0000000000..ba3ef93a10
--- /dev/null
+++ b/web/spiderweb/src/ssl/s.spider
@@ -0,0 +1,220 @@
+# Copyright 1989 by Norman Ramsey, Odyssey Research Associates
+# Not to be sold, but may be used freely for any purpose
+# For more information, see file COPYRIGHT in the parent directory
+language Synthesizer extension ssl
+
+at_sign #
+
+comment begin <"/*"> end <"*/">
+
+default translation <*> mathness yes
+
+token identifier category simp mathness yes
+token number category literal mathness yes
+token newline category ignore_scrap mathness maybe translation <>
+token pseudo_semi category semi mathness maybe translation <>
+
+module definition decl use math
+
+token + category binop
+token - category unorbinop
+token * category star
+token / category binop
+token < category less translation <>
+token > category greater translation <>
+token = category binop
+token . category binop
+token ^ category at translation <"\\H">
+token ~ category unorbinop translation <"\\TI">
+token & category unop translation <"\\AMP">
+token ? translation <"\\?"> category question
+token % translation <"\\%"> category binop
+token @ category at mathness no
+token .. category at translation <"..">
+# following must tangleto " # " because # at beginning of line freaks
+# The preprocessor -- this doesn't look like preproc directive...
+token # translation <"\\SH"> category unorbinop tangleto <space-"#"-space>
+token ( category open
+token [ category lbrack
+token ) category close
+token ] category close
+token { translation <"\\{"> category lbrace
+token } translation <"\\}"> category close
+token , category comma
+token ; category semi
+token : category colon
+token | category bar
+token $ category dollar translation <"\\DO">
+token != name not_eq translation <"\\I"> category binop
+token <= name lt_eq translation <"\\L"> category binop
+token >= name gt_eq translation <"\\G"> category binop
+token == name eq_eq translation <"\\S"> category binop
+token && name and_and translation <"\\W"> category binop
+token || name or_or translation <"\\V"> category binop
+token -> name minus_gt translation <"\\MG"> category binop
+token >> name gt_gt translation <"\\GG"> category binop
+token << name lt_lt translation <"\\LL"> category binop
+token :: name double_colon translation <"::"> category binop
+token ::= name produces translation <"\\CCE"> category colon
+
+macros begin
+\def\AMP{{\sl\amp}}
+\def\SH{\mathbin{\#}}
+\def\CCE{::=}
+\def\MG{\mathrel{\to}}
+\def\GG{\mathrel{>\!>}}
+\def\LL{\mathrel{<\!<}}
+\let\LN\langle
+\let\RN\rangle
+\let\openbraces=\{
+\let\closebraces=\}
+\def\{{\ifmmode\openbraces\else$\openbraces$\fi}
+\def\}{\ifmmode\closebraces\else$\closebraces$\fi}
+\let\dothickspace=\;
+\def\;{\ifmmode\dothickspace\else\relax$\dothickspace$\relax\fi}
+\let\domedspace=\>
+\def\>{\ifmmode\domedspace\else\relax$\domedspace$\relax\fi}
+\let\dothinspace=\,
+\def\,{\ifmmode\dothinspace\else\relax$\dothinspace$\relax\fi}
+\def\?{\mathrel?}
+\def\MO{\mathord{}} % to fake out math ::= <force>
+macros end
+
+
+ilk and_like category and
+ilk in_like category in
+ilk let_like category let translation <*-indent-"\\"-space-opt-0>
+ilk math_like category math
+ilk on_like category on
+ilk transform_like category transform
+ilk with_like category with
+
+reserved and ilk and_like
+reserved as ilk math_like
+reserved class ilk math_like
+reserved default ilk math_like
+reserved demand ilk math_like
+reserved exported ilk math_like
+reserved ext_computers ilk math_like
+reserved false ilk math_like
+reserved foreign ilk math_like
+reserved in ilk in_like
+reserved inh ilk inh_like
+ilk inh_like category math translation <"\\&{inherited}">
+reserved inherited ilk math_like
+reserved left ilk math_like
+reserved list ilk math_like
+reserved let ilk let_like
+reserved local ilk math_like
+reserved nil ilk math_like
+reserved nil_attr ilk math_like
+reserved nonassoc ilk math_like
+reserved on ilk on_like
+reserved optional ilk math_like
+reserved prec ilk math_like
+reserved repeated ilk math_like
+reserved right ilk math_like
+reserved root ilk math_like
+reserved store ilk math_like
+reserved style ilk math_like
+reserved syn ilk syn_like
+ilk syn_like category math translation <"\\&{synthesized}">
+reserved synthesized ilk math_like
+reserved transform ilk transform_like
+reserved true ilk math_like
+reserved typedef ilk math_like
+reserved with ilk with_like
+
+at colon <opt-3> --> math
+at <opt-5> --> math
+decl <force> decl --> decl
+decl <force> simp* colon <"\\MO"-indent-force> --> mbar
+decl simp [ simp* ] --> decl simp math
+dollar dollar --> math
+dollar --> unop
+<force> in open <indent-force> --> wbegin
+in --> math
+# following for semantic equations and attribute declarations
+lbrace <indent-force> (decl) <force> close <outdent-force> --> math
+# following for attribution expression
+math lbrace close --> math
+# following for function declaration MUST PRECEDE "open math close"
+# we need (math|decl) because it might hit attribute decl too
+open math close lbrace --> openfunc
+open math [ close ignore_scrap ] --> open math close
+openfunc <indent-force> (math|decl) <force> close <outdent-force> --> math
+# Now in the hideous case where we have mistakenly confused an attribution
+# expression for a function declaration, we correct our error
+openfunc close --> math
+# following for upward remote attribute reference
+lbrace math close --> math
+
+lbrack <indent> math <outdent> close --> math
+
+
+
+math <force> bar --> math
+math colon <"\\MO"> --> mcolon
+
+math open close --> math
+# no space here
+math <"\\;"-opt-0> lbrack --> lbrack
+
+[ star ] colon --> math colon
+math star --> unop
+star --> math
+
+math <"\\>"> math --> math
+math (binop|unorbinop) math --> math
+math unop --> math
+(unop|unorbinop) math --> math
+
+math semi --> decl
+
+mbar math <force> bar --> mbar
+mbar math <force> semi <outdent> --> decl
+
+mcolon <indent-force> math <force> semi <outdent> --> decl
+mcolon <indent-force> math <outdent-force> close --> close
+mcolon <indent-force> math comma --> mcmcom
+
+mcmcom math comma --> mbar
+mcmcom <outdent-force> math colon <"\\MO"> --> mcolon
+
+
+math comma <"\\,"> math --> math
+
+
+on --> math
+open math close --> math
+open close --> math
+# The following doesn't do indentation right
+# <indent-force> question math <force> colon ? <outdent> - - > #4
+<indent-force> question math <force> colon --> condbegin
+[ condbegin math <outdent> ] (semi|close|comma|colon) --> math (semi|close|comma|colon)
+
+less <"\\LN"> simp <"\\RN"> greater --> math
+less <"<"> --> binop
+greater <">"> --> binop
+
+literal <opt-5> --> math
+simp --> math
+tbegin <indent-force> decl <outdent> --> decl
+transform <"\\;"> math --> tbegin
+wbegin math close <outdent-force> --> math
+wbegin close <outdent-force> --> math
+# following for leaving commas in last clause in with statements
+wbegin mcmcom <outdent-force> close <outdent-force> --> math
+with math (math|semi) --> math
+with math <"\\,"> open <indent-force> --> wbegin
+
+# let statements
+math <"\\"-space-opt-3> and <"\\"-space> math --> math
+(forcelet|let) math semi <force> --> forcelet
+forcelet math <outdent-force> in <"\\"-space> open <indent-force> --> letopen
+letopen math <force> close <outdent> --> math
+let math in <"\\"-space> open <indent-force> --> letopen
+# following recognizes semi as a possible terminator as well as separator
+forcelet <backup> in <"\\"-space> open <force> --> letopen
+
+? ignore_scrap --> #1
diff --git a/web/spiderweb/src/turing+/example.mail b/web/spiderweb/src/turing+/example.mail
new file mode 100644
index 0000000000..c1513a4b93
--- /dev/null
+++ b/web/spiderweb/src/turing+/example.mail
@@ -0,0 +1,195 @@
+From att!surya.ho.att.com!ko Fri Mar 22 10:31:23 1991
+Received: from Princeton.EDU (Princeton.EDU.) by fs.Princeton.EDU (4.0/1.105)
+ id AA21961; Fri, 22 Mar 91 10:31:21 EST
+Received: from att.UUCP by Princeton.EDU (5.61++/2.69/princeton)
+ id AA18354; Fri, 22 Mar 91 10:31:17 -0500
+Received: from spark.ho.att.com by surya.ho.att.com (4.1/SMI-4.1)
+ id AA09832; Thu, 21 Mar 91 17:27:35 EST
+Date: Thu, 21 Mar 91 17:27:35 EST
+From: surya.ho.att.com!ko
+Message-Id: <9103212227.AA09832@surya.ho.att.com>
+Received: by spark.ho.att.com (4.1/SMI-4.1)
+ id AA06596; Thu, 21 Mar 91 17:35:07 EST
+To: att!att.uucp, nr@Princeton.EDU
+Subject: Example file
+Status: RO
+
+Here is an example Turing Web file. Note: I have made a small
+modification to "webkernel.tex" by adding \date and \author macros.
+These are used in the file that follows. I include the modification
+below:
+
+\def\rhead{\.{WEB} OUTPUT} % this running head is reset by starred sections
+\def\title{} % an optional title can be set by the user
+% The following two are optional, and can be set by the user.
+% (Kostas Oikonomou, Nov. 1990.)
+\def\author{}
+\def\date{}
+\def\topofcontents{\centerline{\titlefont\title}\vskip1cm\centerline{\author}
+ \vskip0.4cm\centerline{\date}\vfill} % this material will start the table of contents page
+\def\botofcontents{\vfill} % this material will end the table of contents page
+
+
+
+
+----------------------------- paths.web ----------------------------------------
+
+\def \title {General Least-Cost Paths in Graphs}
+\def \author {Kostas N. Oikonomou}
+\def \date {August 1990}
+
+
+% See the TeXbook, p.154 for this!
+\font \bbb = msbm10
+\newfam\msbmfam
+\textfont\msbmfam=\bbb
+\def \Nat {{\fam\msbmfam N}}
+\def \Real {{\fam\msbfam R}}
+\def \c#1{\vert#1\vert}
+
+@* The {\it paths\/} module.
+
+Let $G$ be a complete directed graph on $V=\{0,1,\ldots,n\}$. The edges
+are $E=\{(i,j)\mid i<j\}$. Let each edge have a cost (length) $\ell(i,j)$.
+The cost of a {\it path\/} from $i$ to $j$ may be defined in various ways,
+as a function of the costs (lengths) of the edges that make it up. For
+example, it could be the sum of the lengths of the edges, it could be the
+length of the longest edge, the length of the shortest edge, etc. We are
+interested in finding best (least-cost) paths in $G$ from $i$ to $n$, with
+a specified number $m$ of edges.
+
+We will be able to do this efficiently if the function $C$ defining the
+cost of a path $i,i_1,\ldots,i_{m-1},j$ from $i$ to $j$ is s.t. it satisfies
+the optimality principle of dynamic programming. That is $C$ must be s.t.
+$$
+\min_{(i_1,\ldots,i_{m-1})} C(i,i_1,\ldots,i_{m-1},j) = \min_{i_1}
+f \bigl( C(i,i_1), \min_{(i_2,\ldots,i_{m-1})} C(i_1,\ldots,i_{m-1},j) \bigr), \eqno (1)
+$$
+where $f(\cdot,\cdot)$ is some function, e.g. ``$+$'', and where the
+``min'' could be replaced by ``max''. (An interesting recent reference on
+generalizations of the optimality principle and related subjects is {\sl
+Generalized Dynamic Programming for Stochastic Combinatorial
+Optimization\/}, Carraway et al., Op. Res., Vol. 37, No. 5, 1989.)
+Although our $G$ is directed, so that the minima in (1) are to be taken
+over sequences such as $i<i_1<\cdots<i_{m-1}<j$, it should be clear that
+(1) also applies to a complete undirected $G$, if the minima are taken over
+unconstrained paths.
+
+Module |paths| contains a procedure |least_cost| which, given the function
+$f$ appearing in (1), returns in $c^*(1..m)$ the cost of the best 0-to-$n$
+paths in $G$ with $1,2,\dots,m$ edges. The function |relation| expresses a
+relation between $c^*(k)$ and $c^*(k-1)$, for checking purposes; if no such
+relation is known, define the function to be identically true. The module
+also contains a procedure |least_cost_path|, which returns in $I(0 .. k)$ the
+vertices on the best $k$-edge path from 0 to $n$, for any $k\le m$.
+
+@(paths.ch@> =
+@t\% The ``include'' allows {\tt paths.ch} to be used unchanged by different parent modules:@>
+include "paths.parent"
+stub module paths
+import (n, m)
+export (least_cost, least_cost_path)
+procedure least_cost (var c_star : array 1 .. * of real, function l(i,j : nat) : real, @| function f(c1,c2 : real) : real, function relation (c1,c2 : real) : boolean)
+procedure least_cost_path (k : nat, var I : array 0 .. * of nat)
+end paths
+
+@ To find the paths and their costs, define
+$$
+c_k(i) = \min_{j:i<j<n} (\hbox{\rm cost of the best $i$-to-$n$ path with
+$k\ge 1$ edges}).
+$$
+It follows from (1) that $c_k(i)$ satisfies the recurrence
+$$
+c_k(i) = \min_{j:i<j<n} f\bigl(\ell(i,j), c_{k-1}(j)\bigr), \qquad k\ge 2.
+\eqno (2)
+$$
+This recurrence can be solved by noting that
+$$
+\forall i,\quad c_1(i) = \ell(i,n).
+$$
+Using this in (2) allows us to compute $c_2(i)$ for all $i$, and so on. To
+conserve memory space, note that we don't really need to have a matrix
+$c(k,i)$, but just two arrays |c_k| and |c_k_1| to hold $c_k(\cdot)$
+and $c_{k-1}(\cdot)$.
+
+Besides computing the cost of the best 0-to-$n$ paths, we also want to know
+what these paths are. To do this, it suffices to remember for each $i$ and
+$k$ the $j=J(k,i)$ that minimizes the r.h.s. of (2).
+
+@
+@<Compute $c_k(i)$ and $J(k,i)$ for all $i$@> =
+for i : 0 .. n-2
+c_k(i) := infinity
+for j : i+1 .. n-1
+const c := f(l(i,j), c_k_1(j))
+if c < c_k(i) then
+c_k(i) := c
+J(k,i) := j
+end if
+end for
+end for
+
+@
+@<Solve recurrence (2)@> =
+const infinity := 10.0 ** 200
+for k : 2 .. m
+@<Compute $c_k(i)$...@>
+@<Remember $c_k(0)$ and check its relationship with $c_{k-1}(0)$@>
+@<Set $c_{k-1}(\cdot)$ to $c_k(\cdot)$@>
+end for
+
+@
+@<Procedure |least_cost|@> =
+body procedure least_cost
+c_star(1) := l(0,n)
+@<The arrays |c_k| and |c_k_1|@>
+@<Solve recurrence (2)@>
+end least_cost
+
+@ Procedure |least_cost_path| calculates in $I_0,\dots,I_k$ the
+vertices on the least-cost path from 0 to $n$ in $G$ with $k$ edges. It
+uses the function $J(k,i)$ computed by procedure |least_cost|.
+@<Procedure |least_cost_path|@> =
+body procedure least_cost_path
+I(0) := 0
+I(k) := n
+for i : 1 .. k-1
+I(i) := J(k-(i-1), I(i-1))
+assert I(i) > I(i-1)
+end for
+assert I(k-1) < n
+end least_cost_path
+
+@
+@(paths.ch@> +=
+body module paths
+var J : array 2 .. m, 0 .. n-2 of nat
+@<Procedure |least_cost|@>
+@<Procedure |least_cost_path|@>
+end paths
+
+@ We store $c_k(0)$, the cost of the best 0-to-$n$ $k$-edge path, in
+$c^*(k)$. If we know a relationship between the cost of the best path with
+$k$ edges and that of the one with $k-1$ edges, e.g. $c^*(k)>c^*(k-1)$, the
+function |relation| allows us to check that it holds.
+@<Remember...@> =
+c_star(k) := c_k(0)
+assert relation (c_star(k), c_star(k-1))
+
+@
+@<The arrays |c_k| and |c_k_1|@> =
+var c_k, c_k_1 : array 0 .. n-1 of real
+for i : 0 .. n-1 % Here k = 2.
+c_k_1(i) := l(i,n)
+end for
+c_k(n-1) := l(n-1,n) % Here k = 1 and this never changes.
+
+@
+@<Set $c_{k-1}(\cdot)$...@> =
+for i : 0 .. n-2
+c_k_1(i) := c_k(i)
+end for
+
+
+@* Index.
+
diff --git a/web/spiderweb/src/turing+/make b/web/spiderweb/src/turing+/make
new file mode 100644
index 0000000000..5c74e37aa9
--- /dev/null
+++ b/web/spiderweb/src/turing+/make
@@ -0,0 +1,3 @@
+#!/bin/sh
+/bin/make -f ../master/WebMakefile CPUTYPE=`cputype`\
+ THETANGLE=turing+tangle THEWEAVE=turing+weave SPIDER=turing+.spider "$@"
diff --git a/web/spiderweb/src/turing+/turing+.spider b/web/spiderweb/src/turing+/turing+.spider
new file mode 100644
index 0000000000..6c95ceaed8
--- /dev/null
+++ b/web/spiderweb/src/turing+/turing+.spider
@@ -0,0 +1,527 @@
+#------------------------------- turing+.spider --------------------------------
+
+# Kostas N. Oikonomou, April 1990 and on ...
+# Thanks to Norman Ramsey for helpful suggestions.
+
+# ********
+# Named types seem to be O.K.
+# Unions have to be tested with named types.
+# ********
+
+# NOTE: newlines are important in the WeB file. They designate the end of statements.
+
+
+language Turing extension t
+
+at_sign @
+
+# This says how to treat "@<...@> =" and "@<...@>". See "Specifying the
+# treatment of modules" in the Spider User's Guide.
+module definition stmt use stmt
+
+comment begin <"%"> end newline
+macros begin
+\def \commentbegin {\%}
+macros end
+
+# Line numbers are not necessary. The compiler handles the tangled output
+# with no problem. However, there is no way to turn line numbers off!
+line begin <"%"-"line"> end <"">
+
+default translation <*> mathness yes
+default mathness yes translation <*>
+
+#----------------------------------------------------------------------------
+# Tokens
+#----------------------------------------------------------------------------
+
+token identifier category expn mathness yes
+token number category expn mathness yes
+# Note: newline's have to be treated carefully; for example, if they are
+# found in math mode, webmac.tex ignores them.
+token newline category newl translation <> mathness maybe
+token pseudo_semi translation <> category semi mathness maybe
+
+token ( category open
+token ) category close
+token * category star
+token + category binop
+token . category binop
+token , category comma translation <",\\,"-opt-3>
+token - category unorbinop
+token / category binop
+# This definition seems to be needed for good formatting of labels of case statements.
+token : category colon translation <"\\mathbin{:}"> mathness yes
+token < category binop
+token = category equal
+token > category binop
+token # category expn translation <"\\#">
+token -> category binop translation <"\\rightarrow">
+token .. category dotdot translation <"\\mathbin{..}">
+# We want the exponentiation operator "**" to be formatted as "^". However,
+# "^" is defined in webmac.tex, so we need the following definition:
+token ** category binop translation <"\\char`^">
+token := category assign translation <"\\mathbin{:=}"> mathness yes
+token >= category binop translation <"\\ge">
+token <= category binop translation <"\\le">
+
+# In the following, section references are to the Turing Report, in
+# "The Turing Programming Language: Design and Definition", 1988.
+
+#----------------------------------------------------------------------------
+# Section 4.2: Programs and Declarations
+#----------------------------------------------------------------------------
+
+# 4.2.3, 4.2.4. Constant and variable declarations. See pp. 12-13 of the
+# Spider User's Guide for the "*" s.
+reserved var ilk varconst_like
+reserved const ilk varconst_like
+ilk varconst_like category varconst
+reserved pervasive ilk pervasive_like
+ilk pervasive_like category pervasive
+varconst <"\\"-space> pervasive --> varconst
+# For "var r := 3.141":
+varconst <"\\"-space> expn* assign expn newl --> stmt
+# "idtypespec" is an auxiliary category which we will also use later.
+# (See 4.6.1b for the "id, id" part.) "typespec" is defined in sec. 4.3 on
+# types.
+[ expn colon (typespec|expn) ] !dotdot --> idtypespec !dotdot
+# "vcidtypespec" is another auxiliary category, which is also used later.
+varconst <"\\"-space> idtypespec* --> vcidtypespec
+# For "var r : real", or "var x : named_type":
+vcidtypespec newl --> stmt
+# For "var r : real := 3.141":
+vcidtypespec assign expn newl --> stmt
+# Initializing value:
+reserved init ilk init_like
+ilk init_like category init
+# The context is so that the "init" rule in 4.4.6 can work.
+[ init <"\\,"> expn ] !assign --> expn !assign
+
+# 4.2.4. Collections:
+reserved collection ilk collection_like
+ilk collection_like category collection
+reserved forward ilk forward_like
+ilk forward_like category forward
+reserved of ilk of_like
+ilk of_like category of
+forward <"\\"-space> expn --> typespec
+collection <"\\"-space> of <"\\"-space> (typespec|expn) --> typespec
+
+# 4.2.5. Bindings:
+reserved bind ilk bind_like
+ilk bind_like category bind
+# We introduce the auxiliary category "binding". To correctly parse
+# "bind a to A.a", etc, we need a context:
+[ expn <"\\"-space> to <"\\"-space> expn ] !(binop|open) --> binding !(binop|open)
+varconst <"\\"-space> binding --> binding
+binding comma binding --> binding
+bind <"\\"-space> binding newl --> stmt
+
+
+#----------------------------------------------------------------------------
+# Section 4.3: Types
+#----------------------------------------------------------------------------
+
+# Type declaration:
+reserved type ilk type_like
+ilk type_like category type
+type <"\\"-space> pervasive --> type
+type <"\\"-space> idtypespec* newl --> stmt
+
+# Typespec:
+# a. Standard type:
+reserved boolean ilk typespec_like
+reserved char ilk typespec_like
+reserved int ilk typespec_like
+reserved int1 ilk typespec_like
+reserved int2 ilk typespec_like
+reserved int4 ilk typespec_like
+reserved nat ilk typespec_like
+reserved real ilk typespec_like
+reserved real4 ilk typespec_like
+reserved real8 ilk typespec_like
+ilk typespec_like category typespec
+# Strings are tricky (see 4.4.4), so define a new category:
+reserved string ilk strng_like
+ilk strng_like category strng
+[ strng ] !open --> typespec !open
+strng <"\\,"> open (expn|star) close --> typespec
+# To allow the typespec to be on a line by itself (e.g. ... newl record ... end record):
+newl typespec --> typespec
+
+# b. Subrange type. This is tricky! If the context were not there,
+# then, for example, "1..a+b" would be parsed as "typespec + b".
+# Also, note that if spaces are not left around the "..", parsing will be
+# confused because, e.g., "1..expn" is indistinguishable from "1.expn".
+# Finally, see sec. 4.6.1 for "star".
+[ expn dotdot (expn|star) ] !(binop|star|unorbinop|open) --> typespec !(binop|star|unorbinop|open)
+
+# c. Enumerated type:
+reserved enum ilk enum_like
+ilk enum_like category enum
+enum <"\\,"> expn --> typespec
+
+# d. Array type:
+reserved array ilk array_like
+ilk array_like category array
+typespec comma typespec --> typespec
+array <"\\"-space> typespec <"\\"-space> of <"\\"-space> (typespec|expn) --> typespec
+
+# e. Set type:
+reserved set ilk set_like
+ilk set_like category set
+set <"\\"-space> of <"\\"-space> typespec --> typespec
+
+# f. Record type. We use the auxiliary category "recordbody".
+# Some of the productions are also used by union" and "case".
+reserved record ilk record_like
+ilk record_like category record
+<force-indent-indent> record <force-indent> --> recordbody
+# Eat up a newline, if present (this is to allow free formatting of the record).
+(recordbody|unionbody|casebody) newl --> #1
+recordbody idtypespec <force> --> recordbody
+# End rule for record, union, and case:
+(recordbody|unionbody|casebody) <outdent-force> end <"\\"-space> (record|union|case) <outdent-outdent-force> --> typespec
+
+# g. Union type. Based on "record".
+reserved union ilk union_like
+ilk union_like category union
+reserved label ilk label_like
+ilk label_like category label
+label <"\\"-space> expn colon <"\\"-space> --> labelexpn
+label colon <"\\"-space> --> labelexpn
+<force-indent-indent> union <"\\"-space> idtypespec <"\\"-space> of <force-indent> --> unionbody
+<force-indent-indent> union colon typespec <"\\"-space> of <force-indent> --> unionbody
+(unionbody|casebody) labelexpn <force> --> #1
+unionbody <indent> idtypespec <force-outdent> --> unionbody
+
+# h. Pointer type:
+reserved pointer ilk pointer_like
+ilk pointer_like category pointer
+reserved to ilk to_like
+ilk to_like category to
+pointer <"\\"-space> to <"\\"-space> expn --> typespec
+
+# i. Named type:
+# Named typed are taken care of by productions in 4.2.3, 4.2.4, and 4.3d.
+
+
+
+#----------------------------------------------------------------------------
+# Section 4.4: Subprograms and Modules.
+#----------------------------------------------------------------------------
+
+# 4.4.1. Subprogram declarations.
+# We use the auxiliary category "subproghead".
+# NOTES on the next production:
+# 1. It is extended to Turing Plus.
+# 2. It's too hard to handle the fact that a subprogram stub may be followed
+# by an import list, which must be indented, but then we must outdent, with no
+# matching "end"! So, for subprogram stubs, do the outdenting manually. Module
+# stubs, however, are handled perfectly! See the Turing+ extensions section.
+(forward|stub) <"\\"-space> subproghead --> subproghead
+reserved body ilk body_like
+ilk body_like category body
+reserved procedure ilk subprog_like
+reserved function ilk subprog_like
+ilk subprog_like category subprog
+body <"\\"-space> (subprog|module) <"\\"-space> expn* newl <force-indent> --> stmt
+
+# 2. Subprogram headers. We use the auxiliary category "parlist", defined in no. 3.
+(subprog|module) <"\\"-space> expn* --> subproghead
+# The following also handles functions that return named types.
+subproghead colon (typespec|expn) --> subproghead
+subproghead <"\\,"> open parlist close --> subproghead
+subproghead <"\\"-space> idtypespec --> subproghead
+subproghead newl <force-indent> --> stmt
+
+# 3. Parameter declarations:
+open [ (idtypespec|vcidtypespec|subproghead) ] --> open parlist
+parlist comma (idtypespec|vcidtypespec) --> parlist
+[ parlist comma subproghead ] !(open|colon) --> parlist !(open|colon)
+
+# 4. Parameter types:
+# Array parameters: see 4.3b and 4.3d.
+
+# 5. Import. This should not be so complicated!
+reserved import ilk import_like
+ilk import_like category import
+import <"\\"-space> open --> importlist
+importlist (expn|comma) --> importlist
+importlist (varconst|forward) <"\\"-space> expn --> importlist
+importlist close newl --> stmt
+
+# 6. Subprogram body:
+reserved pre ilk result_like
+reserved post ilk result_like
+# We use the auxiliary category "initstmt".
+init <"\\"-space> expn assign --> initstmt
+initstmt (expn|comma|assign) --> initstmt
+initstmt newl --> stmt
+<outdent-force> end <"\\"-space> expn newl --> stmt
+
+# 4.4.2. Module declarations:
+reserved module ilk module_like
+ilk module_like category module
+reserved export ilk import_like
+reserved opaque ilk forward_like
+
+
+
+#----------------------------------------------------------------------------
+# Section 4.5: Statements and I/O.
+#----------------------------------------------------------------------------
+
+# Statements:
+# a. Assignments.
+expn assign expn newl --> stmt
+# b. Procedure call on a line by itself.
+expn newl --> stmt
+
+# c, e, h, k, l, n:
+reserved assert ilk result_like
+reserved result ilk result_like
+reserved when ilk result_like
+reserved new ilk result_like
+reserved free ilk result_like
+reserved tag ilk result_like
+ilk result_like category result
+# Note: if the "newl" were not there, the "assert i" part of "assert i > 0"
+# would fire the production!
+result <"\\"-space> expn newl --> stmt
+
+# d, h. Return and exit:
+reserved exit ilk return_like
+reserved return ilk return_like
+ilk return_like category return
+return newl --> stmt
+return <"\\"-space> result <"\\"-space> expn newl --> stmt
+
+# j. Begin, end:
+reserved begin ilk begin_like
+ilk begin_like category begin
+<force> begin <force-indent> --> stmt
+reserved end ilk end_like
+ilk end_like category end
+<outdent-force> end newl --> stmt
+
+# f. If statements:
+reserved if ilk if_like
+ilk if_like category if
+reserved then ilk then_like
+ilk then_like category then
+reserved else ilk else_like
+ilk else_like category else
+reserved elsif ilk elsif_like
+ilk elsif_like category elsif
+if <"\\"-space> expn <"\\"-space> then <force-indent> --> stmt
+<force-outdent> else <force-indent> --> stmt
+<force-outdent> elsif <"\\"-space> expn <"\\"-space> then <force-indent> --> stmt
+# The "end if" rule is in fgm.
+
+# g. Loop statements:
+reserved loop ilk loop_like
+ilk loop_like category loop
+reserved invariant ilk result_like
+loop <force-indent> --> stmt
+# The "end loop" rule is in fgm.
+
+# i. Case statements. "Union" is used.
+reserved case ilk case_like
+ilk case_like category case
+case <"\\"-space> expn <"\\"-space> of <force-indent> --> casebody
+casebody <indent> stmt <force-outdent> --> casebody
+
+# m. For statements:
+reserved for ilk for_like
+ilk for_like category for
+reserved decreasing ilk decreasing_like
+ilk decreasing_like category decreasing
+for <"\\"-space> decreasing --> for
+for <"\\"-space> expn --> for
+for colon typespec --> for
+for newl <force-indent> --> stmt
+# The "end for" rule is in fgm.
+
+# fgm: the common "end ..." rule:
+<outdent-force> end <"\\"-space> (for|if|loop) newl --> stmt
+
+# o. Put statements:
+reserved put ilk put_like
+ilk put_like category put
+reserved skip ilk skip_like
+ilk skip_like category expn
+# Context needed for correct parsing of e.g. "put a(i)/b(i)".
+[ put <"\\"-space> expn ] !(open|star|unorbinop|binop|comma) --> put !(open|star|unorbinop|binop|comma)
+[ put colon expn ] !comma --> put !comma
+put <"\\"-space> dotdot --> put
+put newl --> stmt
+
+# p. Get statements:
+reserved get ilk get_like
+ilk get_like category get
+# A getItem.
+expn colon star --> expn
+[ get <"\\"-space> expn ] !(comma|colon|open) --> get !(comma|colon|open)
+[ get colon expn ] !(comma|colon|open) --> get !(comma|colon|open)
+get newl --> stmt
+
+# Formatting rules for statements.
+# The first rule is needed for statements separated by blank lines:
+stmt newl --> stmt
+stmt <force> stmt --> stmt
+
+
+#----------------------------------------------------------------------------
+# Section 4.6: References and Expressions.
+#----------------------------------------------------------------------------
+
+ilk expn_like category expn
+
+# 4.6.1. References:
+# a. An identifier is already an expression, hence a reference.
+# b.
+# Note: because of its role in strings, * is "star", and has to be handled explicitly.
+[ expn (star|unorbinop|binop|comma) expn ] !open --> expn !open
+expn open expn close --> expn
+open expn close --> expn
+
+# 4.6.2. Expressions:
+# b. Constants:
+reserved false ilk expn_like
+reserved true ilk expn_like
+# c. Substrings:
+open [ star ] close --> open expn close
+open [ star unorbinop expn ] close --> open expn close
+# d. Set constructors:
+expn open close --> expn
+reserved all ilk expn_like
+# e. Binary operators:
+# See 4.6.1b. However, "div" and "mod" are handled specially:
+ilk mod_like category mod
+reserved div ilk mod_like
+reserved mod ilk mod_like
+[ expn <"\\"-space> mod <"\\"-space> expn ] !open --> expn !open
+# f. Unary operators:
+!expn [ unorbinop expn ] --> !expn expn
+# g: see 4.6.1b.
+
+# Special handling of boolean expressions:
+reserved and ilk and_like
+ilk and_like category binop translation <"\\land">
+reserved or ilk or_like
+ilk or_like category binop translation <"\\lor">
+# "not" requires special handling because of "not=" and "not in".
+# First, "not" itself:
+reserved not ilk not_like
+ilk not_like category not translation <"\\">
+not <"neg"> expn --> expn
+# Now "not=":
+!not [ equal ] --> !not binop
+not <"not"> equal --> binop
+# Now "in":
+reserved in ilk in_like
+ilk in_like category in translation <"\\">
+!not [ in <"in"> ] --> !not binop
+# Finally, "not in":
+not <"not"> in <"in"> --> binop
+
+
+
+#----------------------------------------------------------------------------
+# Section 4.6.9: Predefined Functions
+#----------------------------------------------------------------------------
+
+#reserved eof ilk expn_like
+#reserved pred ilk expn_like
+#reserved succ ilk expn_like
+#reserved length ilk expn_like
+#reserved index ilk expn_like
+#reserved repeat ilk expn_like
+#reserved abs ilk expn_like
+#reserved max ilk expn_like
+#reserved min ilk expn_like
+#reserved sign ilk expn_like
+#reserved sqrt ilk expn_like
+#reserved sin ilk expn_like
+#reserved cos ilk expn_like
+#reserved arctan ilk expn_like
+#reserved sind ilk expn_like
+#reserved sind ilk expn_like
+#reserved cosd ilk expn_like
+#reserved arctand ilk expn_like
+#reserved ln ilk expn_like
+#reserved exp ilk expn_like
+#reserved floor ilk expn_like
+#reserved ceil ilk expn_like
+#reserved round ilk expn_like
+#reserved intreal ilk expn_like
+#reserved chr ilk expn_like
+#reserved ord ilk expn_like
+#reserved intstr ilk expn_like
+#reserved strint ilk expn_like
+#reserved erealstr ilk expn_like
+#reserved frealstr ilk expn_like
+#reserved realstr ilk expn_like
+#reserved strreal ilk expn_like
+
+
+#----------------------------------------------------------------------------
+# Section 4.6.10: Attributes
+#----------------------------------------------------------------------------
+
+#reserved lower ilk expn_like
+#reserved upper ilk expn_like
+#reserved nil ilk expn_like
+
+
+#----------------------------------------------------------------------------
+# Section 4.6.11: Predefined Procedures
+#----------------------------------------------------------------------------
+
+#reserved rand ilk expn_like
+#reserved randint ilk expn_like
+#reserved randomize ilk expn_like
+#reserved randnext ilk expn_like
+#reserved randseed ilk expn_like
+#reserved open ilk expn_like
+#reserved close ilk expn_like
+
+#----------------------------------------------------------------------------
+# Section 4.7: Source Inclusion Facility
+#----------------------------------------------------------------------------
+
+reserved include ilk result_like
+
+
+#----------------------------------------------------------------------------
+#----------------------------------------------------------------------------
+# Turing Plus Extensions
+#----------------------------------------------------------------------------
+#----------------------------------------------------------------------------
+
+# Separate Compilation
+# --------------------
+
+reserved child ilk result_like
+reserved parent ilk result_like
+reserved grant ilk import_like
+
+reserved stub ilk stub_like
+ilk stub_like category stub
+# For subprogram stubs, see 4.4.1.
+# Module stubs. This is nice! I am (pleasantly) surprised that it works.
+stub <"\\"-space> module <"\\"-space> expn newl <force-indent> --> modulestub
+modulestub <force> stmt <force> --> modulestub
+modulestub <force> subproghead newl <force> --> modulestub
+modulestub <outdent-force> end <"\\"-space> expn newl --> stmt
+
+# Control of checking
+# -------------------
+
+reserved checked ilk return_like
+reserved unchecked ilk return_like
+
+? ignore_scrap --> #1
+
diff --git a/web/spiderweb/src/turing/make b/web/spiderweb/src/turing/make
new file mode 100644
index 0000000000..0d9c844c17
--- /dev/null
+++ b/web/spiderweb/src/turing/make
@@ -0,0 +1,3 @@
+#!/bin/sh
+/bin/make -f ../master/WebMakefile CPUTYPE=`cputype`\
+ THETANGLE=turingtangle THEWEAVE=turingweave SPIDER=turing.spider "$@"
diff --git a/web/spiderweb/src/turing/turing.spider b/web/spiderweb/src/turing/turing.spider
new file mode 100644
index 0000000000..218c7b6ccd
--- /dev/null
+++ b/web/spiderweb/src/turing/turing.spider
@@ -0,0 +1,624 @@
+From ko@surya.ho.att.com Fri Jun 28 12:27:21 1991
+Return-Path: <ko@surya.ho.att.com>
+Received: from alpha.xerox.com by palain.PARC (4.1/SMI-4.1)
+ id AA06309; Fri, 28 Jun 91 12:27:17 PDT
+Received: from Revere.Parc.Xerox.xns by alpha.xerox.com via XNS id <11725>; Fri, 28 Jun 1991 12:22:35 PDT
+Received: from Princeton.EDU ([128.112.128.1]) by alpha.xerox.com with SMTP id <11654>; Fri, 28 Jun 1991 12:20:30 PDT
+Received: from fs.Princeton.EDU by Princeton.EDU (5.65b/2.77/princeton)
+ id AA27002; Fri, 28 Jun 91 15:20:17 -0400
+Received: from Princeton.EDU (Princeton.EDU.) by fs.Princeton.EDU (4.0/1.105)
+ id AA25725; Fri, 28 Jun 91 15:20:13 EDT
+Received: from att.att.com by Princeton.EDU (5.65b/2.77/princeton)
+ id AA26997; Fri, 28 Jun 91 15:20:07 -0400
+Received: from spark.ho.att.com by surya.ho.att.com (4.1/SMI-4.1)
+ id AA19211; Mon, 17 Jun 91 10:42:57 EDT
+Original-From: surya.ho.att.com!ko
+Received: by spark.ho.att.com (4.1/SMI-4.1)
+ id AA07125; Mon, 17 Jun 91 10:42:57 EDT
+X-Ns-Transport-Id: 08002008D0FD000D0F2A
+Date: Mon, 17 Jun 1991 07:42:57 PDT
+From: ko@surya.ho.att.com
+Subject: Turing Web
+To: att.uucp@surya.ho.att.com, nr@princeton.edu
+Message-Id: <9106171442.AA19211@surya.ho.att.com>
+Status: R
+
+ I have an updated version of Turing Web, which I enclose.
+
+ Kostas
+
+
+# Version of June 1991.
+
+# ********
+# Named types seem to be O.K.
+# Unions have to be tested with named types.
+# ********
+
+
+# Kostas N. Oikonomou, April 1990 and on ...
+# Thanks to Norman Ramsey for helpful suggestions.
+
+# NOTE: newlines are important in the WeB file. They designate the end of statements.
+
+language Turing extension t
+
+at_sign @
+
+# This says how to treat "@<...@> =" and "@<...@>". See "Specifying the
+# treatment of modules" in the Spider User's Guide.
+module definition stmt use stmt
+
+comment begin <"%"> end newline
+macros begin
+\def \commentbegin {\%}
+macros end
+
+# Line numbers are not necessary. The compiler handles the tangled output
+# with no problem. However, there is no way to turn line numbers off!
+line begin <"%"-"line"> end <"">
+
+default translation <*> mathness yes
+default mathness yes translation <*>
+
+#----------------------------------------------------------------------------
+# Tokens
+#----------------------------------------------------------------------------
+
+token identifier category expn mathness yes
+token number category expn mathness yes
+# Note: newline's have to be treated carefully; for example, if they are
+# found in math mode, webmac.tex ignores them.
+token newline category newl translation <> mathness maybe
+token pseudo_semi translation <> category semi mathness maybe
+
+token ( category open
+token ) category close
+token * category star
+token + category binop
+token . category binop
+token , category comma translation <",\\,"-opt-3>
+token - category unorbinop
+token / category binop
+# This definition seems to be needed for good formatting of labels of case statements.
+token : category colon translation <"\\mathbin{:}"> mathness yes
+token < category binop
+token = category equal
+token > category binop
+token # category expn translation <"\\#">
+token -> category binop translation <"\\rightarrow">
+token .. category dotdot translation <"\\mathbin{..}">
+# We want the exponentiation operator "**" to be formatted as "^". However,
+# "^" is defined in webmac.tex, so we need the following definition:
+token ** category binop translation <"\\char`^">
+token := category assign translation <"\\mathbin{:=}"> mathness yes
+token >= category binop translation <"\\ge">
+token <= category binop translation <"\\le">
+token @ category atsign
+
+# In the following, section references are to the Turing Report, in
+# "The Turing Programming Language: Design and Definition", 1988.
+
+#----------------------------------------------------------------------------
+# Section 4.2: Programs and Declarations
+#----------------------------------------------------------------------------
+
+# 4.2.3, 4.2.4. Constant and variable declarations. See pp. 12-13 of the
+# Spider User's Guide for the "*" s.
+reserved var ilk varconst_like
+reserved const ilk varconst_like
+ilk varconst_like category varconst
+reserved pervasive ilk pervasive_like
+ilk pervasive_like category pervasive
+varconst <"\\"-space> pervasive --> varconst
+# For "var r := 3.141":
+varconst <"\\"-space> expn* assign expn newl --> stmt
+# NOTES for the following production:
+# 1. "idtypespec" is an auxiliary category which we will also use later.
+# 2. "typespec" is defined in sec. 4.3 on types.
+# 3. See 4.6.1b for the "id, id" case.
+# 4. For the "|dotdot", see the Turing+ extensions, section 6.10.
+[ expn colon (typespec|expn) ] !dotdot --> idtypespec !dotdot
+# "vcidtypespec" is another auxiliary category, which is also used later.
+varconst <"\\"-space> idtypespec* --> vcidtypespec
+# For "var r : real", or "var x : named_type":
+vcidtypespec newl --> stmt
+# For "var r : real := 3.141":
+vcidtypespec assign expn newl --> stmt
+# Initializing value:
+reserved init ilk init_like
+ilk init_like category init
+# The context is so that the "init" rule in 4.4.6 can work.
+[ init <"\\,"> expn ] !assign --> expn !assign
+
+# 4.2.4. Collections:
+reserved collection ilk collection_like
+ilk collection_like category collection
+reserved forward ilk forward_like
+ilk forward_like category forward
+reserved of ilk of_like
+ilk of_like category of
+forward <"\\"-space> expn --> typespec
+collection <"\\"-space> of <"\\"-space> (typespec|expn) --> typespec
+
+# 4.2.5. Bindings:
+reserved bind ilk bind_like
+ilk bind_like category bind
+# We introduce the auxiliary category "binding". To correctly parse
+# "bind a to A.a", etc, we need a context:
+[ expn <"\\"-space> to <"\\"-space> expn ] !(binop|open) --> binding !(binop|open)
+varconst <"\\"-space> binding --> binding
+binding comma binding --> binding
+bind <"\\"-space> binding newl --> stmt
+
+
+#----------------------------------------------------------------------------
+# Section 4.3: Types
+#----------------------------------------------------------------------------
+
+# Type declaration:
+reserved type ilk type_like
+ilk type_like category type
+type <"\\"-space> pervasive --> type
+type <"\\"-space> idtypespec* newl --> stmt
+
+# Typespec:
+# a. Standard type:
+reserved boolean ilk typespec_like
+reserved char ilk typespec_like
+reserved int ilk typespec_like
+reserved int1 ilk typespec_like
+reserved int2 ilk typespec_like
+reserved int4 ilk typespec_like
+reserved nat ilk typespec_like
+reserved real ilk typespec_like
+reserved real4 ilk typespec_like
+reserved real8 ilk typespec_like
+ilk typespec_like category typespec
+# Strings are tricky (see 4.4.4), so define a new category:
+reserved string ilk strng_like
+ilk strng_like category strng
+[ strng ] !open --> typespec !open
+strng <"\\,"> open (expn|star) close --> typespec
+# To allow the typespec to be on a line by itself (e.g. ... newl record ... end record):
+newl typespec --> typespec
+
+# b. Subrange type. This is tricky! If the context were not there,
+# then, for example, "1..a+b" would be parsed as "typespec + b".
+# Also, note that if spaces are not left around the "..", parsing will be
+# confused because, e.g., "1..expn" is indistinguishable from "1.expn".
+# Finally, see sec. 4.6.1 for "star".
+[ expn dotdot (expn|star) ] !(binop|star|unorbinop|open) --> typespec !(binop|star|unorbinop|open)
+
+# c. Enumerated type:
+reserved enum ilk enum_like
+ilk enum_like category enum
+enum <"\\,"> expn --> typespec
+
+# d. Array type:
+reserved array ilk array_like
+ilk array_like category array
+typespec comma typespec --> typespec
+array <"\\"-space> typespec <"\\"-space> of <"\\"-space> (typespec|expn) --> typespec
+
+# e. Set type:
+reserved set ilk set_like
+ilk set_like category set
+set <"\\"-space> of <"\\"-space> typespec --> typespec
+
+# f. Record type. We use the auxiliary category "recordbody".
+# Some of the productions are also used by "union" and "case".
+reserved record ilk record_like
+ilk record_like category record
+<force-indent-indent> record <force-indent> --> recordbody
+# Eat up a newline, if present (this is to allow free formatting of the record).
+(recordbody|unionbody|casebody) newl --> #1
+recordbody idtypespec <force> --> recordbody
+# End rule for record and union:
+(recordbody|unionbody) <outdent-force> end <"\\"-space> (record|union) <outdent-outdent-force> --> typespec
+
+# g. Union type. Based on "record".
+reserved union ilk union_like
+ilk union_like category union
+reserved label ilk label_like
+ilk label_like category label
+label <"\\"-space> expn colon <"\\"-space> --> labelexpn
+label colon <"\\"-space> --> labelexpn
+<force-indent-indent> union <"\\"-space> idtypespec <"\\"-space> of <force-indent> --> unionbody
+<force-indent-indent> union colon typespec <"\\"-space> of <force-indent> --> unionbody
+(unionbody|casebody) labelexpn <force> --> #1
+unionbody <indent> idtypespec <force-outdent> --> unionbody
+
+# h. Pointer type:
+reserved pointer ilk pointer_like
+ilk pointer_like category pointer
+reserved to ilk to_like
+ilk to_like category to
+pointer <"\\"-space> to <"\\"-space> expn --> typespec
+
+# i. Named type:
+# Named typed are taken care of by productions in 4.2.3, 4.2.4, and 4.3d.
+
+
+
+#----------------------------------------------------------------------------
+# Section 4.4: Subprograms and Modules.
+#----------------------------------------------------------------------------
+
+# 4.4.1. Subprogram declarations.
+
+reserved body ilk body_like
+ilk body_like category body
+reserved procedure ilk subprog_like
+reserved function ilk subprog_like
+ilk subprog_like category subprog
+# 4.4.1 b, c.
+# NOTES on the next production:
+# 1. It is extended to Turing Plus ("stub").
+# 2. It's too hard to handle the fact that a subprogram stub may be followed
+# by an import list, which must be indented, but then we must outdent, with no
+# matching "end"! So, for
+# external, forward, and stub
+# subprograms, do the outdenting MANUALLY by @+@t\2@>.
+# Module stubs, however, are handled nicely. See the Turing+ extensions section.
+(external|forward|stub) <"\\"-space> subprog --> subprog
+
+# 4.4.1 d.
+body <"\\"-space> (subprog|module) <"\\"-space> expn* newl <force-indent> --> stmt
+
+# 2. Subprogram headers. We use the auxiliary categories "subproghead" and
+# "parlist". ("parlist" is defined in no. 3 below.)
+(subprog|module) <"\\"-space> expn* --> subproghead
+# The following also handles functions that return named types.
+subproghead colon (typespec|expn) --> subproghead
+subproghead <"\\,"> open parlist close --> subproghead
+subproghead <"\\"-space> idtypespec --> subproghead
+subproghead newl <force-indent> --> stmt
+
+# 3. Parameter declarations:
+open [ (idtypespec|vcidtypespec) ] --> open parlist
+parlist comma (idtypespec|vcidtypespec) --> parlist
+# To ensure that the "subproghead" productions above have priority:
+open [ subproghead ] !(open|colon) --> open parlist !(open|colon)
+[ parlist comma subproghead ] !(open|colon) --> parlist !(open|colon)
+
+# 4. Parameter types:
+# Array parameters: see 4.3b and 4.3d.
+
+# 5. Import. This should not be so complicated!
+reserved import ilk import_like
+ilk import_like category import
+import <"\\"-space> open --> importlist
+importlist (expn|comma) --> importlist
+importlist (varconst|forward) <"\\"-space> expn --> importlist
+importlist close newl --> stmt
+
+# 6. Subprogram body:
+reserved pre ilk result_like
+reserved post ilk result_like
+# We use the auxiliary category "initstmt".
+init <"\\"-space> expn assign --> initstmt
+initstmt (expn|comma|assign) --> initstmt
+initstmt newl --> stmt
+<outdent-force> end <"\\"-space> expn newl --> stmt
+
+# 4.4.2. Module declarations:
+reserved module ilk module_like
+ilk module_like category module
+reserved export ilk import_like
+reserved opaque ilk forward_like
+
+
+
+#----------------------------------------------------------------------------
+# Section 4.5: Statements and I/O.
+#----------------------------------------------------------------------------
+
+# Statements:
+# a. Assignments.
+expn assign expn newl --> stmt
+# b. Procedure call on a line by itself.
+expn newl --> stmt
+
+# c, e, h, k, l, n:
+reserved assert ilk result_like
+reserved result ilk result_like
+reserved when ilk result_like
+reserved new ilk result_like
+reserved free ilk result_like
+reserved tag ilk result_like
+ilk result_like category result
+# Note: if the "newl" were not there, the "assert i" part of "assert i > 0"
+# would fire the production!
+result <"\\"-space> expn newl --> stmt
+
+# d, h. Return and exit:
+reserved exit ilk return_like
+reserved return ilk return_like
+ilk return_like category return
+return newl --> stmt
+# This is for "exit when ...".
+return <"\\"-space> result <"\\"-space> expn newl --> stmt
+
+# j. Begin, end:
+reserved begin ilk begin_like
+ilk begin_like category begin
+<force> begin <force-indent> --> stmt
+reserved end ilk end_like
+ilk end_like category end
+<outdent-force> end newl --> stmt
+
+# f. If statements:
+reserved if ilk if_like
+ilk if_like category if
+reserved then ilk then_like
+ilk then_like category then
+reserved else ilk else_like
+ilk else_like category else
+reserved elsif ilk elsif_like
+ilk elsif_like category elsif
+if <"\\"-space> expn <"\\"-space> then <force-indent> --> stmt
+<force-outdent> else <force-indent> --> stmt
+<force-outdent> elsif <"\\"-space> expn <"\\"-space> then <force-indent> --> stmt
+# The "end if" rule is in fgm.
+
+# g. Loop statements:
+reserved loop ilk loop_like
+ilk loop_like category loop
+reserved invariant ilk result_like
+loop <force-indent> --> stmt
+# The "end loop" rule is in fgm.
+
+# i. Case statements. Also see "Union".
+reserved case ilk case_like
+ilk case_like category case
+case <"\\"-space> expn <"\\"-space> of <force-indent> --> casebody
+casebody <indent> stmt <force-outdent> --> casebody
+casebody <outdent-force> end <"\\"-space> case newl --> stmt
+
+# m. For statements:
+reserved for ilk for_like
+ilk for_like category for
+reserved decreasing ilk decreasing_like
+ilk decreasing_like category decreasing
+for <"\\"-space> decreasing --> for
+for <"\\"-space> expn --> for
+for colon typespec --> for
+for newl <force-indent> --> stmt
+# The "end for" rule is in fgm.
+
+# fgm: the common "end ..." rule:
+<outdent-force> end <"\\"-space> (for|if|loop) newl --> stmt
+
+# o. Put statements:
+reserved put ilk put_like
+ilk put_like category put
+reserved skip ilk skip_like
+ilk skip_like category expn
+# Context needed for correct parsing of e.g. "put a(i)/b(i)".
+[ put <"\\"-space> expn ] !(open|star|unorbinop|binop|comma) --> put !(open|star|unorbinop|binop|comma)
+[ put colon expn ] !comma --> put !comma
+put <"\\"-space> dotdot --> put
+put newl --> stmt
+
+# p. Get statements:
+reserved get ilk get_like
+ilk get_like category get
+# A getItem.
+expn colon star --> expn
+[ get <"\\"-space> expn ] !(comma|colon|open) --> get !(comma|colon|open)
+[ get colon expn ] !(comma|colon|open) --> get !(comma|colon|open)
+get newl --> stmt
+
+# Formatting rules for statements.
+# The first rule is needed for statements separated by blank lines:
+stmt newl --> stmt
+stmt <force> stmt --> stmt
+
+
+#----------------------------------------------------------------------------
+# Section 4.6: References and Expressions.
+#----------------------------------------------------------------------------
+
+ilk expn_like category expn
+
+# 4.6.1. References:
+# a. An identifier is already an expression, hence a reference.
+# b.
+# Note: because of its role in strings, * is "star", and has to be handled explicitly.
+[ expn (star|unorbinop|binop|comma) expn ] !open --> expn !open
+expn open expn close --> expn
+open expn close --> expn
+
+# 4.6.2. Expressions:
+# b. Constants:
+reserved false ilk expn_like
+reserved true ilk expn_like
+# c. Substrings:
+open [ star ] close --> open expn close
+open [ star unorbinop expn ] close --> open expn close
+# d. Set constructors:
+expn open close --> expn
+reserved all ilk expn_like
+# e. Binary operators:
+# See 4.6.1b. However, "div" and "mod" are handled specially:
+ilk mod_like category mod
+reserved div ilk mod_like
+reserved mod ilk mod_like
+[ expn <"\\"-space> mod <"\\"-space> expn ] !open --> expn !open
+# f. Unary operators:
+!expn [ unorbinop expn ] --> !expn expn
+# g: see 4.6.1b.
+
+# Special handling of boolean expressions:
+reserved and ilk and_like
+ilk and_like category binop translation <"\\land">
+reserved or ilk or_like
+ilk or_like category binop translation <"\\lor">
+# "not" requires special handling because of "not=" and "not in".
+# First, "not" itself:
+reserved not ilk not_like
+ilk not_like category not translation <"\\">
+not <"neg"> expn --> expn
+# Now "not=":
+!not [ equal ] --> !not binop
+not <"not"> equal --> binop
+# Now "in":
+reserved in ilk in_like
+ilk in_like category in translation <"\\">
+!not [ in <"in"> ] --> !not binop
+# Finally, "not in":
+not <"not"> in <"in"> --> binop
+
+
+
+#----------------------------------------------------------------------------
+# Section 4.6.9: Predefined Functions
+#----------------------------------------------------------------------------
+
+#reserved eof ilk expn_like
+#reserved pred ilk expn_like
+#reserved succ ilk expn_like
+#reserved length ilk expn_like
+#reserved index ilk expn_like
+#reserved repeat ilk expn_like
+#reserved abs ilk expn_like
+#reserved max ilk expn_like
+#reserved min ilk expn_like
+#reserved sign ilk expn_like
+#reserved sqrt ilk expn_like
+#reserved sin ilk expn_like
+#reserved cos ilk expn_like
+#reserved arctan ilk expn_like
+#reserved sind ilk expn_like
+#reserved sind ilk expn_like
+#reserved cosd ilk expn_like
+#reserved arctand ilk expn_like
+#reserved ln ilk expn_like
+#reserved exp ilk expn_like
+#reserved floor ilk expn_like
+#reserved ceil ilk expn_like
+#reserved round ilk expn_like
+#reserved intreal ilk expn_like
+#reserved chr ilk expn_like
+#reserved ord ilk expn_like
+#reserved intstr ilk expn_like
+#reserved strint ilk expn_like
+#reserved erealstr ilk expn_like
+#reserved frealstr ilk expn_like
+#reserved realstr ilk expn_like
+#reserved strreal ilk expn_like
+
+
+#----------------------------------------------------------------------------
+# Section 4.6.10: Attributes
+#----------------------------------------------------------------------------
+
+#reserved lower ilk expn_like
+#reserved upper ilk expn_like
+#reserved nil ilk expn_like
+
+
+#----------------------------------------------------------------------------
+# Section 4.6.11: Predefined Procedures
+#----------------------------------------------------------------------------
+
+#reserved rand ilk expn_like
+#reserved randint ilk expn_like
+#reserved randomize ilk expn_like
+#reserved randnext ilk expn_like
+#reserved randseed ilk expn_like
+#reserved open ilk expn_like
+#reserved close ilk expn_like
+
+#----------------------------------------------------------------------------
+# Section 4.7: Source Inclusion Facility
+#----------------------------------------------------------------------------
+
+reserved include ilk result_like
+
+#----------------------------------------------------------------------------
+# Section 4.13: External Subprograms
+#----------------------------------------------------------------------------
+
+reserved external ilk ext_like
+ilk ext_like category external
+external <"\\"-space> expn --> external
+# Now see 4.4.1.
+
+
+
+#----------------------------------------------------------------------------
+#----------------------------------------------------------------------------
+# Turing Plus Extensions: from the Turing Plus Report, August 1988.
+#----------------------------------------------------------------------------
+#----------------------------------------------------------------------------
+
+# -------------------------------
+# Section 5: Separate Compilation
+# -------------------------------
+
+reserved child ilk result_like
+reserved parent ilk result_like
+reserved grant ilk import_like
+
+reserved stub ilk stub_like
+ilk stub_like category stub
+# For subprogram stubs, see 4.4.1.
+# Module stubs. This is nice! I am (pleasantly) surprised that it works.
+stub <"\\"-space> module <"\\"-space> expn newl <force-indent> --> modulestub
+modulestub <force> stmt <force> --> modulestub
+modulestub <force> subproghead newl <force> --> modulestub
+modulestub <outdent-force> end <"\\"-space> expn newl --> stmt
+
+
+
+# --------------------------------------------------------
+# Section 6.6: Type Cheats
+# --------------------------------------------------------
+
+type <"\\,"> open (typespec|strng) comma expn close --> expn
+
+
+# --------------------------------------------------------
+# Section 6.9: External Variables and External Subprograms
+# --------------------------------------------------------
+
+# For the external subprograms, see the Turing section 4.13.
+external <"\\"-space> varconst --> varconst
+
+
+# -------------------------------------------
+# Section 6.10: Variable Number of Parameters
+# -------------------------------------------
+
+expn colon dotdot --> idtypespec
+
+# ---------------------------------------
+# Section 6.11: The Indirection Operation
+# ---------------------------------------
+
+(typespec|strng) <"\\,"> atsign <"\\,"> open expn close --> expn
+
+
+# -----------------------------------
+# Section 6.12: Addresses as Integers
+# -----------------------------------
+
+reserved addressint ilk typespec_like
+
+
+# ---------------------------------
+# Section 6.17: Control of checking
+# ---------------------------------
+
+reserved checked ilk return_like
+reserved unchecked ilk uncheck_like
+ilk uncheck_like category unchecked
+unchecked newl --> stmt
+unchecked <"\\"-space> collection --> collection
+
+
+
+? ignore_scrap --> #1
+
diff --git a/web/spiderweb/src/webkernel.tex b/web/spiderweb/src/webkernel.tex
new file mode 100644
index 0000000000..1e88863fea
--- /dev/null
+++ b/web/spiderweb/src/webkernel.tex
@@ -0,0 +1,383 @@
+% Copyright 1989-92 by Norman Ramsey, Odyssey Research Associates
+% Not to be sold, but may be used freely for any purpose
+% For more information, see file COPYRIGHT
+
+%\let\plainmark=\mark
+%\def\mark#1{\message{(Marking ``#1'')}\plainmark{#1}}
+
+% standard macros for WEB listings (in addition to PLAIN.TEX)
+% rename some old favorites
+\let\amp=\&
+\let\SS=\S
+\let\PP=\P
+\let\em=\it % compatibility with latex
+
+\newif\iftwoside\twosidefalse
+\parskip 0pt % .1pt plus 0.1pt mins 0.1pt % no stretch between paragraphs
+\parindent 1em % for paragraphs and for the first line of Pascal text
+
+\font\eightrm=cmr8
+\font\sc=cmcsc10
+\let\mainfont=\tenrm
+\font\titlefont=cmr7 scaled\magstep4 % title on the contents page
+\font\ttitlefont=cmtt10 scaled\magstep2 % typewriter type in title
+\font\tentex=cmtex10 % TeX extended character set (used in strings)
+\let\idfont\it
+\let\reservedfont\bf
+
+\def\today{\ifcase\month\or
+ January\or February\or March\or April\or May\or June\or
+ July\or August\or September\or October\or November\or December\fi
+ \space\number\day, \number\year}
+
+\def\\#1{\leavevmode\hbox{\idfont#1\/\kern.05em}} % italic type for identifiers
+\def\|#1{\leavevmode\hbox{$#1$}} % one-letter identifiers look better this way
+\def\&#1{\leavevmode\hbox{\reservedfont#1\/}} % boldface type for reserved words
+\def\.#1{\leavevmode\hbox{\tentex % typewriter type for strings
+ \let\\=\BS % backslash in a string
+ \let\'=\RQ % right quote in a string
+ \let\`=\LQ % left quote in a string
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ \let\~=\TL % tilde in a string
+ \let\ =\SP % space in a string
+ \let\_=\UL % underline in a string
+ \let\&=\AM % ampersand in a string
+ #1}}
+\def\#{\hbox{\tt\char`\#}} % parameter sign
+\def\${\hbox{\tt\char`\$}} % dollar sign
+\def\%{\hbox{\tt\char`\%}} % percent sign
+\def\^{\ifmmode\mathchar"222 \else\char`^ \fi} % pointer or hat
+% circumflex accents can be obtained from \^^D instead of \^
+\def\AT!{@} % at sign for control text
+\def\@{@} % at sign in strings
+% EVERY WEAVE MUST DEFINE \? WHERE ? IS THE AT SIGN!!!!
+
+% Macros to surround text in |...|
+\def\CD{\relax\ifmmode\let\DC\egroup\hbox\bgroup\else\let\DC\relax\fi}
+\let\DC=\relax
+
+\chardef\AM=`\& % ampersand character in a string
+\chardef\BS=`\\ % backslash in a string
+\chardef\LB=`\{ % left brace in a string
+\def\LQ{{\tt\char'22}} % left quote in a string
+\chardef\RB=`\} % right brace in a string
+\def\RQ{{\tt\char'23}} % right quote in a string
+\def\SP{{\tt\char`\ }} % (visible) space in a string
+\chardef\TL=`\~ % tilde in a string
+\chardef\UL=`\_ % underline character in a string
+
+\newbox\bak \setbox\bak=\hbox to -1em{} % backspace one em
+\newbox\bakk\setbox\bakk=\hbox to -2em{} % backspace two ems
+
+\newcount\ind % current indentation in ems
+\def\0{\ifmmode\ifinner$\par % forced break
+ \hangindent\ind em\noindent\kern\ind em\ignorespaces$\fi
+ \else\par % forced break
+ \hangindent\ind em\noindent\kern\ind em\ignorespaces\fi}
+\def\1{\global\advance\ind by1\hangindent\ind em} % indent one more notch
+\def\2{\global\advance\ind by-1} % indent one less notch
+\def\3#1{\hfil\penalty#10\hfilneg} % optional break within a statement
+\def\4{\copy\bak} % backspace one notch
+\def\5{\hfil\penalty-1\hfilneg\kern2.5em\copy\bakk\ignorespaces}% optional break
+%\def\6{\ifmmode\else\par % forced break with no indentation
+% \hangindent\ind em\noindent\kern\ind em\copy\bakk\ignorespaces\fi}
+\def\6{\ifmmode\else\par % forced break with no indentation
+ \hangindent\ind em\startline\ignorespaces\fi}
+\def\7{\Y\6} % forced break and a little extra space
+\def\8{\unskip} % no indentation--works only in code, not in |...|
+\def\startline{\noindent
+ \count255=\ind\advance\count255by-2
+ \hskip\count255 em}
+
+\let\yskip=\smallskip
+\def\note#1#2.{\Y\noindent{\hangindent2em\baselineskip10pt\eightrm#1 #2.\par}}
+\def\lapstar{\rlap{*}}
+\def\startsection{\Q\noindent{\let\*=\lapstar\bf\modstar.\quad}}
+\def\defin#1{\global\advance\ind by 2 \1\&{#1 }} % begin `define' or `format'
+\def\A{\note{See also}} % cross-reference for multiply defined section names
+\def\B{\mathopen{\.{@\commentbegin}}} % begin controlled comment
+\def\C#1{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % C comments
+ \XX\hfil\penalty-1\hfilneg\quad
+ $\commentbegin\,${#1}$\,\commentend$\XX}
+\def\D{\defin{define}} % macro definition
+\def\F{\defin{format}} % format definition
+\def\J{\.{@\&}} % TANGLE's join operation
+\outer\def\M#1.{\MN#1.\ifon\vfil\penalty-100\vfilneg % beginning of section
+ \vskip12ptminus3pt\startsection\ignorespaces}
+\outer\def\N#1.#2.{\MN#1.\headcheck#2\headcheck
+ \edef\rhead{\uppercase{\ignorespaces\themodtitle}} % define running headline
+ \message{*\modno} % progress report
+ \edef\next{\write\cont{\thetocskip
+ \Z{\theopen\relax
+ \themodtitle}{\modno}{\noexpand\the\pageno}}}\next % to contents file
+ \ifon\startsection{\bf\ignorespaces\themodtitle.\quad}\ignorespaces}
+\def\MN#1.{\par % common code for \M, \N
+ {\xdef\modstar{#1}\let\*=\empty\xdef\modno{#1}}
+ \ifx\modno\modstar \onmaybe \else\ontrue \fi \mark{\modno}}
+\def\O#1{% octal, hex or decimal constant
+ {\def\?{\kern.2em}%
+ \def\${\ell}% long constant
+ \def\_{\cdot 10^{\aftergroup}}% power of ten
+ \def\~{\hbox{\rm\char'23\kern-.2em\it\aftergroup\?\aftergroup}}% octal
+ \def\^{\hbox{\rm\char"7D\tt\aftergroup}}% double quotes for hex constant
+ #1}}
+\def\P{\rightskip=0pt plus 100pt minus 10pt % go into Pascal mode
+ \sfcode`;=3000
+ \pretolerance 10000
+ \hyphenpenalty 10000 \exhyphenpenalty 10000
+ \global\ind=2 \1\startline}%\ \unskip}
+\def\Q{\rightskip=0pt % get out of Pascal mode
+ \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50 }
+\def\T{\mathclose{\.{@\commentend}}} % terminate controlled comment
+\def\U{\note{This code is used in}} % cross-reference for uses of sections
+\def\X#1:#2\X{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % section name
+ \XX$\langle\,$#2{\eightrm\kern.5em#1}$\,\rangle$\XX}
+\def\XF#1:#2\XF{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % section name
+ \XX{\tt(#2{\eightrm\kern.5em#1})}\XX}
+\def\Y{\par\yskip}
+\def\){\hbox{\.{@\$}}} % sign for string pool check sum
+\def\]{\hbox{\.{@\\}}} % sign for forced line break
+\def\=#1{\kern2pt\hbox{\vrule\vtop{\vbox{\hrule
+ \hbox{\strut\kern2pt\.{#1}\kern2pt}}
+ \hrule}\vrule}\kern2pt} % verbatim string
+\let\~=\ignorespaces
+\let\*=*
+
+
+\def\DO{\hbox{\sl\char'044}} % slant dollar sign
+\let\G=\ge % greater than or equal sign
+\def\H{{\rm\char'136}} % hat
+\let\I=\ne % unequal sign
+\let\K=\gets % left arrow
+\let\L=\le % less than or equal sign
+\let\R=\lnot % logical not
+\let\S=\equiv % equivalence sign
+\let\TI\sim % tilde
+\let\V=\lor % logical or
+\let\W=\land % logical and
+\let\Z=\let % now you can \send the control sequence \Z
+
+
+\def\onmaybe{\let\ifon=\maybe} \let\maybe=\iftrue
+\newif\ifon \newif\iftitle \newif\ifpagesaved
+\def\lheader{\mainfont\the\pageno\eightrm\qquad\rhead\hfill\title\qquad
+ \tensy x\mainfont\topmark} % top line on left-hand pages
+\def\rheader{\tensy x\mainfont\topmark\eightrm\qquad\title\hfill\rhead
+ \qquad\mainfont\the\pageno} % top line on right-hand pages
+\def\lfooter{\hfil} % bottom line on left-hand-pages
+\def\rfooter{\hfil} % bottom line on left-hand-pages
+\def\page{\box255 }
+\def\normaloutput#1#2#3#4#5{%
+%\message{(At start top, first, and bottom marks: \topmark, \firstmark, \botmark)}%
+\shipout\vbox{
+ \iftwoside\else\ifodd\pageno\hoffset=\pageshift\fi\fi
+ \vbox to\fullpageheight{
+ \iftitle
+ \else\hbox to\pagewidth{\vbox to10pt{}%
+ \ifodd\pageno#3\else
+ \iftwoside#2\else#3\fi
+ \fi}%
+ \fi
+ \vfill#1% parameter #1 is the page itself
+ \iftitle\global\titlefalse
+ \else\baselineskip=24pt\hbox to\pagewidth{\strut % see TeXbook p256
+ \ifodd\pageno#5\else
+ \iftwoside#4\else#5\fi
+ \fi}%
+ \fi
+ }%
+}%
+\global\advance\pageno by1
+%\message{(At end top, first, and bottom marks: \topmark, \firstmark, \botmark)}%
+}
+
+
+\def\rhead{\.{WEB} OUTPUT} % this running head is reset by starred sections
+\def\title{} % an optional title can be set by the user
+\def\topofcontents{\centerline{\titlefont\title}
+ \vfill} % this material will start the table of contents page
+\def\botofcontents{\vfill} % this material will end the table of contents page
+\def\contentspagenumber{0} % default page number for table of contents
+\newdimen\pagewidth \pagewidth=6.5in % the width of each page
+\newdimen\pageheight \pageheight=8.4in % the height of each page
+\newdimen\fullpageheight \fullpageheight=9in % page height including
+ % headlines and footlines
+\newdimen\pageshift \pageshift=0in % shift righthand pages wrt lefthand ones
+\catcode`\@=11 % make at letter
+\def\m@g{\mag=\count@\pagewidth=6.5truein\pageheight=8.4truein
+ \fullpageheight=9truein\setpage}
+\catcode`\@=12 % make at other
+\def\setpage{\hsize\pagewidth\vsize\pageheight} % use after changing page size
+
+\edef\contentsfile{\jobname.toc } % file that gets table of contents info
+\def\readcontents{\expandafter\input \contentsfile}
+
+\newwrite\cont
+\output{\setbox0=\page % the first page is garbage
+ \openout\cont=\contentsfile
+ \write\cont{\string\catcode`\string\@=11}% a hack to make contents
+ % take stuff in \.{---}
+ \global\output{\normaloutput\page\lheader\rheader\lfooter\rfooter}}
+\setpage
+\vbox to \vsize{} % the first \topmark won't be null
+% Delete as per bug report from kademan@stat.wisc.edu
+% Causes headings on first page to be missing
+% \eject
+
+\def\ch{\note{The following sections were changed by the change file:}
+ \let\*=\relax}
+\newbox\sbox % saved box preceding the index
+\newbox\lbox % lefthand column in the index
+\def\inx{\par\vskip6pt plus 1fil % we are beginning the index
+ \write\cont{} % ensure that the contents file isn't empty
+ \closeout\cont % the contents information has been fully gathered
+ \output{\ifpagesaved\normaloutput{\box\sbox}\lheader\rheader
+ \lfooter\rfooter\fi
+ \global\setbox\sbox=\page \global\pagesavedtrue}
+ \pagesavedfalse \eject % eject the page-so-far and predecessors
+ \setbox\sbox\vbox{\unvbox\sbox} % take it out of its box
+ \vsize=\pageheight \advance\vsize by -\ht\sbox % the remaining height
+ \hsize=.5\pagewidth \advance\hsize by -10pt
+ % column width for the index (20pt between cols)
+ \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines
+ \def\lr{L} % this tells whether the left or right column is next
+ \output{\if L\lr\global\setbox\lbox=\page \gdef\lr{R}
+ \else\normaloutput{\vbox to\pageheight{\box\sbox\vss
+ \hbox to\pagewidth{\box\lbox\hfil\page}}}\lheader\rheader
+ \lfooter\rfooter
+ \global\vsize\pageheight\gdef\lr{L}\global\pagesavedfalse\fi}
+ \message{Index:}
+ \parskip 0pt plus .5pt
+ \outer\def\:##1, {\par\hangindent2em\noindent##1:\kern1em} % index entry
+ \def\[##1]{$\underline{##1}$} % underlined index item
+ \rm \rightskip0pt plus 2.5em \tolerance 10000 \let\*=\lapstar
+ \hyphenpenalty 10000 \parindent0pt}
+\def\fin{\par\vfill\eject % this is done when we are ending the index
+ \ifpagesaved\null\vfill\eject\fi % output a null index column
+ \if L\lr\else\null\vfill\eject\fi % finish the current page
+ \parfillskip 0pt plus 1fil
+ \def\rhead{NAMES OF THE SECTIONS}
+ \message{Section names:}
+ \output{\normaloutput\page\lheader\rheader\lfooter\rfooter}
+ \setpage
+ \def\note##1##2.{\quad{\eightrm##1 ##2.}}
+ \def\U{\note{Used in}} % cross-reference for uses of sections
+ \def\:{\par\hangindent 2em}\let\*=*}
+\def\con{\par\vfill\eject % finish the section names
+ \rightskip 0pt \hyphenpenalty 50 \tolerance 200
+ \setpage
+ \output{\normaloutput\page\lheader\rheader\lfooter\rfooter}
+ \titletrue % prepare to output the table of contents
+ \pageno=\contentspagenumber \def\rhead{TABLE OF CONTENTS}
+ \message{Table of contents:}
+ \topofcontents
+ \line{\hfil Section\hbox to3em{\hss Page}}
+ \def\Z##1##2##3{\line{{\ignorespaces##1}
+ \leaders\hbox to .5em{.\hfil}\hfil\ ##2\hbox to3em{\hss##3}}}
+ \readcontents\relax % read the contents info
+ \botofcontents \end} % print the contents page(s) and terminate
+%\tracingstats1 % temporary (during development)
+
+
+\def\vert{|}
+
+%%% this stuff is to allow inital =,1,2,3,4 in starred modules
+%%% = means ``part'', don't skip page
+%%% normal starred module is 0
+%%% 1,2,3,4 are submodules, and are indented
+%%%
+%%% @*= bold name in table of contents
+%%% causes page eject
+%%% suppresses page eject following
+%%%
+%%% @*1,2 first level of indentation
+%%% @*3,4 second level of indentation
+%%%
+%%% @*1,3 cause page eject
+%%% @*2,4 don't cause page eject
+%%%
+
+
+\newif\ifcancel\cancelfalse
+\catcode`\@=11
+\def\ifnextchar#1#2#3{\let\@tempe=#1\def\@tempa{#2}\def\@tempb{#3}\@ifnch}
+\def\@ifnch{\ifx \@tempc \@tempe\let\@tempd\@tempa\else\let\@tempd\@tempb\fi
+ \@tempd}
+\def\makethechar#1{\let\@tempc=#1}
+\catcode`\@=12
+
+\def\headcheck#1#2\headcheck{%
+ \makethechar{#1}%
+ \def\theskipper{\vfil\penalty-100\vfilneg\vskip12ptminus3pt}%
+ % skip before new module
+ \def\theopen{}% opening skip in toc entry
+ \def\thetocskip{}% vertical skip before toc entry
+ \def\themodtitle{{#2}}
+ \ifnextchar={%
+ \def\theskipper{\vfil\eject}%
+ \canceltrue
+ \def\theopen{\bf}%
+ \def\thetocskip{\vskip3ptplus1in\penalty-100
+ \vskip0ptplus-1in}%
+ }{\ifnextchar1{%
+ \cancelfalse
+ \def\theskipper{\vfil\eject}%
+ \def\theopen{\hskip2em}%
+ }{\ifnextchar2{%
+ \cancelfalse
+ \def\theopen{\hskip2em}%
+ }{\ifnextchar3{%
+ \cancelfalse
+ \def\theskipper{\vfil\eject}%
+ \def\theopen{\hskip4em}%
+ }{\ifnextchar4{%
+ \cancelfalse
+ \def\theopen{\hskip4em}%
+ }{% else
+ \ifcancel\else
+ \def\theskipper{\vfil\eject}%
+ \fi
+ \cancelfalse
+ \def\themodtitle{#1{#2}}%
+ }}}}}%
+ \theskipper
+}
+
+
+%%%%%%%% for verbatim quoting of code
+% The following are copied from manmanc.tex and are taken from p421 of
+% the TeXbook ... modified to \verbatim...\endverbatim
+% macros for verbatim scanning
+\chardef\other=12
+\def\ttverbatim{\begingroup
+ \catcode`\|=\other
+ \catcode`\\=\other
+ \catcode`\{=\other
+ \catcode`\}=\other
+ \catcode`\$=\other
+ \catcode`\&=\other
+ \catcode`\#=\other
+ \catcode`\%=\other
+ \catcode`\~=\other
+ \catcode`\_=\other
+ \catcode`\^=\other
+ \obeyspaces \obeylines \tt}
+{\obeyspaces\global\let =\ } % from texbook, p 381
+
+
+%\outer\def\verbatim{$$\let\par=\endgraf \ttverbatim \parskip=0pt
+% \catcode`\|=0 \rightskip-5pc \ttfinish}
+%{\catcode`\|=0 |catcode`|\=\other % | is temporary escape character
+% |obeylines % end of line is active
+% |gdef|ttfinish#1^^M#2\endverbatim{#1|vbox{#2}|endgroup$$}}
+
+\outer\def\verbatimcode{\par\ttverbatim\leftskip=2em\parskip=0pt
+ \ttfinishcode}
+{\catcode`\|=0 |catcode`|\=\other % | is temporary escape character
+ |obeylines % end of line is active
+ |gdef|ttfinishcode#1^^M#2\endverbatimcode{#1|vbox{#2}|endgroup}}
+
+
+% end of manmac stuff
+
diff --git a/web/spiderweb/todo b/web/spiderweb/todo
new file mode 100644
index 0000000000..d7f43e7734
--- /dev/null
+++ b/web/spiderweb/todo
@@ -0,0 +1,16 @@
+WEB CHANGES THAT WILL NEVER HAPPEN
+*) Make it possible to introduce a limited set of new @ codes.
+5) Add other web tools to the distribution
+6) give depend a -F option to list the full pathname???
+Look over tangle and add variable controlling when line numbers are
+ inserted into |tok_mem|.
+put `balance' into spider and document
+Write line number inversion tool
+Make WEAVE back-end retargetable
+Modularize WEB source in two steps: first language split, then
+ sensible code.
+To parameterize the translation of identifiers.
+To parameterize case-sensitivity of language.
+Correct TANGLE to include the proper language-dependent meta-comment support.
+Restore @\ ??
+Implement @?
diff --git a/web/spiderweb/tools/Makefile b/web/spiderweb/tools/Makefile
new file mode 100644
index 0000000000..eb2e676894
--- /dev/null
+++ b/web/spiderweb/tools/Makefile
@@ -0,0 +1,42 @@
+#
+DVI=dvi
+CFLAGS=-DDEBUG -g -DSTAT
+
+# Change the following three directories to match your installation
+
+WEBSOURCE=$(HOME)/src/web# # root of the WEB source distribution
+DEST=/usr/charybdis/ada/bin# # place where the executables go
+MACROS=$(HOME)/tex/macros# # place where the macros go
+
+MASTER=$(WEBSOURCE)/master# # master source directory
+
+CTANGLE=ceetangle -I$(MASTER)
+CWEAVE=ceeweave -I$(MASTER)
+AWKTANGLE=ktangle -I$(MASTER)
+
+depend: depend.o $(MASTER)/pathopen.o
+ cc $(CFLAGS) -o $(DEST)/depend depend.o $(MASTER)/pathopen.o
+
+depend.c: depend.web
+ $(CTANGLE) depend
+
+$(MASTER)/pathopen.c: $(MASTER)/pathopen.web # no change file
+ $(CTANGLE) $(MASTER)/pathopen
+ mv pathopen.h $(MASTER)
+
+$(MASTER)/pathopen.o: $(MASTER)/pathopen.c
+ cc $(CFLAGS) -c $(MASTER)/pathopen.c
+ mv pathopen.o $(MASTER)
+
+
+
+# This cleanup applies to every language
+
+clean:
+ if [ -f WebMakefile ]; then exit 1; fi # don't clean the master!
+ if [ -f spiderman.tex ]; then exit 1; fi # don't clean the manual!
+# -rm -f tangle.* weave.* common.* # remove links that may be obsolete
+# -rm -f *.unsorted *.list grammar.web outtoks.web scraps.web
+# -rm -f cycle.test spider.slog
+ -rm -f *.c *.o *.tex *.toc *.dvi *.log *.makelog *~ *.wlog *.printlog
+
diff --git a/web/spiderweb/tools/depend.web b/web/spiderweb/tools/depend.web
new file mode 100644
index 0000000000..42049d4947
--- /dev/null
+++ b/web/spiderweb/tools/depend.web
@@ -0,0 +1,128 @@
+\def\title{Finding dependencies in a {\tt WEB} file}
+@*Introduction.
+Often we want to know what files another {\tt WEB} file depends on, for
+use in ``{\tt make depend}.''
+This program reads a {\tt WEB} file, looking for |"@i"| at the
+beginning of a line, and writes
+the names of all of the include files on standard output.
+It searches the paths set by the |WEBPATH| environment variable.
+
+Usage is:
+$${\tt depend [-a<at-sign>] [-I<directory>] [files...]}$$
+If no at sign is specified, we use |'@@'|.
+If no files are specified, we read from standard input.
+In no case do we write the name of the file given on the command line.
+
+@ The main program just processes the arguments.
+|switchar(c)| tells whether |c| introduces an option.
+@d switchar(c) = ((c)=='-')
+@u
+#include <stdio.h>
+#include <ctype.h>
+@i pathopen.h
+static char at_sign = '@@';
+
+main(argc,argv)
+ int argc; char **argv;
+{
+ FILE *fp;
+
+ @<Read options and set |argc|, |argv| to remaining args@>@;
+
+ pathaddpath(getenv("WEBPATH"),':');
+
+ if (argc==0)
+ depend(stdin);
+ else while (argc-->0)
+ if ((fp=pathopen(*argv++))!=NULL)
+ depend(fp);
+ else {
+ fprintf(stderr,"Can't find %s on search path\n",*--argv);
+ exit(1);
+ }
+}
+
+@ @<Read options...@>=
+while (--argc>0)
+ if (switchar(**++argv))
+ switch(*++(*argv)) {
+ case 'a':
+ ++*argv;
+ @<Set |at_sign| according to |**argv|@>@;
+ break;
+ case 'I':
+ pathaddname(++(*argv));
+ break;
+ default:
+ fprintf(stderr,"Unknown option -%c\n", **argv);
+ break;
+ }
+ else break;
+
+@ Since {\tt \#} is hard to write in {\tt Makefile}, we
+let {\tt s} stand for {\tt \#}.
+@<Set |at_sign| according to |**argv|@>=
+at_sign = **argv;
+if (at_sign=='s') at_sign='#';
+
+@ All the real work is done by the recursive function |depend|, which
+searches for {\tt @@i} and prints its findings on |stdout|.
+@u
+depend (fp)
+ FILE *fp;
+{
+ int c;
+ char filename[128], *fn;
+ FILE *fp2;
+
+ c='\n'; /* begin like at the end of a line */
+ do {
+ if (c=='\n') {
+ end_line:
+ if ((c=getc(fp))==EOF) break;
+ if (c==at_sign) {
+ if ((c=getc(fp))==EOF) break;
+ if (c=='i' || c=='I') { /* live one */
+ @<Get name, print, and call |depend|@>@;
+ } else if (c=='\n') goto end_line;
+ } else if (c=='\n') goto end_line;
+ }
+ } while ((c=getc(fp))!=EOF);
+ fclose(fp);
+}
+
+@ @<Get name, print, and call |depend|@>=
+while ((c=getc(fp))!=EOF)
+ if (!isspace(c)) break;
+if (c==EOF) break;
+fn=filename;
+do {
+ if (isspace(c)) break;
+ else {
+ *fn++=c;
+ putchar(c);
+ }
+} while ((c=getc(fp))!=EOF);
+*fn='\0';
+putchar('\n');
+if ((fp2=pathopen(filename))!=NULL)
+ depend(fp2);
+else {
+ fprintf(stderr,"Can't find %s on search path\n",filename);
+ exit(1);
+}
+if (c==EOF) break;
+if (c=='\n') goto end_line;
+/* N.B. to reiterate |isspace(c)|, so |c!=at_sign| */
+
+@ Here's what |pathopen| and friends call in case of overflow.
+@u
+overflow(s)
+ char *s;
+{
+ fprintf(stderr,"Sorry, capacity exceeded: %s\n",s);
+ exit(1);
+}
+
+@*Index.
+
diff --git a/web/spiderweb/tools/excerpt/excerpt b/web/spiderweb/tools/excerpt/excerpt
new file mode 100644
index 0000000000..8a956d80c4
--- /dev/null
+++ b/web/spiderweb/tools/excerpt/excerpt
@@ -0,0 +1,54 @@
+#!/bin/sh
+# Take excerpts from a TeX file generated by Weave
+
+LIB=$HOME/lib/`cputype`
+
+if [ $# -ne 1 ]; then
+ echo "Usage: excerpt name" 1>&2
+ exit 1
+fi
+
+if [ -r $1.tex ]; then
+ lines=`sed '/^ *\([0-9]*\).*\\N[0-9]*[.] *\([^ ]\)\([^.]*\)[.].*$/!d
+/^ *\([0-9]*\).*\\N[0-9]*[.] *\([^ ]\)\([^.]*\)[.].*$/=
+s/^.*\\N[0-9]*[.] *\([^ ]\)\([^.]*\)[.].*$/\1 \2/
+' $1.tex | awk 'BEGIN { FS=" " # tab
+ OFS=" " # tab
+ level["="]=-1
+ level["1"]=1
+ level["2"]=2
+ level["3"]=3
+ level["4"]=4
+ }
+NF==1 {line=$1}
+NF==2 {
+# print "\"" $1 "\"", level[$1]
+ if (level[$1]==0) {
+ name = $1 $2
+ } else {
+ name = $2
+ }
+
+ print line
+ print level[$1]+1
+ print name
+ }' | $LIB/section`
+ while true; do
+ echo -n "Did you include the index in the excerpts [ny]? " 1>&2
+ read reply
+ if [ "$reply" = "" ]; then reply="n" ; fi
+ case $reply in
+ [ny]) break ;;
+ *) echo "respond with y or n" 1>&2 ;;
+ esac
+ done
+ echo Splitting $1.tex... 1>&2
+ $LIB/filesplit - $lines < $1.tex > $1-excerpts.tex
+ if [ "$reply" = "n" ]; then
+ echo \\inx\\fin\\con >> $1-excerpts.tex
+ fi
+else
+ echo "I can't find the file $1.tex" 1>&2
+ exit 1
+fi
+
diff --git a/web/spiderweb/tools/excerpt/excerpt.doc b/web/spiderweb/tools/excerpt/excerpt.doc
new file mode 100644
index 0000000000..1a0839cbb5
--- /dev/null
+++ b/web/spiderweb/tools/excerpt/excerpt.doc
@@ -0,0 +1,31 @@
+excerpt allows you to extract pieces of a tex file generated by weave.
+Like the TeX macros, excerpt recognizes the following hierarchy of
+section names:
+ In Text In Contents
+ #*= major division new page Bold title
+ #* ordinary section new page standard title
+ #*1 subsection new page indented
+ #*2 subsection same page indented
+ #*3 subsection new page double-indented
+ #*4 subsection same page double-indented
+
+Each kind of section is said to ``contain'' all sections below it in
+the table. Thus if you have a WEB file with a section called
+``#*=Abstract Syntax.'', that section will contain all of the sections
+up to (and not including) the next #*=. excerpt makes heavy use of
+containment.
+
+If you type `excerpt vcgen', the program will go through a list of all
+of the sections in vcgen.tex, asking you whether you want to include
+each one. You may reply `y' (yes), `n' (no), or `a' (all). Or you
+may hit the carriage return and get the default (all). The replies
+have the following meanings:
+
+ y include the section, and ask about contained subsections
+ n omit this section, along with all the sections it contains
+ a include this section and all the sections it contains
+
+The output is written to `vcgen-excerpts.tex', and must be run through
+TeX and dvi in the usual way. Of course you can use any name, not
+just vcgen.
+
diff --git a/web/spiderweb/tools/excerpt/filesplit.web b/web/spiderweb/tools/excerpt/filesplit.web
new file mode 100644
index 0000000000..23e37eaac9
--- /dev/null
+++ b/web/spiderweb/tools/excerpt/filesplit.web
@@ -0,0 +1,163 @@
+@*Splitting mailing lists.
+The object of the game is to split mailing lists into multiple files.
+Usage is
+$$\hbox{\tt filesplit prefix numbers}$$
+where {\tt prefix} is the prefix of all the output file names, and
+{\tt numbers} is a list of line numbers on which pieces of the file begin.
+The first line of the file is considered line~1
+(for compatibility with {\tt awk(1)}).
+The numbers must be sorted in increasing order.
+A section consists of material from one number to the next.
+The material is printed in a file whose name begins with the {\tt prefix},
+and which ends with a unique suffix (e.g. {\tt 00001, 00002, ...}).
+
+If a section number is preceded by a minus sign,
+the section beginning with that line number gets thrown on the floor
+instead of printed.
+
+If the prefix is |"-"|, we write all the writable sections to standard
+output.
+This makes it posssible to extract just pieces of a file.
+@<Print usage message and exit@>=
+fprintf(stderr,"Usage:\n");
+fprintf(stderr,"\tfilesplit prefix numbers...\n");
+exit(1);
+
+
+@ @c
+#include <stdio.h>
+main (argc, argv)
+ int argc;
+ char ** argv;
+{
+ char *prefix;
+ @<Variable declarations@>;
+
+
+ if (argc--<3) {
+ @<Print usage message and exit@>;
+ }
+
+ prefix = *++argv;
+ argc--, argv++;
+ @<With |argc=number count| and |argv| pointing to list, process
+ standard input into files@>;
+ exit(0);
+}
+
+@ With only one number left in the list, our job is to print from that
+line to end of file.
+Otherwise, we have two numbers, which we'll call |from_line| and |to_line|.
+We'll track the current line with |this_line|, which will be the number of
+next line schedule to be written to the output (or thrown on the floor).
+We have an implicit initial {\tt -1}, i.e. we don't print the initial
+segment of the file.
+@<Variable dec...@>=
+ int from_line, to_line;
+ int this_line; /* the number of the next line scheduled to be
+ printed */
+
+@
+@<With |argc=number count| and |argv| pointing to list, process
+ standard input into files@>=
+multi_output=1;
+@<If |prefix=="-"|, make |stdout| the output file and set |multi_output=0|@>;
+printing=0;
+from_line=0;
+this_line=1;
+while (argc!=0) {
+ @<Read an argument into |to_line|, set |next_printing|,
+ check for order,
+ and advance |argv|@>;
+ @<If |printing && multi_output|,
+ choose a name for the output file and open it@>;
+ while (this_line != to_line) {
+ @<Copy current line to output file
+ (or throw out if not |printing|)
+ and advance |this_line|,
+ jumping to |finish| on end of file@>;
+ }
+ @<If |printing && multi_output|, close the output file@>;
+ from_line = to_line;
+ printing = next_printing;
+ }
+@<If |printing && multi_output|,
+ choose a name for the output file and open it@>;
+while (1) {
+ @<Copy current line to output file...@>;
+ }
+finish:
+ @<Yelp if we ended prematurely@>;
+
+
+@ We ended prematurely if |from_line!=to_line|.
+@<Yelp...@>=
+if (from_line != to_line)
+ fprintf(stderr,"filesplit: premature end of file\n");
+
+
+
+
+@ We might as well get the details of the output files done with now.
+@<Variable dec...@>=
+ FILE *output;
+ char filename[255];
+ int sequence_number=0;
+ int multi_output;
+@ @<If |prefix=="-"|, make |stdout| the output file and set |multi_output=0|@>=
+if (!strcmp(prefix,"-")) {
+ output=stdout;
+ multi_output=0;
+ }
+
+@ @<If |printing && multi_output|, choose a name...@>=
+if (printing && multi_output) {
+ sprintf(filename,"%s%05d", prefix, sequence_number++);
+ if ((output=fopen(filename,"w"))==NULL) {
+ @<Print an error message and exit@>;
+ }
+ }
+
+@ @<If |printing && multi_output|, close the output file@>=
+if (printing && multi_output) fclose(output);
+
+@ Here's how the copying works
+@<Copy current line to output file...@>=
+while ((c=getchar())!=EOF) {
+ if (printing) putc(c,output);
+ if (c=='\n') {
+ this_line++;
+ break;
+ }
+ }
+if (c==EOF) goto finish;
+@ @<Variable dec...@>=char c;
+
+@ Since we determine sign when we read the target, we save the sign to set
+|printing| the next time around.
+@<Variable dec...@>=int printing, next_printing;
+
+
+
+@ Here's our argument processing:
+@ @<Read an argument into |to_line|...@>=
+sscanf(*argv++,"%d",&to_line); argc--;
+if (to_line<0) {
+ to_line = - to_line;
+ next_printing = 0;
+ }
+else {
+ next_printing=1;
+ }
+
+if (to_line <= from_line) {
+ fprintf(stderr,"filesplit: numbers out of order\n");
+ exit(-1);
+ }
+
+
+@ @<Print an error message and exit@>=
+fprintf(stderr,"filesplit: I couldn't open a file or something\n");
+exit(-1);
+
+@*Index.
diff --git a/web/spiderweb/tools/excerpt/section.c b/web/spiderweb/tools/excerpt/section.c
new file mode 100644
index 0000000000..355cf9a2a9
--- /dev/null
+++ b/web/spiderweb/tools/excerpt/section.c
@@ -0,0 +1,70 @@
+#include <stdio.h>
+main() {
+ FILE * ttyin, *ttyout;
+ char buffer[800];
+ char ttybuffer[80];
+ int line;
+ int level,skiplevel;
+ int skipping=0;
+ int all=0;
+ char *name = buffer;
+
+#define barf fprintf(stderr,"section: file error\n"); exit(1);
+ if (NULL==(ttyin=fopen("/dev/tty","r"))) {
+ barf;
+ }
+ if (NULL==(ttyout=fopen("/dev/tty","w"))) {
+ barf;
+ }
+ printf("1 ");
+ level=skiplevel=99;
+ while (gets(buffer)!=NULL) {
+ sscanf(buffer,"%d", &line);
+ if (gets(buffer)==NULL) {barf;}
+ sscanf(buffer,"%d", &level);
+ if (gets(buffer)==NULL) {barf;}
+/* fprintf(ttyout,"Checking level %d section on line %4d \"%s\"\n",
+/* level, line, name);
+/* fprintf(ttyout,"skipping=%d and skiplevel=%d\n", skipping,skiplevel);
+ */
+ if ((!skipping) || level <= skiplevel) {
+ if (all && level>skiplevel) {
+ fprintf(ttyout," includes \"%s\"...\n", name);
+ } else {
+ int querycount=0;
+ skiplevel=level;
+ *ttybuffer='X';
+ while (*ttybuffer !='y' && *ttybuffer != 'n' && *ttybuffer != 'a'
+ && *ttybuffer != '\0') {
+ fprintf(ttyout,"Print level %d section \"%s\" [ayn]? ",
+ level, name);
+ fflush(ttyout);
+ fgets(ttybuffer,80,ttyin);
+ if (++querycount>10) {
+ fprintf(ttyout,
+ "If you won't type 'y', 'n', 'a', or <CR>, I'll just quit\n");
+ exit(8);
+ }
+
+ }
+ if (*ttybuffer=='n') {
+ if (!skipping) printf ("%d ", -line);
+ skipping = 1;
+ all = 0;
+ } else if (*ttybuffer=='a' || *ttybuffer=='\0') {
+ if (skipping) printf ("%d ", line);
+ skipping = 0;
+ all=1;
+ } else {
+ if (skipping) printf ("%d ", line);
+ skipping = 0;
+ all=0;
+ }
+ }
+ }
+ }
+}
+
+
+
+
diff --git a/web/spiderweb/tools/shortindex b/web/spiderweb/tools/shortindex
new file mode 100644
index 0000000000..5fe0918471
--- /dev/null
+++ b/web/spiderweb/tools/shortindex
@@ -0,0 +1,3 @@
+#!/bin/csh -f
+# Make a ``short index'' for file $1
+grep "^\\:\{" $1.tex | cat ~ada/tex/indexhead.tex - ~ada/tex/indextail.tex > short$1.tex
diff --git a/web/spiderweb/tools/tie/@read@.me b/web/spiderweb/tools/tie/@read@.me
new file mode 100644
index 0000000000..9fbc4d20f5
--- /dev/null
+++ b/web/spiderweb/tools/tie/@read@.me
@@ -0,0 +1,29 @@
+This file contains a description of the files contained on the
+TIE distribution tape/diskettes and some hints for installation.
+
+If TIE is distributed together with CWEB in tape format this file is
+file number 8 on a tape.
+
+
+File Description
+ @read@.me This file
+ tie.web WEB source of the TIE processor
+ tie.chf A sample change file for TIE
+ tiedoc.tex The LaTeX source file of the TIE documentation
+
+
+Hints for installation
+
+We assume that you have a working WEB system.
+Use the sample change file to create a change file for your compiler
+and operating system.
+
+Run TANGLE to create TIE.PAS from TIE.WEB and your new change file,
+then compile TIE.PAS to obtain a working TIE processor.
+
+Run LaTeX and a driver program for your printer to create copies of the
+TIE documentation.
+
+Now the TIE processor is ready for use.
+
+
diff --git a/web/spiderweb/tools/tie/Makefile b/web/spiderweb/tools/tie/Makefile
new file mode 100644
index 0000000000..b6bf452145
--- /dev/null
+++ b/web/spiderweb/tools/tie/Makefile
@@ -0,0 +1,13 @@
+CC=lcc
+CFLAGS=-g -DDEBUG
+WEBS=character.web datadecl.web error.web history.web io.web tie.web
+DEST=.
+
+tie: tie.o
+ $(CC) $(CFLAGS) -o $(DEST)/tie tie.o
+
+tie.c: $(WEBS)
+ ceetangle tie
+
+clean:
+ -rm -f *.o *.log *.dvi *.toc *.aux tie.c tie.tex *~
diff --git a/web/spiderweb/tools/tie/cf1 b/web/spiderweb/tools/tie/cf1
new file mode 100644
index 0000000000..5b1165435c
--- /dev/null
+++ b/web/spiderweb/tools/tie/cf1
@@ -0,0 +1,14 @@
+@x
+line 2
+line 3
+@y
+changed line 2
+changed line 3
+inserted line
+@z
+
+@x
+line 7
+@y
+changed line 7
+@z
diff --git a/web/spiderweb/tools/tie/cf2 b/web/spiderweb/tools/tie/cf2
new file mode 100644
index 0000000000..386bc37587
--- /dev/null
+++ b/web/spiderweb/tools/tie/cf2
@@ -0,0 +1,19 @@
+@x
+line 1
+changed line 2
+changed line 3
+inserted line
+line 4
+@y
+final line 2
+final line 3
+changed line 4
+@z
+
+@x
+changed line 7
+line 8
+@y
+final line 7
+final line 8
+@z
diff --git a/web/spiderweb/tools/tie/cf3 b/web/spiderweb/tools/tie/cf3
new file mode 100644
index 0000000000..6c0e2458da
--- /dev/null
+++ b/web/spiderweb/tools/tie/cf3
@@ -0,0 +1,5 @@
+@x
+changed line 4
+@y
+final line 4
+@z
diff --git a/web/spiderweb/tools/tie/character.web b/web/spiderweb/tools/tie/character.web
new file mode 100644
index 0000000000..8d354334e7
--- /dev/null
+++ b/web/spiderweb/tools/tie/character.web
@@ -0,0 +1,148 @@
+@* The character set.
+One of the main goals in the design of \.{WEB} has been to make it readily
+portable between a wide variety of computers. Yet \.{WEB} by its very
+nature must use a greater variety of characters than most computer
+programs deal with, and character encoding is one of the areas in which
+existing machines differ most widely from each other.
+
+To resolve this problem, all input to \.{WEAVE} and \.{TANGLE} is converted
+to an internal seven-bit code that is essentially standard ASCII, the
+``American Standard Code for Information Interchange.'' The conversion
+is done immediately when each character is read in. Conversely,
+characters are converted from ASCII to the user's external
+representation just before they are output.
+
+Such an internal code can be accessed by users of \.{WEB} by means of
+constructions like \.{@@'A'}, which should be distinguished from
+\.{'A'}. The former is transformed by
+\.{TANGLE} into an integer that is the internal code of \.A, but
+the latter, a |char| constant, is not touched by
+\.{WEB}, and will be interpreted by the \cee\ complier according to
+the machine's character set. (Actually, of course, it gets translated
+into \.{WEB}'s internal code just like any other character in the
+input file, but then it gets translated back at output time.)
+@^ASCII code@>
+
+Here is a table of the standard visible ASCII codes (\.{ } stands for
+a blank space):
+$$\def\:{\char\count255\global\advance\count255 by 1}
+\count255='40
+\vbox{
+\hbox{\hbox to 40pt{\it\hfill0\/\hfill}%
+\hbox to 40pt{\it\hfill1\/\hfill}%
+\hbox to 40pt{\it\hfill2\/\hfill}%
+\hbox to 40pt{\it\hfill3\/\hfill}%
+\hbox to 40pt{\it\hfill4\/\hfill}%
+\hbox to 40pt{\it\hfill5\/\hfill}%
+\hbox to 40pt{\it\hfill6\/\hfill}%
+\hbox to 40pt{\it\hfill7\/\hfill}}
+\vskip 4pt
+\hrule
+\def\^{\vrule height 10.5pt depth 4.5pt}
+\halign{\hbox to 0pt{\hskip -24pt\O{#0}\hfill}&\^
+\hbox to 40pt{\tt\hfill#\hfill\^}&
+&\hbox to 40pt{\tt\hfill#\hfill\^}\cr
+04&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+05&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+06&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+07&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+10&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+11&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+12&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+13&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+14&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+15&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+16&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+17&\:&\:&\:&\:&\:&\:&\:\cr}
+\hrule width 280pt}$$
+
+We introduce new types to distinguish between the transliterated characters
+and the characters in the outside world. Let all
+``interesting'' values that a |char| variable may take lie between
+|first_text_char| and |last_text_char|; for the ASCII code we can
+take |first_text_char=0| and |last_text_char=0177|. We will tell \.{WEB}
+to convert all input characters in this range to its own code, and balk at
+characters outside the range. We make two assumptions:
+|first_text_char>=0| and |char| has room for at least eight bits.
+@^system dependencies@>
+
+@d first_text_char = 0 /* lowest interesting value of a |char| */
+@d last_text_char = 0177 /* highest interesting value of a |char| */
+
+@<Input and output types@>=
+typedef char ASCII; /* type of characters inside \.{WEB} */
+typedef char outer_char; /* type of characters outside \.{WEB} */
+
+@ The \.{WEAVE} and \.{TANGLE} processors convert between ASCII code and
+the user's external character set by means of arrays |xord| and |xchr|
+that are analogous to PASCAL's |ord| and |chr| functions.
+
+@<Globals...@>=
+ASCII xord[last_text_char]; /* specifies conversion of input characters */
+outer_char xchr[0200]; /* specifies conversion of output characters */
+
+@ Every system supporting \cee\ must be able to read and write the 95
+visible characters of standard ASCII above (although not necessarily using the
+ASCII codes to represent them). Conversely, these characters, plus
+the newline, are sufficient to write any \cee\ program. Other
+characters are desirable mainly in strings, and they can be referred
+to by means of escape sequences like \.{'\t'}.
+
+The basic implementation of \.{WEB}, then, only has to assign an
+|xord| to these 95 characters (newlines are swallowed by the reading
+routines). The easiest way to do this is to assign the characters to
+their positions in |xchr| and then invert the correspondence:
+
+@c
+common_init()
+{
+ strcpy(xchr," !\"#$%&'()*+,-./0123456789\
+:;<=>?@@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ");
+ @<System-dependent parts of character set@>;
+ @<Invert |xchr| to get |xord|@>;
+}
+
+@ The following system-independent code makes the |xord| array contain
+a suitable inverse to the information in |xchr|.
+
+@<Invert |xchr|...@>= {
+ int i; /* to invert the correspondence */
+ for (i=first_text_char; i<=last_text_char; i++) xord[i]='\040';
+ for (i=1; i<0177; i++) xord[xchr[i]]=i;
+}
+
+@ Some \cee\ compilers accept an extended character
+set, so that one can type things like \.^^Z\ instead of \.{!=}.
+If that's the case in your system, you should change this module,
+assigning positions |01| to |037| in the most convenient way;
+for example, at MIT you can just say
+$$\hbox{|for (i=1; i<=037; i++) xchr[i]=i;|}$$
+since \.{WEB}'s character set is essentially identical to MIT's,
+even with respect to characters less than |040| (see the definitions
+below). If, however, the changes do not conform with these
+definitions you should change the definitions as well.
+@^system dependencies@>
+@^notes to myself@>
+
+@<System-dependent parts of character set@>= /* nothing needs to be done */
+
+@
+@d text_char = char /* the data type of characters in text files */
+
+
+@<Input and output types@>=
+typedef char ascii_code; /* ascii codes from 0 to 127 */
+typedef FILE *text_file;
+
+
+@ One of the \ASCII{} codes below 040 has been given a
+symbolic name in \.{TIE} because it is used with a special
+meaning.
+
+@d tab_mark = '\t' /* \ASCII{} code used as tab-skip */
+
+
+@ When we initialize the |xord| array and the remaining
+parts of |xchr|, it will be convenient to make use of an
+index variable, |i|.
+
diff --git a/web/spiderweb/tools/tie/datadecl.web b/web/spiderweb/tools/tie/datadecl.web
new file mode 100644
index 0000000000..08b2ed2119
--- /dev/null
+++ b/web/spiderweb/tools/tie/datadecl.web
@@ -0,0 +1,74 @@
+@* Data structures.
+
+\noindent The multiple input files (master file and change
+files) are treated the same way. To organize the
+simultaneous usage of several input files, we introduce the
+data types |in_file_modes|.
+
+The mode |search| indicates that \.{TIE} searches for a
+match of the input line with any line of an input file in
+|reading| mode. |test| is used whenever a match is found
+and it has to be tested if the next input lines do match
+also. |reading| describes that the lines can be read without
+any check for equality to other lines. |ignore| denotes
+that the file cannot be used. This may happen because an
+error has been detected or because the end of the file has
+been found.
+
+\leavevmode |file_types| is used to describe whether a file
+is a master file or a change file.
+@d search = 1
+@d test = 2
+@d reading = 3
+@d ignore = 4
+
+@d master = 1
+@d chf = 2
+
+@<Types...@>=
+typedef char in_file_modes;
+typedef char file_types;
+
+@ We have to add a boolean type since none is present in C.
+@d true = 1
+@d false = 0
+@<Types...@>=
+typedef char boolean;
+
+@ The following data structures join all informations needed to use
+these input files.
+
+@d normal = 1
+@d pre = 2
+@d post = 3
+
+@<Types...@>=
+typedef char out_md_type;@/
+typedef char *name_type;@/
+typedef int buffer_index;
+typedef int file_index;
+typedef struct {
+ name_type name_of_file;
+ ascii_code buffer[buf_size+1];
+ in_file_modes mode;
+ int lineno;
+ file_types type_of_file;
+ int limit;
+} input_description;
+
+
+
+@ These data types are used in the global variable section.
+
+@<Globals...@>=
+int actual_input, test_input;
+boolean input_has_ended;
+ input_description input_organization[max_file_index+1];
+ text_file input_files[max_file_index+1];
+int no_ch;
+boolean prod_chf;
+out_md_type out_mode;
+int verbose = 0; /* noisy if nonzero */
+
+
+
diff --git a/web/spiderweb/tools/tie/error.web b/web/spiderweb/tools/tie/error.web
new file mode 100644
index 0000000000..6e9cb913ca
--- /dev/null
+++ b/web/spiderweb/tools/tie/error.web
@@ -0,0 +1,56 @@
+@* Reporting errors to the user.
+
+\noindent There may be errors if a line in a given change
+file does not match a line in the master file or a
+replacement in a previous change file. Such errors are
+reported to the user by saying
+$$
+ \hbox{|err_print('! Error message')|.}
+$$
+Please note that no trailing point is supplied by the error
+message because it is appended by |err_print|. Non
+recoverable errors are handled by calling |fatal_error| that
+outputs a message and then calls `|jump_out()|'.
+
+\leavevmode |err_print| will print the error message
+followed by an indication of where the error was spotted in
+the source files. |fatal_error| cannot state any files
+because the problem is usually to access these.
+
+For |err_print| messages the following procedure is used to
+write the proper name of an input file.
+
+@d fatal_error(X) = {print_nl(X); print_ln("."); history=fatal; jump_out();}
+
+@<Error handling...@>=
+ print_name_of_file(cur_index)
+ file_index cur_index;
+{
+ fprintf(stderr,"%s",input_organization[cur_index].name_of_file);
+}
+
+
+@ The actual error indications are provided by a procedure
+called |err_loc|.
+
+@<Error handling...@>=
+ err_loc(i) /* prints location of error */
+int i;
+{
+ fprintf(stderr,
+ " (file %s, l.%d).\n",input_organization[i].name_of_file,
+ input_organization[i].lineno);
+@^system dependencies@>
+}
+
+@ If it is necessary to abort the job because of a fatal
+error, the program calls the `|jump_out()|' procedure, which
+does something system-dependent.
+@^system dependencies@>
+@ The |jump_out()| procedure just cuts across all active
+procedure levels and jumps out of the program.
+It is implemented by a call to |exit()|.
+@^system dependencies@>
+
+@<Error handling...@>=
+ jump_out() { exit(history==spotless ? 0 : 1);}
diff --git a/web/spiderweb/tools/tie/history.web b/web/spiderweb/tools/tie/history.web
new file mode 100644
index 0000000000..a6a9a7ef4d
--- /dev/null
+++ b/web/spiderweb/tools/tie/history.web
@@ -0,0 +1,25 @@
+@*Job history.
+ We introduce a history variable that allows us to set a
+return code if the operating system and the local \PASCAL\
+compiler allow it. First we introduce the coded values for
+the history.
+
+@d spotless = 0
+@d troublesome = 1
+@d fatal = 2
+
+@<Globals in ...@>=
+@!int history;
+
+
+@ We must initialize this variable at the very beginning.
+
+@<Set initial values@>=
+history=spotless;
+@ At the end of the job we may want to print out the history.
+@<Print the job |history|...@>=
+switch ( history) {
+case spotless: if (verbose) print_ln("(No errors were found.)"); break;
+case troublesome: print_ln("(Pardon me, but I think I spotted something wrong.)"); break;
+case fatal: print_ln("(That was a fatal error, my friend.)"); break;
+}
diff --git a/web/spiderweb/tools/tie/io.web b/web/spiderweb/tools/tie/io.web
new file mode 100644
index 0000000000..e3dc7e894b
--- /dev/null
+++ b/web/spiderweb/tools/tie/io.web
@@ -0,0 +1,108 @@
+@* Input and output.
+
+\noindent Terminal output is done by writing on file
+|term_out|, which is assumed to consist of characters of
+type |text_char|. Terminal input is read from |term_in|.
+@^system dependencies@>
+
+@d print(X) = fprintf(stderr,X) /* `|print|' means write on the terminal */
+@d new_line = putc('\n',stderr) /* start new line */
+@d print_ln(X) = {print(X); new_line;}
+@d print_nl(X) = { new_line; print(X);}
+
+@d term_in = stdin
+@d term_out = stderr
+
+@ The |update_terminal| procedure is called when we want to
+make sure that everything we have output to the terminal so
+far has actually left the computer's internal buffers and
+been sent.
+@^system dependencies@>
+
+@d update_terminal = fflush(term_out) {empty the terminal output buffer}
+
+
+@ If an error occurs we indicate this calling a procedure
+named |err_print|. This procedure is implemented as a
+macro. It gives a message and an indication of the
+offending file. The actions to determine the error location
+will be explained later.
+
+@d err_print(MSG,LOC) = {print_nl(MSG); err_loc(LOC); history=troublesome;}
+
+
+@ The basic procedure |get_ln_from_file| can be used to get
+a line from an input file. The line is stored in
+|input_files[i].buffer|. The components |limit| and |lineno|
+are updated. If the end of the file is reached
+|input_files[i].mode| is set to |ignore|. On some systems
+it might be useful to replace tab characters by a proper
+number of spaces since several editors used to create change
+files insert tab characters into a source file not under
+control of the user. So it might be a problem to create a
+matching change file.
+@^tab character expansion@>
+
+We define |get_line| to read a line from a file specified by
+number. To ease an inplementation without arrays of files
+we introduce one more parameter. In such cases |get_line|
+is best replaced by a procedure containing a |case|
+statement to select the file needed.
+
+@d get_line(X) = get_ln_from_file(X,input_files[X]);
+
+@c
+ get_ln_from_file(i,cur_file)
+ int i;
+ text_file cur_file;
+{
+int final_limit;
+int c;
+ if (input_organization[i].mode==ignore) return;
+ if (feof(cur_file)) @<Handle end of file and return@>;
+ @<Get line into buffer@>;
+}
+
+@ End of file is special if this file is the master file.
+@<Handle end of file ...@>=
+{
+ input_organization[i].mode=ignore;
+ if (input_organization[i].type_of_file==master) input_has_ended=true;
+ return;
+}
+
+
+@ Lines must fit into the buffer completely.
+Tab character expansion might be done here.
+@^tab character expansion@>
+
+@<Get line into buffer@>=
+(input_organization[i].lineno)++;
+input_organization[i].limit=0; final_limit = 0;
+while ((input_organization[i].limit<=buf_size) && (c=getc(cur_file)) != EOF
+ && c!='\n')
+{
+ input_organization[i].buffer[input_organization[i].limit]=xord[c];
+ (input_organization[i].limit)++;
+ if ((input_organization[i].buffer[input_organization[i].limit-1]!=' ')
+ && (input_organization[i].buffer[input_organization[i].limit-1]
+ != tab_mark))
+ final_limit=input_organization[i].limit;
+}
+ if (input_organization[i].limit>buf_size)
+ if ((c=getc(cur_file))!=EOF && c!='\n') {
+ ungetc(c,cur_file); err_print("! Input line too long",i);
+@.Input line too long@>
+ }
+@<Check for end of file@>@;
+input_organization[i].limit=final_limit;
+
+@ We have to check for end of file in the middle of reading
+@<Check for end of file@>=
+if (input_organization[i].limit==0 && c==EOF)
+ @<Handle end of file...@>@;
+
+
+
+
+
diff --git a/web/spiderweb/tools/tie/master b/web/spiderweb/tools/tie/master
new file mode 100644
index 0000000000..fa2da6e55c
--- /dev/null
+++ b/web/spiderweb/tools/tie/master
@@ -0,0 +1,10 @@
+line 1
+line 2
+line 3
+line 4
+line 5
+line 6
+line 7
+line 8
+line 9
+line 10
diff --git a/web/spiderweb/tools/tie/newmaster b/web/spiderweb/tools/tie/newmaster
new file mode 100644
index 0000000000..930094b813
--- /dev/null
+++ b/web/spiderweb/tools/tie/newmaster
@@ -0,0 +1,9 @@
+final line 2
+final line 3
+final line 4
+line 5
+line 6
+final line 7
+final line 8
+line 9
+line 10
diff --git a/web/spiderweb/tools/tie/tie.c b/web/spiderweb/tools/tie/tie.c
new file mode 100644
index 0000000000..679787ad26
--- /dev/null
+++ b/web/spiderweb/tools/tie/tie.c
@@ -0,0 +1,696 @@
+/*2:*/
+#line 66 "tie.web"
+
+#include<stdio.h>
+/*56:*/
+#line 72 "character.web"
+
+typedef char ASCII;
+typedef char outer_char;
+
+/*:56*//*61:*/
+#line 133 "character.web"
+
+typedef char ascii_code;
+typedef FILE *text_file;
+
+
+/*:61*/
+#line 68 "tie.web"
+
+/*9:*/
+#line 28 "datadecl.web"
+
+typedef char in_file_modes;
+typedef char file_types;
+
+/*:9*//*10:*/
+#line 35 "datadecl.web"
+
+typedef char boolean;
+
+/*:10*//*11:*/
+#line 45 "datadecl.web"
+
+typedef char out_md_type;
+typedef char *name_type;
+typedef int buffer_index;
+typedef int file_index;
+typedef struct{
+name_type name_of_file;
+ascii_code buffer[100+1];
+in_file_modes mode;
+int lineno;
+file_types type_of_file;
+int limit;
+}input_description;
+
+
+
+/*:11*/
+#line 69 "tie.web"
+
+/*8:*/
+#line 165 "tie.web"
+
+int next_available_file= 0;
+#line 1 "datadecl.web"
+/*:8*//*12:*/
+#line 63 "datadecl.web"
+
+int actual_input,test_input;
+boolean input_has_ended;
+input_description input_organization[9+1];
+text_file input_files[9+1];
+int no_ch;
+boolean prod_chf;
+out_md_type out_mode;
+int verbose= 0;
+
+
+
+#line 168 "tie.web"
+
+
+
+
+/*:12*//*14:*/
+#line 190 "tie.web"
+boolean lines_dont_match();
+/*:14*//*16:*/
+#line 204 "tie.web"
+boolean e_of_ch_module();
+
+/*:16*//*18:*/
+#line 219 "tie.web"
+boolean e_of_ch_module();
+
+/*:18*//*21:*/
+#line 236 "tie.web"
+boolean file_open();
+
+/*:21*//*40:*/
+#line 529 "tie.web"
+long int lines_processed= 0;
+/*:40*//*49:*/
+#line 11 "history.web"
+
+int history;
+
+
+/*:49*//*57:*/
+#line 80 "character.web"
+
+ASCII xord[0177];
+outer_char xchr[0200];
+
+/*:57*/
+#line 70 "tie.web"
+
+/*52:*/
+#line 25 "error.web"
+
+print_name_of_file(cur_index)
+file_index cur_index;
+{
+fprintf(stderr,"%s",input_organization[cur_index].name_of_file);
+}
+
+
+/*:52*//*53:*/
+#line 36 "error.web"
+
+err_loc(i)
+int i;
+{
+fprintf(stderr,
+" (file %s, l.%d).\n",input_organization[i].name_of_file,
+input_organization[i].lineno);
+
+}
+
+/*:53*//*55:*/
+#line 55 "error.web"
+
+jump_out(){exit(history==0?0:1);}
+#line 1 "character.web"
+/*:55*/
+#line 71 "tie.web"
+
+
+main(argc,argv)
+int argc;
+char * *argv;
+{
+int i,j;
+
+/*50:*/
+#line 17 "history.web"
+
+history= 0;
+/*:50*/
+#line 79 "tie.web"
+
+if(verbose)
+{fprintf(stderr,"This is TIE, C Version 0.1 (ported to C)");putc('\n',stderr);};
+/*7:*/
+#line 137 "tie.web"
+
+while(--argc>0){
+if( * *++argv=='-')
+switch( *++ *argv){
+case'm':
+prod_chf= 0;
+break;
+case'c':
+prod_chf= 1;
+break;
+case'v':
+verbose++;
+break;
+default:
+fprintf(stderr,"Bad option -%c ignored\n",
+ * *argv);
+break;
+}
+else{
+if(next_available_file>9)
+{{putc('\n',stderr);fprintf(stderr,"too many files");};{fprintf(stderr,".");putc('\n',stderr);};history= 2;jump_out();};
+input_organization[next_available_file++].name_of_file= *argv;
+}
+}
+
+
+/*:7*/
+#line 83 "tie.web"
+;
+/*30:*/
+#line 374 "tie.web"
+
+common_init();
+for(i= 0;i<next_available_file;i++){
+input_organization[i].mode= 1;
+input_organization[i].lineno= 0;
+input_organization[i].type_of_file= 2;
+input_organization[i].limit= 0;
+for(j= 0;j<=100;j++)input_organization[i].buffer[j]= 0;
+}
+actual_input= 0;
+out_mode= 1;
+open_input();
+
+
+/*:30*/
+#line 84 "tie.web"
+;
+/*3:*/
+#line 93 "tie.web"
+
+input_has_ended= 0;
+while(!input_has_ended||(actual_input!=0))process_line();
+if(out_mode==3)
+write_string(stdout,"@z\n");
+/*41:*/
+#line 530 "tie.web"
+if(verbose)fprintf(stderr,"\n");
+
+
+#line 1 "io.web"
+/*:41*/
+#line 98 "tie.web"
+;
+
+
+/*:3*/
+#line 85 "tie.web"
+;
+/*4:*/
+#line 105 "tie.web"
+
+for(i= 1;i<next_available_file;i++)
+if(input_organization[i].mode!=4)
+{{putc('\n',stderr);fprintf(stderr,"! Change file entry did not match");};err_loc(i);history= 1;};
+
+
+/*:4*/
+#line 86 "tie.web"
+;
+
+/*51:*/
+#line 20 "history.web"
+
+switch(history){
+case 0:if(verbose){fprintf(stderr,"(No errors were found.)");putc('\n',stderr);};break;
+case 1:{fprintf(stderr,"(Pardon me, but I think I spotted something wrong.)");putc('\n',stderr);};break;
+case 2:{fprintf(stderr,"(That was a fatal error, my friend.)");putc('\n',stderr);};break;
+}
+#line 1 "error.web"
+/*:51*/
+#line 88 "tie.web"
+
+jump_out();
+}
+
+/*:2*//*13:*/
+#line 177 "tie.web"
+
+boolean lines_dont_match(i,j)
+int i,j;
+{
+buffer_index k,lmt;
+if(input_organization[i].limit!=input_organization[j].limit)
+return 1;
+lmt= input_organization[i].limit;
+for(k= 0;k<lmt;k++)
+if(input_organization[i].buffer[k]!=input_organization[j].buffer[k])
+return 1;
+return 0;
+}
+/*:13*//*15:*/
+#line 194 "tie.web"
+
+boolean e_of_ch_module(i)
+int i;
+{
+return((input_organization[i].limit>=2)&&
+(input_organization[i].buffer[0]=='@')&&
+((input_organization[i].buffer[1]=='Z')||
+(input_organization[i].buffer[1]=='z')));
+}
+
+/*:15*//*17:*/
+#line 209 "tie.web"
+
+boolean e_of_ch_preamble(i)
+int i;
+{
+return((input_organization[i].limit>=2)&&
+(input_organization[i].buffer[0]=='@')&&
+((input_organization[i].buffer[1]=='Y')||
+(input_organization[i].buffer[1]=='y')));
+}
+
+/*:17*//*20:*/
+#line 228 "tie.web"
+
+boolean file_open(f,name)
+text_file *f;
+name_type name;
+{
+return(( *f= fopen(name,"r"))!=NULL);
+}
+
+/*:20*//*22:*/
+#line 240 "tie.web"
+
+/*25:*/
+#line 297 "tie.web"
+
+init_change_file(i,b)
+int i;
+boolean b;
+{
+/*26:*/
+#line 312 "tie.web"
+
+while(1){
+get_ln_from_file(i,input_files[i]);;
+if(input_organization[i].mode==4)return;
+if(input_organization[i].limit<2)continue;
+if(input_organization[i].buffer[0]!='@')continue;
+if((input_organization[i].buffer[1]>='X')
+&&(input_organization[i].buffer[1]<='Z'))
+input_organization[i].buffer[1]+= 'z'-'Z';
+if(input_organization[i].buffer[1]=='x')break;
+if((input_organization[i].buffer[1]=='y')||
+(input_organization[i].buffer[1]=='z'))
+if(b)
+{{putc('\n',stderr);fprintf(stderr,"! Where is the matching @x?");};err_loc(i);history= 1;};
+
+}
+
+
+
+/*:26*/
+#line 302 "tie.web"
+;
+/*27:*/
+#line 333 "tie.web"
+
+do{
+get_ln_from_file(i,input_files[i]);;
+if(input_organization[i].mode==4){
+{{putc('\n',stderr);fprintf(stderr,"! Change file ended after @x");};err_loc(i);history= 1;};
+
+return;
+}
+}while(input_organization[i].limit<=0);
+
+
+/*:27*/
+#line 303 "tie.web"
+;
+}
+
+
+/*:25*/
+#line 241 "tie.web"
+
+open_input()
+{
+int i;
+/*23:*/
+#line 271 "tie.web"
+
+if(!file_open(&(input_files[0]),input_organization[0].name_of_file)){
+{{putc('\n',stderr);fprintf(stderr,"! Master file can\'t be opened");};{fprintf(stderr,".");putc('\n',stderr);};history= 2;jump_out();};
+}
+
+else{
+if(verbose){
+fprintf(stderr,"(");
+print_name_of_file(0);
+{fprintf(stderr,")");putc('\n',stderr);};
+}
+input_organization[0].type_of_file= 1;
+get_ln_from_file(0,input_files[0]);;
+}
+
+
+/*:23*/
+#line 245 "tie.web"
+;
+actual_input= 0;
+no_ch= 0;
+while(++no_ch<next_available_file){
+if(!file_open(&(input_files[no_ch]),input_organization[no_ch].name_of_file)){
+{{putc('\n',stderr);fprintf(stderr,"! Change file can\'t be opened");};{fprintf(stderr,".");putc('\n',stderr);};history= 2;jump_out();};
+}
+
+else{
+if(verbose){
+fprintf(stderr,"(");
+print_name_of_file(no_ch);
+{fprintf(stderr,")");putc('\n',stderr);};
+}
+init_change_file(no_ch,1);
+}
+}
+
+if(--no_ch==0)
+{{putc('\n',stderr);fprintf(stderr,"! No change file found");};{fprintf(stderr,".");putc('\n',stderr);};history= 2;jump_out();};
+
+for(i= next_available_file;i<=9;i++)
+input_organization[i].mode= 4;
+}
+
+/*:22*//*28:*/
+#line 347 "tie.web"
+
+put_line(j)
+int j;
+{
+int i;
+for(i= 0;i<input_organization[j].limit;i++)
+fputc(xchr[input_organization[j].buffer[i]],stdout);
+fputc('\n',stdout);
+}
+
+/*:28*//*29:*/
+#line 358 "tie.web"
+
+write_string(fp,s)
+text_file fp;
+char *s;
+{
+while( *s!='\0'){
+putc( *s,fp);s++;}
+}
+
+
+
+
+/*:29*//*32:*/
+#line 394 "tie.web"
+
+process_line()
+{
+int i;
+/*39:*/
+#line 521 "tie.web"
+
+if(++lines_processed%100==0&&verbose){
+if(lines_processed%500==0)
+fprintf(stderr,"%d",lines_processed);
+else
+fprintf(stderr,".");
+}
+
+/*:39*/
+#line 398 "tie.web"
+;
+/*33:*/
+#line 410 "tie.web"
+
+while(e_of_ch_module(actual_input)){
+if(input_organization[actual_input].type_of_file==1)
+
+{{putc('\n',stderr);fprintf(stderr,"! This can\'t happen");};{fprintf(stderr,".");putc('\n',stderr);};history= 2;jump_out();};
+input_organization[actual_input].mode= 1;
+init_change_file(actual_input,1);
+while((input_organization[actual_input].mode!=3)
+&&(actual_input>0))actual_input--;
+}
+if(input_has_ended&&(actual_input==0))return;
+test_input= (next_available_file);
+i= actual_input;
+while((test_input==(next_available_file))&&(i<no_ch)){
+i++;
+switch(input_organization[i].mode){
+case 1:if(!lines_dont_match(actual_input,i)){
+input_organization[i].mode= 2;
+test_input= i;
+}
+break;
+case 2:
+if(lines_dont_match(actual_input,i))
+{
+
+input_organization[i].mode= 1;
+{{putc('\n',stderr);fprintf(stderr,"! Sections do not match");};err_loc(actual_input);history= 1;};
+
+err_loc(i);
+init_change_file(i,0);
+}
+else test_input= i;
+break;
+case 3:;
+break;
+case 4:;
+break;
+}
+}
+
+
+/*:33*/
+#line 399 "tie.web"
+;
+/*34:*/
+#line 451 "tie.web"
+
+if(prod_chf){
+while(1){
+/*35:*/
+#line 464 "tie.web"
+
+{
+if(out_mode==1)
+if(test_input!=(next_available_file)){
+write_string(stdout,"@x\n");
+out_mode= 2;
+}
+else break;
+}
+
+
+/*:35*/
+#line 454 "tie.web"
+;
+/*36:*/
+#line 477 "tie.web"
+
+{
+if(out_mode==2){
+if(test_input==(next_available_file)){
+write_string(stdout,"@y\n");
+out_mode= 3;
+}else{
+if(input_organization[actual_input].type_of_file==1)
+put_line(actual_input);
+break;
+}
+}
+}
+
+
+/*:36*/
+#line 455 "tie.web"
+;
+/*37:*/
+#line 494 "tie.web"
+
+{
+if(out_mode==3){
+if(input_organization[actual_input].type_of_file==2){
+if(test_input==(next_available_file))put_line(actual_input);
+break;
+}else{
+write_string(stdout,"@z\n");
+out_mode= 1;
+}
+}
+}
+
+
+/*:37*/
+#line 456 "tie.web"
+;
+}
+}else
+if(test_input==(next_available_file))put_line(actual_input);
+
+
+/*:34*/
+#line 400 "tie.web"
+;
+/*38:*/
+#line 508 "tie.web"
+
+get_ln_from_file(actual_input,input_files[actual_input]);;
+if(test_input!=(next_available_file)){
+get_ln_from_file(test_input,input_files[test_input]);;
+if(e_of_ch_preamble(test_input)){
+get_ln_from_file(test_input,input_files[test_input]);;
+input_organization[test_input].mode= 3;
+actual_input= test_input;
+test_input= (next_available_file);
+}
+}
+
+/*:38*/
+#line 402 "tie.web"
+;
+}
+
+
+/*:32*//*45:*/
+#line 54 "io.web"
+
+get_ln_from_file(i,cur_file)
+int i;
+text_file cur_file;
+{
+int final_limit;
+int c;
+if(input_organization[i].mode==4)return;
+if(feof(cur_file))/*46:*/
+#line 67 "io.web"
+
+{
+input_organization[i].mode= 4;
+if(input_organization[i].type_of_file==1)input_has_ended= 1;
+return;
+}
+
+
+/*:46*/
+#line 62 "io.web"
+;
+/*47:*/
+#line 79 "io.web"
+
+(input_organization[i].lineno)++;
+input_organization[i].limit= 0;final_limit= 0;
+while((input_organization[i].limit<=100)&&(c= getc(cur_file))!=EOF
+&&c!='\n')
+{
+input_organization[i].buffer[input_organization[i].limit]= xord[c];
+(input_organization[i].limit)++;
+if((input_organization[i].buffer[input_organization[i].limit-1]!=' ')
+&&(input_organization[i].buffer[input_organization[i].limit-1]
+!='\t'))
+final_limit= input_organization[i].limit;
+}
+if(input_organization[i].limit>100)
+if((c= getc(cur_file))!=EOF&&c!='\n'){
+ungetc(c,cur_file);{{putc('\n',stderr);fprintf(stderr,"! Input line too long");};err_loc(i);history= 1;};
+
+}
+/*48:*/
+#line 101 "io.web"
+
+if(input_organization[i].limit==0&&c==EOF)
+/*46:*/
+#line 67 "io.web"
+
+{
+input_organization[i].mode= 4;
+if(input_organization[i].type_of_file==1)input_has_ended= 1;
+return;
+}
+
+
+/*:46*/
+#line 103 "io.web"
+
+
+
+
+
+
+#line 1 "history.web"
+/*:48*/
+#line 97 "io.web"
+
+input_organization[i].limit= final_limit;
+
+/*:47*/
+#line 63 "io.web"
+;
+}
+
+/*:45*//*58:*/
+#line 96 "character.web"
+
+common_init()
+{
+strcpy(xchr," !\"#$%&'()*+,-./0123456789\
+:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ");
+/*60:*/
+#line 127 "character.web"
+
+
+/*:60*//*64:*/
+#line 551 "tie.web"
+
+#line 552 "tie.web"
+xchr['\t']= '\t';
+
+
+/*:64*/
+#line 101 "character.web"
+;
+/*59:*/
+#line 108 "character.web"
+{
+int i;
+for(i= 0;i<=0177;i++)xord[i]= '\040';
+for(i= 1;i<0177;i++)xord[xchr[i]]= i;
+}
+
+/*:59*/
+#line 102 "character.web"
+;
+}
+
+/*:58*/
diff --git a/web/spiderweb/tools/tie/tie.chf b/web/spiderweb/tools/tie/tie.chf
new file mode 100644
index 0000000000..c7c75980c0
--- /dev/null
+++ b/web/spiderweb/tools/tie/tie.chf
@@ -0,0 +1,191 @@
+@x
+@d banner=='This is TIE, Version 1.3'
+@y
+@d banner=='This is TIE, Version 1.3 (MUNIX changes by THD/ITI)'
+@z
+
+@x
+@!max_name_length=54; {adapt this to your local name space}
+@y
+@!max_name_length=120; {adapt this to your local name space}
+@z
+
+@x
+@!ascii_code=0..127; {seven-bit numbers, a subrange of the integers}
+@y
+@!ascii_code=packed 0..127;
+@z
+
+@x
+@!text_file=packed file of text_char;
+@y
+@!text_file=text;
+@z
+
+@x
+xchr["\"]:='\';
+@y
+xchr["\"]:='\\';
+@z
+
+@x
+for i:=1 to @'37 do xchr[i]:=' ';
+@y
+for i:=1 to @'37 do xchr[i]:=' ';
+xchr[tab_mark]:=chr(tab_mark);
+@z
+
+@x
+reset(term_in,'TTY:','/I')
+@y
+reset(term_in,'/dev/tty')
+@z
+
+@x
+rewrite(term_out,'TTY:');
+@y
+rewrite(term_out,'/dev/tty');
+@z
+
+@x
+@d update_terminal == break(term_out) {empty the terminal output buffer}
+@y
+@d update_terminal == write_ln(term_out) {empty the terminal output buffer}
+@z
+
+Delete definition of |get_line|. Replace by procedure.
+@x
+@d get_line(#)==get_ln_from_file(#,input_files[#]);
+@y
+@z
+
+Add the definition now
+@x
+exit: end;
+@y
+exit: end;
+
+procedure get_line(i:file_index);@/
+begin
+ case i of
+ 0 : get_ln_from_file(0,infile0);
+ 1 : get_ln_from_file(1,infile1);
+ 2 : get_ln_from_file(2,infile2);
+ 3 : get_ln_from_file(3,infile3);
+ 4 : get_ln_from_file(4,infile4);
+ 5 : get_ln_from_file(5,infile5);
+ 6 : get_ln_from_file(6,infile6);
+ 7 : get_ln_from_file(7,infile7);
+ 8 : get_ln_from_file(8,infile8);
+ 9 : get_ln_from_file(9,infile9);
+ end;
+end;
+@z
+
+@x
+@!input_files: array[0..max_file_index] of text_file;
+@y
+@!infile0,@!infile1,@!infile2,@!infile3,@!infile4,@!infile5:text_file;
+@!infile6,@!infile7,@!infile8,@!infile9:text_file;
+@z
+
+@x
+@ We continue with a function to open a text file. Success
+is indicated by a boolean result. We assume that empty
+files can be handled like non existent ones.
+@^system dependencies@>
+
+@p function file_open(var f:text_file;name:name_type):boolean;
+begin
+ reset(f,name.name);
+ file_open:=not eof(f);
+end;
+@y
+@ We continue with a function to open a text file. Success
+is indicated by a boolean result. We assume that empty
+files can be handled like non existent ones.
+@^system dependencies@>
+We use a special function to determine missing files.
+@p function lookop(var n:string):integer; externc;
+function file_open(var f:text_file;name:name_type):boolean;@/
+var curname:string;
+begin
+ curname:=con@&vert(name.name,string);
+ if lookop(curname)=1 then
+ begin
+ reset(f,curname);
+ file_open:=not eof(f);
+ end else file_open:=false;
+end;
+@z
+
+@x
+ for i:=1 to max_name_length do name_of_file.name[i]:=' ';
+ for i:=1 to prefix.nam_len do name_of_file.name[i]:=prefix.name[i];
+ for i:=1 to extension.nam_len do
+ name_of_file.name[prefix.nam_len+i]:=extension.name[i];
+@y
+ for i:=1 to prefix.nam_len do name_of_file.name[i]:=prefix.name[i];
+ for i:=1 to extension.nam_len do
+ name_of_file.name[prefix.nam_len+i]:=extension.name[i];
+ name_of_file.name[prefix.nam_len+extension.nam_len+1]:=chr(0);
+@z
+
+@x
+ if not file_open(input_files[0],input_organization[0].name_of_file) then
+@y
+ if not file_open(infile0,input_organization[0].name_of_file) then
+@z
+
+@x
+procedure open_input; {prepare to read |input_files|}
+label done;
+var i:integer;
+@y
+procedure open_input; {prepare to read |input_files|}
+label done;
+var i:integer;
+ b:boolean;
+@z
+
+@x
+ if not file_open(input_files[no_ch],
+ input_organization[no_ch].name_of_file)
+@y
+ case no_ch of
+ 1: b:=file_open(infile1,input_organization[1].name_of_file);
+ 2: b:=file_open(infile2,input_organization[2].name_of_file);
+ 3: b:=file_open(infile3,input_organization[3].name_of_file);
+ 4: b:=file_open(infile4,input_organization[4].name_of_file);
+ 5: b:=file_open(infile5,input_organization[5].name_of_file);
+ 6: b:=file_open(infile6,input_organization[6].name_of_file);
+ 7: b:=file_open(infile7,input_organization[7].name_of_file);
+ 8: b:=file_open(infile8,input_organization[8].name_of_file);
+ 9: b:=file_open(infile9,input_organization[9].name_of_file);
+ end;
+ if not b
+@z
+
+@x
+cf_ext.name[1]:='.';
+cf_ext.name[2]:='C';
+cf_ext.name[3]:='F';
+cf_ext.name[4]:=' ';
+cf_ext.nam_len:=4;
+for i:=cf_ext.nam_len+1 to max_name_length do cf_ext.name[i]:=' ';
+@y
+cf_ext.name[1]:='.';
+cf_ext.name[2]:='c';
+cf_ext.name[3]:='f';
+cf_ext.name[4]:=' ';
+cf_ext.name[5]:=chr(0);
+cf_ext.nam_len:=4;
+@z
+
+@x
+ {here files should be closed if the operating system requires it}
+@y
+ {here files should be closed if the operating system requires it}
+ {terminate with return code}
+ halt(history);
+@z
diff --git a/web/spiderweb/tools/tie/tie.preamble b/web/spiderweb/tools/tie/tie.preamble
new file mode 100644
index 0000000000..d559d506d6
--- /dev/null
+++ b/web/spiderweb/tools/tie/tie.preamble
@@ -0,0 +1,31 @@
+
+\def\hang{\hangindent 3em\indent\ignorespaces}
+\font\mc=cmcsc10
+\def\PASCAL{{\mc Pascal}}
+\def\cee{{\mc C}}
+\def\ASCII{{\mc ascii}}
+\def\pb{$\.|\ldots\.|$} % pascal brackets (|...|)
+\def\v{\.{\char'174}} % vertical (|) in typewriter font
+\mathchardef\BA="3224 % double arrow
+\def\({} % kludge for alphabetizing certain module names
+
+\def\title{TIE}
+\def\topofcontents{\null\vfill
+ \centerline{\titlefont The {\ttitlefont TIE} processor}
+ \vskip 15pt
+ \centerline{(Version 1.3)}
+ \vfill}
+\def\botofcontents{
+\null\vfill
+\item{$\copyright$}1983, 1984, 1986
+ by Technische Hochschule Darmstadt,\hfill\break
+Fachbereich Informatik, Institut f\"ur Theoretische Informatik\hfill\break
+All rights reserved.\hfill\break
+This program is put into the public domain and may be used freely
+for any non commercial purposes.
+}
+
+
+
+
+
diff --git a/web/spiderweb/tools/tie/tie.web b/web/spiderweb/tools/tie/tie.web
new file mode 100644
index 0000000000..24594a4f3e
--- /dev/null
+++ b/web/spiderweb/tools/tie/tie.web
@@ -0,0 +1,558 @@
+% This is TIE.WEB
+%------------------------------------------------------------
+
+% Version 0.1 ported from PASCAL (NR) 24 August 87
+
+% Here is TeX material that gets inserted after \input webmac
+@i tie.preamble
+
+@* Introduction.
+
+\noindent Whenever a programmer wants to change a given
+\.{WEB} program because of system dependencies, he will
+create a new change file. In addition there may be a second
+change file to modify system independent modules of the
+program. But the \.{WEB} file cannot be tangled and weaved
+with more than one change file simultaneously. Therefore,
+we introduce the present program to merge a \.{WEB} file and
+several change files producing a new \.{WEB} file. Since
+the input files are tied together, the program is called
+\.{TIE}. Furthermore, the program can be used to merge
+several change files giving a new single change file. This
+method seems to be more important because it doesn't modify
+the original source file. The use of \.{TIE} can be
+expanded to other programming languages since this processor
+only knows about the structure of change files and does not
+interpret the master file at all.
+
+The program \.{TIE} has to read lines from several input
+files to bring them in some special ordering. For this
+purpose an algorithm is used which looks a little bit
+complicated. But the method used only needs one buffer line
+for each input file. Thus the storage requirement of
+\.{TIE} does not depend on the input data.
+
+The program uses only few features of the local \PASCAL\
+compiler that may need to be changed in other installations.
+The changes needed may be similar to those used to change
+the \.{WEB} processors \.{TANGLE} and \.{WEAVE}. All places
+where changes may be needed are listed in the index under
+the entry ``system dependencies''.
+@!@^system dependencies@>
+
+This version of \.{TIE} has been ported from a \PASCAL version
+{$\copyright$}1983, 1984, 1986 by Technische Hochschule Darmstadt,
+Fachbereich Informatik, Institut f\"ur Theoretische Informatik.
+No attempt has been made to take advantage of the many nice features
+of C (for example to remove the restriction on the number of change
+files).
+There is no warranty, express or implied.
+
+The ``banner line'' defined here should be changed whenever
+\.{TIE} is modified. This program is put into the public
+domain. Nevertheless the copyright notice must not be
+replaced or modified.
+
+
+
+@d banner = "This is TIE, C Version 0.1 (ported to C)"
+
+@ Here is where \.{TIE} starts, and where it ends.
+If a command line interface is present, changes to
+initialize the access might be needed here.
+@^system dependencies@>
+@^command line processing@>
+
+@c
+#include <stdio.h>
+@<Input and output types@>@;
+@<Types in the outer block@>@;
+@<Globals in the outer block@>@;
+@<Error handling procedures@>@;
+@#
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int i,j;
+
+ @<Set initial values@>@;
+ if (verbose)
+ print_ln(banner); /* print a ``banner line'' */
+ @<Read the arguments, setting the master file, the change files,
+ and any options@>;
+ @<Initialize the input system@>;
+ @<Process the input@>;
+ @<Check that all changes have been read@>;
+ /* here files should be closed if the operating system requires it */
+ @<Print the job |history| if |verbose| is appropriate@>
+ jump_out();
+}
+
+@ The guts of the program are simple: we drag each line through the mud:
+@<Process the input@>=
+input_has_ended=false;
+while (!input_has_ended || (actual_input!=0)) process_line();
+if (out_mode == post) /* last line has been changed */
+ write_string(out_file,"@@z\n");
+@<Write carriage return for end of counts@>;
+
+
+@ At the end of the program, we will tell the user if a
+change file had a line that didn't match any relevant line
+in the master file.
+
+@<Check that all changes have been read@>=
+for (i=1; i<next_available_file; i++) /* all change files */
+ if (input_organization[i].mode != ignore)
+ err_print("! Change file entry did not match",i);
+@.Change file entry ...@>
+
+@ Here are some macros for common programming idioms.
+
+@d loop = while (true)
+@d do_nothing = /* empty statement */
+@f loop while
+
+
+@ The following parameters should be sufficient for most
+applications of \.{TIE}. Note that |max_file_index| should
+not be enlarged without changing the processing of change
+file names.
+@^system dependencies@>
+
+@d buf_size = 100 /* maximum length of one input line*/
+@d max_file_index = 9/* we dont think that anyone needs more than 9 change files*/
+@d max_name_length = 54 /* adapt this to your local name space*/
+
+
+@* Handling multiple change files.
+We read the master and change files from the argument vector.
+The master file is first, followed by (eventually any number) up to 9
+change files.
+The only options are |"-m"| to produce a master file, and |"-c"| to
+produce a change file.
+The last one wins.
+
+@<Read the arguments...@>=
+while (--argc>0) {
+ if (**++argv=='-')
+ switch (*++*argv) {
+ case 'm':
+ prod_chf=false;
+ break;
+ case 'c':
+ prod_chf=true;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ default:
+ fprintf(stderr, "Bad option -%c ignored\n",
+ **argv);
+ break;
+ }
+ else {
+ if (next_available_file > max_file_index)
+ fatal_error("too many files");
+ input_organization[next_available_file++].name_of_file=*argv;
+ }
+}
+
+
+@ |next_available_file| tells us what file numebr is available as
+a change file.
+@<Globals...@>=
+int next_available_file=0;
+@i datadecl.web
+
+
+
+
+@*Routines that test input/output conditions.
+
+\noindent Here's a simple function that checks if two lines
+are different.
+
+@c
+boolean lines_dont_match(i,j)
+ int i,j;
+{
+ buffer_index k, lmt;
+ if (input_organization[i].limit != input_organization[j].limit)
+ return true;
+ lmt=input_organization[i].limit;
+ for (k=0; k<lmt; k++)
+ if (input_organization[i].buffer[k] != input_organization[j].buffer[k])
+ return true;
+ return false;
+}
+@ @<Globals...@>=boolean lines_dont_match();
+@ The function |e_of_ch_module| returns true if the input
+line from file |i| is equal to \.{@@z}.
+
+@c
+boolean e_of_ch_module(i)
+ int i;
+{
+ return ((input_organization[i].limit>=2) &&
+ (input_organization[i].buffer[0]=='@@') &&
+ ((input_organization[i].buffer[1]=='Z') ||
+ (input_organization[i].buffer[1]=='z')));
+}
+
+@ @<Globals...@>=boolean e_of_ch_module();
+
+@ The function |e_of_ch_preamble| returns true if the input
+line from file |i| is equal to \.{@@y}.
+
+@c
+boolean e_of_ch_preamble(i)
+ int i;
+{
+ return ((input_organization[i].limit>=2) &&
+ (input_organization[i].buffer[0]=='@@') &&
+ ((input_organization[i].buffer[1]=='Y') ||
+ (input_organization[i].buffer[1]=='y')));
+}
+
+@ @<Globals...@>=boolean e_of_ch_module();
+
+@*Routines that manipulate input and output.
+
+@ We continue with a function to open a text file. Success
+is indicated by a boolean result. We assume that empty
+files can be handled like non existent ones.
+@^system dependencies@>
+
+@c
+boolean file_open(f,name)
+ text_file *f;
+ name_type name;
+{
+ return ((*f=fopen(name,"r"))!=NULL);
+}
+
+@ @<Globals...@>=boolean file_open();
+
+@ This procedure opens all the input files.
+
+@c
+@<Procedures for |open_input|@>@;@%
+ open_input() /* prepare to read |input_files| */
+{
+int i;
+ @<Get the master file started@>;
+ actual_input=0;
+no_ch=0;
+while (++no_ch<next_available_file) {
+ if (!file_open(&(input_files[no_ch]),input_organization[no_ch].name_of_file)) {
+ fatal_error("! Change file can\'t be opened");
+ }
+@.Change file can't be opened@>
+ else {
+ if (verbose) {
+ print("(");
+ print_name_of_file(no_ch);
+ print_ln(")");
+ }
+ init_change_file(no_ch,true);
+ }
+}
+
+ if (--no_ch==0)
+ fatal_error("! No change file found");
+@.No change file found@>
+ for (i=next_available_file; i<=max_file_index; i++)
+ input_organization[i].mode=ignore;
+}
+
+@ The master file is actually started just like the change files.
+@<Get the master file started@>=
+ if (!file_open(&(input_files[0]),input_organization[0].name_of_file)) {
+ fatal_error("! Master file can\'t be opened");
+ }
+@.Master file can't be opened@>
+ else {
+ if (verbose) {
+ print("(");
+ print_name_of_file(0);
+ print_ln(")");
+ }
+ input_organization[0].type_of_file = master;
+ get_line(0);
+}
+
+
+@ The main output goes to |out_file|.
+@d out_file = stdout
+
+
+@ Procedure |init_change_file(i,b)| is used to ignore all
+lines of the input file with index |i| until the next change
+module is found. The boolean parameter |b| indicates
+whether we do not want to see "@@x" or "@@y" entries during
+our skip.
+
+@<Procedures for |open_input|@>=
+ init_change_file(i,b)
+ int i;
+ boolean b;
+{
+ @<Skip over comment lines; |return| if end of file@>;
+ @<Skip to the next nonblank line; |return| if end of file@>;
+}
+
+
+@ While looking for a line that begins with \.{@@x} in the
+change file, we allow lines that begin with \.{@@}, as long
+as they don"t begin with \.{@@y} or \.{@@z} (which would
+probably indicate that the change file is fouled up).
+
+@<Skip over comment lines...@>=
+loop {
+ get_line(i);
+ if (input_organization[i].mode==ignore) return;
+ if (input_organization[i].limit<2) continue;
+ if (input_organization[i].buffer[0] != '@@') continue;
+ if ((input_organization[i].buffer[1]>='X')
+ && (input_organization[i].buffer[1]<='Z'))
+ input_organization[i].buffer[1] += 'z'-'Z'; /* lowercasify */
+ if (input_organization[i].buffer[1]=='x') break;
+ if ((input_organization[i].buffer[1]=='y') ||
+ (input_organization[i].buffer[1]=='z'))
+ if (b) /* waiting for start of change */
+ err_print("! Where is the matching @@x?",i);
+@.Where is the match...@>
+}
+
+
+
+@ Here we are looking at lines following the \.{@@x}.
+
+@<Skip to the next nonblank line...@>=
+do {
+ get_line(i);
+ if (input_organization[i].mode==ignore) {
+ err_print("! Change file ended after @@x",i);
+@.Change file ended...@>
+ return;
+ }
+} while (input_organization[i].limit<=0);
+
+
+@ The |put_line| procedure is used to write a line from
+input buffer |j| to the output file.
+
+@c
+ put_line(j)
+ int j;
+{
+ int i; /* index into the buffer */
+ for (i=0; i<input_organization[j].limit; i++)
+ fputc(xchr[input_organization[j].buffer[i]],out_file);
+ fputc('\n',out_file);
+}
+
+@ Writing strings to the output
+@c
+write_string(fp, s)
+ text_file fp;
+ char *s;
+{
+ while (*s != '\0') {
+ putc(*s,fp);s++;}
+}
+
+
+
+
+@ To start with our inputs we set the indication that all
+change files are in state |search|. That means that we must
+skip to the next (in this case the first) change entry.
+
+@<Initialize the input system@>=
+common_init();
+for (i=0; i<next_available_file; i++) {
+ input_organization[i].mode=search;
+ input_organization[i].lineno=0;
+ input_organization[i].type_of_file=chf;
+ input_organization[i].limit=0;
+ for (j=0 ; j<= buf_size; j++) input_organization[i].buffer[j]=0;
+ }
+actual_input=0;
+out_mode=normal;
+ open_input();
+
+
+@*The major line-eating routines.
+@ To process the input file the procedure |process_line|
+reads a line of the actual input file and updates the
+|input_organization| for all files with index |i| greater
+|actual_input|.
+
+@c
+process_line()
+{
+ int i;
+ @<Count lines processed, and shout at each hundred@>;
+ @<Set |actual_input| and |test_input|, and set their modes@>;
+ @<Write one (decorated) line of output, and set output mode@>;
+ @<Read lines from |actual_input|
+ (and |test_input| if necessary, checking for preamble end)@>;
+}
+
+
+@ If |test_input| is |none|, no change file is tested.
+
+@d none = (next_available_file)
+
+@<Set |actual_input| and |test_input|, and set their modes@>=
+while (e_of_ch_module(actual_input)) {
+ if (input_organization[actual_input].type_of_file==master)
+ /* emergency exit, everything mixed up! */
+ fatal_error("! This can\'t happen");
+ input_organization[actual_input].mode=search;
+ init_change_file(actual_input,true);
+ while ((input_organization[actual_input].mode!=reading)
+ && (actual_input>0)) actual_input--;
+}
+if (input_has_ended && (actual_input==0)) return;
+test_input=none;
+i=actual_input;
+while ((test_input==none) && (i<no_ch)) {
+ i++;
+ switch (input_organization[i].mode) {
+case search: if (!lines_dont_match(actual_input,i)) {
+ input_organization[i].mode=test;
+ test_input=i;
+ }
+ break;
+case test:
+ if (lines_dont_match(actual_input, i))
+ {
+ /* error, modules do not match */
+ input_organization[i].mode=search;
+ err_print("! Sections do not match",actual_input);
+@.Sections do not match@>
+ err_loc(i);
+ init_change_file(i,false);
+ }
+ else test_input=i;
+ break;
+case reading:do_nothing; /* this can't happen */
+ break;
+case ignore: do_nothing; /* nothing to do */
+ break;
+}
+}
+
+
+@ @<Write one (decorated) line of output, and set output mode@>=
+if (prod_chf) {
+ loop {
+ @<Test for normal@>;
+ @<Test for pre@>;
+ @<Test for post@>;
+}
+} else
+if (test_input==none) put_line(actual_input);
+
+
+@ Check whether we have to start a change file entry.
+
+@<Test for normal@>=
+{
+ if (out_mode==normal)
+ if (test_input!=none) {
+ write_string(out_file,"@@x\n");
+ out_mode=pre;
+ }
+ else break;
+}
+
+
+@ Check whether we have to start the replacement text.
+
+@<Test for pre@>=
+{
+ if (out_mode==pre) {
+ if (test_input==none) {
+ write_string(out_file,"@@y\n");
+ out_mode=post;
+ } else {
+ if (input_organization[actual_input].type_of_file==master)
+ put_line(actual_input);
+ break;
+ }
+ }
+}
+
+
+@ Check whether a change file entry is complete.
+
+@<Test for post@>=
+{
+ if (out_mode==post) {
+ if (input_organization[actual_input].type_of_file==chf) {
+ if (test_input==none) put_line(actual_input);
+ break;
+ } else {
+ write_string(out_file,"@@z\n");
+ out_mode=normal;
+ }
+ }
+}
+
+
+@ @<Read lines from |actual_input| (and |test_input| if necessary, checking for preamble end)@>=
+get_line(actual_input);
+if (test_input!=none) {
+ get_line(test_input);
+ if (e_of_ch_preamble(test_input)) {
+ get_line(test_input); /* update input file */
+ input_organization[test_input].mode=reading;
+ actual_input=test_input;
+ test_input=none;
+ }
+}
+
+@ We shout at the user about lines processed...
+@<Count lines proc...@>=
+if (++lines_processed % 100 == 0 && verbose) {
+ if (lines_processed % 500 == 0)
+ fprintf(stderr,"%d",lines_processed);
+ else
+ fprintf(stderr,".");
+ }
+
+@ @<Globals in...@>=long int lines_processed=0;
+@ @<Write carriage return...@>=if (verbose) fprintf(stderr,"\n");
+
+
+@i io.web
+@i history.web
+@i error.web
+@i character.web
+
+@* System-dependent changes.
+
+\noindent This section should be replaced, if necessary, by
+changes to the program that are necessary to make \.{TIE}
+work at a particular installation. It is usually best to
+design your change file so that all changes to previous
+modules preserve the module numbering; then everybody's
+version will be consistent with the printed program. More
+extensive changes, which introduce new modules, can be
+inserted here; then only the index itself will get a new
+module number.
+@^system dependencies@>
+
+@<System-dependent parts of char...@>=
+xchr['\t']='\t';
+
+
+@* Index.
+
+\noindent Here is the cross-reference table for the \.{TIE}
+processor.
diff --git a/web/spiderweb/tools/tie/tie.web,v b/web/spiderweb/tools/tie/tie.web,v
new file mode 100644
index 0000000000..8794b356a1
--- /dev/null
+++ b/web/spiderweb/tools/tie/tie.web,v
@@ -0,0 +1,576 @@
+head 1.1;
+branch ;
+access ;
+symbols ;
+locks nr:1.1; strict;
+comment @@;
+
+
+1.1
+date 92.07.06.18.51.25; author nr; state Exp;
+branches ;
+next ;
+
+
+desc
+@tie program
+@
+
+
+
+1.1
+log
+@Initial revision
+@
+text
+@% This is TIE.WEB
+%------------------------------------------------------------
+
+% Version 0.1 ported from PASCAL (NR) 24 August 87
+
+% Here is TeX material that gets inserted after \input webmac
+@@i tie.preamble
+
+@@* Introduction.
+
+\noindent Whenever a programmer wants to change a given
+\.{WEB} program because of system dependencies, he will
+create a new change file. In addition there may be a second
+change file to modify system independent modules of the
+program. But the \.{WEB} file cannot be tangled and weaved
+with more than one change file simultaneously. Therefore,
+we introduce the present program to merge a \.{WEB} file and
+several change files producing a new \.{WEB} file. Since
+the input files are tied together, the program is called
+\.{TIE}. Furthermore, the program can be used to merge
+several change files giving a new single change file. This
+method seems to be more important because it doesn't modify
+the original source file. The use of \.{TIE} can be
+expanded to other programming languages since this processor
+only knows about the structure of change files and does not
+interpret the master file at all.
+
+The program \.{TIE} has to read lines from several input
+files to bring them in some special ordering. For this
+purpose an algorithm is used which looks a little bit
+complicated. But the method used only needs one buffer line
+for each input file. Thus the storage requirement of
+\.{TIE} does not depend on the input data.
+
+The program uses only few features of the local \PASCAL\
+compiler that may need to be changed in other installations.
+The changes needed may be similar to those used to change
+the \.{WEB} processors \.{TANGLE} and \.{WEAVE}. All places
+where changes may be needed are listed in the index under
+the entry ``system dependencies''.
+@@!@@^system dependencies@@>
+
+This version of \.{TIE} has been ported from a \PASCAL version
+{$\copyright$}1983, 1984, 1986 by Technische Hochschule Darmstadt,
+Fachbereich Informatik, Institut f\"ur Theoretische Informatik.
+No attempt has been made to take advantage of the many nice features
+of C (for example to remove the restriction on the number of change
+files).
+There is no warranty, express or implied.
+
+The ``banner line'' defined here should be changed whenever
+\.{TIE} is modified. This program is put into the public
+domain. Nevertheless the copyright notice must not be
+replaced or modified.
+
+
+
+@@d banner = "This is TIE, C Version 0.1 (ported to C)"
+
+@@ Here is where \.{TIE} starts, and where it ends.
+If a command line interface is present, changes to
+initialize the access might be needed here.
+@@^system dependencies@@>
+@@^command line processing@@>
+
+@@c
+#include <stdio.h>
+@@<Input and output types@@>@@;
+@@<Types in the outer block@@>@@;
+@@<Globals in the outer block@@>@@;
+@@<Error handling procedures@@>@@;
+@@#
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int i,j;
+
+ @@<Set initial values@@>@@;
+ print_ln(banner); /* print a ``banner line'' */
+ @@<Read the arguments, setting the master file, the change files,
+ and any options@@>;
+ @@<Initialize the input system@@>;
+ @@<Process the input@@>;
+ @@<Check that all changes have been read@@>;
+ /* here files should be closed if the operating system requires it */
+ @@<Print the job |history|@@>;
+ jump_out();
+}
+
+@@ The guts of the program are simple: we drag each line through the mud:
+@@<Process the input@@>=
+input_has_ended=false;
+while (!input_has_ended || (actual_input!=0)) process_line();
+if (out_mode == post) /* last line has been changed */
+ write_string(out_file,"@@@@z\n");
+@@<Write carriage return for end of counts@@>;
+
+
+@@ At the end of the program, we will tell the user if a
+change file had a line that didn't match any relevant line
+in the master file.
+
+@@<Check that all changes have been read@@>=
+for (i=1; i<next_available_file; i++) /* all change files */
+ if (input_organization[i].mode != ignore)
+ err_print("! Change file entry did not match",i);
+@@.Change file entry ...@@>
+
+@@ Here are some macros for common programming idioms.
+
+@@d loop = while (true)
+@@d do_nothing = /* empty statement */
+@@f loop while
+
+
+@@ The following parameters should be sufficient for most
+applications of \.{TIE}. Note that |max_file_index| should
+not be enlarged without changing the processing of change
+file names.
+@@^system dependencies@@>
+
+@@d buf_size = 100 /* maximum length of one input line*/
+@@d max_file_index = 9/* we dont think that anyone needs more than 9 change files*/
+@@d max_name_length = 54 /* adapt this to your local name space*/
+
+
+@@* Handling multiple change files.
+We read the master and change files from the argument vector.
+The master file is first, followed by (eventually any number) up to 9
+change files.
+The only options are |"-m"| to produce a master file, and |"-c"| to
+produce a change file.
+The last one wins.
+
+@@<Read the arguments...@@>=
+while (--argc>0) {
+ if (**++argv=='-')
+ switch (*++*argv) {
+ case 'm':
+ prod_chf=false;
+ break;
+ case 'c':
+ prod_chf=true;
+ break;
+ default:
+ fprintf(stderr, "Bad option -%c ignored\n",
+ **argv);
+ break;
+ }
+ else {
+ if (next_available_file > max_file_index)
+ fatal_error("too many files");
+ input_organization[next_available_file++].name_of_file=*argv;
+ }
+ }
+
+
+@@ |next_available_file| tells us what file numebr is available as
+a change file.
+@@<Globals...@@>=
+int next_available_file=0;
+@@i datadecl.web
+
+
+
+
+@@*Routines that test input/output conditions.
+
+\noindent Here's a simple function that checks if two lines
+are different.
+
+@@c
+boolean lines_dont_match(i,j)
+ int i,j;
+{
+ buffer_index k, lmt;
+ if (input_organization[i].limit != input_organization[j].limit)
+ return true;
+ lmt=input_organization[i].limit;
+ for (k=0; k<lmt; k++)
+ if (input_organization[i].buffer[k] != input_organization[j].buffer[k])
+ return true;
+ return false;
+}
+@@ @@<Globals...@@>=boolean lines_dont_match();
+@@ The function |e_of_ch_module| returns true if the input
+line from file |i| is equal to \.{@@@@z}.
+
+@@c
+boolean e_of_ch_module(i)
+ int i;
+{
+ return ((input_organization[i].limit>=2) &&
+ (input_organization[i].buffer[0]=='@@@@') &&
+ ((input_organization[i].buffer[1]=='Z') ||
+ (input_organization[i].buffer[1]=='z')));
+}
+
+@@ @@<Globals...@@>=boolean e_of_ch_module();
+
+@@ The function |e_of_ch_preamble| returns true if the input
+line from file |i| is equal to \.{@@@@y}.
+
+@@c
+boolean e_of_ch_preamble(i)
+ int i;
+{
+ return ((input_organization[i].limit>=2) &&
+ (input_organization[i].buffer[0]=='@@@@') &&
+ ((input_organization[i].buffer[1]=='Y') ||
+ (input_organization[i].buffer[1]=='y')));
+}
+
+@@ @@<Globals...@@>=boolean e_of_ch_module();
+
+@@*Routines that manipulate input and output.
+
+@@ We continue with a function to open a text file. Success
+is indicated by a boolean result. We assume that empty
+files can be handled like non existent ones.
+@@^system dependencies@@>
+
+@@c
+boolean file_open(f,name)
+ text_file *f;
+ name_type name;
+{
+ return ((*f=fopen(name,"r"))!=NULL);
+}
+
+@@ @@<Globals...@@>=boolean file_open();
+
+@@ This procedure opens all the input files.
+
+@@c
+@@<Procedures for |open_input|@@>@@;@@%
+ open_input() /* prepare to read |input_files| */
+{
+int i;
+ @@<Get the master file started@@>;
+ actual_input=0;
+no_ch=0;
+while (++no_ch<next_available_file) {
+ if (!file_open(&(input_files[no_ch]),input_organization[no_ch].name_of_file)) {
+ fatal_error("! Change file can\'t be opened");
+ }
+@@.Change file can't be opened@@>
+ else {
+ print("(");
+ print_name_of_file(no_ch);
+ print_ln(")");
+ init_change_file(no_ch,true);
+ }
+}
+
+ if (--no_ch==0)
+ fatal_error("! No change file found");
+@@.No change file found@@>
+ for (i=next_available_file; i<=max_file_index; i++)
+ input_organization[i].mode=ignore;
+}
+
+@@ The master file is actually started just like the change files.
+@@<Get the master file started@@>=
+ if (!file_open(&(input_files[0]),input_organization[0].name_of_file)) {
+ fatal_error("! Master file can\'t be opened");
+ }
+@@.Master file can't be opened@@>
+ else {
+ print("(");
+ print_name_of_file(0);
+ print_ln(")");
+ input_organization[0].type_of_file = master;
+ get_line(0);
+}
+
+
+@@ The main output goes to |out_file|.
+@@d out_file = stdout
+
+
+@@ Procedure |init_change_file(i,b)| is used to ignore all
+lines of the input file with index |i| until the next change
+module is found. The boolean parameter |b| indicates
+whether we do not want to see "@@@@x" or "@@@@y" entries during
+our skip.
+
+@@<Procedures for |open_input|@@>=
+ init_change_file(i,b)
+ int i;
+ boolean b;
+{
+ @@<Skip over comment lines; |return| if end of file@@>;
+ @@<Skip to the next nonblank line; |return| if end of file@@>;
+}
+
+
+@@ While looking for a line that begins with \.{@@@@x} in the
+change file, we allow lines that begin with \.{@@@@}, as long
+as they don"t begin with \.{@@@@y} or \.{@@@@z} (which would
+probably indicate that the change file is fouled up).
+
+@@<Skip over comment lines...@@>=
+loop {
+ get_line(i);
+ if (input_organization[i].mode==ignore) return;
+ if (input_organization[i].limit<2) continue;
+ if (input_organization[i].buffer[0] != '@@@@') continue;
+ if ((input_organization[i].buffer[1]>='X')
+ && (input_organization[i].buffer[1]<='Z'))
+ input_organization[i].buffer[1] += 'z'-'Z'; /* lowercasify */
+ if (input_organization[i].buffer[1]=='x') break;
+ if ((input_organization[i].buffer[1]=='y') ||
+ (input_organization[i].buffer[1]=='z'))
+ if (b) /* waiting for start of change */
+ err_print("! Where is the matching @@@@x?",i);
+@@.Where is the match...@@>
+}
+
+
+
+@@ Here we are looking at lines following the \.{@@@@x}.
+
+@@<Skip to the next nonblank line...@@>=
+do {
+ get_line(i);
+ if (input_organization[i].mode==ignore) {
+ err_print("! Change file ended after @@@@x",i);
+@@.Change file ended...@@>
+ return;
+ }
+} while (input_organization[i].limit<=0);
+
+
+@@ The |put_line| procedure is used to write a line from
+input buffer |j| to the output file.
+
+@@c
+ put_line(j)
+ int j;
+{
+ int i; /* index into the buffer */
+ for (i=0; i<input_organization[j].limit; i++)
+ fputc(xchr[input_organization[j].buffer[i]],out_file);
+ fputc('\n',out_file);
+}
+
+@@ Writing strings to the output
+@@c
+write_string(fp, s)
+ text_file fp;
+ char *s;
+{
+ while (*s != '\0') {
+ putc(*s,fp);s++;}
+}
+
+
+
+
+@@ To start with our inputs we set the indication that all
+change files are in state |search|. That means that we must
+skip to the next (in this case the first) change entry.
+
+@@<Initialize the input system@@>=
+common_init();
+for (i=0; i<next_available_file; i++) {
+ input_organization[i].mode=search;
+ input_organization[i].lineno=0;
+ input_organization[i].type_of_file=chf;
+ input_organization[i].limit=0;
+ for (j=0 ; j<= buf_size; j++) input_organization[i].buffer[j]=0;
+ }
+actual_input=0;
+out_mode=normal;
+ open_input();
+
+
+@@*The major line-eating routines.
+@@ To process the input file the procedure |process_line|
+reads a line of the actual input file and updates the
+|input_organization| for all files with index |i| greater
+|actual_input|.
+
+@@c
+process_line()
+{
+ int i;
+ @@<Count lines processed, and shout at each hundred@@>;
+ @@<Set |actual_input| and |test_input|, and set their modes@@>;
+ @@<Write one (decorated) line of output, and set output mode@@>;
+ @@<Read lines from |actual_input|
+ (and |test_input| if necessary, checking for preamble end)@@>;
+}
+
+
+@@ If |test_input| is |none|, no change file is tested.
+
+@@d none = (next_available_file)
+
+@@<Set |actual_input| and |test_input|, and set their modes@@>=
+while (e_of_ch_module(actual_input)) {
+ if (input_organization[actual_input].type_of_file==master)
+ /* emergency exit, everything mixed up! */
+ fatal_error("! This can\'t happen");
+ input_organization[actual_input].mode=search;
+ init_change_file(actual_input,true);
+ while ((input_organization[actual_input].mode!=reading)
+ && (actual_input>0)) actual_input--;
+}
+if (input_has_ended && (actual_input==0)) return;
+test_input=none;
+i=actual_input;
+while ((test_input==none) && (i<no_ch)) {
+ i++;
+ switch (input_organization[i].mode) {
+case search: if (!lines_dont_match(actual_input,i)) {
+ input_organization[i].mode=test;
+ test_input=i;
+ }
+ break;
+case test:
+ if (lines_dont_match(actual_input, i))
+ {
+ /* error, modules do not match */
+ input_organization[i].mode=search;
+ err_print("! Sections do not match",actual_input);
+@@.Sections do not match@@>
+ err_loc(i);
+ init_change_file(i,false);
+ }
+ else test_input=i;
+ break;
+case reading:do_nothing; /* this can't happen */
+ break;
+case ignore: do_nothing; /* nothing to do */
+ break;
+}
+}
+
+
+@@ @@<Write one (decorated) line of output, and set output mode@@>=
+if (prod_chf) {
+ loop {
+ @@<Test for normal@@>;
+ @@<Test for pre@@>;
+ @@<Test for post@@>;
+}
+} else
+if (test_input==none) put_line(actual_input);
+
+
+@@ Check whether we have to start a change file entry.
+
+@@<Test for normal@@>=
+{
+ if (out_mode==normal)
+ if (test_input!=none) {
+ write_string(out_file,"@@@@x\n");
+ out_mode=pre;
+ }
+ else break;
+}
+
+
+@@ Check whether we have to start the replacement text.
+
+@@<Test for pre@@>=
+{
+ if (out_mode==pre) {
+ if (test_input==none) {
+ write_string(out_file,"@@@@y\n");
+ out_mode=post;
+ } else {
+ if (input_organization[actual_input].type_of_file==master)
+ put_line(actual_input);
+ break;
+ }
+ }
+}
+
+
+@@ Check whether a change file entry is complete.
+
+@@<Test for post@@>=
+{
+ if (out_mode==post) {
+ if (input_organization[actual_input].type_of_file==chf) {
+ if (test_input==none) put_line(actual_input);
+ break;
+ } else {
+ write_string(out_file,"@@@@z\n");
+ out_mode=normal;
+ }
+ }
+}
+
+
+@@ @@<Read lines from |actual_input| (and |test_input| if necessary, checking for preamble end)@@>=
+get_line(actual_input);
+if (test_input!=none) {
+ get_line(test_input);
+ if (e_of_ch_preamble(test_input)) {
+ get_line(test_input); /* update input file */
+ input_organization[test_input].mode=reading;
+ actual_input=test_input;
+ test_input=none;
+ }
+}
+
+@@ We shout at the user about lines processed...
+@@<Count lines proc...@@>=
+if (++lines_processed % 100 == 0) {
+ if (lines_processed % 500 == 0)
+ fprintf(stderr,"%d",lines_processed);
+ else
+ fprintf(stderr,".");
+ }
+
+@@ @@<Globals in...@@>=long int lines_processed=0;
+@@ @@<Write carriage return...@@>=fprintf(stderr,"\n");
+
+
+@@i io.web
+@@i history.web
+@@i error.web
+@@i character.web
+
+@@* System-dependent changes.
+
+\noindent This section should be replaced, if necessary, by
+changes to the program that are necessary to make \.{TIE}
+work at a particular installation. It is usually best to
+design your change file so that all changes to previous
+modules preserve the module numbering; then everybody's
+version will be consistent with the printed program. More
+extensive changes, which introduce new modules, can be
+inserted here; then only the index itself will get a new
+module number.
+@@^system dependencies@@>
+
+@@<System-dependent parts of char...@@>=
+xchr['\t']='\t';
+
+
+@@* Index.
+
+\noindent Here is the cross-reference table for the \.{TIE}
+processor.
+@
diff --git a/web/spiderweb/tools/tie/tie.web.dist b/web/spiderweb/tools/tie/tie.web.dist
new file mode 100644
index 0000000000..07cc03db1d
--- /dev/null
+++ b/web/spiderweb/tools/tie/tie.web.dist
@@ -0,0 +1,1336 @@
+% This is TIE.WEB in text format, as of December 30, 1986.
+%------------------------------------------------------------
+
+%
+% Version 1.0 was completed Nov 30, 1983.
+% Version 1.1 was released Mar 19, 1984.
+% Version 1.2 was restructured for release. (kg) (86-12-22)
+% Version 1.3 allowed to change the last line,
+% made none a constant,
+% read empty lines correct,
+% edited system dependent parts. (js) (86-12-30)
+%
+
+% Here is TeX material that gets inserted after \input webmac
+
+\def\hang{\hangindent 3em\indent\ignorespaces}
+\font\mc=cmcsc10
+\def\PASCAL{{\mc Pascal}}
+\def\ASCII{{\mc ascii}}
+\def\pb{$\.|\ldots\.|$} % pascal brackets (|...|)
+\def\v{\.{\char'174}} % vertical (|) in typewriter font
+\mathchardef\BA="3224 % double arrow
+\def\({} % kludge for alphabetizing certain module names
+
+\def\title{TIE}
+\def\topofcontents{\null\vfill
+ \centerline{\titlefont The {\ttitlefont TIE} processor}
+ \vskip 15pt
+ \centerline{(Version 1.3)}
+ \vfill}
+\def\botofcontents{
+\null\vfill
+\item{$\copyright$}1983, 1984, 1986
+ by Technische Hochschule Darmstadt,\hfill\break
+Fachbereich Informatik, Institut f\"ur Theoretische Informatik\hfill\break
+All rights reserved.\hfill\break
+This program is put into the public domain and may be used freely
+for any non commercial purposes.
+}
+
+
+
+
+
+@* Introduction.
+
+\noindent Whenever a programmer wants to change a given
+\.{WEB} program because of system dependencies, he will
+create a new change file. In addition there may be a second
+change file to modify system independent modules of the
+program. But the \.{WEB} file cannot be tangled and weaved
+with more than one change file simultaneously. Therefore,
+we introduce the present program to merge a \.{WEB} file and
+several change files producing a new \.{WEB} file. Since
+the input files are tied together, the program is called
+\.{TIE}. Furthermore, the program can be used to merge
+several change files giving a new single change file. This
+method seems to be more important because it doesn't modify
+the original source file. The use of \.{TIE} can be
+expanded to other programming languages since this processor
+only knows about the structure of change files and does not
+interpret the master file at all.
+
+The program \.{TIE} has to read lines from several input
+files to bring them in some special ordering. For this
+purpose an algorithm is used which looks a little bit
+complicated. But the method used only needs one buffer line
+for each input file. Thus the storage requirement of
+\.{TIE} does not depend on the input data.
+
+The program uses only few features of the local \PASCAL\
+compiler that may need to be changed in other installations.
+The changes needed may be similar to those used to change
+the \.{WEB} processors \.{TANGLE} and \.{WEAVE}. All places
+where changes may be needed are listed in the index under
+the entry ``system dependencies''.
+@!@^system dependencies@>
+
+The ``banner line'' defined here should be changed whenever
+\.{TIE} is modified. This program is put into the public
+domain. Nevertheless the copyright notice must not be
+replaced or modified.
+
+@d banner=='This is TIE, Version 1.3'
+@d copyright==
+ 'Copyright (c) 1983, 1984, 1986 by THD/ITI. All rights reserved.'
+
+
+@ If it is necessary to abort the job because of a fatal
+error, the program calls the `|jump_out|' procedure, which
+goes to the label |end_of_TIE|.
+
+@d end_of_TIE = 9999 {go here to wrap it up}
+
+@p @t\4@>@<Compiler directives@>
+program TIE(out_file);
+ label end_of_TIE; {go here to finish}
+ const @<Constants in the outer block@>@;
+ type @<Types in the outer block@>@;
+ var @<Globals in the outer block@>@;
+ @t\4@>@<Error handling procedures@>@;
+ procedure initialize;
+ var @<Local variables for initialization@>@;
+ begin @<Set initial values@>
+ end;
+
+@ Some of this code ist optional for use when debugging
+only; such material is enclosed between the delimiters
+|debug| and |gubed|.
+
+@d debug==@t@>@{ {change this to `|debug==@t@>|' when debugging}
+@d gubed==@t@>@} {change this to `|gubed==@t@>|' when debugging}
+@f debug==repeat
+@f gubed==until
+
+
+@ The \PASCAL\ compiler used to develop this system has
+``compiler directives'' that can appear in comments whose
+first character is a dollar sign. In production versions of
+\.{TIE} these directives tell the compiler that it is safe
+to avoid range checks and to leave out the extra code it
+inserts for the \PASCAL\ debugger's benefit, although
+interrupts will occur if there is arithmetic overflow.
+@^system dependencies@>
+
+@<Compiler directives@>=
+@{@&@=$D-@> @} {no range check, catch arithmetic overflow, no debug overhead}
+@!debug @{@&@=$D+@> @}@+ gubed @; {but turn everything on when debugging}
+
+
+@ Labels are given symbolic names by the following
+definitions. We insert the label `|exit|:' just before the
+`\ignorespaces|end|\unskip' of a procedure in which we have
+used the `|return|' statement defined below. Loops that are
+set up with the \&{loop} construction defined below are
+commonly exited by going to `|done|' or to `|found|' or to
+`|not_found|', and they are sometimes repeated by going to
+`|continue|'.
+
+@d exit=10 {go here to leave a procedure}
+@d continue=20 {go here to resume a loop}
+@d done=30 {go here to exit a loop}
+@d found=31 {go here when you've found it}
+@d not_found=32 {go here when you've found something else}
+
+
+@ Here are some macros for common programming idioms.
+
+@d incr(#) == #:=#+1 {increase a variable by unity}
+@d decr(#) == #:=#-1 {decrease a variable by unity}
+@d loop == @+ while true do@+ {repeat over and over until a |goto| happens}
+@d do_nothing == {empty statement}
+@d return == goto exit {terminate a procedure call}
+@f return == nil
+@f loop == xclause
+
+
+@ We assume that |case| statements may include a default
+case that applies if no matching label is found. Thus, we
+shall use constructions like
+$$
+\vbox{
+ \halign{#\hfil\cr
+ |case x of|\cr
+ \qquad 1: $\langle\,$code for $x=1\,\rangle$;\cr
+ \qquad 3: $\langle\,$code for $x=3\,\rangle$;\cr
+ \qquad |othercases| $\langle\,$code for |x<>1| and |x<>3|$\,\rangle$\cr
+ |endcases|\cr
+ }}
+$$
+since most \PASCAL\ compilers have plugged this hole in the
+language by incorporating some sort of default mechanism.
+For example, the compiler used to develop \.{WEB} and \TeX\
+allows `|others|:' as a default label, and other \PASCAL s
+allow syntaxes like `\ignorespaces|else|\unskip' or
+`\&{otherwise}' or `\\{otherwise}:', etc. The definitions
+of |othercases| and |endcases| should be changed to agree
+with local conventions. (Of course, if no default mechanism
+is available, the |case| statements of this program must be
+extended by listing all remaining cases.)
+@^system dependencies@>
+
+@d othercases == others: {default for cases not listed explicitly}
+@d endcases == @+end {follows the default case in an extended |case| statement}
+@f othercases == else
+@f endcases == end
+
+
+@ The following parameters should be sufficient for most
+applications of \.{TIE}. Note that |max_file_index| should
+not be enlarged without changing the processing of change
+file names.
+@^system dependencies@>
+
+@<Constants...@>=
+@!buf_size=100; {maximum length of one input line}
+@!max_file_index=9;{we dont think that anyone needs more than 9 change files}
+@!max_name_length=54; {adapt this to your local name space}
+
+
+@ We introduce a history variable that allows us to set a
+return code if the operating system and the local \PASCAL\
+compiler allow it. First we introduce the coded values for
+the history.
+
+@d spotless=0
+@d troublesome=1
+@d fatal=2
+
+@<Globals in ...@>=
+@!history:integer;
+
+
+@ We must initialize this variable at the very beginning.
+
+@<Set initial values@>=
+history:=spotless;
+
+
+
+
+
+@* The character set.
+
+\noindent One of the main goals in the design of \.{TIE} has
+been to make it readily portable between a wide variety of
+computers. Yet \.{TIE} by its very nature must use a
+greater variety of characters than most computer programs
+deal with, and character encoding is one of the areas in
+which existing machines differ most widely from each other.
+
+To resolve this problem, all input to \.{TIE} is converted
+to an internal seven-bit code that is essentially standard
+\ASCII{}, the ``American Standard Code for Information
+Interchange.'' The conversion is done immediately when each
+character is read in. Conversely, characters are converted
+from \ASCII{} to the user's external representation just
+before they are output.
+
+\noindent Here is a table of the standard visible \ASCII{} codes:
+$$\def\:{\char\count255\global\advance\count255 by 1}
+\count255='40
+\vbox{
+\hbox{\hbox to 40pt{\it\hfill0\/\hfill}%
+\hbox to 40pt{\it\hfill1\/\hfill}%
+\hbox to 40pt{\it\hfill2\/\hfill}%
+\hbox to 40pt{\it\hfill3\/\hfill}%
+\hbox to 40pt{\it\hfill4\/\hfill}%
+\hbox to 40pt{\it\hfill5\/\hfill}%
+\hbox to 40pt{\it\hfill6\/\hfill}%
+\hbox to 40pt{\it\hfill7\/\hfill}}
+\vskip 4pt
+\hrule
+\def\^{\vrule height 10.5pt depth 4.5pt}
+\halign{\hbox to 0pt{\hskip -24pt\O{#0}\hfill}&\^
+\hbox to 40pt{\tt\hfill#\hfill\^}&
+&\hbox to 40pt{\tt\hfill#\hfill\^}\cr
+04&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+05&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+06&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+07&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+10&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+11&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+12&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+13&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+14&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+15&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+16&\:&\:&\:&\:&\:&\:&\:&\:\cr\noalign{\hrule}
+17&\:&\:&\:&\:&\:&\:&\:\cr}
+\hrule width 280pt}$$
+(Actually, of course, code @'040 is an invisible blank
+space.) Code @'136 was once an upward arrow (\.{\char'13}),
+and code @'137 was once a left arrow (\.^^X), in olden times
+when the first draft of \ASCII{} code was prepared; but
+\.{TIE} works with today's standard \ASCII{} in which those
+codes represent circumflex and underline as shown.
+
+@<Types...@>=
+@!ascii_code=0..127; {seven-bit numbers, a subrange of the integers}
+
+
+@ The original \PASCAL\ compiler was designed in the late
+60s, when six-bit character sets were common, so it did not
+make provision for lowercase letters. Nowadays, of course,
+we need to deal with both capital and small letters in a
+convenient way, so \.{TIE} assumes that it is being used
+with a \PASCAL\ whose character set contains at least the
+characters of standard \ASCII{} as listed above. Some
+\PASCAL\ compilers use the original name |char| for the data
+type associated with the characters in text files, while
+other \PASCAL s consider |char| to be a 64-element subrange
+of a larger data type that has some other name.
+
+In order to accommodate this difference, we shall use the
+name |text_char| to stand for the data type of the
+characters in the input and output files. We shall also
+assume that |text_char| consists of the elements
+|chr(first_text_char)| through |chr(last_text_char)|,
+inclusive. The following definitions should be adjusted if
+necessary.
+@^system dependencies@>
+
+@d text_char == char {the data type of characters in text files}
+@d first_text_char=0 {ordinal number of the smallest element of |text_char|}
+@d last_text_char=127 {ordinal number of the largest element of |text_char|}
+
+@<Types...@>=
+@!text_file=packed file of text_char;
+
+
+@ The \.{TIE} processor convert between \ASCII{} code and
+the user's external character set by means of arrays |xord|
+and |xchr| that are analogous to \PASCAL's |ord| and |chr|
+functions.
+
+@<Globals...@>=
+@!xord: array [text_char] of ascii_code;
+ {specifies conversion of input characters}
+@!xchr: array [ascii_code] of text_char;
+ {specifies conversion of output characters}
+
+
+@ If we assume that every system using \.{WEB} is able to
+read and write the visible characters of standard \ASCII{}
+(although not necessarily using the \ASCII{} codes to
+represent them), the following assignment statements
+initialize most of the |xchr| array properly, without
+needing any system-dependent changes. For example, the
+statement \.{xchr["A"]:=\'A\'} that appears in the present
+\.{WEB} file might be encoded in, say, {\mc EBCDIC} code on
+the external medium on which it resides, but \.{TANGLE} will
+convert from this external code to \ASCII{} and back again.
+Therefore the assignment statement \.{XCHR[65]:=\'A\'} will
+appear in the corresponding \PASCAL\ file, and \PASCAL\ will
+compile this statement so that |xchr[65]| receives the
+character \.A in the external (|char|) code. Note that it
+would be quite incorrect to say \.{xchr["A"]:="A"}, because
+|"A"| is a constant of type |integer|, not |char|, and
+because we have $|"A"|=65$ regardless of the external
+character set.
+
+@<Set init...@>=
+xchr[" "]:=' ';
+xchr["!"]:='!';
+xchr[""""]:='"';
+xchr["#"]:='#';
+xchr["$"]:='$';
+xchr["%"]:='%';
+xchr["&"]:='&';
+xchr["'"]:='''';@/
+xchr["("]:='(';
+xchr[")"]:=')';
+xchr["*"]:='*';
+xchr["+"]:='+';
+xchr[","]:=',';
+xchr["-"]:='-';
+xchr["."]:='.';
+xchr["/"]:='/';@/
+xchr["0"]:='0';
+xchr["1"]:='1';
+xchr["2"]:='2';
+xchr["3"]:='3';
+xchr["4"]:='4';
+xchr["5"]:='5';
+xchr["6"]:='6';
+xchr["7"]:='7';@/
+xchr["8"]:='8';
+xchr["9"]:='9';
+xchr[":"]:=':';
+xchr[";"]:=';';
+xchr["<"]:='<';
+xchr["="]:='=';
+xchr[">"]:='>';
+xchr["?"]:='?';@/
+xchr["@@"]:='@@';
+xchr["A"]:='A';
+xchr["B"]:='B';
+xchr["C"]:='C';
+xchr["D"]:='D';
+xchr["E"]:='E';
+xchr["F"]:='F';
+xchr["G"]:='G';@/
+xchr["H"]:='H';
+xchr["I"]:='I';
+xchr["J"]:='J';
+xchr["K"]:='K';
+xchr["L"]:='L';
+xchr["M"]:='M';
+xchr["N"]:='N';
+xchr["O"]:='O';@/
+xchr["P"]:='P';
+xchr["Q"]:='Q';
+xchr["R"]:='R';
+xchr["S"]:='S';
+xchr["T"]:='T';
+xchr["U"]:='U';
+xchr["V"]:='V';
+xchr["W"]:='W';@/
+xchr["X"]:='X';
+xchr["Y"]:='Y';
+xchr["Z"]:='Z';
+xchr["["]:='[';
+xchr["\"]:='\';
+xchr["]"]:=']';
+xchr["^"]:='^';
+xchr["_"]:='_';@/
+xchr["`"]:='`';
+xchr["a"]:='a';
+xchr["b"]:='b';
+xchr["c"]:='c';
+xchr["d"]:='d';
+xchr["e"]:='e';
+xchr["f"]:='f';
+xchr["g"]:='g';@/
+xchr["h"]:='h';
+xchr["i"]:='i';
+xchr["j"]:='j';
+xchr["k"]:='k';
+xchr["l"]:='l';
+xchr["m"]:='m';
+xchr["n"]:='n';
+xchr["o"]:='o';@/
+xchr["p"]:='p';
+xchr["q"]:='q';
+xchr["r"]:='r';
+xchr["s"]:='s';
+xchr["t"]:='t';
+xchr["u"]:='u';
+xchr["v"]:='v';
+xchr["w"]:='w';@/
+xchr["x"]:='x';
+xchr["y"]:='y';
+xchr["z"]:='z';
+xchr["{"]:='{';
+xchr["|"]:='|';
+xchr["}"]:='}';
+xchr["~"]:='~';@/
+xchr[0]:=' '; xchr[@'177]:=' '; {these \ASCII{} codes are not used}
+
+
+@ One of the \ASCII{} codes below @'40 has been given a
+symbolic name in \.{TIE} because it is used with a special
+meaning.
+
+@d tab_mark=@'11 {\ASCII{} code used as tab-skip}
+
+
+@ When we initialize the |xord| array and the remaining
+parts of |xchr|, it will be convenient to make use of an
+index variable, |i|.
+
+@<Local variables for init...@>=
+@!i:0..last_text_char;
+
+
+@ Here now is the system-dependent part of the character
+set. If \.{TIE} is being implemented on a garden-variety
+\PASCAL\ for which only standard \ASCII{} codes will appear
+in the input and output files, you don't need to make any
+changes here.
+@^system dependencies@>
+
+Changes to the present module will make \.{TIE} more
+friendly on computers that have an extended character set,
+so that one can type things like \.^^Z. If you have an
+extended set of characters that are easily incorporated into
+text files, you can assign codes arbitrarily here, giving an
+|xchr| equivalent to whatever characters the users of
+\.{TIE} are allowed to have in their input files, provided
+that unsuitable characters do not correspond to special
+codes like |carriage_return| that are listed above.
+
+@<Set init...@>=
+for i:=1 to @'37 do xchr[i]:=' ';
+
+
+@ The following system-independent code makes the |xord|
+array contain a suitable inverse to the information in
+|xchr|.
+
+@<Set init...@>=
+for i:=first_text_char to last_text_char do xord[chr(i)]:=@'40;
+for i:=1 to @'176 do xord[xchr[i]]:=i;
+
+
+
+
+
+@* Input and output.
+
+\noindent Terminal output is done by writing on file
+|term_out|, which is assumed to consist of characters of
+type |text_char|. Terminal input is read from |term_in|.
+@^system dependencies@>
+
+@d print(#)==write(term_out,#) {`|print|' means write on the terminal}
+@d print_ln(#)==write_ln(term_out,#)
+@d new_line==write_ln(term_out) {start new line}
+@d print_nl(#)== @+ begin new_line; print(#) @+ end
+
+@<Globals...@>=
+@!term_in:text_file;
+@!term_out:text_file;
+
+
+@ To initialize terminal input we do a reset, just when the
+first character is needed. This allows output before the
+first input line is read even if ``lazy input'' is not
+supported by your \PASCAL\ compiler.
+@^system dependencies@>
+
+@<Reset terminal input@>=
+reset(term_in,'TTY:','/I')
+
+
+@ Similarly we initialize terminal output to a file that
+should be associated to the user's terminal interactively.
+@^system dependencies@>
+
+@<Set init...@>=
+rewrite(term_out,'TTY:');
+
+
+@ The |update_terminal| procedure is called when we want to
+make sure that everything we have output to the terminal so
+far has actually left the computer's internal buffers and
+been sent.
+@^system dependencies@>
+
+@d update_terminal == break(term_out) {empty the terminal output buffer}
+
+
+@ If an error occurs we indicate this calling a procedure
+named |err_print|. This procedure is implemented as a
+macro. It gives a message and an indication of the
+offending file. The actions to determine the error location
+will be explained later.
+
+@d error_loc(#) == err_loc(#); history:=troublesome; @+ end
+@d err_print(#) == @+ begin print_nl(#); error_loc
+
+
+@ The basic procedure |get_ln_from_file| can be used to get
+a line from an input file. The line is stored in
+|input_files[i].buffer|. The components |limit| and |line|
+are updated. If the end of the file is reached
+|input_files[i].mode| is set to |ignore|. On some systems
+it might be useful to replace tab characters by a proper
+number of spaces since several editors used to create change
+files insert tab characters into a source file not under
+control of the user. So it might be a problem to create a
+matching change file.
+@^tab character expansion@>
+
+We define |get_line| to read a line from a file specified by
+number. To ease an inplementation without arrays of files
+we introduce one more parameter. In such cases |get_line|
+is best replaced by a procedure containing a |case|
+statement to select the file needed.
+
+@d get_line(#)==get_ln_from_file(#,input_files[#]);
+
+@p
+procedure get_ln_from_file(i:integer;var cur_file:text_file);
+ label exit;
+ var final_limit:0..buf_size;
+ begin
+ with input_organization[i] do
+ begin
+ if mode=ignore then return;
+ if eof(cur_file) then @<Handle end of file and return@>;
+ @<Get line into buffer@>;
+ end;
+exit: end;
+
+
+@ End of file is special if this file is the master file.
+
+@<Handle end of file ...@>=
+begin
+ mode:=ignore;
+ if type_of_file=master then input_has_ended:=true;
+ return;
+end
+
+
+@ Lines must fit into the buffer completely.
+Tab character expansion might be done here.
+@^tab character expansion@>
+
+@<Get line into buffer@>=
+incr(line);
+limit:=0; final_limit := 0;
+while (not eoln(cur_file) and (limit<=buf_size)) do
+begin
+ buffer[limit]:=xord[cur_file^]; get(cur_file); incr(limit);
+ if (buffer[limit-1]<>" ")and(buffer[limit-1]<>tab_mark) then
+ final_limit:=limit;
+end;
+limit:=final_limit;
+if not eoln(cur_file) then err_print('! Input line too long')(i);
+@.Input line too long@>
+read_ln(cur_file)
+
+
+
+
+
+@* Data structures.
+
+\noindent The multiple input files (master file and change
+files) are treated the same way. To organize the
+simultaneous usage of several input files, we introduce the
+data types |in_file_modes|.
+
+The mode |search| indicates that \.{TIE} searches for a
+match of the input line with any line of an input file in
+|reading| mode. |test| is used whenever a match is found
+and it has to be tested if the next input lines do match
+also. |reading| describes that the lines can be read without
+any check for equality to other lines. |ignore| denotes
+that the file cannot be used. This may happen because an
+error has been detected or because the end of the file has
+been found.
+
+\leavevmode |file_types| is used to describe whether a file
+is a master file or a change file.
+
+@<Types...@>=
+@!in_file_modes=(@!search,@!test,@!reading,@!ignore);@/
+@!file_types=(@!master,@!chf);
+
+
+@ The following data structures join all informations needed to use
+these input files.
+
+@<Types...@>=
+@!out_md_type=(@!normal,@!pre,@!post);@/
+@!name_type=record @!name:array[1..max_name_length] of char;
+ @!nam_len:0..max_name_length;
+ end;
+@!buffer_index=0..buf_size;@/
+@!file_index=0..max_file_index;@/
+@!input_description=record
+ @!name_of_file: name_type;
+ @!buffer: array[0..buf_size]of ascii_code;
+ @!mode: in_file_modes;
+ @!line: integer;
+ @!type_of_file: file_types;
+ @!limit: buffer_index;
+ end;
+
+
+@ These data types are used in the global variable section.
+
+@<Globals...@>=
+@!actual_input,@!test_input:integer;
+@!input_has_ended:boolean;
+@!input_organization: array[0..max_file_index] of input_description;
+@!input_files: array[0..max_file_index] of text_file;
+@!no_ch,@!cmd:integer;
+@!c:char;
+i,j:integer;
+@!prod_chf:boolean;
+@!name_field:name_type;
+@!master_ext:name_type;
+@!cf_ext:name_type;
+@!no_ext:name_type;
+@!out_mode:out_md_type;
+@!ext_start:0..max_name_length;
+
+
+
+
+
+@* Reporting errors to the user.
+
+\noindent There may be errors if a line in a given change
+file does not match a line in the master file or a
+replacement in a previous change file. Such errors are
+reported to the user by saying
+$$
+ \hbox{|err_print('! Error message')|.}
+$$
+Please note that no trailing point is supplied by the error
+message because it is appended by |err_print|. Non
+recoverable errors are handled by calling |fatal_error| that
+outputs a message and then calls `|jump_out|'.
+
+\leavevmode |err_print| will print the error message
+followed by an indication of where the error was spotted in
+the source files. |fatal_error| cannot state any files
+because the problem is usually to access these.
+
+For |err_print| messages the following procedure is used to
+write the proper name of an input file.
+
+@d fatal_error(#)==begin print_nl(#); print_ln('.'); history:=fatal; jump_out;
+ end
+
+@<Error handling...@>=
+procedure print_name_of_file(cur_index:file_index);
+var i:integer;
+begin
+ with input_organization[cur_index] do
+ for i:=1 to name_of_file.nam_len do print(name_of_file.name[i]);
+end;
+
+
+@ The actual error indications are provided by a procedure
+called |err_loc|.
+
+@<Error handling...@>=
+procedure err_loc(i:integer); {prints location of error}
+begin
+ with input_organization[i] do
+ begin
+ print(' (file ');
+ print_name_of_file(i);
+ print(', l.',line:1,').');
+ new_line;
+ end;
+end;
+
+
+@ The |jump_out| procedure just cuts across all active
+procedure levels and jumps out of the program. This is the
+only non-local |goto| statement in \.{TIE}. It is used when
+no recovery from a particular error has been provided.
+
+Some \PASCAL\ compilers do not implement non-local |goto|
+statements. In such cases the code that appears at label
+|end_of_TIE| should be copied into the |jump_out| procedure,
+followed by a call to a system procedure that terminates the
+program.
+@^system dependencies@>
+
+@<Error handling...@>=
+procedure jump_out;
+begin goto end_of_TIE;
+end;
+
+
+
+
+
+@* Handling multiple change files.
+
+\noindent In the standard version we read the name of the
+files from the console. Handling of the end of line
+indicator might need a system dependent update. There might
+be system dependent changes to get the names of the files
+from the command line.
+
+If \.{TIE} is used on a system which allows filenames only
+in upper or lower case, |read_chr| should be replaced by a
+procedure that converts the characters properly.
+@^system dependencies@>
+
+@d read_chr(#)==read(term_in,#)
+
+@p procedure rd_file;
+var c:char;
+begin
+ name_field.nam_len:=0;
+ while (not eoln(term_in) and (name_field.nam_len<max_name_length)) do
+ begin
+ incr(name_field.nam_len);
+ read_chr(c);
+ name_field.name[name_field.nam_len]:=c;
+ end;
+ if name_field.nam_len>0 then
+ if not eoln(term_in) then
+ fatal_error('! File name too long');
+@.File name too long@>
+end;
+
+
+@ To do our job we need the master file's name.
+
+@<Read master file name@>=
+begin
+ print_nl('Please enter the name of the master file: ');
+@.Please enter the name ...@>
+ update_terminal;
+ @<Reset terminal input@>;
+ rd_file;
+ if name_field.nam_len=0 then
+ fatal_error('! Illegal file name');
+@.Illegal file name@>
+ @<Ignore master file extension@>;
+ if name_field.nam_len+4>max_name_length then
+ fatal_error('! File name too long');
+@.File name too long@>
+end
+
+
+@ The extension of the master source file is to be ignored.
+We assume that extensions are separated from the base name
+by a period. Let us scan from the tail to the last period.
+We skip only characters, digits and underscore characters.
+Finding any other character stops extension scanning.
+
+@<Ignore master file extension@>=
+begin if name_field.nam_len>3 then with name_field do
+ begin i:=nam_len; ext_start:=0; {extension not yet found}
+ while i>0 do
+ if name[i]='.' then begin ext_start:=i; i:=0 end
+ else
+ if (name[i]>='a') and (name[i]<='z') then i:=i-1 else
+ if (name[i]>='A') and (name[i]<='Z') then i:=i-1 else
+ if (name[i]>='0') and (name[i]<='9') then i:=i-1 else
+ if (name[i]='_') then i:=i-1 else i:=0;
+ if ext_start>0 then
+ begin {initialize master file extension}
+ for i:=ext_start to nam_len do
+ master_ext.name[i-ext_start+1]:=name[i];
+ master_ext.nam_len:=nam_len-ext_start+1;
+ for i:=master_ext.nam_len+1 to max_name_length do
+ master_ext.name[i]:=' ';
+ nam_len:=ext_start-1;
+ end;
+ end
+end
+
+
+@ We must determine the name of a change file, too.
+This might be changed to command line parameter processing.
+@^command line processing@>
+
+@<Read change file name@>=
+begin
+ print_ln('Please enter the name of change file ',no_ch:1);
+ print('or <Return> if there are no more change files: ');
+ update_terminal;
+ read_ln(term_in);
+ rd_file;
+end
+
+
+@ The selection whether a new master file or a mixed change
+file should be produced might be replaced by a command line
+switch, too.
+@^command line processing@>
+
+@<Change or master file producing@>=
+repeat
+ print_nl('Do you want to create a new master or a change file (m/c)? ');
+@.Do you want to create ...@>
+ update_terminal;
+ read_ln(term_in); read_chr(c);
+ cmd:=xord[c];
+ if (cmd>="a") and (cmd<="z") then cmd:=cmd+"A"-"a";
+until (cmd="C")or(cmd="M");
+prod_chf:=(cmd="C")
+
+
+@ We continue with a function to open a text file. Success
+is indicated by a boolean result. We assume that empty
+files can be handled like non existent ones.
+@^system dependencies@>
+
+@p function file_open(var f:text_file;name:name_type):boolean;
+begin
+ reset(f,name.name);
+ file_open:=not eof(f);
+end;
+
+
+@ The procedure |insert_name| initializes the name of the
+file number |cur_index| to ``prefix'' ``extension''.
+
+@p procedure insert_name(cur_index:file_index;prefix:name_type;
+ extension:name_type);
+var i:integer;
+begin
+ with input_organization[cur_index] do
+ begin
+ for i:=1 to max_name_length do name_of_file.name[i]:=' ';
+ for i:=1 to prefix.nam_len do name_of_file.name[i]:=prefix.name[i];
+ for i:=1 to extension.nam_len do
+ name_of_file.name[prefix.nam_len+i]:=extension.name[i];
+ name_of_file.nam_len:=prefix.nam_len+extension.nam_len;
+ end;
+end;
+
+
+@
+@<Get the master file started@>=
+ insert_name(0,name_field,master_ext);
+ if not file_open(input_files[0],input_organization[0].name_of_file) then
+ fatal_error('! Master file can''t be opened')
+@.Master file can't be opened@>
+ else
+ begin
+ print('(');
+ print_name_of_file(0);
+ print_ln(')');
+ input_organization[0].type_of_file:=master;
+ get_line(0);
+ end;
+
+
+@ This is a procedure to open all input files. Changes
+might be used to get the names of the files from a command
+line. In this interactive version \.{TIE} will try to use
+change files with extensions \.{CF1} to \.{CF9}
+automatically---and there is no way to inhibit this, if
+those files exist.
+@^command line processing@>
+
+@p
+@t\4@>@<Procedures for |open_input|@>
+procedure open_input; {prepare to read |input_files|}
+label done;
+var i:integer;
+begin
+ @<Initialize extensions@>;
+ @<Get the master file started@>;
+ actual_input:=0;
+ for i:=1 to max_file_index do
+ begin
+ cf_ext.name[cf_ext.nam_len]:=xchr["0"+i];
+ insert_name(i,name_field,cf_ext);
+ end;
+ no_ch:=0;
+ while no_ch<9 do
+ begin
+ incr(no_ch);
+ if not file_open(input_files[no_ch],
+ input_organization[no_ch].name_of_file)
+ then
+ begin
+ @<Read change file name@>;
+ if name_field.nam_len=0 then begin decr(no_ch); goto done; end;
+ insert_name(no_ch,name_field,no_ext);
+ decr(no_ch);
+ end else
+ begin
+ print('(');
+ print_name_of_file(no_ch);
+ print_ln(')');
+ init_change_file(no_ch,true);
+ end;
+ end;
+done:
+ if no_ch=0 then
+ fatal_error('! No change file found');
+@.No change file found@>
+ for i:=no_ch+1 to max_file_index do input_organization[i].mode:=ignore;
+end;
+
+
+@ According to the names given above, we initialize the
+extension names. We need the standard change file
+extensions that are \.{CF}$i$ and a ``dummy'' entry for
+change files that do not need additional extensions.
+
+@<Initialize extensions@>=
+cf_ext.name[1]:='.';
+cf_ext.name[2]:='C';
+cf_ext.name[3]:='F';
+cf_ext.name[4]:=' ';
+cf_ext.nam_len:=4;
+for i:=cf_ext.nam_len+1 to max_name_length do cf_ext.name[i]:=' ';
+no_ext.nam_len:=0;
+for i:=1 to max_name_length do no_ext.name[i]:=' '
+
+
+@ The main output goes to |out_file|.
+
+@<Globals...@>=
+@!out_file:text_file;
+
+
+@ The following code opens |out_file|. Since this file is
+mentioned in the program header we assume that the \PASCAL\
+runtime system has checked the existence of the file.
+@^system dependencies@>
+
+@<Set init...@>=
+rewrite(out_file);
+
+
+
+
+
+@*Input/output organization.
+
+\noindent Here's a simple function that checks if two lines
+are different.
+
+@p function lines_dont_match(i,j:integer):boolean;
+label exit;
+var k,lmt:buffer_index;
+begin
+ lines_dont_match:=true;
+ if input_organization[i].limit <> input_organization[j].limit
+ then return;
+ lmt:=input_organization[i].limit;
+ if lmt > 0 then
+ for k:=0 to lmt-1 do
+ if input_organization[i].buffer[k] <>
+ input_organization[j].buffer[k] then return;
+ lines_dont_match:=false;
+exit: end;
+
+
+@ Procedure |init_change_file(i,b)| is used to ignore all
+lines of the input file with index |i| until the next change
+module is found. The boolean parameter |b| indicates
+whether we do not want to see '@@x' or '@@y' entries during
+our skip.
+
+@<Procedures for |open_input|@>=
+procedure init_change_file(i:integer;b:boolean);
+label continue, done, exit;
+begin
+ with input_organization[i] do
+ begin
+ @<Skip over comment lines; |return| if end of file@>;
+ @<Skip to the next nonblank line; |return| if end of file@>;
+ end;
+exit: end;
+
+
+@ While looking for a line that begins with \.{@@x} in the
+change file, we allow lines that begin with \.{@@}, as long
+as they don't begin with \.{@@y} or \.{@@z} (which would
+probably indicate that the change file is fouled up).
+
+@<Skip over comment lines...@>=
+loop@+ begin get_line(i);
+ if mode=ignore then return;
+ if limit<2 then goto continue;
+ if buffer[0] <> "@@" then goto continue;
+ if (buffer[1]>="X") and (buffer[1]<="Z") then
+ buffer[1]:=buffer[1]+"z"-"Z"; {lowercasify}
+ if buffer[1]="x" then goto done;
+ if (buffer[1]="y") or (buffer[1]="z") then
+ if b then {waiting for start of change}
+ err_print('! Where is the matching @@x?')(i);
+@.Where is the match...@>
+continue: end;
+done:
+
+
+@ Here we are looking at lines following the \.{@@x}.
+
+@<Skip to the next nonblank line...@>=
+repeat
+ get_line(i);
+ if mode=ignore then
+ begin
+ err_print('! Change file ended after @@x')(i);
+@.Change file ended...@>
+ return;
+ end;
+until limit>0
+
+
+@ The |put_line| procedure is used to write a line from
+input buffer |j| to the output file.
+
+@p procedure put_line(j:integer);
+var i:integer; {index into the buffer}
+begin
+ with input_organization[j] do
+ for i:=0 to limit-1 do write(out_file,xchr[buffer[i]]);
+ write_ln(out_file);
+end;
+
+
+@ The function |e_of_ch_module| returns true if the input
+line from file |i| is equal to \.{@@z}.
+
+@p function e_of_ch_module(i:integer):boolean;
+begin
+ e_of_ch_module:=false;
+ with input_organization[i] do
+ if limit>=2 then if buffer[0]="@@" then
+ if (buffer[1]="Z") or (buffer[1]="z") then e_of_ch_module:=true;
+end;
+
+
+@ The function |e_of_ch_preamble| returns true if the input
+line from file |i| is equal to \.{@@y}.
+
+@p function e_of_ch_preamble(i:integer):boolean;
+begin
+ e_of_ch_preamble:=false;
+ with input_organization[i] do
+ if limit>=2 then if buffer[0]="@@" then
+ if (buffer[1]="Y") or (buffer[1]="y") then e_of_ch_preamble:=true;
+end;
+
+
+@ To start with our inputs we set the indication that all
+change files are in state |search|. That means that we must
+skip to the next (in this case the first) change entry.
+
+@<Initialize the input system@>=
+for i:=0 to max_file_index do
+ with input_organization[i] do
+ begin
+ mode:=search; line:=0; type_of_file:=chf; limit:=0;
+ for j:=1 to max_name_length do name_of_file.name[j]:=' ';
+ for j:=0 to buf_size do buffer[j]:=0;
+ end;
+actual_input:=0;
+out_mode:=normal
+
+
+@ To process the input file the procedure |process_line|
+reads a line of the actual input file and updates the
+|input_organization| for all files with index |i| greater
+|actual_input|.
+
+@p procedure process_line;
+label done, exit;
+var i:integer;
+begin
+ @<Init process@>;
+ @<Handle output@>;
+ @<Step to next line@>;
+exit: end;
+
+
+@ If |test_input| is |none|, no change file is tested.
+
+@d none == (max_file_index+1)
+
+@<Init process@>=
+while e_of_ch_module(actual_input) do
+ with input_organization[actual_input] do
+ begin
+ if type_of_file=master then {emergency exit, everything mixed up!}
+ fatal_error('! This can''t happen');
+ mode:=search;
+ init_change_file(actual_input,true);
+ while ((input_organization[actual_input].mode<>reading)
+ and (actual_input>0)) do decr(actual_input);
+ end;
+if input_has_ended and (actual_input=0) then return;
+test_input:=none;
+i:=actual_input;
+while ((test_input=none) and (i<no_ch)) do
+begin
+ incr(i);
+ case input_organization[i].mode of
+ search: if not lines_dont_match(actual_input,i) then
+ begin
+ input_organization[i].mode:=test;
+ test_input:=i;
+ end;
+ test: begin
+ if lines_dont_match(actual_input, i) then
+ begin
+ {error, modules do not match}
+ input_organization[i].mode:=search;
+ err_print('! Sections do not match')(actual_input);
+@.Sections do not match@>
+ err_loc(i);
+ init_change_file(i,false);
+ end else test_input:=i;
+ end;
+ reading:do_nothing; {this can't happen}
+ ignore: do_nothing; {nothing to do}
+ end;
+end
+
+
+@ @<Handle output@>=
+if prod_chf then
+begin
+ loop @+ begin
+ @<Test for normal@>;
+ @<Test for pre@>;
+ @<Test for post@>;
+ end;
+done:
+end else
+if test_input=none then put_line(actual_input)
+
+
+@ Check whether we have to start a change file entry.
+
+@<Test for normal@>=
+begin
+ if out_mode=normal then
+ if test_input<>none then
+ begin
+ write(out_file,xchr["@@"]); write_ln(out_file,xchr["x"]);
+ out_mode:=pre;
+ end else goto done;
+end
+
+
+@ Check whether we have to start the replacement text.
+
+@<Test for pre@>=
+begin
+ if out_mode=pre then
+ begin
+ if test_input=none then
+ begin
+ write(out_file,xchr["@@"]); write_ln(out_file,xchr["y"]);
+ out_mode:=post;
+ end else
+ begin
+ if input_organization[actual_input].type_of_file=master then
+ put_line(actual_input);
+ goto done;
+ end;
+ end;
+end
+
+
+@ Check whether a change file entry is complete.
+
+@<Test for post@>=
+begin
+ if out_mode=post then
+ begin
+ if input_organization[actual_input].type_of_file=chf then
+ begin
+ if test_input=none then put_line(actual_input);
+ goto done;
+ end else
+ begin
+ write(out_file,xchr["@@"]); write_ln(out_file,xchr["z"]);
+ write_ln(out_file);
+ out_mode:=normal;
+ end;
+ end;
+end
+
+
+@ @<Step to next line@>=
+get_line(actual_input);
+if test_input<>none then
+begin
+ get_line(test_input);
+ if e_of_ch_preamble(test_input) then
+ begin
+ get_line(test_input); {update input file}
+ input_organization[test_input].mode:=reading;
+ actual_input:=test_input;
+ test_input:=none;
+ end;
+end
+
+
+@ @<Process the input@>=
+input_has_ended:=false;
+while not input_has_ended or (actual_input<>0) do process_line;
+if out_mode = post then {last line has been changed}
+ begin write(out_file,xchr["@@"]); write_ln(out_file,xchr["z"]);
+ end;
+
+
+@ At the end of the program, we will tell the user if the
+change file had a line that didn't match any relevant line
+in the master file.
+
+@<Check that all changes have been read@>=
+for i:=1 to max_file_index do {all change files}
+ if input_organization[i].mode <> ignore then
+ err_print('! Change file entry did not match')(i);
+@.Change file entry ...@>
+
+
+
+
+
+@* The main program.
+
+\noindent Here is where \.{TIE} starts, and where it ends.
+If a command line interface is present, changes to
+initialize the access might be needed here.
+@^system dependencies@>
+@^command line processing@>
+
+@p begin initialize;
+ print_ln(banner); {print a ``banner line''}
+ print_ln(copyright); {include the copyright notice}
+ @<Initialize the input system@>;
+ @<Read master file name@>;
+ open_input;
+ @<Change or master file producing@>;
+ @<Process the input@>;
+ @<Check that all changes have been read@>;
+end_of_TIE:
+ {here files should be closed if the operating system requires it}
+ @<Print the job |history|@>;
+end.
+
+
+@ Some implementations may wish to pass the |history| value
+to the operating system so that it can be used to govern
+whether or not other programs are started. Here we simply
+report the history to the user.
+@^system dependencies@>
+
+@<Print the job |history|@>=
+case history of
+spotless: print_nl('(No errors were found.)');
+troublesome: print_nl('(Pardon me, but I think I spotted something wrong.)');
+fatal: print_nl('(That was a fatal error, my friend.)');
+end {there are no other cases}
+
+
+
+
+
+@* System-dependent changes.
+
+\noindent This section should be replaced, if necessary, by
+changes to the program that are necessary to make \.{TIE}
+work at a particular installation. It is usually best to
+design your change file so that all changes to previous
+modules preserve the module numbering; then everybody's
+version will be consistent with the printed program. More
+extensive changes, which introduce new modules, can be
+inserted here; then only the index itself will get a new
+module number.
+@^system dependencies@>
+
+
+
+
+
+@* Index.
+
+\noindent Here is the cross-reference table for the \.{TIE}
+processor.
diff --git a/web/spiderweb/tools/tie/tiedoc.tex b/web/spiderweb/tools/tie/tiedoc.tex
new file mode 100644
index 0000000000..ba2dd767e5
--- /dev/null
+++ b/web/spiderweb/tools/tie/tiedoc.tex
@@ -0,0 +1,149 @@
+\documentstyle{article}
+\font\mc=cmcsc10
+\def\TANGLE{{\tt TANGLE}}
+\def\TIE{{\tt TIE}}
+\def\WEAVE{{\tt WEAVE}}
+\def\WEB{{\tt WEB}}
+\def\CWEB{{\mc cweb}}
+\def\PASCAL{{\mc Pascal}}
+\title{The TIE Processor}
+\author{Klaus Guntermann\\
+TH Darmstadt\\
+Fachbereich Informatik\\
+Institut f\"ur Theoretische Informatik}
+
+\date{December 1986}
+\begin{document}
+\maketitle
+\section{Introduction}
+
+To install a program on a computer usually
+system dependent changes are needed.
+The \WEB\ system allows to describe these changes in a
+so called change file.
+To incorporate the changes into the program \TANGLE\ processes
+the original source file and inserts the changes into the proper places.
+
+Sometimes it is good practice to develop a set of change files to be able to
+distinguish between different changes like
+program enhancements, bug fixes, system dependent changes
+and output device dependent modifications.
+Additionally this allows combinations of changes that can be used with a set of
+programs that share some common features.
+
+The processors \TANGLE\ and \WEAVE\ can handle only one change file.
+The combination of change files is done best in another preprocessing step.
+\TIE\ is able to create either a new master file or a single change file that
+comprises the effect of all change files.
+
+Since \TIE\ does not know anything about \WEB\ programs but only about the
+structure of change files, it is possible to use this program for other
+programming languages as well.
+You just pretend that you want to create a new master file and \TIE\ will go
+and insert all the changes from your change files.
+
+
+
+\section{Application}
+
+The current version of \TIE\ accepts a master file and up to 9 change files.
+Because in general it is important to use the changes in their proper sequence
+the order of the files must be chosen carefully.
+
+The standard version of \TIE\ prompts the user for the names of the change
+files interactively.
+The implementor may choose to replace this by a command line interface if the
+operating system and the compiler support such features.
+Within this document we will refer to the interactive version of \TIE.
+
+First the name of the master file must be entered.
+The extension of this name (beginning with a period)
+is stripped to get the base name of the file.
+The base name and the extensions {\tt CF1}, \dots, {\tt CF9}
+are checked.
+If such files exist they are opened and are allocated as current change files.
+As soon as one of these files is not found the user is asked to supply
+additional change file names.
+Thus change files with other names may be used deliberately.
+If there are no more changes the user enters an empty name just hitting
+``Return''.
+Then the processing mode still must be supplied.
+The user may request the creation of a new master file by selection of mode
+``m'' or he may want to create a single change file by selection of mode ``c''.
+
+The name of the output file created is not specified interactively.
+It depends on the runtime system of the \PASCAL\ compiler and the
+operating system whether it must be given before the program is started
+or at some point when the file is to be opened.
+
+The multiple change files are used as if the single change files were merged
+into the master files step by step.
+Thus more than 9 change files might be incorporated by repeated application of
+\TIE.
+
+Please note that even when multiple change files are processed each of the
+files is read only once.
+For each of the change files and for the master file there is only one line in
+memory at a time (neglecting operating system buffering).
+Thus the storage requirement of \TIE\ does not depend on the size of the change
+files or the size of a single changed section.
+
+\vfill\eject
+\def\eof{$\langle$EOF$\rangle$}
+\section{Example}
+
+To illustrate the actions \TIE\ performs you may inspect the following example
+that exercises some of the border line cases.
+
+$$\vbox{
+\halign{#\hfill\qquad\quad&#\hfill\qquad\quad&#\hfill\qquad\quad&#\hfill\cr
+``master'' &{\tt CF1} &{\tt CF2} &{\tt CF3}\cr
+line 1 &@x &@x &@x\cr
+line 2 &line 2 &line 1 &changed line 4\cr
+line 3 &line 3 &changed line 2 &@y\cr
+line 4 &@y &changed line 3 &final line 4\cr
+line 5 &changed line 2 &inserted line &@z\cr
+line 6 &changed line 3 &line 4 &\eof\cr
+line 7 &inserted line &@y\cr
+line 8 &@z &final line 2\cr
+line 9 & &final line 3\cr
+line 10 &@x &changed line 4\cr
+\eof &line 7 &@z\cr
+ &@y\cr
+ &changed line 7 &@x\cr
+ &@z &changed line 7\cr
+ &\eof &line 8\cr
+ & &@y\cr
+ & &final line 7\cr
+ & &final line 8\cr
+ & &@z\cr
+ & &\eof\cr}
+}$$
+\vfill\eject
+Using these input files and running \TIE\ twice to create a new master file
+and a new change file will result in the following output files:
+
+$$\vbox{
+\halign{#\hfill\qquad\quad&&#\hfill\qquad\quad\cr
+``master'' &``change''\cr
+final line 2 &@x\cr
+final line 3 &line 1\cr
+final line 4 &line 2\cr
+line 5 &line 3\cr
+line 6 &line 4\cr
+final line 7 &@y\cr
+final line 8 &final line 2\cr
+line 9 &final line 3\cr
+line 10 &final line 4\cr
+\eof &@z\cr
+ &\cr
+ &@x\cr
+ &line 7\cr
+ &line 8\cr
+ &@y\cr
+ &final line 7\cr
+ &final line 8\cr
+ &@z\cr
+ &\eof\cr}
+}$$
+\end{document}