Path: utzoo!utgpu!watserv1!watmath!att!linac!uwm.edu!wuarchive!cs.utexas.edu!sun-barr!newstop!exodus!SGI.COM From: weissman%pianoforte.esd.sgi.com@SGI.COM (Terry Weissman) Newsgroups: comp.sources.x Subject: v11i062: seahaven - solitaire card game, Part02/02 Message-ID: <7931@exodus.Eng.Sun.COM> Date: 13 Feb 91 07:15:29 GMT References: Sender: news@exodus.Eng.Sun.COM Lines: 2062 Approved: argv@sun.com Submitted-by: Terry Weissman Posting-number: Volume 11, Issue 62 Archive-name: seahaven/part02 #!/bin/sh # to extract, remove the header and type "sh filename" if `test ! -s ./auto.h` then echo "writing ./auto.h" cat > ./auto.h << '\Rogue\Monster\' struct SolutionLogRec { int rank; int suit; int dest; // 0-9 = stack, -99 = space, other = king SolutionLogRec *next; }; typedef struct SolutionLogRec *SolutionLog; extern int AutoPlay(); extern SolutionLog solutionhead; \Rogue\Monster\ else echo "will not over write ./auto.h" fi if `test ! -s ./card.C` then echo "writing ./card.C" cat > ./card.C << '\Rogue\Monster\' /* * Author: Terry Weissman * weissman@sgi.com */ #include "seahaven.h" extern char *card_bits[52]; struct WindowCardRec { Window window; Card card; }; typedef struct WindowCardRec *WindowCard; static WindowCardRec windowcard[100]; static int numwindowcard = 0; static GC highlightgc; static void RegisterWindow(Card card, Window window) { int i; if (windowcard == 0 || window > windowcard[numwindowcard - 1].window) { windowcard[numwindowcard].window = window; windowcard[numwindowcard].card = card; numwindowcard++; return; } for (i=0 ; i window) { for (int j = numwindowcard ; j > i ; j--) { windowcard[j] = windowcard[j-1]; } windowcard[i].window = window; windowcard[i].card = card; numwindowcard++; return; } } Punt("Bug in RegisterWindow!"); } Card WindowToCard(Window w) { int l, h, i; l = 0; h = numwindowcard; while (l < h) { i = (l + h) / 2; if (w == windowcard[i].window) return windowcard[i].card; if (w > windowcard[i].window) l = i + 1; else h = i; } if (w == windowcard[i].window) return windowcard[i].card; return NULL; } CardRec::CardRec(int s, int v, unsigned long fore, unsigned long back, char *bitmap) { suit = s; value = v; XSetWindowAttributes attributes; long valuemask = CWEventMask | CWBackPixmap; attributes.event_mask = ButtonPressMask | ButtonReleaseMask | ButtonMotionMask; attributes.background_pixmap = XCreatePixmapFromBitmapData(dpy, toplevel, bitmap, CARDWIDTH, CARDHEIGHT, fore, back, DefaultDepth(dpy, screen)); window = XCreateWindow(dpy, toplevel, v * CARDWIDTH, s * CARDHEIGHT, CARDWIDTH, CARDHEIGHT, 0, (int) CopyFromParent, InputOutput, (Visual *) CopyFromParent, valuemask, &attributes); XMapWindow(dpy, window); RegisterWindow(this, window); } Stack CardRec::getStack() { return stack; } // single stacks are symmetric for saving purposes Stack CardRec::getFoldedStack() { if (stack ==singlestack[0] || stack == singlestack[1] || stack == singlestack[2] || stack == singlestack[3]) return singlestack[0]; else return stack; } int CardRec::getSuit() { return suit; } int CardRec::getValue() { return value; } int CardRec::getX() { return x; } int CardRec::getY() { return y; } // single stacks are symmetric for saving purposes int CardRec::getFoldedY() { if (stack ==singlestack[0] || stack == singlestack[1] || stack == singlestack[2] || stack == singlestack[3]) return 0; else return y; } void CardRec::setLoc(int newx, int newy) { if (x != newx || y != newy) { x = newx; y = newy; XMoveWindow(dpy, window, x, y); } } void CardRec::raise() { XRaiseWindow(dpy, window); } void CardRec::raiseAbove(Card c) { XWindowChanges values; values.sibling = c->window; values.stack_mode = Above; XConfigureWindow(dpy, window, CWSibling | CWStackMode, &values); } void CardRec::raiseBelow(Card c) { XWindowChanges values; values.sibling = c->window; values.stack_mode = Below; XConfigureWindow(dpy, window, CWSibling | CWStackMode, &values); } void CardRec::setStack(Stack s) { stack = s; } void CardRec::highlight() { XFillRectangle(dpy, window, highlightgc, 0, 0, CARDWIDTH, CARDHEIGHT); } void CardRec::repaint() { XClearWindow(dpy, window); } Bool CardHandleEvent(XEvent *event) { Card card = WindowToCard(event->xany.window); if (!card || event->type == KeyPress) return False; if (event->type == ButtonPress) { if (event->xbutton.button > 1) { int suit = card->getSuit(); int value = card->getValue() + ((event->xbutton.button == 3) ? 1 : -1); if (value < 0 || value >= NUMVALUES) return True; cards[suit][value]->highlight(); XEvent ev; do { GetInterestingEvent(&ev); } while (ev.type != ButtonRelease); cards[suit][value]->repaint(); return True; } Card list[20]; int origx[20], origy[20]; int num = 0; int i; for (; card ; card = card->getStack()->getCardAbove(card)) { origx[num] = card->getX(); origy[num] = card->getY(); list[num++] = card; } list[num-1]->raise(); for (i=num-2 ; i>=0 ; i--) { list[i]->raiseBelow(list[i+1]); } Bool abort = False; for (;;) { XEvent ev; GetInterestingEvent(&ev); if (ev.type == ButtonPress) { abort = True; break; } while (ev.type == MotionNotify && XPending(dpy)) { XEvent ev2; XPeekEvent(dpy, &ev2); if (ev2.type == Expose) { XNextEvent(dpy, &ev2); if (ev2.xexpose.count == 0) score->repaint(); continue; } if (ev2.type != MotionNotify) break; GetInterestingEvent(&ev); } if (ev.type == MotionNotify || ev.type == ButtonRelease) { for (i=0 ; isetLoc (origx[i] + ev.xbutton.x_root - event->xbutton.x_root, origy[i] + ev.xbutton.y_root - event->xbutton.y_root); } if (ev.type == ButtonRelease) { Stack stack = StackFromPoint(list[0]->getX(), list[0]->getY()); if (!stack || stack == list[0]->getStack()) { abort = True; } if (!abort && stack->getType() == Single) { if (NumAvailableSingles() < num) abort = True; if (!abort && !stack->addCard(list[num-1])) { abort = True; } if (!abort) { for (i=num-2 ; i>=0 ; i--) { GetAvailableSingle()->addCard(list[i]); } AutoMoves(); UndoBoundary(); break; } } for (i=1 ; igetSuit() != list[i-1]->getSuit() || list[i]->getValue() != list[i-1]->getValue() - 1) { abort = True; break; } } if (NumAvailableSingles() < num - 1) abort = True; if (!abort && num > 1) { Card top = stack->getTopCard(); if ((top == NULL && list[0]->getValue() != NUMVALUES - 1) || (top != NULL && (top->getSuit() != list[0]->getSuit() || top->getValue() != list[0]->getValue() + 1))) { abort = True; } else { for (i=num-1 ; i>0 ; i--) { GetAvailableSingle()->addCard(list[i], DontMove); } } } if (!abort && !stack->addCard(list[0])) abort = True; if (!abort) { for (i=1 ; iaddCard(list[i])) { Punt("Bug in CardHandleEvent!"); } } AutoMoves(); UndoBoundary(); } break; } } } if (abort) { for (i=0 ; isetLoc(origx[i], origy[i]); } } return True; } void CardInit() { unsigned long red = GetColor("red", BlackPixel(dpy, screen)); unsigned long white = GetColor("white", WhitePixel(dpy, screen)); unsigned long black = GetColor("black", BlackPixel(dpy, screen)); for (int s=0 ; s= 2) ? black : red, white, card_bits[s * 13 + v]); } } highlightgc = XCreateGC(dpy, toplevel, 0, NULL); XSetForeground(dpy, highlightgc, GetColor("blue", BlackPixel(dpy, screen))); } \Rogue\Monster\ else echo "will not over write ./card.C" fi if `test ! -s ./main.C` then echo "writing ./main.C" cat > ./main.C << '\Rogue\Monster\' /* * Author: Terry Weissman * weissman@sgi.com */ #define MAIN #include "seahaven.h" #include #include #include #include void Punt(char *str) { fprintf(stderr, "%s: %s\n", progname, str); exit(1); } static void Usage() { fprintf(stderr, "Usage: %n [-d display] [-speedup speedfactor]\n", progname); exit(1); } main(int argc, char **argv) { char *displayname = NULL; Bool sync = False; int i; progname = argv[0]; speedup = 6; for (i=1 ; ic_class != StaticGray && visual->c_class != GrayScale && visual->bits_per_rgb > 1); backpixel = GetColor("forestgreen", WhitePixel(dpy, screen)); XSetWindowAttributes attributes; long valuemask = CWEventMask | CWBackPixel; attributes.event_mask = KeyPressMask; attributes.background_pixel = backpixel; toplevel = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, GAMEWIDTH, GAMEHEIGHT, 1, (int) CopyFromParent, InputOutput, (Visual *) CopyFromParent, valuemask, &attributes); XSetIconName(dpy, toplevel, "Seahaven"); XStoreName(dpy, toplevel, "Seahaven Towers"); font = XLoadQueryFont (dpy, "-*-helvetica-medium-r-normal--*-120-*-*-p-*-iso8859-1"); if (font == NULL) font = XLoadQueryFont(dpy, "fixed"); if (font == NULL) Punt("Can't find a font!"); CardInit(); StackInit(); score = new ScoreRec(); int y = GAMEHEIGHT - font->ascent - font->descent - 10; int width, width2, width3; Window undobutton = CreateButtonWindow("Undo (U)", 10, y, SouthWestGravity, &width); Window redobutton = CreateButtonWindow("Redo (R)", 10 + width + 5, y, SouthWestGravity, &width2); Window autobutton = CreateButtonWindow("Autoplay", 10 + width + 5 + width2 + 5, y, SouthWestGravity, NULL); Window quitbutton = CreateButtonWindow("Quit", 0, 0, SouthEastGravity, &width); Window newgamebutton = CreateButtonWindow("New Game", 0, 0, SouthEastGravity, &width2); Window restartbutton = CreateButtonWindow("Restart", 0, 0, SouthEastGravity, &width3); XMoveWindow(dpy, quitbutton, GAMEWIDTH - width - 10, y); XMoveWindow(dpy, newgamebutton, GAMEWIDTH - width - width2 - 20, y); XMoveWindow(dpy, restartbutton, GAMEWIDTH - width - width2 - width3 - 30, y); XMapWindow(dpy, toplevel); for (;;) { XEvent event; GetInterestingEvent(&event); if (!CardHandleEvent(&event)) { if (event.type == KeyPress) { char buf[100]; int length; length = XLookupString((XKeyEvent *)&event, buf, 100, NULL, NULL); for (i=0 ; i ./patchlevel.h << '\Rogue\Monster\' #define PATCHLEVEL 0 \Rogue\Monster\ else echo "will not over write ./patchlevel.h" fi if `test ! -s ./score.C` then echo "writing ./score.C" cat > ./score.C << '\Rogue\Monster\' /* * Author: Terry Weissman * weissman@sgi.com */ #include "seahaven.h" #include #include #include // For getenv() ScoreRec::ScoreRec() { int x = 10; int y = GAMEHEIGHT - 20 - 5 * (font->ascent + font->descent); XSetWindowAttributes attributes; long valuemask = CWEventMask | CWBackPixel | CWWinGravity; attributes.event_mask = ExposureMask; attributes.background_pixel = GetColor("forestgreen", WhitePixel(dpy, screen)); attributes.win_gravity = SouthWestGravity; window = XCreateWindow(dpy, toplevel, x, y, GAMEWIDTH, GAMEHEIGHT, 0, (int) CopyFromParent, InputOutput, (Visual *) CopyFromParent, valuemask, &attributes); XLowerWindow(dpy, window); XMapWindow(dpy, window); sprintf(savefile, "%s/.seahavensave", getenv("HOME")); FILE *fid = fopen(savefile, "r"); if (fid) { fscanf(fid, "%d %d %d %d %d %d\n", &wins, &losses, &streak, &maxwinstreak, &maxlosestreak, &wonlast); for (int i=0 ; i<52 ; i++) { int suit, value; fscanf(fid, "%d %d\n", &suit, &value); deck[i] = cards[suit][value]; } fclose(fid); LoadStacks(deck); } else { wins = 0; streak = 0; losses = 0; maxwinstreak = 0; maxlosestreak = 0; wonlast = True; NewGame(); } gc = XCreateGC(dpy, window, 0, NULL); XSetForeground(dpy, gc, GetColor("black", BlackPixel(dpy, screen))); XSetFont(dpy, gc, font->fid); woncurgame = lostcurgame = False; message = ""; } void ScoreRec::printLine(char *str, int value, char *plural) { char buf[200]; cury += font->ascent + font->descent; sprintf(buf, str, value, value == 1 ? "" : plural); if (buf[0]) XDrawString(dpy, window, gc, curx, cury, buf, strlen(buf)); } void ScoreRec::repaint(Bool erasefirst) { curx = 0; cury = 0; if (erasefirst) XClearWindow(dpy, window); printLine("%5d win%s", wins); printLine("%5d loss%s", losses, "es"); printLine("%5d game%s played", wins + losses); curx = GAMEWIDTH / 2; cury = 0; if (streak > 0) { if (wonlast) printLine("%5d game winning streak", streak); else printLine("%5d game losing streak", streak); } if (maxwinstreak > 0) { printLine("%5d game%s in longest winning streak", maxwinstreak); } if (maxlosestreak > 0) { printLine("%5d game%s in longest losing streak", maxlosestreak); } curx /= 2; printLine(message); } void ScoreRec::wonGame() { if (!woncurgame && !lostcurgame) { woncurgame = True; wins++; if (!wonlast) streak = 0; streak++; if (maxwinstreak < streak) maxwinstreak = streak; wonlast = True; message = ""; repaint(True); } } void ScoreRec::lostGame() { if (!woncurgame && !lostcurgame) { lostcurgame = True; losses++; if (wonlast) streak = 0; streak++; if (maxlosestreak < streak) maxlosestreak = streak; wonlast = False; message = ""; repaint(True); } } void ScoreRec::newGame() { woncurgame = lostcurgame = False; setMessage(""); } Bool ScoreRec::getGameWonOrLost() { return woncurgame || lostcurgame; } void ScoreRec::saveGameBegin() { curx = 0; } void ScoreRec::saveGameCard(Card c) { deck[curx++] = c; } void ScoreRec::saveGameEnd() { if (curx != 52) Punt("Bug in ScoreRec::saveGameEnd!"); FILE *fid = fopen(savefile, "w"); if (!fid) Punt("Can't open file in ScoreRec::saveGameEnd!"); fprintf(fid, "%d %d %d %d %d %d\n", wins, losses, streak, maxwinstreak, maxlosestreak, wonlast); for (int i=0 ; i<52 ; i++) { fprintf(fid, "%d %d\n", deck[i]->getSuit(), deck[i]->getValue()); } fclose(fid); } void ScoreRec::setMessage(char *msg) { if (strcmp(message, msg)) { char *oldmsg = message; message = msg; repaint(*oldmsg != 0); } } \Rogue\Monster\ else echo "will not over write ./score.C" fi if `test ! -s ./seahaven.h` then echo "writing ./seahaven.h" cat > ./seahaven.h << '\Rogue\Monster\' /* * Author: Terry Weissman * weissman@sgi.com */ #define NeedFunctionPrototypes 1 #include #ifndef NULL #define NULL 0 #endif NULL #ifdef MAIN #define global #else #define global extern #endif typedef class StackRec *Stack; typedef class CardRec *Card; class CardRec { public: CardRec(int suit, int value, unsigned long fore, unsigned long back, char *bitmap); // Window getWindow(); Stack getStack(); int getSuit(); int getValue(); int getX(); int getY(); Stack getFoldedStack(); int getFoldedY(); void setLoc(int, int); void raise(); void raiseAbove(Card); void raiseBelow(Card); void setStack(Stack); // To be called only by StackRec::addCard void highlight(); void repaint(); private: int suit; int value; Window window; int x, y; Stack stack; }; enum StackType {Single, Play, Done}; enum AnimType {Normal, Animate, DontMove}; class StackRec { public: StackRec(int x, int y); virtual void clear(); virtual int getX(); virtual int getY(); virtual Card getTopCard(); virtual Card getCardAbove(Card); virtual Card popCard(); virtual Bool addCard(Card, AnimType animate = Normal); // Return TRUE iff successful. virtual void repositionAll(); virtual int getStackingHeight(); virtual StackType getType(); protected: int x, y; int numcards; Card cards[20]; private: friend class Stack_Iterator; }; class Stack_Iterator { public: Stack_Iterator(Stack s) { stack = s; i = s->numcards; } Card operator()() { if (--i < 0) return 0; else return stack->cards[i]; } private: Stack stack; int i; // current index }; class ScoreRec { public: ScoreRec(); void repaint(Bool erasefirst = False); void wonGame(); void lostGame(); void newGame(); Bool getGameWonOrLost(); void saveGameBegin(); void saveGameCard(Card); void saveGameEnd(); void setMessage(char *); private: void printLine(char *, int value = 0, char *plural = "s"); Window window; GC gc; int wins, losses, streak, maxwinstreak, maxlosestreak; int wonlast; // Should be Bool, but this makes save easier int curx, cury; char savefile[512]; Card deck[52]; Bool woncurgame; Bool lostcurgame; char *message; }; typedef struct ScoreRec *Score; class UndoListRec { public: UndoListRec(); void clear(); void add(Card, Stack); void addBoundary(); void doUndo(); Bool isEmpty(); private: int num; int max; Card *cards; Stack *stacks; }; typedef class UndoListRec *UndoList; static const int NUMSUITS = 4; static const int NUMVALUES = 13; static const int CARDWIDTH = 48; static const int CARDHEIGHT = 66; static const int GAMEWIDTH = 700; static const int GAMEHEIGHT = 550; static const int NUMPLAYSTACK = 10; static const int NUMSINGLESTACK = 4; static const int CARDSPERPLAYSTACK = 5; global char *progname; global Display *dpy; global Window toplevel; global int screen; global Colormap cmap; global Bool hascolor; global Card cards[NUMSUITS][NUMVALUES]; global int speedup; global Score score; global XFontStruct *font; global unsigned long backpixel; global Bool inautoplay; // From main.C void Punt(char *); // From util.C extern unsigned long GetColor(char *, unsigned long); extern void GetInterestingEvent(XEvent *); extern Window CreateButtonWindow(char *, int, int, int, int *); // From card.C void CardInit(); Bool CardHandleEvent(XEvent *); // From stack.C void StackInit(); void NewGame(); void AutoMoves(); int NumAvailableSingles(); Stack GetAvailableSingle(); Stack StackFromPoint(int x, int y); void DoUndo(); void DoRedo(); void DoRestart(); void UndoBoundary(); void LoadStacks(Card deck[52]); extern Stack playstack[NUMPLAYSTACK]; extern Stack singlestack[NUMSINGLESTACK]; extern Stack donestack[NUMSUITS]; void DoAutoPlay(); \Rogue\Monster\ else echo "will not over write ./seahaven.h" fi if `test ! -s ./stack.C` then echo "writing ./stack.C" cat > ./stack.C << '\Rogue\Monster\' /* * Author: Terry Weissman * weissman@sgi.com */ #include "seahaven.h" #include "auto.h" #include // For time() #include // For random() #include #include Stack playstack[NUMPLAYSTACK]; Stack singlestack[NUMSINGLESTACK]; Stack donestack[NUMSUITS]; static Stack allstacks[100]; static int numstacks = 0; static int initializing = False; static int undoing = False; class StackPlayRec : public StackRec { public: StackPlayRec(int x, int y); virtual Bool addCard(Card, AnimType animate = Normal); virtual StackType getType(); private: }; class StackSingleRec : public StackRec { public: StackSingleRec(int x, int y); virtual Bool addCard(Card, AnimType animate = Normal); virtual StackType getType(); private: }; class StackDoneRec : public StackRec { public: StackDoneRec(int x, int y); virtual Bool addCard(Card, AnimType animate = Normal); virtual int getStackingHeight(); virtual StackType getType(); private: }; UndoListRec::UndoListRec() { max = 100; cards = (Card *) malloc(max * sizeof(Card)); stacks = (Stack *) malloc(max * sizeof(Stack)); clear(); } void UndoListRec::clear() { num = 0; } void UndoListRec::add(Card c, Stack s) { if (num >= max) { max += 100; cards = (Card *) realloc((char *) cards, max * sizeof(Card)); stacks = (Stack *) realloc((char *) stacks, max * sizeof(Stack)); } cards[num] = c; stacks[num] = s; num++; } void UndoListRec::addBoundary() { if (num > 0 && cards[num - 1] != NULL) add(NULL, NULL); } void UndoListRec::doUndo() { initializing = True; // Hack to fool StackPlayRec::addCard. if (num > 0 && cards[num - 1] == NULL) num--; while (num > 0 && cards[num - 1] != NULL) { num--; stacks[num]->addCard(cards[num]); } initializing = False; for (int i=0 ; irepositionAll(); } Bool UndoListRec::isEmpty() { for (int i = 0 ; iadd(c, s); } void UndoBoundary() { undostack.addBoundary(); redostack.clear(); } void DoUndo() { undoing = True; undostack.doUndo(); undoing = False; redostack.addBoundary(); } void DoRedo() { redostack.doUndo(); undostack.addBoundary(); } void DoRestart() { while (!undostack.isEmpty()) DoUndo(); } StackRec::StackRec(int newx, int newy) { x = newx; y = newy; numcards = 0; allstacks[numstacks++] = this; } void StackRec::clear() { numcards = 0; } int StackRec::getX() { return x; } int StackRec::getY() { return y; } Card StackRec::getTopCard() { if (numcards == 0) return NULL; return cards[numcards - 1]; } Card StackRec::getCardAbove(Card c) { int i; for (i=0 ; i b) ? a : b; } void StackRec::repositionAll() { for (int i=0 ; isetLoc(x, y + i * getStackingHeight()); } } Card StackRec::popCard() { if (numcards == 0) return NULL; numcards--; return cards[numcards]; } Bool StackRec::addCard(Card c, AnimType animate) { if (c->getStack() == this) Punt("Error in StackRec::addCard!"); if (animate == Animate) { c->raise(); int oldx = c->getX(); int oldy = c->getY(); int newx = x; int newy = y + numcards * getStackingHeight(); int numsteps = Max(Abs(oldx - newx), Abs(oldy - newy)) / speedup; float curx = (float) oldx; float cury = (float) oldy; for (int i = 0 ; isetLoc((int) curx, (int) cury); XFlush(dpy); } } if (animate != DontMove) { if (numcards > 0) c->raiseAbove(cards[numcards - 1]); c->setLoc(x, y + numcards * getStackingHeight()); if (inautoplay) XFlush(dpy); } Stack old = c->getStack(); if (old && old->popCard() != c) { Punt("Couldn't find card in old stack in StackRec::addCard!"); } AddUndo(c, c->getStack()); c->setStack(this); cards[numcards++] = c; return True; } int StackRec::getStackingHeight() { return 22; } StackType StackRec::getType() { Punt("Invalid call to base class: StackRec::getType()"); return Single; } StackPlayRec::StackPlayRec(int x, int y) : (x, y) { } Bool StackPlayRec::addCard(Card c, AnimType animate) { if (!initializing) { if (numcards == 0) { if (c->getValue() != NUMVALUES - 1) return False; } else { if (c->getSuit() != cards[numcards - 1]->getSuit() || c->getValue() != cards[numcards - 1]->getValue() - 1) return False; } } return StackRec::addCard(c, animate); } StackType StackPlayRec::getType() { return Play; } StackSingleRec::StackSingleRec(int x, int y) : (x, y) { XSetWindowAttributes attributes; long valuemask = CWBackPixel | CWBorderPixel; attributes.background_pixel = GetColor("darkgreen", WhitePixel(dpy, screen)); attributes.border_pixel = GetColor("green", BlackPixel(dpy, screen)); Window w = XCreateWindow(dpy, toplevel, x - 1, y - 1, CARDWIDTH, CARDHEIGHT, 1, (int) CopyFromParent, InputOutput, (Visual *) CopyFromParent, valuemask, &attributes); XLowerWindow(dpy, w); XMapWindow(dpy, w); } StackSingleRec::addCard(Card c, AnimType animate) { if (numcards) return False; return StackRec::addCard(c, animate); } StackType StackSingleRec::getType() { return Single; } StackDoneRec::StackDoneRec(int x, int y) : (x, y) { } StackDoneRec::addCard(Card c, AnimType animate) { if (numcards == 0) { if (c->getValue() != 0) return False; } else { if (c->getSuit() != cards[numcards - 1]->getSuit() || c->getValue() != cards[numcards - 1]->getValue() + 1) return False; } return StackRec::addCard(c, animate); } StackDoneRec::getStackingHeight() { return 0; } StackType StackDoneRec::getType() { return Done; } static int Random(int i) { return random() % i; } void AutoMoves() { Bool found; int i; do { found = False; for (i=0 ; igetTopCard(); if (card) { Card dcard = donestack[card->getSuit()]->getTopCard(); if (card->getValue() == (dcard ? dcard->getValue() + 1 : 0)) { donestack[card->getSuit()]->addCard(card, inautoplay ? Normal : Animate); found = True; } } } } while (found); for (i=0 ; igetTopCard(); if (card == NULL || donestack[i]->getTopCard()->getValue() < NUMVALUES - 1) return; } score->wonGame(); } int NumAvailableSingles() { int result = 0; for (int i=0 ; igetTopCard() == NULL) result++; } return result; } Stack GetAvailableSingle() { for (int i=0 ; igetTopCard() == NULL) return singlestack[i]; } return NULL; } Stack StackFromPoint(int x, int y) { Stack *checklist; int num; if (y < playstack[0]->getY() - 20) { checklist = singlestack; num = NUMSINGLESTACK; } else { checklist = playstack; num = NUMPLAYSTACK; } for (int i=0 ; i= checklist[i]->getX() - CARDWIDTH / 2 && x < checklist[i]->getX() + CARDWIDTH / 2) return checklist[i]; } return NULL; } void NewGame() { int i, j, k, w; if (score) { score->lostGame(); // Has no effect if wonGame() already called. score->newGame(); } initializing = True; for (i=0 ; iclear(); } Card deck[NUMSUITS * NUMVALUES]; i = 0; for (int s = 0 ; s < NUMSUITS ; s++) { for (int v = 0 ; v < NUMVALUES ; v++) { deck[i++] = cards[s][v]; cards[s][v]->setStack(NULL); } } if (score) score->saveGameBegin(); for (k=0 ; kaddCard(deck[w]); if (score) score->saveGameCard(deck[w]); deck[w] = deck[--i]; } } for (j=0 ; jaddCard(deck[j]); if (score) score->saveGameCard(deck[j]); } if (score) score->saveGameEnd(); initializing = False; AutoMoves(); undostack.clear(); redostack.clear(); } void LoadStacks(Card deck[52]) { int i, j, k, w; initializing = True; for (i=0 ; iclear(); } initializing = True; for (int s = 0 ; s < NUMSUITS ; s++) { for (int v = 0 ; v < NUMVALUES ; v++) { cards[s][v]->setStack(NULL); } } w = 0; for (k=0 ; kaddCard(deck[w++]); } } for (j=0 ; j<2 ; j++) { singlestack[j + 1]->addCard(deck[w++]); } initializing = False; AutoMoves(); undostack.clear(); redostack.clear(); } class StackNoticeExitRec { public: StackNoticeExitRec() {} ~StackNoticeExitRec(); }; StackNoticeExitRec::~StackNoticeExitRec() { if (score->getGameWonOrLost()) NewGame(); // Force save. } StackNoticeExitRec noticeexit; void StackInit() { int i; srandom(int(time(NULL))); for (i=0 ; ilostGame(); DoRestart(); XFlush(dpy); inautoplay = True; int solvable = AutoPlay(); if (solvable) { score->setMessage("Solvable."); while (solutionhead) { SolutionLog temp = solutionhead; solutionhead = solutionhead->next; Card card = cards[temp->suit][temp->rank]; if (temp->dest == -999) { AutoMoves(); UndoBoundary(); } else if (temp->dest == -99) { GetAvailableSingle()->addCard(card); } else if (temp->dest <= NUMPLAYSTACK) { playstack[temp->dest - 1]->addCard(card); } else { if (temp->rank == NUMVALUES - 1) { // King to empty stack. for (int i=0 ; igetTopCard() == NULL) { playstack[i]->addCard(card); break; } } } else { cards[temp->suit][temp->rank+1]->getStack()->addCard(card); } } delete temp; XFlush(dpy); // For debugging. } } else { score->setMessage("Unsolvable."); } inautoplay = False; XUndefineCursor(dpy, toplevel); } \Rogue\Monster\ else echo "will not over write ./stack.C" fi if `test ! -s ./store.C` then echo "writing ./store.C" cat > ./store.C << '\Rogue\Monster\' #include "seahaven.h" struct HashBucket { struct { Stack s; int y; // hack, really want position w/in stack as an index } cardpos[52]; HashBucket *next; }; static const int NUMHASHSLOTS = 337; HashBucket *hashtable[NUMHASHSLOTS] = {NULL}; void InitHashTable() { for (int i=0; i< NUMHASHSLOTS; i++) { if (hashtable[i]) { HashBucket *t = hashtable[i], *n; do { n = t->next; delete t; } while (t = n); hashtable[i] = NULL; } } } #ifdef notdef // the single stacks are symmetric, so store them as singlestack[0] and y=0 inline void FoldStack(Stack reals, int realy, Stack &s, int &y) { extern Stack singlestack[]; if (reals == singlestack[0] || reals == singlestack[1] || reals == singlestack[2] || reals == singlestack[3]) { s = singlestack[0]; y = 0; } else { s = reals; y = realy; } } #endif // retruns true if found it Bool hashlookup(int key) { if (!hashtable[key]) return False; HashBucket *t = hashtable[key]; do { int i; Card *c; Bool match; for (i=0, c = &cards[0][0]; i < 52; i++, c++) { match = True; if ( (*c)->getFoldedY() != t->cardpos[i].y || (*c)->getFoldedStack() != t->cardpos[i].s ) { match = False; break; } } if (match) return True; } while (t = t->next); return False; } // returns true if new state Bool CheckNewState() { unsigned int hashkey = 0; // compute key int i; Card *c; for (i=0, c = &cards[0][0]; i < 52; i++, c++) { hashkey += ((int) (*c)->getFoldedStack() << (*c)->getValue()); } if (hashlookup(hashkey % NUMHASHSLOTS)) return False; else return True; } void hashinsert(int key, HashBucket *pail) { pail->next = hashtable[key]; hashtable[key] = pail; } void SaveState() { HashBucket *pail = new HashBucket; unsigned int hashkey = 0; int i; Card *c; for (i=0, c = &cards[0][0]; i < 52; i++, c++) { pail->cardpos[i].s = (*c)->getFoldedStack(); pail->cardpos[i].y = (*c)->getFoldedY(); hashkey += ((int) pail->cardpos[i].s << (*c)->getValue()); } hashinsert(hashkey % NUMHASHSLOTS, pail); } \Rogue\Monster\ else echo "will not over write ./store.C" fi if `test ! -s ./util.C` then echo "writing ./util.C" cat > ./util.C << '\Rogue\Monster\' /* * Author: Terry Weissman * weissman@sgi.com */ #include "seahaven.h" #include unsigned long GetColor(char *name, unsigned long def) { XColor col1, col2; if (hascolor && XAllocNamedColor(dpy, cmap, name, &col1, &col2)) { return col2.pixel; } else { return def; } } void GetInterestingEvent(XEvent *event) { XNextEvent(dpy, event); while (event->type == Expose) { if (event->xexpose.count == 0) score->repaint(); XNextEvent(dpy, event); } } Window CreateButtonWindow(char *label, int x, int y, int gravity, int *width) { static GC textgc = NULL, cleargc = NULL; int w = XTextWidth(font, label, strlen(label)) + 4; int h = font->ascent + font->descent + 4; if (width) *width = w; Pixmap pixmap = XCreatePixmap(dpy, toplevel, w, h, DefaultDepth(dpy, screen)); if (textgc == NULL) { textgc = XCreateGC(dpy, toplevel, 0, NULL); XSetForeground(dpy, textgc, GetColor("black", BlackPixel(dpy, screen))); XSetFont(dpy, textgc, font->fid); cleargc = XCreateGC(dpy, toplevel, 0, NULL); XSetForeground(dpy, cleargc, backpixel); } XFillRectangle(dpy, pixmap, cleargc, 0, 0, w, h); XDrawString(dpy, pixmap, textgc, 2, 2 + font->ascent, label, strlen(label)); XSetWindowAttributes attributes; long valuemask = CWEventMask | CWBackPixmap | CWWinGravity; attributes.event_mask = ButtonPressMask; attributes.background_pixmap = pixmap; attributes.win_gravity = gravity; Window window = XCreateWindow(dpy, toplevel, x, y, w, h, 1, (int) CopyFromParent, InputOutput, (Visual *) CopyFromParent, valuemask, &attributes); XMapWindow(dpy, window); return window; } \Rogue\Monster\ else echo "will not over write ./util.C" fi if `test ! -s ./cardbitmaps.uue` then echo "writing ./cardbitmaps.uue" cat > ./cardbitmaps.uue << '\Rogue\Monster\' begin 444 cardbitmaps.C.Z M'YV0+U0H`*$"A!`V8<:L`:$DX4(S;^2`(%)DR)TT;LB\N3-GH$""((:\@9-' M3IHS:.B`0#$F!8@8.7+`8/AF3ADX:$`<>9.G#!TZ93Q./)F&3A@V((K$J9,& M3ILR;E2*E`,G8A@Z:=ZX\2C42@P7,UN\Q-$B"!0I+6#*Y`J2"IHT6.& MSITP+2>1MWS,B2)U." M_7<8, M#`H26&&!"SJ(!X037GCA@!@2.""$_7U'H7P?,ICA@P.>Z)^*(L)(HH3D>0AC MB"%R:**-&N(X(G\TXN'B>RGV^*-Y,,DWPXT@'EFBA4Q&F9Z.>(C!XXHQ:CAC M=^3EH*246%)IAI?W+6FDC$!R"1Z9[YF)I8\'KG=EEF\Z&62"8-*I)Y4T%%DG MFA&J"5^><$X)HI]Z%LIBH"^>Z>BBC?[YZ(9I1IIHDX!:&N(,.)C'*:!/#JKA M#6.81VJF1,)H1AGKL:IEI:EJN.IZZ(5YJ*JNDE?KGK!"*6NNZKV*(JZT@AJD MJ%B:46IZ-^R:XZVR+OM=L\8*BJ@9G:8W@[-':CJ@&2UR&V>HB)8!HKB&#JOA M&"#>4*VW<9:)JJ^2QFHKH_9>FB>5R.H[Z9;P3OJLNO7ZNRBYA&*:;L`%#XRP MP-T^N!G#!N/!KGDYB/=PPP->G%[&!%<[N6IT`?.S#GW%5IC!$= M7B"@(8-UV&GW)-N$QVWXVT>K+:S037.-QPUF_]LK#FQ*+>R4D1<,\(.95\QG MYS+W*@.B-H`H+:](7MLBL`X?6WF(X"*)+J1=JAKNNXFO=_OEWUD9LKGRS4ZI MUV-^F9[8,+C+^YK&TTZ@FZ@/_CKT."(JYIQ@#_\DGEO?-I@Z^] MU1S/6_[XYUMK_L^YL[_YUXK?2W'V\Z^?ON/Z6XZS^^R#'_W,ES_0[8Q?!L3= M`.4'K?V%#WW^0]W]ZM>^"9ZM9P1$6P*7US_\:?!]*>L@!0L(0J>)\(+BT]R( M)A:_@HG-9!#,W@M7!J/2R>=T,_1:_V(W(6!1B6H8;,_NPO2R&'YKB'NB&<5X M:"+AD5!#P+N/$UF'*.0I#TLYB$\*ARWB+^RE7!*--#A!L.D MQ!9&$`=:-*+Y0&9!R:GQC,XK'.+:QD>YT3P6,$'O8Z"`H0C)>>GR4@ZS09KC%Z0.HDE&][G=)E4'9)89R4)R>ZV8I3:<^5?90 M@3O,I0G=V41XTE-(O]QF+PF4SRU:L9WJ0^:XY,A,@'JSD@N<)@(WJS5>6'X*T*SV-4I73*#Q*N<7Y$$M1F`R`93J]`^ M9\#"QV5M5YR4[("VM9[+1M8\DXV;9_FJTM!V-GA.VV78*A2#N!&3M,K4#_5V M]5/HB6F9[[FBQ90ZOV"V23XYY1=8GWE7-4GSJTZSYD4UJM-':M6>A;5K1/'* M38\6][D<%.P3ESO/KH8TG=:=KE$1B]T'CI>!X1WG=RM:7E&>-Z_I!>]Z.1K? MBL[7H-R%K73'V=YP[I>:&ZHL1$6*TJJ]MV(CS9?88M#8CD'V8P;FY68K>P.H M`7%*,/V.:=LSV@?15,*>$BUJ&`?5NS%M--X]`/5X;<<5+:.T.2+EH?O*8SPEE^I89H]ZE MKG-K#=TD6Y6J*39R=S544@*ADKGQ7"5^5\I3A"9[0OE<8K.WJZ>?1MN-0S4O MQ?B%U&\2JIE>O>JPG>QL5]?7UKK6IK`=;>YURWK``,:!@$,)TG3#*,%1P[.G M'(RQ".?KSZ:R,&8S[.=%U*MI:SR6DL$%W=2PPWLE;M[;":?];^XZFN6DU?*8:9R:/YX M5BP/LF\VZ/+@Q)QSNLIZ+3,_:1!DYM?=":SZZ+[N*A?UY(?;U&>[[-G M+F*=T!,.^,0G5[F%2]I4F@TQHWT9[']'/-)C-P^E%PMMBV.Z[X\6#.^W%2'MWV3SM^3:]OR`)8\N@^\ZZ/+ ME_+@M92^M?58O$/<4X"..XBU=6*VLWOCK%\[/\==<+4?O-'OOC,269H\VL<8 M]K]]?8\";ZF%]LCP[GVY\9\^U9M[?O*<5S?F_?M\^BJ_^4H/<.*/5V";3PK? M_1K]=QS[\:X7V>VH%SN&]4-PLT_\P^B/_>U=_Z"'IUW^$L<]Y+DO4_*\]D$T M1SXR=FJ$Y7'\5WPBAVHFI%?>IU`IUW(E$W.:!R.$]7(%"'HR$X"QMG_,IW-& MEW-6UG/0H5;3<0-"!U<>B'-B-H&+@X'65SLUUW3MQCFYIB:.!X%>AP6 M9G>YA7=GQFD-5UN@]G>]=X#YTEMDB'P"9`8)"'VM1G4[F![%!@/'9GKW%`.L M1'LVU7_)YT8LU5K+MH=UUX('9FV!V#'_UX"/@=FLAI'M`2'I"2(5+ M.'Y'B(7+=XEXP%GS-X6Y!WR=*(5`17ONYX1>57%"=''\DV,:5X3!%XK#]X/% M]VO`M8!V&'E,YX*-B%Z0J(#7@:28C..(GCIY+>!HN=F(GF2&TW&99*-9:E:(EF MB5E*I8K^QXJR*("B*&K`Z);H6(L$B8]SZ8M5F7D<>7TA@Y+DQW6YZ)64I7XX MN7I1*'MG^9:<2([;2);9R(0S"9DGPY8[19>;^'M>*9>6B"/$UXX\QI2,68P" MJ8@8F8/R5IK*F(S-J&#/2(G1B'$G4XW39589)U) MAIW!*(^=IY!31E8\YY""1()]DP,3^8$6"9^E27VG*4`D29HP274@B9^CY)'' MR(8UB#E'R6#0^!Y=]T-0^)6&29G].8ZDJ)9HYZ"Z.9C+Z9B329Q4TI.#V)9W MEV9?N'?+R9EY1(;0V2])&8L*R#_#59KSLWCC:1Y365T`V94=6)FON9652*.- M"988VE!I:8HZ^9(0]*.M.*"7UH66J)R<**(YV#\V<&-01:$KE5,YD(=%&E,; M:IIW>&TZ]8?]1%V&F%W,2)?T"6Y*&8E'"0-00X0&*J6T:5FJ%W_"68X]FI,R MN9-RFIO#":$VZI.866I"V7<$6:*N&)HJ*J6=EYJL*9M["7[TUGU].B%;]R`' MVGXM69OO9Z>^.7'`V9@/ZJ9!BH0::)R)J)UVJ7]B6)WD1*C->9>B.3;B.4?D M24'V.'U819`C%*MZN9W_&9\+B9YFI9Y9ME8Q``/O^:O(>IZVBJ@OVB&$)W5J M$A/RD49L%H'3RH-!TITP0*WPI:KWP:TRFJUW!JX$"IMMZCC=60;@6I@NB8I/ MDJ[K^JF.,P-E!ST6>G:S&:J'V3MWMH6KV*&R]J&!"H^W=6I/^G%1ZJ%_9P94 M:J5Y-"=>JD`NRH7X-"\Q&K%8Z49A:I7]DVU:>I1DXRG4:E5)Z2EI:^0 MB9OWBK(L*Z\Z2JI_ZE5*FJHZZIEI6JAD1)TW^Z(SVJ1]N:Q7.DQ:F9(Y>HYO M6F%QZHUWZK)YVK*H^+(3:HDR"[!`:T(#2+#R>+#'D[`]NQX-VVNXQ(>XAJ7U ME+%=BD0_-&\PLK%U63+3V+&)Z*@@VUC0,P;2J*F8:"J;-G"1.:>/B:&\F:!0 MJXF=2J2,6;75Y&)>VZ19^QTV`#TY0#,&2+1262&3:ZB-AU*4NYB^S&=FCVG6S*DVU[[A`.-RY^E&V7*6KMZU)!H]7/441W7<4A#EX*V M^X#8.KLON"$7TFV?5U.A1(S+VU3-6S//"S//VV8LBC:O,[V(=Y#$.R^4=IHG MRIS5FGB,\V[]ODL#"6)-46H=#FRC!]8BZ-L&].'(A)[82 MG,%BJB7!A;P-C"14:J8:&US\&\+?"J/%V['@2@.Z=<`]LJ8KC"C%BB1/J;'N MR)=C:K4PS+$@;(L%A;;UB:;:.V0=M:@0AJL[#+>J":E[^4/"*S^#NTFIZ[-[ M&2(Y$+O!N#3;JR7\.(Q]^U84";SF^<:=V:S96Z-39\3R<;W#2[V$C,B8-S\T8,CAV\C5:Y*. MW*V!G*)4V<56V;W1FTCF2VOB"[Z7'%MGZLD`2LC;L[XQ2KX4\[[Z<;]Y64WU MZ\I_#%KZ>\)`3!X%_*4'-BL"3,184@-=1P8UH,$X4K\S?"/&3,PU&3P4S'GU2\+--C")G9$=9-:-[<%!J=A8$@,CO-=E$%RZ?#_?/-DB M5;\OC->)HK_'W".G,X>DO2FGH[1J#3N-U=E^^'9S?41DN]H(DL.U/=$(O;9- MS*C_3+?L4]"]_5(.7=%EK#D2W=44[7+-W35K/"+QR]`SD]SQAM566=W1WF4/R3=DP+N!@]/):IX&[,;K.[',+238#6!*Z+V] MDM\,S=^\'=;%G3I`'23^';Y*_=57)]XID\K0"I4=V![W37U<30?CL(*M=P* M!=$4?F$&#=R)_"!17.7??4!4_N11SM)R!MTJK1]C[,D9_<\_E.8?N=#.)V3/ MC<9E]D)N[N$*#L=\;)&XZW/L209XW-Z_6]Y]G.%"_3CMNY\^W6>R^]CD74WM MRZ8AOCSY?53P%&W.Q??M@-CNN_;M7Z$>;X8^7)CN7/)XE)O$6HSF==GM#VS#-;).HD)FVW MS:QQ&50E7NJW"NY#B46V[N1C!.QH3NP;\H_XGNY1#I[DQH[*WNL^#=]\+M-^ MKF5D8-."CH*$'L?0/NS,DNA2O3R,[L^.[NN0F^B@0\T7?TP*I.AI.MI.3SF)"G/N^*..%)KFJMKF$8'NO07NU0/O#(WGD1W^\= M+N;=OM?A_K'K`N_IC.[+SJ%G:^,HWO+L;H8Q+_66WN(Q8^2&_N"X+O%?3_0@ M3NM`7^\)?NS8/D+:GJCC7CT@"^<<9%O&_>YD^M#ZZ/0.MTT86^1M2_53HJLP M7^Y8#/"9A[SA+7E,%>U:HL6RJOCTKN^F&N6`;_0]_]XPK3$(G]X2009M==.# M;OG`._36'F3MF\VO'EBQKJV+7O$9&6H7PL`,.(M6;Z*34ZBH2O,(:J046^YB M6<\0>KFZO^*\'TVVCX4VFX,`KC6LJK"$!_MRDO-^MO-+7?EE[_@`W=(_+_K9 MW_6OKOW4'O:C7_2W7OT^__W5#_;G+_:!7=_4[_WD#_[*E_;[LO;GR^V1[33$ MW4'0V6?V7_SJC/O:3G%=O;PGM?:4E!*`O(\?U2SQ'*ZGVZRV2U>E_3BEJ0+OA!O0'8 MHOP?<3I^UZ-F/$"$8O,0&_E84:;L3D@_[&?^W%_[XWX:+_V%O[&'\;I@QQ-Q MY(/$81NFI^N6%)=Z-E%/Z6$)O+?^`A_):X-)#\FY/:WGT[S@^O*#&F[Z_4$P M&(SDW[^@?VJN[2&?_/>'# M6;,OQ[0A!O8)@U';HU7.CCN9/>Y4"@G(Y!M_U"\$RJ<1N)X47M#Q?`XO!>XT M0NA\3!YO$WG,K@8Z&F'H/&X`,10T="8'?ITW,04YR:;)85"P)GF[.'B`*!(2'#AYZ M/0D(V,B3.!0\MV^?01!M"*2.($Z*5-3P)P&J?/@-*Q>YA M(&R'PD[]K4*D,P:KF_)!A&].<^4@1G@C]E^.@830$`"FHDQ8!"VA/V10*H8D M$KD-D9Q"(@%JA58+Y&2\A#C8:!`_.X5Y(O(-/&TE6'3BL7N%TVX%RL*%1`N' MU>8S0;APCSV\T,<+PU>H*8/&2S^U+P;GR:@BJ_D.D@Y'E,.LN`,%SY-00MXP MGCTA)4@$5Z(1W%1($-8)P2/%!(D?UHI+0!#"2<&#'8C@PT^/3<(XZ:-/**#3B[35;TT*.VV2=`[7_>O)A(\NB03[YE++(C[ M4"6VQ;^EI^@4G\J,?JH(#D3CA_OL(5V<=2#"^:$_>=C]FN*NI_CLUY<$39!_,>(3XDC9)P)(9&LV@2T>(_!(U9JAHRL5,%'.'1O7.` MI[%DV#H&YM&`W@;$'_RN(DXW*K80_9T8_'E#<JLS!J[?EP37XN[; MAF.-?SPN4(;\L`=^Y&3-[RY6,OW&#;=@1*R($[&H32<)V5P>I$H)BPQR$_%# M:W@2ZU162HX"D69=1K&XJJ+C9,2!'%(V]D'8*/1HXA5)\@'$Z<) M3Z0D!W-'_L$<^YQVT''T72H4M^4/$& M8C#)F/MXXT&T@<]03?9(:4@6E2/2NH:-IS\.04_9!-_B#P0U#M)%?J\C5PZ3 MWR9#AX>.+VK(=T@CRZ'^4Y4-A4?&1==T)D%5B220^>9'(LAVMB)#I*V[,3-/ M'UG$!Z$&=8IB;(.(4>\9QKOG]XK>LQR,RW)#-,M;"]1C*21(R1*RHPI2;MPXV)S'+N1&3K"+6DDGZ!(!(C^ ML2PR03$I(,GDD$2713!-$D04E2?UI9NT5NXR3M;)"%*E(!^?K!B'KR=.3/P! M%,_>^@J/MPM0&L426*Q.(,A<0?#2D^4WY.6&2L;KD&7'2%O!S%DI,YU/S:QO M-W-2WDAT=2'B5[N$F`\B?BW(3>DI%`OT&)4I,E_]RN0B*MDB@$R0/C!$A4M7 M21F3I?3@.!\,YYW(E4A]7AYA]!Y;"@U^3:PW\L1FM@1#/*YJ>LL/62R)YM8, MF*321X%*$#(M?HHIQ6#]9D MKHBYN7XG20-=)\UX:K3?F3Q1E_5[78R/_7W,R_)M6H.AA4_P&>$`XZO4%.*3JL%"]0G6_N8QDI4M,_I1':I9WZI@^X1^7K/S MP$^HUC]864#:G+#LX\Q,9+>_:!F,JW%RD(#]KW3&RZ1,RH.1E'(Z*L0M<@,, M&P"U9%$Q^(-D'H9QN:U4V%ZS7S#J M#@Y.&;;7:MB$X)_E(G3607(G0U\D8^R@3NY)`D[WZ3GDY0&AE\7+7DZ3?+GM M<.(A[([U9T]"T;$1/15*=3QVUW&$7%'MDD7WQ18U'R"M>9HY-F?W5&`LW)Y$ M46221\RF/?TD]R2BM`M2@D_V^>SHZ%7\:1?0!4(_2'8!^:A8:U`7,/D]G*!( M_?:G^IJ?Y;,N/BM2EDC33/X\7X94@U83^+77Z)<`%9L%E-#8,KV'0!\H+EN@ M>#,]`#/S(,Q8Z&>[?HGBE'K2Q\',#EM:,Z&I='5VT%>:0(N9+!VAE.KCM#5= MHTH!XX`09Q^'G.'(?`9:R-P.Y9UV25W^R'#9F\8DOD*.SA1R(J6.H<\P(X:4 MHJL1CH(Y)XE$YX42C2!,E.UQTRF:+;OG1R)SJDN-+4\+^-'4Z3\+H^U4I%F_ MDA;2ID0#O(`Y`)U"Q3/J1M.H]22!ZXWA^:Y<:"C#BCG==7:4(AH6IQ;KFMJA M.W`7TJ@U2A@U4?-C&-2C>='\1=*,]$@9*?2SGQXUH\K/6&DC/V@MY4J5!NFQ M-;'YUN2.7/.EIL*NB0'$TU8)UN@];')3E!J4L%Q1C-C`P*-A%Z4H>J M2=6#DJVHZE1)*51)Z"X],)BM5:50SF9*TQ1,C4W'HX<&/=-VV%(;#H41,Z"U M"=-06HXH!J!6*LA: MJ20>D*U[=+YI5B#J,2%B"W2(#4/)]46:A^2NI0_EH2]4,![7OYC./H6VB#/( M[E0PB[O&0#MI3IT6K8VZDM5.U%B@Z\7L'\#J.#6L$/"W?3N_NB$B(-HCI_J4?&Z2_/J1OBAC[:(6S[]>.0";W>#>@"6L MC37+?0P".RLC:Z$,F?\T4$J$,1#H!JI2?+`HLV_.PT1I]!9EHN)XZ7"I<45' M-"\J'<@38MYUD1*E.#.'M.M@W'L`)D:UV$,J,*@9;KT?PI4%,M-F>6/_J`W2 MK1JV-0;9B[I>4>EO]:W[%+A&5#,X9&=DDS5V158/$E(E>V3]YI-E=E%6K;97 M[G@1K=\/L:]GT.JE3O!:&N7IJE.Q472+S-B9(BW771M.?D]R8M*JN-MCIV4\G:X0=F6-`H.HQS`KQLBQ_C'4>MOZ! MV$,'2B!MF,UN1NZI+M2XMY%J"(APL<<5Q@H0&?MI:6QPG1<]MKGD6)M'7IU' MJJ603V*C`AC8.FB1K'ZUL@\1U[K#+WAEPPC2(Z[7M4EM2])1:B6IP&2K6A;. M*E5?RUO/K+Q#LTT5S_':7#L/TVN-[+7J%=L6I/=*7W5,?>F/8S;33@TP&U!D M1&+5*(6VSU'Y5%&*^5UW1L;$DX!V M7\C;6OLHT:BA16\25C%TOH9W80MJAJ6VKXZICC_3%P91WU)3?7&NHD)(35$. M)>[//*I=T4CVF043`<4`2CV+T30M9L,647)/KEL,H3O5<;S:U]=3RQ?AN8>B M=+8R,B`+<8FLMH6,CG:[-D1;*SV)KK2ELDG6Z&Y97;MD:>7/?79!5_Q-6:4[ M=)ENE7TZ<97-PM?Z:B41T5U5G5:/_Y%;2UDXSVWX8;ERY^22N7GF(Y%$RSU: M4LI["B<%)]>]'\V0`I+1?(=/#6P_VK,'1,#^W;YZ31EM]42XB);+$$J' MRQ2?;O9YBG,T\FA<03%1YXREI8_"Y;.07;W9D3HBK@R","\&O-UGQIC8[JL1 ME:/W7,F:_%D.9ZY1S;S,3RGAW._@>NN;K!4@M!:R(MU;6VVC;K1=NKW7\:+7 M2[MLA>VOA;;(+MUJ65$;;)4O0[RWZX7KE5MC>VU[KI.UOE!6^-I6:QLON>W> MG1)C=X'A/RR)=_>EF74DS=#LHMZT"W?7[MQLNQ,B]1*(O$4\8ZY-W)N4L@TU MPX#[+P1MR\BW'^[?'A1Z&XP&KNZ=GP87PB+>GX.W+BN&O4B^%]',QW@X>179 MJS.&D#89=>`-*_L(`DA4@:Z>)+)"A5P238*BYP2*H>:B].M/^ MTM:;^X%IK\[M%;3>KVIUDVX/YKU"%OMB6>U+NP*G#`YZLQ?L!CYV9B;C M+_LEO2#.]`I')\R37&[79:&VLDTN81Q9?7?M[BVZ/Q@,!U\A/.6\KV`-ORU8 M-Y)?]&M^P6^+?)B%%9H*"16,W!BGP:1::+<*P]U7F,`(\.L](/I75?)?S>%_ M_>T@QIBS=?"14P/,@^?AR61(E%7+C`&DR'`-[QLEPL4+\K;']25Q@V(.9IH- MM:3"7NIA*%PJ8>XHSD$P&(/>XE5I ME.`PE0REKJ.\;M*7TY+?8$NYFW$ MB2()<\LMC(?=;BN>O_VP7-:IQ$F'A2Z3Y#Q9V//ZXG[;&._HM/7"5'?JAN&C MRV7'G)<=$6A8*X[?K[N-$YK8?>>-9[(HWH2CV MM^2I#Q]+52EXP9B3[+-1;K%B77*:=6%I&'S$YTT$)=PQ8!XK\0.^Q&0XV7'8 M\1=IU5P%7H87>`*+7Q>\:1UF0$:&ZO@F2^`07)!7\)!ZOZ>7)S-D<.Q('S*J MQ1[GV*LQ2,(Y&F_K#?8:PMAY[&`6:HU3L@?=Q1-Y'0-/G;R6\G#OL,)*4QP# MR[.[D+\RW(W(?-,68V-0R)4)[_;#Q(QR9L(LJQ M^)/+(?4KE,TR+7:_L#AQ M>>4J<7+Y\*ORPTO5$`/D2ZFJ^!DCID"'^/\FXGBG_DYS-29E";C*1&*^,08& MI4EFO"@9'A^ZE1P46_)'>LE1#9%>7K7L31USX724-IDT%T-9;)E=,"''Z>N0!\8Q_;S-^L\66O>[!_?QZIS$1T:5K MLRZWY=OIEU^Q6*8]K'@H&^0V>)5/VTR6SUM9.?_>JKN1$7.WCHY";0<"M!&UF<48U%LH'D&G4[0AL],2EU081D_HOUQS%W.A M5K<(.IE2%SR]0_LSLOO/492D`&I8'7W'K94$MWX75A]J1Z>8$_6)ILQ"4$5C MY@?=C5-UF)9*!VK?5NC>";IV5G)!GL9:;`A/9#U-SMCPC*?.\W@R3W#-NIXG M2A/20I%(AV1A=:39FX6UQ+N04V-::'N`\^A3EE[95Z2.SV`(_3#JG).C8OC5 M166$,I67!W=.<"`U^QSL.SJPJ43!]M.3E+M=4$MZ/`;H8:QE!Q24OECK6ETU M]G&=UIVZ5;N1G_HQ@NHQ3:JK]"J_ZM0(IX.MRD9ZI[/X1M4W&:A!BPECH2W, M0NL)&)H[62@-O:`VU$2LY9.'A8JK"^^UO6U ML%NKCG4^C7M6-FP$`1O]9]"LI+$,DV+L"WI3VZW_ZF7I;)2FAU)*?7LI0S3= M;;"ND5*3;>MH:-5JNY`U++CCJY_E M9VM;'E^Y\`TCTO8Z[1IBE,Z=;S26OKVMN';#[9ON=N^Q0;[=,:&%UV][-D_8 MFN:`<7/=MLJ0D7!G)-_\/H&S0YV'$)7L'7"!#9P)N-[NUQ:2[#UL`!.YXV?" MCJWW.DA,;M!"J'/W:E&IH$73NI&6RI->:CI3W:,;WLJCSIVQ03>%3L?$V=B2 M[)+!NG\U%F[9/)4^OW`=F=;X-1'M68?1>ZX&;EM=>06_"FC8A\[R>=W`F>93ON1+6[A+%(ON&WUY/&S M@A>O#9Y-[;:4M=[@N?RC>VQ M=^@-*&`J7!]%<KLDS:Y=65,^TT_H7I\3S>VK/QBZOQ*HG$J':C.FC3 MG.OR,ZB=LM4>@L7CMC7N9O,$R\81;+"N?V,[R(#SEF'GF#D"+K0*6"2/S#E0 M80>Y_ZY=FCK[\.8$Y\#KY:2=AZ0\2)1B9FN53.R(NW1+;`"NH4T'R[<(KLY! M%RN+:T%W>Q^".5YT)*M63B/S$46OH9HHMUA,VIT_<[;M[VKS=L!8/ M9U:8[CGU^1_MY$OWGKZ[2+K5.O+1U^`\=X)A.F8-@*-+0J.A17)]F<=TAQF6LP-GUA6B+9YQ/ M,5&]FWRF:1Y(7\FL0Z6$,H#5.5DWZ@:)G47VXS;%7!*4>W3';J9G^V0W\#$] MMJ]T!0_;$?Q,E^FO4:U#8YTNVWUPA4_]1P4;C?)D->`8END.^+KCOFRNT28`XKW-KOM^";AD1]P]M?=[\I7WFG1 MP(TR>\_))QHYZ\=3N=;EN_`;EBDK,T-TPM6B*V1ESO$QFK]S7/^NG;NT@%<@ M'QUL5OGPBLHWO(9O\'\^PV/X!%]OC>UFIWL\+-BZU=GF9E]L:'MW4BV@K'7^O=&\1;JC'(OYW%6[GH#J'%/)MVTF/\<6,""_A5*>V%OZ M#2N3LSS/V_(G:ZYKX$H=G%.QK.Z\"G(_EOE.F31_LIK_'/==2.;WZ4SK'U9_ M=\%74_;:^=K:V`EK0"^\ZO&R!WI"/^\W/8?/MC%\M6MC)_@Z'2?<[.T(>6HY MZF_?E2,U?$;':3DYB^KI'>\C.TD7]`$[TT?\3E_;\2JH5\.-&;25YT$=\5VEAWX-UCTC35J,/M8\> MW99V+CS5%]%&_]A5F4UCY1&=J?F]MM?,XU)'87UO7]_IILJ?U#4:0X=J]^YT M/7P1!N\-O[(3W`YMCT?\C$:=YSQOUFY9'S4YT<>?PH^S)))\_#[P"S_G/],- M&@`'9AD,W=GRB5[G6O0BDU,[WNFW.#I??\N%DNSSI[S,7^WGBZT[;K?N M31LXM!?^L]+#=MS[^'GS(]3?R092Y)/+J@^*"5.;S_J'G^N#PZ.1G4G4NN_H M>)[`O_NW;)5AN,)G_)Q0;7\KD(G/73/7^<4O3W'Z%YL-Z^8J;)?ZZ.UF>%771?0_='@]%E,(AR-RN5?3$6Y%%#75:,K?V04NP MG&@7!YU5<9^3,O?M<.'=#G4'6@QYH-UT.*F!@=\)B`#&?X_:J%;_Y7`8&J:V M.X%X%R!CE0$R9B;>XMR85#<#WGS+WK`7UA5IQAY9AZ0E>[N@`",&KDQ3&I06OEAI01$R MZ,DH@W<4EL8A<6EVF;@BL7V`ZY^7%JN%?F:1W$3PP2AOH`E8BY%[DV!30(MGE1H.W$_M%_<)[L=K+Y=Z/>);CG^7K=W*:6[U5W^]Z*MZ1(;_.?`0@) M;H-C6AO("*Z`8EI\9@_V9/BBW[(%%SV?GUTT;P1T\."4I6Z63JR:B@3LA M8;>4Q+A.HH@H&/(]@2-?0#B.O7\*(`V`630N5F#O9'[0<:&9"^4\O8*/7>;R MOI5KZ9M2N+Y]:VA;M;:70$\XH%.D`_:"VEWV-+<%@_];T/=A@7]:C_B4P2DO MA-[Y=#2D3_V:`'>W+83<8*R#R&%!E%PZ>.2`->S>@.?N56Z4U,26N1E;F92& ML4DM$;MIC7]^!,<-147$9#S/[ M%7ORW,\1R-5S9]URF`M^9'@;887EP5J#S)QS'9J%.HA:.&IYA\R%X;;5T%P3 MG_,Q_ND\16"`D^YY@7%471C^W878EN6V[V!NEQ1?N+FQ5X5A%95RB3:UV^N6(,9NL!L7UB#V<+B;$1?X[&[CC-CTO/D9 MPALY0;Q)*>Z,T\1,=8/B'N`GCFU#1M*%6`9$;W2?0^@5YGVQX#$T^E1P* M?5=AQ5OA7`L50`8$=R5A$0<@6E5( MG&C#0C5Q`MH39VP-VGOUWFW$MEPT4B&0*%744\M=MW7DC0C#C.V'(Q(0.F*\`?MY4T->FT,L MHF\6W\S(ON%5+^/2@S&TGC248GQXN3G_VV, M'9[>6-/QC<6@CX0UF M*#-2#%FC]9`R4A=?X^?D1H2.59S8*!\XC),/VC@S077\0ML8CWQ;]A9PF)%Q M9'_6R-K=>^]CQY@WMHA_V@VQUV2.T:,\TCG64-GC9=@_7E"F MXWU`-NHCJN.D%X/ACL:<\#@_PH\L(@.I(M*/@2,$&&N5H M/THEE^,6@3]B#=O$_J@E?(Y0U?\XD'".)F3Q%4"^!ZCC-E%`SGRSVJ!H9_UT ML2-SQ^OU:`PA:U81S8(N&UB#+,XT:P4-\#OZ@%QA324&TG5WU'CG?*B/4QHG MEMXI%JR%PF@0QCY8T2\US$@E64.F)(.8!RLD4Q-<9`T6!A7)U/Q2W:,`*:5T MD5VDFG(ZIA85`JQQ/::-LD;@5DZ)ADI?(7,N7I'@HQ*(1QV0Y="ZJ(@PD9I< MW0@$+HZ.X]T(."Z0\F/\Z#XVD(DD([E(/I`.Y-XH.'YX@N08Z/"]=A`?XUC_ M4)#IE/(D,A:+HI+"2+&5C"H%&HE'ZB`6QJ;!CZ"17^0:.260D)8"&EE&LI`Y M8;X@2[J2M*0E"*..<$T9%7&9)X(YR2:"-D=OGM"4$>SDA8U89/!\_H MW0B'"J1U5T1B=T'CEC%$VG/2X2#YD6EYDM>S-Y)T>0.*%&G_$56F)(R216)* M7.0OU4J:D=L>]YA.XI($0ACI5=R2[&0NZ3Q0&FYD"@E'YFF;QL,!3*HAWR.! M0$RB?P$ER!8WIH]'WR,I24J0BN0AV5!JDO2>0CDXKA,;9!7W00)MU"/V:,/P MCQNEL95&#I"K#(A@L05U.M4IUQK">Y8DQF@:/I2%9`09268WG"0%84$2AR/C M[21*FA\-13F)1>H'JF3(P$KR7?;DA@!+VI)D)#RI1K)Z%0(]&50>E8S)+JE/ M@BNG'[_P3V8P9,1`^?(=DSD"S+5NUNQ=5-SD;D8$"D'BY-10.>B4U<0YF6:`)#\E.Q5//EKN9&"Y M5,J3)X-2^5?6DUE(&\E:/)5XAQSI3[Z31:$%YD'!`%:E'GD=/AQ]I-R84#J4 MCB1G"4DVDI^E1$E)$HXV#F!R\,625J0Y:4=&,'TES7A8,B:&)5/Y6H(XL248 M*:4XE1WE>]!+9FI3)8566:*#J]_>5\J1EJCAPQ=1>I8+Y4L9;\249IOD:"1" M=Z8EC()3SI.IY4Y9D]V,44-KB5W*ECC`4)E=%I6()7?9J=26\"2U@5O>4.&C M*@A94X*7@R4;V1:BER2F;ME8]I/P9'MI0A24O^4^"&>B6=:8-)CH6G4 M8)B"9A-H:^Z:'>:AB5I"EB&FXX!/+I:Y)8&P6T)E*"9BZ6B2#RPF?.EB9H?D M8XPI4@&2%`[[>$GV>:^F]O=K&C5,)H5YCCR9MB5K"6+VFF?DN"E;>I@A0Z)) M&NZ3U(94"6S6D?=#I%F\66I[7S3964*4FUZVF63:F4NF:DEK*A7@9GGY8;Z; MYZ8\N6WRF@7G;9E"KIO'9K_46PY.\F9D*%P:F7:;;],47I`M0P:I`C:,#N8H M^3KRF]RFO[D$KI+J9)]I8?R9A*:7&5Y:&..EN1EN-I4+9Y#Y]^Q.#V=F"&;F MD?6(?&FCX8+Y)>B9<`J;BF6QR7">F+7D;+EL M-BG-9IAI61:4TF9Z&7-NF>UFHSEDUFK$9.."[$"%4"&2(T)6<3UF.I-YMD%?)WOU M0E9QK>.R`9A<"&K:P+J6Z";(B7`:GE4FX@EV>A7JILQI&:68 MCR=Y$G&:8P@A==-F%@QOYE/HZVFRZ:EE-0N78">[MGR>"9Q4FUX`RY$]V7,V?0F3L: MC:`F[TBLP`!(9_#8%3*4ZN+WA#,9@Q0.,^BXZ9^V%?\9/W4G/!O'B61.G32; M#`"N,)\BYQXY6"25!^C6:7".'W/(D96>)J6BF,&F&8XE[ MCH^79>\4>8J$`27EF3\*.);"Y?E'TC`[9O5WV;2@G&>7B>1\G@E4.Z6>YN8-.F*EG$.J`6J$6*!!*?;Z>B>?)@(2:F!&,NREVIAIJU@C:+XD1 M5,H)ND6HH)8G##H878\6IQLQ@0:?!P8-JG&^32'+#2I=UIE$*-\YU.29@F?* MJ76:G/J!\IEURJ`LI^I9A,Z>8NCB*97TDI*GX]D[M:$$28NYK1V3>.C%23*. M#1CGSC!3>J)E!E6H?OJ,["?1>5;V#11"_)F*"H.5)*.#R1$S8B$$9QURB_L: M0I46$E8`&[X9+G*+Y**Q4U`24L.HRJ19SI@2I'PX6.F%]6$5%P9$0,_H7B,& ME%QBP`U'[>T0?F(]6&_2FZ:AH=@\\G@7HRVVLA5HUNBCV,-%BL'6I#B.$AJ; MX6K7&4:,GZ'/1G#RF'+H<94JDCHD(<5XC,&.>]Q$27]Z4[\G!NE<&H>@)!C5 M50:+ON0FH8A2?FUEP.,;_@LYH^;@3`9642UIKSF^(&W)YC&R/>$XP MRJ^5E,2H^;C(':,D57R8%WJ>>Z$S"HW:5SPF"J4?9J,40W^H)YZ2"N(1)W01 MC/I(GD@&?*-HS8+H(&JE4RE7&C!ZI96AOUC=4:44`^\6-@R0_D0UM5ZR#!MB MDK),'8#7GQQF@I&(P*6)B"+RAJ&E35IF_J,63T":<0ZD0N+E.#G:C`EIDK&0 M]B.U(M[G376DKP:/:"06II'C<;B^0:85)#Y&4\)OCZDP>0PRIE\=*CI@AJ2L MJ._8+/9Q:6:8:"5VB5DBU;$E\C8+W%[T=#I[^MKZ@I,:/3JI+LJ3GCW%Z$\J M8P:EXJ@'%R>BAF%<&."&4AUXB@(8D^9M%)'& M&YKF1Q**%F=S'&&:H!JH-F.!VE(RB2`ISS$"G`;&@1D``C@!3P`50!$8`:$F M]D229I,-Z:L3+:89?J0`D:(R%RNJT]"B>B@$WHM:87J+;"+P5Q6U+W3G:(6+ MYJ;'B(R*4.2HD-2[**2BF6>?'5@Q"A4HU2K%/.XUR&>Y@GE*D>@IPAB>EH&5 M(QZ@VG2G4&IS)6J M^HUS`"J;2O%UFBSC-T>8QHR.:3EGV]VI=BJLN#,2F$)G?ZG[`3HC*EM9F@(8 M3"=>)Q49F.LCU/AM3(WJPW!*>95OMJ>9$6<(H>EH/0KN:0B8*MY!=]*@*FKW M23XB&SRJW8>"RIU`ZHU*I*ZJ)VE]:CAFDF7JO1FKYJ5IJIF*21Z7M:JL>J:Z ME*!E8(QFH7>D*.CIJJ M/-*III]N!*BJ0RZKDR5_>O38@M#D[,AI`CWHYW)$IUJ%%>H.N/`4JD/G@$J[ M)*J*R*JI>1F!ZXM<1Z\^JE\>!R&I7IESYJSWJFPRI<"J[_JJEBL\JEBJK/YIAHY MR`=EVJ^"K(FH/F*R#II8(\FZ10RMJ2/0:@,>&*&G+9BS@JOJST-:,.RL>%(. M:?,!G>>J?*JZO*JZ:L=*L+VO?Z)'"JKLJ(AFYJIDKI:YZL?*JEZN`MKE:KC$KS)JK M>G$W:_')B2JKCD2+R?\H0);H4G68CJ'&YO-IB#*B"J?96:E2IF8HPAE<:*9L MJ[-IHOAX$Q#..NR)MRZ8>BMCF6:TB[FKRGF=YI@70O;Z8I:4 M<:=Z&"0!:S( MNET1L/JHPSKA&7/#Y;`JN6:NM.KCNI<&J\1JE!.M0JCWG\ZJ>SJ;JRO-R;V^ MDK3G]QJ[(I7+)^VJ2YJP^R2CN81>IQM3VZIS"F;E:NL4@/FGM.#/N4,BKY[I M(P::D@%II=>*OX&MDL1;V0?%E=2K$&B]VI7#I.\Z;U9[Y`/J)D&N[*;AFO?>H:ZJ-B#^PIM3I;Q*W:H)M"OHQS%*L%BKIWI!5NSRJP8 M['1:">H:V:O#.<+"G%5LW1I[WJT4:"2:QX*O7.8+6T?>G%3L&FJ=]:-N;.=* M9.JOCBO^JKDRLE?;FBJ\!I>-*2`*:8*P.0;K*LA>9:\K"]M+MIQ\[!"*:'JR M*Y0=^\4NK?&F$PNG>7EA0@V;5^$@L2`KI,,J'V,E7IJ\^K"#*H`IQ'IW1.P8 MPJAZ3[&.@OG8*7"L+(#!](FQ:@)8U+JNKZ=J(4NW/K,G;/@:RCZ@6BPI>[YZ ML;HK&%LS(+.2)69)N`*E3R.^"GH*L.D,`XOL&+`AI-%*7:"S(>6S:J3ZI`^L MJ1K!BF<3YR7K=JZEV^LIB\=JH&>GN#G-UJ[\[.W*6]ZQ'UL="YTBLG#L&RNZ M6K`)K2)K4BZN#.FQL\&&<]<1\D%\TK&8;)^)S:JONE@G^\=&LP30%\K1CIW[ M+#3;SYJK^Z"R.612K3V"$RJA&I1[PH$J,P"HF*9V\:"JJ>-J+TN4;*T)5WG4 MO+ZB6:M*9L1F7$IL$"CM';+9#9W!S2Z!RRRSBN@XFWNK)8)]4K.PQA9[;#X) MZ&M3"],"KJKLU0B_?K.[:3A;L<:SDRL(&KLMM2FM]YE[*IX?+1=;@6*QX^L1 M:LTJH2HM"(J]=K63X36JQLZLB:S:ZK(9M&FMVKG6^K$!K17KB$JK?2P$8=7Z M'EHM&HK1WK.!+1G8QC:TH:NY)KJ`L M8BO*6@J++;8:V=:FQEFMM^)?FF!U+!WT@#FRM:RMF*@FHK^L$?G+GO/ MZ;3+65$;<;VFU.$OZ]?.JXD"6@N2I*]K)_17O@ZL5VT@"M=2H.2K,SNW7K=N M+5:[T3:W[*M\@-:&H,>MXU"X>@UH+$C'JGJ%R^E[\-UNMVLM:CO7VJVF+37; M+Z2V=*U::] ME8;6=B?+J'W+A-(K,,K19+Y*L_&M"VK=1K4'*WL[/G*U^>T3"]Z6@N54R@!: M';CD;<%:X*YY1>N`BR,%N!^K.UN?);@=U((K$JJY#RY4.^:^N",M[*E4N+B- MYR:KAMRU**Z;6\P^M(TKQNK(5K`P;HKF>[7L*M M'FUAJ\>6MC#N]!DUP*XT`"4JPG*8-@`F2LB>,9LH;*OK+JAF#+9&D)9K<";4 MUHEB'J9H4,M?[K:#:BN:Y!I<2V[N.^J[C:3Q*?0&3]*B>RP?2IWI@HE>? MA:DT)$*[T%ZZ_T)B&J!BMOWI)"O1"JC>;F\X'(:KUI&EB45=ILTJR"B9(J2< MJ*HZ\MX^[X>D/5G6)OOIF3*Z'&:K?:[JU3`.W.T6B;,O[!*A!KTVZBU+I/VP-[0O'M0ZFNE:E*#[]*-O6EXRK$&IQYK_U"< M8@QF[ZR;G')A!2^@J)PF?/1L-VI!"6B-XL/K/!Z$U*ESNOY6O)4-YNGV:EDJ MU&UR*=Z]OQ=Y&C:`AF0$IUAKU'KJVN"'H^)[RH385/(I#D/RDK44;,M[ MV9J,;BKJ&R1J%R%N]]6R.@TO;1(ETQ(--VV]1.W.:X+5!XR@]JGT50:L]5*H M/Z.5,0)`!::!AAH0;*@=ZH=*$"P'"@![H@*,`7@!&?`%B`%%P1RP!12GYQ$K MRAGX#4.PF3J)Q<'90FT6!]M0?L4;/+/Y%6RPA!#(<0;T'"%L)FQWA/`5.0<\&'.`\C`' 69`MS`)D0R-D'@=Q_\!P2PC4-9V!E`!#( ` end \Rogue\Monster\ else echo "will not over write ./cardbitmaps.uue" fi echo "Finished archive 2 of 2" exit -- Dan Heller ------------------------------------------------ O'Reilly && Associates Zyrcom Inc Senior Writer President argv@ora.com argv@zipcode.com