1053Object Third_Floor "Third Floor"1054 with name "trapdoor",1055 description1056 "Atop the marble staircase, this third floor 1057 foyer fans out into Rooms from Chapter V. These run:^1058 ^ south to Corridor 22 (inventories) 1059 and the List Property Office,1060 ^ @00 to Room 24 (Curious Names),1061 ^ @01 to Room 28, which is divided by a glass window.^1062 ^Only a very rickety1063 ladder goes further up, through an open trapdoor to the roof.",1064 d_to Second_Floor, u_to roof,1065 e_to Room24, w_to window_w, s_to Corridor22,1066 has light;10671068Object -> "map"1069 with name "map" "third" "floor",1070 initial "A map of the third floor is embossed in one wall.",1071 description1072 [; font off;1073 print1074 "^+------------------------------------------+1075 ^| |1076 ^| (glass |1077 ^| window) |1078 ^| ! |1079 ^| Room ! 28 --- Stairs --- Room 24 |1080 ^| ! (you are here) Names |1081 ^| | | |1082 ^| | Museum Cafe |1083 ^| Corridor 22 |1084 ^| (Inventories) |1085 ^| / | @@92 |1086 ^| / | @@92 |1087 ^| Room 23 W --- Room 23 --- Room 23 E |1088 ^| (listing List Property (I Ching) |1089 ^| machine) Office |1090 ^+------------------------------------------+^";1091 font on;1092 ],1093 has static;10941095Object -> "Lexicon"1096 with name "lexicon",1097 initial1098 "On the top step is a discarded Lexicon of verbs.",1099 description1100 "(The lexicon has the number 27 written on the spine.)^^1101 Inside are many familiar verbs that you regularly use1102 when navigating through Inform games. There are also1103 some special ones, only available in the Museum...^^1104 ~megalook~ : like ~look~ but much fuller;^1105 ~threefold ~ : this doesn't1106 actually do anything, but it shows how a verb can1107 be parsed which has three objects, not just 0 to 21108 as usual;^1109 ~time 1110 (go out onto the Balcony to see sunrise at 6 AM);^1111 ~fp ~ : shows how floating-point1112 numbers can be parsed;^1113 ~dial ~ : likewise phone numbers.^^1114 Also, in the Museum, ~lock~ and ~unlock~ are cunningly1115 able to presume keys as their second objects.";11161117! --------------------------------------------------------------------------11181119Object Corridor22 "Corridor 22"1120 with description1121 "Runs south of the top floor foyer, and leads to Room 23,1122 such a long room that you can enter it to southwest, south1123 or southeast.^^1124 In the floor is a curious solid quartz window.",1125 n_to Third_Floor,1126 s_to Room23, se_to Room23b, sw_to Room23a,1127 d_to "Solid quartz.",1128 has light;11291130Object -> "quartz window"1131 with name "quartz" "window",1132 before1133 [; Examine, Search, LookUnder:1134 print "Through the window you can hazily make out the contents 1135 of the Grammar Hall below...^";1136 if (Locale(Grammar_Hall, "You can see",1137 "You can also see")~=0)1138 " on the floor below.";1139 rtrue;1140 ],1141 has scenery;11421143Object -> "Geoffrey's book"1144 with name "book" "old" "harmless" "lethal" "of" "geoffrey^s",1145 invent "that harmless old book of Geoffrey's",1146 before1147 [; Examine:1148 self.invent = "that lethal old book of Geoffrey's";1149 "The apparently harmless book turns fiery hot in your hands, 1150 and your eyes are dragged toward the hideous sigils 1151 inscribed within it... Just in time, you break the gorgon 1152 gaze and look away.^^1153 [From this moment, its inventory entry changes.]";1154 ],1155 has proper;11561157Object -> "platinum pyramid"1158 with name "platinum" "pyramid",1159 description "No matter how many times you pick this up and put it 1160 down again, it never becomes an ~ordinary~ object for room 1161 description purposes -- it always has a line to itself.",1162 describe1163 [; "^The platinum pyramid catches the light beautifully.";1164 ];11651166Object -> "ornate box"1167 with name "decorated" "ornate" "box",1168 invent1169 [; if (inventory_stage==1) give self general;1170 else give self ~general;1171 ],1172 short_name1173 [; if (self has general) { print "box"; rtrue; } ],1174 article1175 [; if (self has general)1176 { print "that most remarkably decorated"; rtrue;1177 }1178 else print "an"; ],1179 description1180 "[What's interesting about the ornate box is that its1181 inventory listing overrides its short name entirely,1182 and yet its contents will still be inventoried.]",1183 has open openable container;11841185Object -> -> "pearl"1186 with name "pearl",1187 description "Don't look at me - I'm irrelevant.";11881189! --------------------------------------------------------------------------11901191Object Room23a "Room 23 @01: Inventory Annexe"1192 with description1193 "The @01ern end of Room 23 is a housing for the Listing Machine.",1194 e_to Room23, ne_to Corridor22,1195 has light;11961197Object -> list_machine "listing machine"1198 with name "listing" "list" "machine",1199 describe1200 [ i; print "The listing machine has a go button and a number of 1201 switches, whose current settings are as follows:^";1202 objectloop (i in self)1203 { if (i~=list_go)1204 { print (address) (i.&name)-->0, " ";1205 if (i has on) print "(on)^"; else print "(off)^";1206 }1207 }1208 rtrue;1209 ],1210 has transparent static;12111212Object -> -> list_go "go button"1213 with name "go" "button" "control",1214 before1215 [ i j; Push:1216 objectloop (i in list_machine)1217 if (i~=self && i has on) j=j+i.number;1218 print "~In this style, your inventory is listed as 1219 follows...^";1220 WriteListFrom(child(player), j, 1);1221 "...~";1222 ],1223 has static;12241225Class BitSwitch1226 with name "switch" "control",1227 has switchable static;12281229BitSwitch -> -> "newline switch" 1230 with name "newline", number NEWLINE_BIT;1231BitSwitch -> -> "indent switch" 1232 with name "indent", number INDENT_BIT;1233BitSwitch -> -> "fullinv switch" 1234 with name "fullinv", number FULLINV_BIT, has on;1235BitSwitch -> -> "english switch" 1236 with name "english", number ENGLISH_BIT, has on;1237BitSwitch -> -> "recurse switch" 1238 with name "recurse", number RECURSE_BIT, has on;1239BitSwitch -> -> "always switch" 1240 with name "always", number ALWAYS_BIT;1241BitSwitch -> -> "terse switch" 1242 with name "terse", number TERSE_BIT;1243BitSwitch -> -> "partinv switch" 1244 with name "partinv", number PARTINV_BIT;1245BitSwitch -> -> "defart switch" 1246 with name "defart", number DEFART_BIT;1247BitSwitch -> -> "workflag switch" 1248 with name "workflag", number WORKFLAG_BIT;1249BitSwitch -> -> "isare switch" 1250 with name "isare", number ISARE_BIT;1251BitSwitch -> -> "conceal switch" 1252 with name "conceal", number CONCEAL_BIT;12531254! --------------------------------------------------------------------------12551256[ CoinsTogether cla i x y;1257 objectloop (i ofclass cla)1258 { x=parent(i);1259 if (y==0) y=x; else { if (x~=y) return 0; }1260 }1261 return y;1262];12631264[ Face x; if (x.number==1) print "Heads"; else print "Tails"; ];12651266Array gold_trigrams --> "fortune" "change" "river flowing" "chance"1267 "immutability" "six stones in a circle"1268 "grace" "divine assistance";1269Array silver_trigrams --> "happiness" "sadness" "ambition" "grief"1270 "glory" "charm" "sweetness of nature"1271 "the countenance of the Hooded Man";12721273[ Trigram cla i k state;1274 objectloop (i ofclass cla)1275 { print (Face) i; if (k++<2) print ","; print " ";1276 state=state*2 + (i.number-1);1277 }1278 if (cla == GoldCoin) i=gold_trigrams; else i=silver_trigrams;1279 print "(", (string) i-->state, ")";1280];12811282[ CoinsLT cla k i c;1283 if (inventory_stage==1)1284 { if (cla == GoldCoin) print "the gold"; else print "the silver";1285 print " coins ";1286 k=CoinsTogether(cla);1287 if (k==location || k has supporter)1288 { objectloop (i ofclass cla)1289 { print (name) i;1290 switch(++c)1291 { 1: print ", "; 2: print " and ";1292 3: print " (showing the trigram ", (Trigram) cla, ")";1293 }1294 }1295 rtrue;1296 }1297 c_style = c_style | (ENGLISH_BIT+NOARTICLE_BIT);1298 if (c_style & NEWLINE_BIT ~= 0) c_style = c_style - NEWLINE_BIT;1299 if (c_style & INDENT_BIT ~= 0) c_style = c_style - INDENT_BIT;1300 }1301 rfalse;1302];13031304Class Coin1305 with number 1, article "the",1306 parse_name1307 [ i j w;1308 if (parser_action==##TheSame) return -2;1309 w='gold'; if (self ofclass SilverCoin) w='silver';1310 for (::i++)1311 { j=NextWord();1312 if (j=='coins') parser_action=##PluralFound;1313 else if (j~='coin' or w or self.name) return i;1314 }1315 ],1316 after1317 [ j;1318 Drop, PutOn:1319 self.number=random(2); print (Face) self, ". ";1320 if (self ofclass GoldCoin) j=GoldCoin; else j=SilverCoin;1321 if (CoinsTogether(j)~=0)1322 { print "The ";1323 if (j == GoldCoin) print "gold"; else print "silver";1324 " trigram is now ", (Trigram) j, ".";1325 }1326 new_line; rtrue;1327 ];13281329Class GoldCoin class Coin1330 with list_together [; return CoinsLT(GoldCoin); ];1331Class SilverCoin class Coin1332 with list_together [; return CoinsLT(SilverCoin); ];13331334Object Room23b "Room 23 @00: Chinese Room"1335 with description "A small, well-composed Chinese room for meditation, 1336 through which ~a wind can blow~. (But only if it blows from 1337 @01 back to north@01, because they're the only exits.)1338 From each cornice of the ceiling, a cherub looks down.",1339 w_to Room23, nw_to Corridor22,1340 has light;13411342Object -> "Chinese scroll"1343 with name "chinese" "scroll" "instructions",1344 initial "A scroll hangs on one wall.",1345 description1346 "Instructing you in the arts of the I Ching, the scroll advises 1347 you to throw the two trigrams of gold and silver coins, that 1348 you may find wisdom in the result.";13491350GoldCoin -> "goat" with name "goat";1351GoldCoin -> "deer" with name "deer";1352GoldCoin -> "chicken" with name "chicken";13531354SilverCoin -> "robin" with name "robin";1355SilverCoin -> "snake" with name "snake";1356SilverCoin -> "bison" with name "bison";13571358Global cherub_warning_given;1359Class Cherub1360 with parse_name1361 [ i j flag;1362 for (flag=1:flag==1:)1363 { flag=0;1364 j=NextWord();1365 if (j=='cherub' || j==self.name) flag=1;1366 if (j=='cherubs')1367 { parser_action=##PluralFound; flag=1;1368 if (cherub_warning_given==0)1369 print "(I'll let this go, 1370 but the plural of ~cherub~ is ~cherubim~.)^";1371 cherub_warning_given = true;1372 }1373 if (j=='cherubim')1374 { parser_action=##PluralFound; flag=1; }1375 i++;1376 }1377 return i-1;1378 ],1379 has scenery;13801381Cherub -> "northeast cherub" with name "northeast";1382Cherub -> "southeast cherub" with name "southeast";1383Cherub -> "northwest cherub" with name "northwest";1384Cherub -> "southwest cherub" with name "southwest";13851386! --------------------------------------------------------------------------13871388Object Room23 "Room 23: List Property Office"1389 with description1390 "This the List Property Office (it seems that an ~O~ 1391 was lost some time ago), at the southern end of the top floor; 1392 the management have kindly provided a green baize table, while 1393 the rest is presumably the work of patrons.^^1394 Room 23 continues @00 to @01.",1395 n_to Corridor22,1396 e_to Room23b,1397 w_to Room23a1398 has light;13991400Object -> "green baize table"1401 with name "green" "baize" "table"1402 has scenery supporter;14031404Class PlasticCutlery1405 with name "plastic" "cutlery", article "a plastic",1406 list_together1407 [; if (inventory_stage==1)1408 { if (c_style & NOARTICLE_BIT == 0) c_style=c_style+NOARTICLE_BIT;1409 if (c_style & ENGLISH_BIT == 0) c_style=c_style+ENGLISH_BIT;1410 if (c_style & NEWLINE_BIT ~= 0) c_style=c_style-NEWLINE_BIT;1411 if (c_style & INDENT_BIT ~= 0) c_style=c_style-INDENT_BIT;1412 print "a plastic ";1413 }1414 ];14151416PlasticCutlery -> "fork" with name "fork";1417PlasticCutlery -> "knife" with name "knife";1418PlasticCutlery -> "spoon" with name "spoon";14191420Class Hat with list_together "hats", name "hat" "hats", has clothing;14211422Hat -> "fez" with name "fez";1423Hat -> "Panama" with name "panama";1424Hat -> "sombrero" with name "sombrero";14251426Class Letter1427 with list_together1428 [; if (inventory_stage==1)1429 { print "the letters ";1430 c_style = c_style | (ENGLISH_BIT+NOARTICLE_BIT);1431 if (c_style & NEWLINE_BIT ~= 0) c_style = c_style - NEWLINE_BIT;1432 if (c_style & INDENT_BIT ~= 0) c_style = c_style - INDENT_BIT;1433 }1434 else print " from a Scrabble set";1435 ],1436 short_name1437 [; if (listing_together ofclass Letter) rfalse;1438 print "letter ", (object) self, " from a Scrabble set"; rtrue;1439 ],1440 article "the";14411442Letter -> "X" with name "x";1443Letter -> "Y" with name "y";1444Letter -> "Z" with name "z";1445Letter -> "P" with name "p";1446Letter -> "Q" with name "q";1447Letter -> "R" with name "r";14481449Object -> "defrosting Black Forest gateau"1450 with name "black" "forest" "gateau" "cake",1451 has edible;14521453Object -> "Punch magazine"1454 with name "punch" "magazine",1455 description1456 "Five years out of date by the cover, a hundred by the contents.",1457 list_together 1,1458 has proper;1459Object -> "issue of the Spectator"1460 with name "spectator" "issue" "magazine", article "a recent",1461 description1462 "Up to date by the cover, a nightmare view of the future within.",1463 list_together 1;14641465Object -> "die"1466 with name "die" "dice",1467 after [; Drop: print "It comes up ", random(6); "!"; ];146814691470Class Star1471 with name "star",1472 description1473 "A little star of precious-metal, perhaps exotic currency.",1474 parse_name1475 [ i j w;1476 if (parser_action==##TheSame)1477 { if ((parser_one.&name)-->0 == (parser_two.&name)-->0) return -1;1478 return -2;1479 }1480 w=(self.&name)-->0;1481 for (::i++)1482 { j=NextWord();1483 if (j=='stars') parser_action=##PluralFound;1484 else if (j~='star' or w) return i;1485 }1486 ],1487 list_together "stars",1488 plural1489 [; print (address) (self.&name)-->0;1490 if (~~(listing_together ofclass Star)) print " stars";1491 ],1492 short_name1493 [; if (listing_together ofclass Star)1494 { print (address) (self.&name)-->0; rtrue; }1495 ],1496 article1497 [; if (listing_together ofclass Star) print "one"; else print "a";1498 ];14991500Class GoldStar class Star with name "gold";1501Class SilverStar class Star with name "silver";1502Class BronzeStar class Star with name "bronze";15031504SilverStar -> "silver star";1505SilverStar -> "silver star";1506SilverStar -> "silver star";1507SilverStar -> "silver star";1508BronzeStar -> "bronze star";1509GoldStar -> "gold star";1510GoldStar -> "gold star";1511GoldStar -> "gold star";15121513! --------------------------------------------------------------------------15141515Object Room24 "Curious Names"1516 with description1517 "This is Room 24, @00 of the mezzanine. The exhibits are1518 packed in here, but fortunately there's a plaque making1519 some sense of it all.",1520 w_to Third_Floor, s_to Museum_Cafe,1521 has light;15221523Object -> plaque "plaque"1524 with name "plaque",1525 description1526 "Room 24 Plaque^^1527 Princess is capable of a startling change of name when kissed.^^1528 The genie's lamp, when rubbed, may make alarming things1529 happen to your ability to refer to the colours ~black~ and1530 ~white~. The stones may help you to experiment with this.^^1531 Carrying the magnifying glass allows you to ~magnify~ things.^^1532 The game's parser has been specially programmed for the1533 fly in amber object, so that ~put the fly in amber in box~1534 will work correctly (and not be interpreted as ~put (the fly) in1535 (amber in box)~).",1536 has scenery;15371538Object -> genies_lamp "genie's lamp"1539 with name "lamp",1540 before1541 [; Rub:1542 if (self hasnt general) give self general;1543 else give self ~general;1544 "A genie appears from the lamp, declaring:^^1545 ~Mischief is my sole delight:^ 1546 If white means black, black means white!~";1547 ];15481549Object -> "white stone" with name "white" "stone";1550Object -> "black stone" with name "black" "stone";15511552Object -> "fly in amber" with name "fly" "amber";15531554Object -> magnifier "magnifying glass"1555 with name "glass" "magnifying" "magnifier" "lense",1556 description "Using this, you can ~magnify~ things.";15571558[ MagnifySub;1559 if (magnifier notin player)1560 "You're not holding a magnifying glass.";1561 if (noun==magnifier) "Light is not so flexible as that.";1562 print "You can just make out that ", (the) noun,1563 " is inscribed as being ~object ", noun, "~.^";1564 if (magnifier hasnt general)1565 { give magnifier general;1566 "^(When you're carrying the magnifier, you can refer to 1567 things by their numbers like this; and you can even use 1568 # to mean ~any single object~ and * to mean ~all objects~.)";1569 }1570];15711572[ ParseNoun obj;1573 if (magnifier notin player) return -1;1574 if (NextWord() == 'object' && TryNumber(wn) == obj) return 2;1575 wn--;1576 if (WordLength(wn)==1 && WordAddress(wn)->0 == '#') return 1;1577 if (WordLength(wn)==1 && WordAddress(wn)->0 == '*')1578 { parser_action = ##PluralFound; return 1; }1579 return -1;1580];15811582Object -> "/?%?/ (the artiste formally known as Princess)"1583 with name "princess" "artiste" "formally" "known" "as",1584 description "You somehow feel it would be appropriate 1585 to kiss Princess.",1586 short_name1587 [; if (self hasnt general) { print "Princess"; rtrue; }1588 ],1589 react_before1590 [; Listen: print_ret (name) self, " sings a soft siren song.";1591 ],1592 initial1593 [; print_ret (name) self, " is singing softly.";1594 ],1595 parse_name1596 [ x n; if (self hasnt general)1597 { if (NextWord()=='princess') return 1;1598 return 0;1599 }1600 x=WordAddress(wn);1601 if ( x->0 == '/' && x->1 == '?' && x->2 == '%'1602 && x->3 == '?' && x->4 == '/')1603 { while (wn<=parse->1 && WordAddress(wn++)<x+5) n++;1604 return n;1605 }1606 return -1;1607 ],1608 life1609 [; Kiss: give self general; self.life = NULL;1610 "In a fairy-tale transformation, the Princess 1611 steps back and astonishes the world by announcing 1612 that she will henceforth be known as ~/?%?/~.";1613 ],1614 has animate proper female;16151616! --------------------------------------------------------------------------16171618Object Museum_Cafe "Room 24 Annexe: The Museum Cafe"1619 with description1620 "Very much a self-service refreshments area, which1621 somehow cunningly continues the exhibition from the north.",1622 n_to Room24,1623 has light;16241625Object -> "upright fridge"1626 with name "upright" "fridge",1627 initial "There is an upright fridge in one corner.",1628 after1629 [; Open:1630 print1631 "On the inside of the door is a note to the effect 1632 that the pepper is a standardly-named Inform object 1633 and can be called ~green~, ~pepper~, ~green pepper~, 1634 ~pepper green~, etc.; 1635 whereas, in the case of the red tomato, ~red~ and 1636 ~tomato fried red~, etc., will not be allowed.^^";1637 <<Search self>>;1638 ],1639 has openable container static;16401641Object -> -> "green pepper"1642 with name "green" "pepper",1643 has edible;16441645Object -> -> "red fried tomato"1646 with name "red" "pepper",1647 parse_name1648 [ i w; w=NextWord();1649 while (w=='red' or 'fried')1650 { w=NextWord(); i++;1651 }1652 if (w=='tomato') return i+1;1653 return 0;1654 ],1655 has edible;16561657Object -> "drinks machine"1658 with name "drinks" "machine",1659 initial1660 "Next to the fridge is a drinks machine with buttons 1661 for Cola, Coffee and Tea.",1662 has static transparent;1663Object -> -> "drinks machine button"1664 has scenery1665 with parse_name1666 [ i flag type;1667 for (: flag == 0: i++)1668 { flag = 1;1669 switch(NextWord())1670 { 'button', 'for': flag = 0;1671 'coffee': if (type == 0) { flag = 0; type = 1; }1672 'tea': if (type == 0) { flag = 0; type = 2; }1673 'cola': if (type == 0) { flag = 0; type = 3; }1674 }1675 }1676 if (type==drink.number && i==2 && type~=0 && drink in player)1677 return 0;1678 self.number=type; return i-1;1679 ],1680 number 0,1681 before1682 [; Push, SwitchOn:1683 if (self.number == 0)1684 "You'll have to say which button to press.";1685 if (parent(drink) ~= 0) "The machine's broken down.";1686 drink.number = self.number; move drink to player; itobj = drink;1687 "Whirr! The machine puts ", (a) drink, " into your 1688 glad hands.";1689 Attack: "The machine shudders and squirts cola at you.";1690 Drink: "You can't drink until you've worked the machine.";1691 ];1692Object drink "drink"1693 with parse_name1694 [ i flag type;1695 for (: flag == 0: i++)1696 { flag = 1;1697 switch(NextWord())1698 { 'drink', 'cup', 'of': flag = 0;1699 'coffee': if (type == 0) { flag = 0; type = 1; }1700 'tea': if (type == 0) { flag = 0; type = 2; }1701 'cola': if (type == 0) { flag = 0; type = 3; }1702 }1703 }1704 if (type ~= 0 && type ~= self.number) return 0;1705 return i-1;1706 ],1707 short_name1708 [; print "cup of ";1709 switch (self.number)1710 { 1: print "coffee"; 2: print "tea"; 3: print "cola"; }1711 rtrue;1712 ],1713 number 0,1714 before1715 [; Drink: remove self;1716 "Ugh, that was awful. You crumple the cup and responsibly 1717 dispose of it.";1718 ];17191720! --------------------------------------------------------------------------17211722Class WindowRoom1723 with description1724 [; print "This is one end of a long east/west room. ";1725 if (self==window_w) "An exit leads back @00.";1726 "There appears to be no way in or out at this end.";1727 ],1728 before1729 [; Examine, Search: ;1730 default:1731 if (inp1~=1 && noun~=0 && noun in self.far_side)1732 print_ret (The) noun, " is on the far side of 1733 the glass.";1734 if (inp2~=1 && second~=0 && second in self.far_side)1735 print_ret (The) second, " is on the far side of 1736 the glass.";1737 ],1738 after1739 [; Look:1740 if (ggw has general) rfalse;1741 print "^The room is divided by a great glass window";1742 if (location.far_side hasnt light) " onto darkness.";1743 print ", stretching from floor to ceiling.^";1744 if (Locale(location.far_side,1745 "Beyond the glass you can see",1746 "Beyond the glass you can also see")~=0) ".";1747 ],1748 has light;17491750WindowRoom window_w "Room 28: @01 of Window"1751 with e_to Third_Floor, w_to "The window is in your way.",1752 far_side window_e;17531754Object -> "plastic cup"1755 with name "plastic" "cup";17561757WindowRoom window_e "Room 28: @00 of Window"1758 with far_side window_w;17591760Key -> "bronze key"1761 with name "bronze";17621763Object -> "golden chalice"1764 with name "golden" "chalice" "cup" "grail" "holy";17651766Object ggw "great glass window"1767 with name "great" "glass" "window",1768 before1769 [ place; Examine, Search: place=location;1770 if (place.far_side hasnt light)1771 "The other side is dark.";1772 print "The view through the window:^";1773 give self general;1774 PlayerTo(place.far_side,1); <Look>; PlayerTo(place,1);1775 give self ~general;1776 give place.far_side ~visited; rtrue;1777 ],1778 found_in window_w window_e,1779 has scenery;17801781! ==========================================================================1782
Last updated 23 June 2004.
This site is no longer supported; information may be out of date.
Maintained as a historical archive by the Interactive Fiction Technology Foundation.
Copyright 1993-2018 IFTF, CC-BY-SA unless otherwise noted.
This page was originally managed by Graham Nelson (graham@gnelson.demon.co.uk) assisted by C Knight.