[comp.sys.amiga] Diff

jeff@novavax.UUCP (Jeff Bailey) (10/26/87)

[Plop, plop, Fizz, fizz....]

Well I tried!  Honest, I did!  I sent this thing to the moderator 
(and Fred Fish) and I didn't even get an ACK (except from Fred, Thanks!).
So here it is.  This posting is the first of two parts.  Part one 
(this one) contains the source code for Lattice 3.03.  It shouldn't 
be too hard to get it to compile with Aztec.  See the source code for
comments on usage, bugs, etc.  Note that if you type 'diff' without
any arguments, you'll get a help screen.

------cut here-----
/*
    Name:           Diff.c
    Processor:      VAX | MS-DOS
    Class:          C Program
    Creation Date:  1/8/87
    Revision:
    Author:         D. Krantz

    Description:    File compare and change-bar for text files.
*/

/*
    Source:         Dr. Dobb's Journal of Software Tools
    Issue:          #130 August 1987
    Article:        UTILITIES:  What's the DIFF?  Page 30.
    PD Validation:  Page 39, Column 1, Paragraph 6
                    "I am releasing DIFF into the public domain..."

    Amiga Port:     Jeffrey Bailey
    Revision Date:  10/5/87

    Major Changes:  All internal tracing and debugging routines removed.
                    Memory allocation tracking routines added.
                    CTRL-C trapping added.
                    Minor bugs fixed.
                    Linked list routines partially re-written to allow better
                        usage of memory with a tradeoff in performance.
                        (storage for lines is dynamically allocated to the
                        exact size needed)
                    Added /SOURCE_CODE option.
                    Added /TRIM & /NOTRIM options.
                    Changed /UP_CASE to /NOEXACT for better VMS compatibility.
                    Added register declarations for optimization purposes.

    Known Bugs and Problems:

                    Diff looks for options to start with a forward slash '/'.
                    If a file spec starts with a forward slash, Diff will
                    assume it to be an option and will probably generate an
                    error message.  Two possible solutions:

                        o  Always specify file names in such a way that no
                           leading slashes occur.

                        o  Change OPT_FLAG to another character and re-compile,
                           losing VMS command line "look and feel".

                    Options may be abbreviated.  For example /SOURCE_CODE may
                    be abbreviated as /SOURCE.  However, if you do not specify
                    enough characters, the option may be ambiguous.  If this
                    happens, Diff will not issue a warning; the parser will
                    accept this situation on a first come, first served basis.
                    This was a problem from the original version.  I just didn't
                    think it was worth the effort to fix it.

                    Polling for CTRL-C adds overhead.  I just didn't know of a
                    better way to do it.  Also, instead of the standard "^C",
                    this program prints " Interrupt " in reverse video to
                    maintain the VMS "look and feel".  Feel free to change it.

                    The memory allocation tracking routines add even more
                    overhead.  However, they are necessary because the author
                    of this program was sloppy about resource tracking (VMS
                    does it for you, and with MS-DOS it's not a concern).
                    I couldn't use the system routines AllocRemember() and
                    FreeRemember() because this program frees individual
                    chunks of memory at different points in time.
                    FreeRemember() is an all or nothing process -- unsuitable
                    for this program.  (If I'm incorrect about this, please
                    feel free to change the source.  This is my first major
                    project on the Amiga and I'm not totally familiar with
                    the OS yet.)
*/
#include <stdio.h>
#include <ctype.h>

/*
    All of these #include's are probably not necessary, but the C compiler
    always seems to throw a fit if they aren't in the right order or something.
*/
#include "exec/types.h"
#include "exec/nodes.h"
#include "exec/lists.h"
#include "exec/ports.h"
#include "exec/interrupts.h"
#include "exec/io.h"
#include "exec/memory.h"
#include "libraries/dos.h"
#include "libraries/dosextens.h"

/*
    Declaration for my memory routine.
*/
char *TrackMalloc();

/*
    Specifies the flag character.
*/
#define OPT_FLAG '/'

#define MAXLINE 2048

#define FORMFEED '\014'

struct LINE {
            unsigned long linenum;
            unsigned long pagenum;
            struct LINE *link;
            char *text;
            char *dup;
            };

typedef struct LINE *line_ptr;

typedef char *char_ptr;

typedef FILE *FILE_PTR;

struct LINE root [3];

FILE_PTR msg;

unsigned long line_count [3] = {1, 1, 1};
unsigned long page_count [3] = {1, 1, 1};

int command_errors = 0;
char xx1 [132], xx2 [132];
int files = 0;
char_ptr infile_name [3] = {NULL, xx1, xx2};
char outfile_name [132];
FILE_PTR infile [3];
FILE *outfile;
static line_ptr at [3] = {NULL, &(root [1]), &(root [2])};

int debug = 0;
int trace_enabled = 0;
int bar_col = 0;
unsigned long top_skip = 0;
unsigned long bot_skip = 0;
unsigned long page_len = 66;
int up_case = 0;
int re_sync = 5;
int output = 0;
int blanks = 0;
int lookahead = 200;
int skip1 = 0;
int skip2 = 0;
int trim_lines = 0;

main(argc, argv)
    int argc;
    char *argv [];
    {
    int  i;

    /* Initialize our file pointers so cleanup() only closes open files. */
    i = 0;
    while(i < 3)
        {
        infile [i] = NULL;
        i++;
        }
    outfile = NULL;
    if(argc == 1) help();
    msg = stdout;
    for(i = 1; i < argc; i++)  strip_opt(argv [i]);
    if(files < 2)
        {
        printf("DIFF:  Error:  Must specify two files.\n");
        cleanup();
        }
    open_files();
    if(command_errors)
        cleanup();
    page_skip();
    diff();
    cleanup();
    }

dont_look(line)
    register line_ptr line;
    {
    register char *temp;


    check_ctrl_c();
    if(line == NULL) return(0);
    if(line->linenum <= top_skip) return(1);
    if(line->linenum > page_len - bot_skip) return(1);
    temp = line->text;
    if(!blanks)
        {
        while(*temp != 0)
            {
            switch(*temp)
                {
                case ' ':
                case '\t':
                case '\n':
                    break;
                default :
                    return(0);
                    break;
                }
            temp++;
            }
        return(1);
        }
    return(0);
    }

equal(a, b)
    line_ptr a, b;
    {
    check_ctrl_c();
    if( (a == NULL) || (b == NULL) ) return(0);
    if(up_case) return(!strcmp(a->dup, b->dup));
        else return(!strcmp(a->text, b->text));
    }

position(f, where)
    int  f;
    line_ptr where;
    {
    check_ctrl_c();
    at [f] = &root [f];
    while(at [f]->link != where)
        at[f] = at [f]->link;
    return(0);
    }

char *index(str, c)
    register char *str, c;
    {
    check_ctrl_c();
    while(*str != NULL)
        {
        if(*str == c) return(str);
        str++;
        }
    return(NULL);
    }

line_ptr next_line(f)
    int  f;
    {
    line_ptr place_hold;
    char temp [MAXLINE + 1];

    check_ctrl_c();
    if( at [f]->link != NULL)
        {
        at [f] = at [f]->link;
        return(at [f]);
        }
    else
        {
        at [f]->link = (line_ptr) TrackMalloc(sizeof(struct LINE));
        if(at [f]->link == NULL)
            {
            printf("DIFF:  Out of Memory.\n");
            cleanup();
            }
        place_hold = at [f];
        at [f] = at [f]->link;
        at [f]->link = NULL;
        at [f]->text = NULL;
        at [f]->dup  = NULL;
        if(fgets(temp, MAXLINE, infile [f]) == NULL)
            {
            TrackFree(at [f]);
            at [f] = place_hold;
            at [f]->link = NULL;
            return(NULL);
            }
        if(trim_lines)
            {
            trim(temp);
            strcat(temp, "\n");
            }
        at [f]->text = TrackMalloc(strlen(temp) + 1);
        if(at [f]->text == NULL)
            {
            printf("DIFF:  Out of Memory.\n");
            cleanup();
            }
        strcpy(at [f]->text, temp);
        if( (index( at [f]->text, FORMFEED) != NULL) ||
            (line_count [f] > page_len))
            {
            page_count [f]++;
            line_count [f] = 1;
            }
        at [f]->linenum = line_count [f]++;
        at [f]->pagenum = page_count [f];
        if(up_case)
            {
            at [f]->dup = TrackMalloc(strlen(at [f]->text) + 1);
            if(at [f]->dup == NULL)
                {
                printf("DIFF:  Out of Memory.\n");
                cleanup();
                }
            strcpy(at [f]->dup, at [f]->text);
            upper(at [f]->dup);
            }
        return(at [f]);
        }
    }

discard(f, to)
    int  f;
    line_ptr to;
    {
    register line_ptr temp;

    check_ctrl_c();
    while(1)
        {
        if(root [f].link == NULL) break;
        temp = root [f].link;
        root [f].link = root [f].link->link;
        TrackFree(temp->text);
        if(temp->dup != NULL) TrackFree(temp->dup);
        TrackFree(temp);
        if(temp == to) break;
        }
    at [f] = &root [f];
    return(0);
    }

vfputs(str, file)
    char *str;
    FILE *file;
    {
    check_ctrl_c();
    fputs(str, file);
    return(0);
    }

put(line)
    line_ptr line;
    {
    register line_ptr temp;

    if(output)
        for(temp = root [1].link; ;)
            {
            check_ctrl_c();
            if(temp == NULL) return(0);
            vfputs(temp->text, outfile);
            if(temp == line) return(0);
            temp = temp->link;
            }
    return(0);
    }

char *change_bar(str)
    register char *str;
    {
    register int  i;
    char temp [MAXLINE + 1], *base;

    check_ctrl_c();
    base = temp;
    strcpy(temp, str);
    i = 0;
    if(bar_col != 0)
        {
        while(*base != '\n')
            {
            if((*base == '\r') && (*(base + 1) != '\n')) i = 0;
            base++;
            i++;
            }
        while(i++ < bar_col) *(base)++ = ' ';
        strcpy(base, "|\n");
        }
    else
        {
        if(temp [0] != ' ')
            {
            strcpy(&temp [1], str);
            }
        temp [0] = '|';
        }
    TrackFree(str);
    base = TrackMalloc(strlen(temp) + 1);
    if(base == NULL)
        {
        printf("DIFF:  Out of Memory.\n");
        cleanup();
        }
    strcpy(base, temp);
    return(base);
    }

added(line)
    line_ptr line;
    {
    register line_ptr temp;

    check_ctrl_c();
    for(temp = root [1].link; ;)
        {
        if(temp == NULL) return(0);
        if(!dont_look(temp))
            fprintf(msg, "+ Page %d : Line %d -> %s", temp->pagenum, temp->linenum,
            temp->text);
        if(output)
            if(dont_look(temp)) vfputs(temp->text, outfile);
            else vfputs((temp->text = change_bar(temp->text)), outfile);
        if(temp == line) return(0);
        temp = temp->link;
        }
    }

deleted(line)
    line_ptr line;
    {
    register line_ptr temp;

    check_ctrl_c();
    for(temp = root [2].link; ; )
        {
        if(temp == NULL) return(0);
        if(!dont_look(temp))
            fprintf(msg, "- Page %d : Line %d -> %s", temp->pagenum, temp->linenum,
                temp->text);
        if(temp == line) return(0);
        temp = temp->link;
        }
    return(0);
    }

resync(first, second)
    line_ptr first, second;
    {
    register line_ptr file1_start, file2_start;
    line_ptr last_bad1, last_bad2, t1, t2;
    int  i, j, k, moved1, moved2;

    check_ctrl_c();
    moved1 = 0;
    file1_start = first;

    position(1, first);
    for(k = 0; k < lookahead; k++)
        {
        while(dont_look(file1_start = next_line(1)));
        if(file1_start == NULL) goto no_sy;

        moved2 = 0;
        file2_start = second;

        position(2, second);
        for(j = 0; j < lookahead; j++)
            {
            while(dont_look(file2_start = next_line(2)));
            if(file2_start == NULL) goto eof2;

            t1 = file1_start;
            t2 = file2_start;
            for(i = 0; (i < re_sync) && equal(t1, t2); i++)
                {
                while(dont_look(t1 = next_line(1)));
                while(dont_look(t2 = next_line(2)));
                if( (t1 == NULL) || (t2 == NULL)) break;
                }
            if(i == re_sync) goto synced;

            last_bad2 = file2_start;
            position(2, file2_start);
            while(dont_look(file2_start = next_line(2)));
            moved2++;
            }
eof2:
        check_ctrl_c();
        last_bad1 = file1_start;
        position(1, file1_start);
        while(dont_look(file1_start = next_line(1)));
        moved1++;
        }
    printf("DIFF:  Lost sync in file %s at page %d line %d.\n",
        infile_name [1], first->pagenum, first->linenum);
    fclose(outfile);
    outfile = NULL;
    cleanup();
no_sy:
    check_ctrl_c();
    position(1, first);
    while( (first = next_line(1)) != NULL)
        {
        added(first);
        discard(1, first);
        }
    return(0);
synced:
    check_ctrl_c();
    if(moved1)
        {
        added(last_bad1);
        discard(1, last_bad1);
        }
    position( 1, file1_start);
    if(moved2)
        {
        deleted(last_bad2);
        discard(2, last_bad2);
        }
    position(2, file2_start);
    fprintf(msg, "\n");
    return(0);
    }

diff()
    {
    register line_ptr first, second;

    check_ctrl_c();
    while(1)
        {
        while(dont_look(first = next_line(1)));
        if(first == NULL)
            {
            put(first);
            return(0);
            }
        while(dont_look(second = next_line(2)));
        if(equal(first, second))
            {
            put(first);
            discard(1, first);
            discard(2, second);
            }
        else resync(first, second);
        if(second == NULL) return(0);
        }
    }

page_skip()
    {
    register line_ptr first, second;

    check_ctrl_c();
    while(1)
        {
        first = next_line(1);
        if( (first == NULL) || (first->pagenum > skip1) ) break;
        put(first);
        discard(1, first);
        }
    if(first != NULL) position(1, first);
    while(1)
        {
        second = next_line(2);
        if( (second == NULL) || (second->pagenum > skip2) ) break;
        discard(2, second);
        }
    if(second != NULL) position(2, second);
    return(0);
    }

help()
    {
    printf("\nDIFF");
    printf("\nText File Difference Detector");
    printf("\n");
    printf("\nFormat:");
    printf("\nDIFF [option {option} ...] newfile oldfile [barfile]");
    printf("\n");
    printf("\n    newfile = latest revision of text file.");
    printf("\n    oldfile = baseline to compare against.");
    printf("\n    barfile = output file if change bars are desired.");
    printf("\n");
    printf("\nOptions:");
    printf("\n    /BAR_COL=n    Column of output file in which change bar");
    printf("\n                  will appear.  Default = %d", bar_col);
    printf("\n    /BLANKS       Blank lines are to be considered significant.");
    printf("\n    /NOBLANKS     Blank lines are not significant.  DEFAULT");
    printf("\n    /BOT_SKIP=n   Lines at bottom of page to skip for running");
    printf("\n                  footers and page numbers.  Default = %d",
        bot_skip);
    printf("\n    /EXACT        Case is significant.  DEFAULT");
    printf("\n    /NOEXACT      Upper/Lower case is not considered");
    printf("\n                  significant in the comparison.");
    printf("\n    /LOOKAHEAD=n  Maximum number of lines to look ahead in");
    printf("\n                  each file to resync after a difference.");
    printf("\n                  Default = %d", lookahead);
    printf("\n    /OUTPUT=file  File to which differences summary is written.");
    printf("\n                  Default is to stdout.");
    printf("\n    /PAGE_LEN=n   Lines per page. (embedded form feeds override");
    printf("\n                  this value)  Default = %d", page_len);
    printf("\n    /RE_SYNC=n    Number of lines that must match before the");
    printf("\n                  files are considered synced.  Default = %d",
        re_sync);
    printf("\n    /SKIP1=n      Pages in NEWFILE to skip before comparison");
    printf("\n                  starts.  Also sets /SKIP2.  Default = %d",
        skip1);
    printf("\n    /SKIP2=n      Pages in OLDFILE to skip before comparison.");
    printf("\n                  MUST BE AFTER /SKIP1 !  Default = %d", skip2);
    printf("\n    /SOURCE_CODE  Causes DIFF to stop counting lines for page");
    printf("\n                  breaks.  Everything is considered to be");
    printf("\n                  on page 1.  (embedded form feeds override)");
    printf("\n    /TOP_SKIP=n   Lines at top of page to skip for running");
    printf("\n                  headings and page numbers.  Default = %d",
        top_skip);
    printf("\n    /TRIM_LINES   Trim trailing spaces, tabs, returns, and");
    printf("\n                  newlines from the lines before comparison.");
    printf("\n    /NOTRIM_LINES Do not trim lines before comparison.  DEFAULT");
    printf("\n\n");
    }

open_files()
    {
    int  i;

    check_ctrl_c();
    for(i = 1; i < 3; i++)
        if( (infile [i] = fopen(infile_name [i], "r")) == NULL)
            {
            printf("DIFF:  Error:  Can't open %s for READ!\n", infile_name [i]);
            command_errors++;
            }
    if(files > 2)
        if( (outfile = fopen(outfile_name, "w")) == NULL)
            {
            printf("DIFF:  Error:  Can't open %s for WRITE!\n", outfile_name);
            command_errors++;
            }
    return(0);
    }

redirect(str)
    char *str;
    {
    char filename [132];
    register char *ptr, *dest;

    check_ctrl_c();
    dest = filename;
    if( (ptr = index(str, '=') + 1) == (char *) (NULL + 1) )
        {
        printf("DIFF:  Error in option %s.\n", str);
        command_errors++;
        }
    while( (*(dest++) = *(ptr++)) != '\0');
    *dest = '\0';
    if( (msg = fopen(filename, "w")) == NULL)
        {
        printf("DIFF:  Can't open %s for WRITE!\n", filename);
        command_errors++;
        }
    return(0);
    }

strip_opt(str)
    char *str;
    {
    check_ctrl_c();
    upper(str);
    if( *str == OPT_FLAG)
        {
        if(match(str + 1, "BAR_COL"))
            bar_col = num(str);
        else if(match(str +1, "TOP_SKIP"))
                top_skip = num(str);
        else if(match(str +1, "BOT_SKIP"))
                bot_skip = num(str);
        else if(match(str + 1, "PAGE_LEN"))
                page_len = num(str);
        else if(match(str + 1, "NOEXACT"))
                up_case = 1;
        else if(match(str + 1, "EXACT"))
                up_case = 0;
        else if(match(str + 1, "RE_SYNC"))
                re_sync = num(str);
        else if(match(str + 1, "BLANKS"))
                blanks = 1;
        else if(match(str + 1, "NOBLANKS"))
                blanks = 0;
        else if(match(str + 1, "LOOKAHEAD"))
                lookahead = num(str);
        else if(match(str + 1, "SKIP1"))
                skip1 = skip2 = num(str);
        else if(match(str + 1, "SKIP2"))
                skip2 = num(str);
        else if(match(str + 1, "OUTPUT"))
                redirect(str);
        else if(match(str + 1, "SOURCE_CODE"))
                page_len = 2147483647L;
        else if(match(str + 1, "TRIM_LINES"))
                trim_lines = 1;
        else if(match(str + 1, "NOTRIM_LINES"))
                trim_lines = 0;
        else
            {
            printf("DIFF:  Unrecognized Option:  %s.\n", str);
            command_errors++;
            }
        }
    else
        {
        switch(files)
            {
            case 0:
                strcpy(infile_name [1], str);
                break;
            case 1:
                strcpy(infile_name [2], str);
                break;
            case 2:
                strcpy(outfile_name, str);
                output = 1;
                break;
            default :
                printf("DIFF:  Error:  Too many files specified at %s\n", str);
                command_errors++;
                break;
            }
        files++;
        }
    return(0);
    }

upper(str)
    register char *str;
    {
    check_ctrl_c();
    while(*str != NULL)
        {
        *str = toupper(*str);
        str++;
        }
    }

int match(str, pattern)
    register char *str, *pattern;
    {
    check_ctrl_c();
    while(1)
        {
        if(*str != *pattern) return(0);
        str++;
        pattern++;
        if(*pattern == '\0') return(1);
        if(*str == '\0') return(1);
        if(*str == '=') return(1);
        }
    }

int num(str)
    char *str;
    {
    register char *temp;

    check_ctrl_c();
    temp = index(str, '=');
    if(temp == NULL) return(0);
        else return(atoi(temp + 1));
    }

cleanup()
    {
    int  i;

/*
    Unnecessary, but a good habit to get into.  Added when I was looking
    for a creeping memory loss.
*/
    i = 0;
    while(i < 3)
        {
        if(infile [i] != NULL) fclose(infile [i]);
        infile [i] = NULL;
        i++;
        }
    if(outfile != NULL) fclose(outfile);
    outfile = NULL;
    /* Free up any memory that's not been freed yet.  Necessary. */
    TrackFreeAll();
    exit();
    }

/*
    Node structure for our linked list that keeps track of memory allocations.
    This wouldn't be necessary if the original program wasn't so sloppy
    about it's allocations and deallocations.  Note that this was added
    so the program wouldn't eat memory when run on an Amiga.  (no resource
    tracking, ya know!)  Also note that I couldn't use the native routines
    such as AllocRemember() on the Amiga, 'cause with them it's all or nothing,
    and this program selectively frees memory at odd times.
*/

struct TrackNode    {
                    struct TrackNode *next;
                    char *address;
                    unsigned long size;
                    };

/*
    Base pointer for our linked list.  Also an end-of-list pointer so we
    don't have to scan the entire list to find the end in order to add a
    new node.  Saves lots of time!
*/
static struct TrackNode *TrackBase = NULL;
static struct TrackNode *TrackLEnd  = NULL;

char *TrackMalloc(msize)
    unsigned long msize;
    {
    register struct TrackNode *temp, *current;
    char *memory;

    temp = (struct TrackNode *) AllocMem(sizeof(struct TrackNode), MEMF_PUBLIC);
    if(temp == NULL) return(NULL);
    memory = (char *) AllocMem(msize, MEMF_PUBLIC);
    if(memory == NULL)
        {
        FreeMem(temp, sizeof(struct TrackNode));
        return(NULL);
        }
    if(TrackBase == NULL)
        {
        TrackBase = temp;
        TrackBase->next = NULL;
        TrackBase->address = memory;
        TrackBase->size = msize;
        TrackLEnd = TrackBase;
        }
    else
        {
        current = TrackLEnd;
        current->next = temp;
        current = current->next;
        current->next = NULL;
        current->address = memory;
        current->size = msize;
        TrackLEnd = current;
        }
    return(memory);
    }

/*
    Unfortunately, in this case we must scan the list.  This routine is
    probably relatively slow, although I optimized it as much as possible.
*/
TrackFree(pointer)
    register char *pointer;
    {
    register struct TrackNode *current, *prev;

    current = TrackBase;
    if(current == NULL)
        {
        return(NULL);
        }
    prev = TrackBase;
    while(current->next != NULL && current->address != pointer)
        {
        prev = current;
        current = current->next;
        }
    if(current->address != pointer)
        {
        return(NULL);
        }
    if(current == TrackBase)
        {
        TrackBase = current->next;
        }
    else
        {
        prev->next = current->next;
        }
    FreeMem(current->address, current->size);
    FreeMem(current, sizeof(struct TrackNode));
    if(current == TrackLEnd) TrackLEnd = prev;
    return(1);
    }

/*
    Free up all memory that's still allocated.
*/

TrackFreeAll()
    {
    register struct TrackNode *current, *hold;

    current = TrackBase;
    while(current != NULL)
        {
        FreeMem(current->address, current->size);
        hold = current->next;
        FreeMem(current, sizeof(struct TrackNode));
        current = hold;
        }
    TrackBase = NULL;
    TrackLEnd = NULL;
    return(1);
    }

trim(start)
    char *start;
    {
    int  slen;
    register char *end;

    slen = strlen(start);
    if(slen == 0) return(0);
    end = start + slen - 1;
    while( (*end == ' ' || *end == '\t' || *end == '\n' || *end == '\r')
           && end >= start) end--;
    end++;
    *end = '\0';
    }

ctrl_c_pressed()
    {
    if(SetSignal(0l, 0l) & SIGBREAKF_CTRL_C)
        {
        return(1);
        }
    SetSignal(0l, SIGBREAKF_CTRL_C);
    return(NULL);
    }

check_ctrl_c()
    {
    if(ctrl_c_pressed())
        {
        printf("\n\033[7m Interrupt \033[m\n\n");
        cleanup();
        }
    }

jeff@novavax.UUCP (Jeff Bailey) (10/26/87)

[Plop, plop, Fizz, fizz....]

This is the second part of my posting of the diff program.  Part 1
contains commented source.  You should definitely take a look at it,
if only to read the comments at the beginning of the program - unless
you don't care to know about this program's idiosyncrasies!  Part 2
(this one) contains the uuencoded binary.  It was compiled with
Lattice 3.03 and linked with Blink (nodebug).  Type 'diff' without
any arguments to get a help screen.  For a comprehensive discussion
of the program see the Dr. Dobb's issue noted in the comment field
of Part 1.

-----cut here-----
begin 600 diff
M```#\P`````````U`````````#0```!S````%P``!C0```*N````=P````L`
M```!````00````$````:````*`````$```!$`````0```+(```!3````/```
M``$```&"````!````/P```!;`````P```*$```!9````*`````L````B````
M$````!H````)`````0```!X````:````>````A\````%````!````!$````1
M````!````#8```#E````!@```)L````4````(P```!8````;`````0```#D`
M```=````#0```^D```!S(\````!`(\@```!$(`](YW[^*D`L>0````0CS@``
M`"PCSP```#Q"N0```#B3R4ZN_MHH0"/L`)@````D2JP`K&<``)8@#9"M``0C
MP`````1A``%B('P`````0J=.N0```#!8CR!`(&@`K-'(T<@B:``0T\G3R2`Y
M````0'(`$ADCR0```$S0@5*`0F=2@`)`__Z?P%6`0G<``"`Y````0"!Y````
M1"0`4X#4@1^P```@`%."4<C_]A^\`"`@`%."'[$@`"``4<K_^")/+PE.N0``
M``!P`&!F(^P`.@````1A``#280``O"/`````."\`)$`@*@`D9Q`L>0```#`@
M0"(H``!.KO^"(BH`(&<<)#P```/M3J[_XB/`````2&<*Y8@@0"EH``@`I$AY
M`````$ZY`````'``8`0@+P`$+P!.N0```+1*N0```#AG+"(Y````*&<$3J[_
MW"(Y````2&<$3J[_W"QY````!$ZN_WPB>0```#A.KOZ&(!\N>0```#Q,WW]^
M3G5(YP$&+CP``X`'+'@`!$ZN_Y1,WV"`<&1@G$'L`%Q.KOZ`0>P`7$ZN_HQ.
M=4/Y````4'``3J[]V"/`````,&?`3G4``````^P````!`````````%8````7
M`````0```<(```&V```!?@```7(```%<```!4````4@```$L```!&@```/H`
M``#J````W````*(```"<````@@```'@```!,````.````"@````B````'```
M``@````"`````0```!4```%"`````@```"P```$R````T`````$````S````
M7@````````/R```#Z@```!<`````````````````````````````!```````
M````````````````````````````````````````````````````````````
M`````````&1O<RYL:6)R87)Y`````_(```/I```&-$Y6__R_^0````1D!D[Y
M`````$*N__P@+O_\#(`````#;!+E@"!`T?P```',0I!2KO_\8.)"N0```=@,
MK@````$`"&8$80`-&B/\````&````#QP`2U`__P@+O_\L*X`"&P6Y8`@;@`,
MT<`O$&$`$.Q8CU*N__Q@X`RY`````@```!QL$DAY````<$ZY`````%B/80`5
M)F$`#U1*N0```!AG!&$`%19A``P(80`+4F$`%0I.7DYU3E;__$CG``R_^0``
M``1D!D[Y`````"IN``AA`!?4N_P`````9@IP`$S?,`!.7DYU(!6PN0```$1B
M"G`!3-\P`$Y>3G4@.0```$R0N0```$@B%;*`8PIP`4S?,`!.7DYU*&T`#$JY
M````7&8\$!1*`&<L<@`2%`R!````"F<<#($````)9Q0,@0```"!G#$YQ<`!,
MWS``3EY.=5*,8,YP`4S?,`!.7DYU<`!,WS``3EY.=4Y6``"_^0````1D!D[Y
M`````&$`%RI*K@`(9P9*K@`,9@9P`$Y>3G5*N0```%!G*"!N``PO*``0(&X`
M""\H`!!.N0````!0CTJ`5\%$`4B!2,$@`4Y>3G4@;@`,+R@`#"!N``@O*``,
M3KD`````4(]*@%?!1`%(@4C!(`%.7DYU3E8``$CG`""_^0````1D!D[Y````
M`&$`%J8@+@`(Y8`@0-'\````+"`N``AR%$ZY`````")`T_P`````((D@+@`(
MY8`@0-'\````+")0(&D`"+'N``QG&"!`T?P````L(D#3_````"PD42"J``A@
MSG``3-\$`$Y>3G5.5@``2.<!!+_Y````!&0&3OD`````*FX`"!XN``]A`!8D
M$!5*`&<2L`=F"B`-3-\@@$Y>3G52C6#H<`!,WR"`3EY.=4Y6]_)(YP`@O_D`
M```$9`9.^0````!A`!7H("X`".6`($#1_````"PB4$JI``AG*"!`T?P````L
M(D#3_````"PD42"J``@@0-'\````+"`03-\$`$Y>3G4@+@`(Y8`@0-'\````
M+")0<!0O`"])``AA`!,D6(\@;P`$(4``""`N``CE@"!`T?P````L(E!*J0`(
M9A)(>0```)A.N0````!8CV$`$G`@+@`(Y8`@0-'\````+"U0__P@0-'\````
M+")`T_P````L)%$@J@`(($#1_````"PB4)'((T@`""!`T?P````L(E"1R"-(
M``P@0-'\````+")00JD`$"!`T?P```',+Q`O/```"`!(;O?[3KD```"03^\`
M#$J`9D(@+@`(Y8`@0-'\````+"\080`3(EB/("X`".6`($#1_````"P@KO_\
M($#1_````"PB4)'((T@`""`(3-\$`$Y>3G5*N0```&QG'$AN]_MA`!/H6(](
M>0```*](;O?[3KD`````4(\@+@`(Y8`@0-'\````+")02&[W^R])``A.N0``
M``!8CU*`+P!A`!'L6(\@;P`$(4``#"`N``CE@"!`T?P````L(E!*J0`,9A)(
M>0```+%.N0````!8CV$`$3@@+@`(Y8`@0-'\````+")02&[W^R\I``Q.N0``
M``!0CR`N``CE@"!`T?P````L(E!P#"\`+RD`#&$`_:10CTJ`9A@@+@`(Y8`@
M0-'\`````"`0L+D```!,8QP@+@`(Y8`@0-'\````#%*0($#1_`````!P`2"`
M("X`".6`($#1_````"PB4"!`T?P`````(A!2D"*!($#1_````"PB4"!`T?P`
M```,(U``!$JY````4&<``*0@0-'\````+")0($#1_````"PD4"\J``PO20`,
M3KD`````6(]2@"\`80`0VEB/(&\`""%``!`@+@`(Y8`@0-'\````+")02JD`
M$&822'D```#(3KD`````6(]A`!`F("X`".6`($#1_````"PB4"!`T?P````L
M)%`O*@`,+RD`$$ZY`````%"/("X`".6`($#1_````"PB4"\I`!!A``[.6(\@
M+@`(Y8`@0-'\````+"`03-\$`$Y>3G5.5O_\2.<`)+_Y````!&0&3OD`````
M80`2G"`N``AR%$ZY`````"!`T?P`````2J@`"&=<("X`"'(43KD`````($#1
M_``````J:``(($#1_``````B0-/\`````"1I``@A:@`(``@O+0`,80`0FEB/
M2JT`$&<*+RT`$&$`$(I8CR\-80`0@EB/N^X`#&:,3G$@+@`(Y8`@0-'\````
M+"`N``AR%$ZY`````")`T_P`````((EP`$S?)`!.7DYU3E8``+_Y````!&0&
M3OD`````80`1XB\N``PO+@`(3KD```"64(]P`$Y>3G5.5O_\2.<`!+_Y````
M!&0&3OD`````2KD```!89T`J>0```!QA`!&DN_P`````9@IP`$S?(`!.7DYU
M+SD```'8+RT`#&&.4(^[[@`(9@IP`$S?(`!.7DYU*FT`"&#&<`!,WR``3EY.
M=4Y6]_9(YP$$O_D````$9`9.^0`````J;@`(80`11D'N]_LO#2\(+4CW]DZY
M`````%"/?@!*N0```$!G5"!N]_80$`P```IG&@P```UF#!`H``$,```*9P)^
M`%*N]_92AV#:(`=2A["Y````0&P.(&[W]A"\`"!2KO?V8.9(>0```-\O+O?V
M3KD`````4(]@'A`N]_L,```@9PXO#4AN]_Q.N0````!0CQU\`'SW^R\-80`/
M`EB/2&[W^TZY`````%B/4H`O`&$`#C!8CRU`]_9*@&822'D```#B3KD`````
M6(]A``V22&[W^R\N]_9.N0````!0CR`N]_9,WR"`3EY.=4Y6__Q(YP`$O_D`
M```$9`9.^0````!A`!!(*GD````<N_P`````9@IP`$S?(`!.7DYU+PUA`/@Z
M6(]*@&8@+RT`#"\5+RT`!$AY````^2\Y````/$ZY`````$_O`!1*N0```%AG
M.B\-80#X!EB/2H!G$B\Y```!V"\M``QA`/WL4(]@'"\M``QA`/YT6(\K0``,
M+SD```'8+P!A`/W.4(^[[@`(9@IP`$S?(`!.7DYU*FT`"&``_VI.5O_\2.<`
M!+_Y````!&0&3OD`````80`/D"IY````,+O\`````&8*<`!,WR``3EY.=2\-
M80#W@EB/2H!F("\M``PO%2\M``1(>0```1,O.0```#Q.N0````!/[P`4N^X`
M"&8*<`!,WR``3EY.=2IM``A@K$Y6_]1(YP`,O_D````$9`9.^0````!A``\<
M0J[_V"IN``@O+@`(<`$O`&$`^$I0CT*N_]P@+O_<L+D```!@;``!6'`!+P!A
M`/CL6(\J0"\-80#V\EB/2H!FZ+O\`````&<``6Y"KO_4*&X`#"\N``QP`B\`
M80#X`%"/0J[_X"`N_^"PN0```&!L``#6<`(O`&$`^*)8CRA`+PQA`/:H6(]*
M@&;HN?P`````9P``M"U-_^PM3/_H0J[_Y"`N_^2PN0```%1L6"\N_^@O+O_L
M80#W)E"/2H!G1G`!+P!A`/A66(\O`"U`_^QA`/9:6(]*@&;F<`(O`&$`^#Q8
MCR\`+4#_Z&$`]D!8CTJ`9N9*KO_L9PQ*KO_H9P92KO_D8)P@+O_DL+D```!4
M9P``["U,__`O#'`"+P!A`/<^4(]P`B\`80#W\EB/*$`O#&$`]?A8CTJ`9NA2
MKO_44J[_X&``_R!A``W2+4W_]"\-<`$O`&$`]P90CW`!+P!A`/>Z6(\J0"\-
M80#UP%B/2H!FZ%*N_]A2KO_<8`#^GB!N``@O$"\H``0O.0```"1(>0```2U.
MN0````!/[P`0+SD```'83KD```):6(]"N0```=AA``IZ80`-8B\N``AP`2\`
M80#VF%"/<`$O`&$`]TQ8CRU```A*@&<8+P!A`/S<6(\O+@`(<`$O`&$`^GI0
MCV#6<`!,WS``3EY.=6$`#1Q*KO_89Q@O+O_T80#\KEB/+R[_]'`!+P!A`/I,
M4(\O#7`!+P!A`/8V4(]*KO_49Q@O+O_P80#]/%B/+R[_\'`"+P!A`/HB4(\O
M#'`"+P!A`/8,4(](>0```5XO.0```#Q.N0````!0CW``3-\P`$Y>3G5.5O_X
M2.<`#+_Y````!&0&3OD`````80`,D'`!+P!A`/:(6(\J0"\-80#TCEB/2H!F
MZ+O\`````&82+PUA`/J@6(]P`$S?,`!.7DYU<`(O`&$`]E98CRA`+PQA`/1<
M6(]*@&;H+PPO#6$`]0!0CTJ`9R(O#6$`^FA8CR\-<`$O`&$`^7)0CR\,<`(O
M`&$`^690CV`*+PPO#6$`_-I0C[G\`````&8`_W1P`$S?,`!.7DYU3E;_^$CG
M``R_^0````1D!D[Y`````&$`"]YP`2\`80#UUEB/*D"[_`````!G(B`M``2P
MN0```&1B%B\-80#Y[EB/+PUP`2\`80#X^%"/8,J[_`````!G#"\-<`$O`&$`
M]-A0CW`"+P!A`/6,6(\H0+G\`````&<:("P`!+"Y````:&(.+PQP`B\`80#X
MME"/8-*Y_`````!G#"\,<`(O`&$`])90CW``3-\P`$Y>3G6_^0````1D!D[Y
M`````$AY```!8$ZY`````%B/2'D```%F3KD`````6(](>0```85.N0````!8
MCTAY```!ATZY`````%B/2'D```&03KD`````6(](>0```<9.N0````!8CTAY
M```!R$ZY`````%B/2'D```'U3KD`````6(](>0```B%.N0````!8CTAY```"
M6$ZY`````%B/2'D```):3KD`````6(](>0```F1.N0````!8CR\Y````0$AY
M```"H4ZY`````%"/2'D```+/3KD`````6(](>0```Q!.N0````!8CTAY```#
M34ZY`````%B/+SD```!(2'D```.,3KD`````4(](>0```\=.N0````!8CTAY
M```#^$ZY`````%B/2'D```0N3KD`````6(](>0``!&!.N0````!8CTAY```$
MG$ZY`````%B/+SD```!@2'D```373KD`````4(](>0``!/=.N0````!8CTAY
M```%.$ZY`````%B/2'D```5A3KD`````6(\O.0```$Q(>0``!:).N0````!0
MCTAY```%STZY`````%B/+SD```!42'D```8-3KD`````4(](>0``!DM.N0``
M``!8CR\Y````9$AY```&B4ZY`````%"/2'D```;%3KD`````6(\O.0```&A(
M>0``!P1.N0````!0CTAY```'/$ZY`````%B/2'D```=[3KD`````6(](>0``
M![9.N0````!8CTAY```']$ZY`````%B/+SD```!$2'D```@P3KD`````4(](
M>0``"&Q.N0````!8CTAY```(J$ZY`````%B/2'D```CF3KD`````6(](>0``
M"2=.N0````!8CTYU3E;_]+_Y````!&0&3OD`````80`(IG`!+4#__"`N__P,
M@`````-L6N6`($#1_````<PB0-/\````($AY```)*B\1+T@`#$ZY`````%"/
M(&\`!""`2H!F)"`N__SE@"!`T?P````@+Q!(>0``"2Q.N0````!0CU*Y````
M&%*N__Q@F@RY`````@```!QO.$AY```)5$AY```!2$ZY`````%"/(\````'8
M2H!F&DAY```!2$AY```)5DZY`````%"/4KD````8<`!.7DYU3E;_=$CG``R_
M^0````1D!D[Y`````&$`!]9)[O]\<#TO`"\N``AA`/&"4(\@0%*(*D@@?```
M``&[R&88+RX`"$AY```)?TZY`````%"/4KD````8($Q2C!`5$(!2C4H`9O)"
M%$AY```)FTAN_WQ.N0````!0CR/`````/$J`9AA(;O]\2'D```F=3KD`````
M4(]2N0```!AP`$S?,`!.7DYU3E8``+_Y````!&0&3OD`````80`'."\N``AA
M``,N6(\@;@`($!`,```O9@`"G%*(2'D```F^+PAA``-J4(]*@&<4+RX`"&$`
M`\98CR/`````0&```O`@;@`(4HA(>0``"<8O"&$``SY0CTJ`9Q0O+@`(80`#
MFEB/(\````!$8``"Q"!N``A2B$AY```)SR\(80`#$E"/2H!G%"\N``AA``-N
M6(\CP````$A@``*8(&X`"%*(2'D```G8+PAA``+F4(]*@&<4+RX`"&$``T)8
MCR/`````3&```FP@;@`(4HA(>0``">$O"&$``KI0CTJ`9PQP`2/`````4&``
M`D@@;@`(4HA(>0``">DO"&$``I90CTJ`9PI"N0```%!@``(F(&X`"%*(2'D`
M``GO+PAA``)T4(]*@&<4+RX`"&$``M!8CR/`````5&```?H@;@`(4HA(>0``
M"?<O"&$``DA0CTJ`9PQP`2/`````7&```=8@;@`(4HA(>0``"?XO"&$``B10
MCTJ`9PI"N0```%Q@``&T(&X`"%*(2'D```H'+PAA``("4(]*@&<4+RX`"&$`
M`EY8CR/`````8&```8@@;@`(4HA(>0``"A$O"&$``=90CTJ`9QHO+@`(80`"
M,EB/(\````!H(\````!D8``!5B!N``A2B$AY```*%R\(80`!I%"/2H!G%"\N
M``AA``(`6(\CP````&A@``$J(&X`"%*(2'D```H=+PAA``%X4(]*@&<.+RX`
M"&$`_218CV```00@;@`(4HA(>0``"B0O"&$``5)0CTJ`9PXC_'____\```!,
M8```WB!N``A2B$AY```*,"\(80`!+%"/2H!G#'`!(\````!L8```NB!N``A2
MB$AY```*.R\(80`!"%"/2H!G"D*Y````;&```)@O+@`(2'D```I(3KD`````
M4(]2N0```!A@?"`Y````'`R``````F<T#(`````!9QA*@&9$+RX`""\Y````
M)$ZY`````%"/8$@O+@`(+SD````H3KD`````4(]@-"\N``A(>0```4A.N0``
M``!0CW`!(\````!88!@O+@`(2'D```IJ3KD`````4(]2N0```!A2N0```!QP
M`$Y>3G5.5O_\2.<`!+_Y````!&0&3OD`````*FX`"&$``^9P`!`5+T``!$J`
M9RA2@"!`T?P`````$!`(```!9PP@+P`$!(`````@8`1P`!`5&H!2C6#,3-\@
M`$Y>3G5.5@``2.<`#+_Y````!&0&3OD`````*FX`""AN``QA``.($!42%+`!
M9PIP`$S?,`!.7DYU4HU2C!`42@!F"G`!3-\P`$Y>3G40%4H`9@IP`4S?,`!.
M7DYU$!4,```]9L)P`4S?,`!.7DYU3E;__$CG``2_^0````1D!D[Y`````&$`
M`R9P/2\`+RX`"&$`[-90CRI`N_P`````9@IP`$S?(`!.7DYU($U2B"\(3KD`
M````6(],WR``3EY.=4Y6__R_^0````1D!D[Y`````$*N__P@+O_\#(`````#
M;#;E@"!`T?P```',2I!G$B!`T?P```',+Q!.N0```EI8CR`N__SE@"!`T?P`
M``',0I!2KO_\8+Y*N0```=AG#B\Y```!V$ZY```"6EB/0KD```'880`!;$ZY
M`````$Y>3G5.5O_T2.<`#+_Y````!&0&3OD`````<`$O`'`,+P!.N0````!0
MCRI`N_P`````9@IP`$S?,`!.7DYU<`$O`"\N``A.N0````!0CRU`__1*@&88
M<`PO`"\-3KD````84(]P`$S?,`!.7DYU2KD```J:9AX@34*0(6[_]``$(6X`
M"``((\@```J>(\@```J:8"`H>0``"IX@32B(*$A"E"EN__0`!"EN``@`""/,
M```*GB`N__1,WS``3EY.=4Y6__A(YP`<O_D````$9`9.^0`````J;@`(*'D`
M``J:N?P`````9@IP`$S?.`!.7DYU)GD```J:2I1G#B!L``2QS6<&)DPH5&#N
M(&P`!+'-9PIP`$S?.`!.7DYUN?D```J:9@@CU```"II@`B:4+RP`""\L``1.
MN0```!A0CW`,+P`O#$ZY````&%"/N?D```J>9@8CRP``"IYP`4S?.`!.7DYU
M3E;_^$CG``R_^0````1D!D[Y`````"IY```*FKO\`````&<D+RT`""\M``1.
MN0```!A0CRA5<`PO`"\-3KD````84(\J3&#4D<@CR```"IXCR```"IIP`4S?
M,`!.7DYU3E;_^$CG``2_^0````1D!D[Y`````"\N``A.N0````!8CRU`__Q*
M@&8*<`!,WR``3EY.=2!N``C1[O_\4X@J2!`5#```(&<2#```"6<,#```"F<&
M#```#68*N^X`"&4$4XU@W%*-0A5,WR``3EY.=;_Y````!&0&3OD`````<``O
M`"\`3KD```!$4(\(```,9P1P`4YU+SP``!``0J=.N0```$10CW``3G6_^0``
M``1D!D[Y`````&&V2H!G$DAY```*HDZY`````%B/80#\\$YU``````/L````
M'0````$``!BH```8;@``&`8``!>F```7`@``%D8``!7````5<@``%0@``!2N
M```18```$,(```_R```-8@``#+H```P(```)?```"0@```A0```'3@``!N8`
M``:V```%_````K````)L```!\@```6X```#`````!@```+X````#```8O```
M%^X``!?H```7M```%XX``!>&```77@``%U8``!<L```7%```%N@``!;.```6
MQ@``%L```!:H```4F@``%)0``!2&```4>@``%%8``!1"```4)```%!P``!0.
M```4````$^X``!/>```3R@``$[H``!.D```3?@``$VX``!-2```30@``$SP`
M`!,@```3$```$O0``!+D```2T@``$L(``!*N```2G@``$H(``!)R```28```
M$E```!(\```2+```$A```!(````1Y```$=0``!&X```1J```$8P``!%,```1
M/@``$1X``!$(```0^@``$*X``!"@```0?```$'0``!!D```05@``$$X``!`H
M```0(@``#]X```_0```/P@``#[0```^F```/H```#Y(```^$```/=@``#V@`
M``]:```/5```#T8```\X```/,@``#R0```\6```/$```#P(```[T```.[@``
M#N````[2```.Q```#K8```ZP```.H@``#I0```Z&```.>```#FH```Y<```.
M5@``#D@```XZ```.+```#AX```X8```."@``#?P```WN```-X```#=(```W$
M```-M@``#:@```V:```-C```#7X```UP```-+@``#.0```OB```+'```"Q8`
M``J6```*,@``"?8```FL```)2```"*8```B0```(&@``!\(```>L```'>@``
M!O0```:,```%Y```!<H```6J```%H```!88```5X```%1@``!3P```4P```%
M)@``!1P```4.```%!```!/(```3H```$V```!-````2N```$C@``!'0```1F
M```$-```!!H```0(```#\````^0```/.```#F````X@```-X```#:@```V(`
M``-6```#/````RX```,(```"\````N(```+:```"R@```DP```)$```",```
M`@P```&2```!'````0(```#\````Z@```)P```"&````?@```"$````$```6
M*@``%AP``!84```6!@``%>X``!7B```4:@``$3```!":```0D```$((``!`:
M```+Z```"SH```LL```)3@``"1H```C:```(N@``")8```AB```'&```!OP`
M``:@```&2@``!D(```8V```&'````Z8```(@````3@```#8````H`````0``
M``4``!6L`````0````<``!34`````0````D``!8T`````0````P```.X````
M!@````X``!$H```0B```$#0``!8B```5]@``"S(````#````#P``"^X```E4
M```(G`````$````0```&T````#<````8```8P@``%(P``!04```11```$0``
M`!"F```07```#^0```_6```/R```#[H```^L```/F```#XH```]\```/;@``
M#V````],```//@``#RH```\<```/"```#OH```[F```.V```#LH```Z\```.
MJ```#IH```Z,```.?@``#G````YB```.3@``#D````XR```.)```#A````X"
M```-]```#>8```W8```-R@``#;P```VN```-H```#9(```V$```-=@``"R(`
M``@@```%C```!'H```-"````C`````$````;```$)`````(````<```!T@``
M`:H````)````'0``%'```!1<```42```"#0```?F```'S```!W````6Z```$
MG@````0````>```8&```"`````56```$1`````$````B````2@````0````G
M```&F```!BX```84```"&````!T````K```8L```&'8``!@.```7K@``%PH`
M`!9.```5R```%7H``!40```4M@``$6@``!#*```/^@``#6H```S"```,$```
M"80```D0```(6```!U8```;N```&O@``!@0```*X```"=````?H```%V````
MR`````X````)````,P``&)P``!B"```7V@``%\H``!=^```7<```%I8``!:`
M```67`````````/R```#Z@```JX````!`````0````$````!`````0````$`
M``````````````````!`````Q``````````4````*```````````````````
M````````````0@`````````%``````````````#(````````````````1$E&
M1CH@($5R<F]R.B`@375S="!S<&5C:69Y('1W;R!F:6QE<RX*`$1)1D8Z("!/
M=70@;V8@365M;W)Y+@H`"@!$249&.B`@3W5T(&]F($UE;6]R>2X*`$1)1D8Z
M("!/=70@;V8@365M;W)Y+@H`?`H`1$E&1CH@($]U="!O9B!-96UO<GDN"@`K
M(%!A9V4@)60@.B!,:6YE("5D("T^("5S`"T@4&%G92`E9"`Z($QI;F4@)60@
M+3X@)7,`1$E&1CH@($QO<W0@<WEN8R!I;B!F:6QE("5S(&%T('!A9V4@)60@
M;&EN92`E9"X*``H`"D1)1D8`"E1E>'0@1FEL92!$:69F97)E;F-E($1E=&5C
M=&]R``H`"D9O<FUA=#H`"D1)1D8@6V]P=&EO;B![;W!T:6]N?2`N+BY=(&YE
M=V9I;&4@;VQD9FEL92!;8F%R9FEL95T`"@`*("`@(&YE=V9I;&4@/2!L871E
M<W0@<F5V:7-I;VX@;V8@=&5X="!F:6QE+@`*("`@(&]L9&9I;&4@/2!B87-E
M;&EN92!T;R!C;VUP87)E(&%G86EN<W0N``H@("`@8F%R9FEL92`](&]U='!U
M="!F:6QE(&EF(&-H86YG92!B87)S(&%R92!D97-I<F5D+@`*``I/<'1I;VYS
M.@`*("`@("]"05)?0T],/6X@("`@0V]L=6UN(&]F(&]U='!U="!F:6QE(&EN
M('=H:6-H(&-H86YG92!B87(`"B`@("`@("`@("`@("`@("`@('=I;&P@87!P
M96%R+B`@1&5F875L="`]("5D``H@("`@+T),04Y+4R`@("`@("!";&%N:R!L
M:6YE<R!A<F4@=&\@8F4@8V]N<VED97)E9"!S:6=N:69I8V%N="X`"B`@("`O
M3D]"3$%.2U,@("`@($)L86YK(&QI;F5S(&%R92!N;W0@<VEG;FEF:6-A;G0N
M("!$149!54Q4``H@("`@+T)/5%]32TE0/6X@("!,:6YE<R!A="!B;W1T;VT@
M;V8@<&%G92!T;R!S:VEP(&9O<B!R=6YN:6YG``H@("`@("`@("`@("`@("`@
M("!F;V]T97)S(&%N9"!P86=E(&YU;6)E<G,N("!$969A=6QT(#T@)60`"B`@
M("`O15A!0U0@("`@("`@($-A<V4@:7,@<VEG;FEF:6-A;G0N("!$149!54Q4
M``H@("`@+TY/15A!0U0@("`@("!5<'!E<B],;W=E<B!C87-E(&ES(&YO="!C
M;VYS:61E<F5D``H@("`@("`@("`@("`@("`@("!S:6=N:69I8V%N="!I;B!T
M:&4@8V]M<&%R:7-O;BX`"B`@("`O3$]/2T%(14%$/6X@($UA>&EM=6T@;G5M
M8F5R(&]F(&QI;F5S('1O(&QO;VL@86AE860@:6X`"B`@("`@("`@("`@("`@
M("`@(&5A8V@@9FEL92!T;R!R97-Y;F,@869T97(@82!D:69F97)E;F-E+@`*
M("`@("`@("`@("`@("`@("`@1&5F875L="`]("5D``H@("`@+T]55%!55#UF
M:6QE("!&:6QE('1O('=H:6-H(&1I9F9E<F5N8V5S('-U;6UA<GD@:7,@=W)I
M='1E;BX`"B`@("`@("`@("`@("`@("`@($1E9F%U;'0@:7,@=&\@<W1D;W5T
M+@`*("`@("]004=%7TQ%3CUN("`@3&EN97,@<&5R('!A9V4N("AE;6)E9&1E
M9"!F;W)M(&9E961S(&]V97)R:61E``H@("`@("`@("`@("`@("`@("!T:&ES
M('9A;'5E*2`@1&5F875L="`]("5D``H@("`@+U)%7U-93D,];B`@("!.=6UB
M97(@;V8@;&EN97,@=&AA="!M=7-T(&UA=&-H(&)E9F]R92!T:&4`"B`@("`@
M("`@("`@("`@("`@(&9I;&5S(&%R92!C;VYS:61E<F5D('-Y;F-E9"X@($1E
M9F%U;'0@/2`E9``*("`@("]32TE0,3UN("`@("`@4&%G97,@:6X@3D571DE,
M12!T;R!S:VEP(&)E9F]R92!C;VUP87)I<V]N``H@("`@("`@("`@("`@("`@
M("!S=&%R=',N("!!;'-O('-E=',@+U-+25`R+B`@1&5F875L="`]("5D``H@
M("`@+U-+25`R/6X@("`@("!086=E<R!I;B!/3$1&24Q%('1O('-K:7`@8F5F
M;W)E(&-O;7!A<FES;VXN``H@("`@("`@("`@("`@("`@("!-55-4($)%($%&
M5$52("]32TE0,2`A("!$969A=6QT(#T@)60`"B`@("`O4T]54D-%7T-/1$4@
M($-A=7-E<R!$249&('1O('-T;W`@8V]U;G1I;F<@;&EN97,@9F]R('!A9V4`
M"B`@("`@("`@("`@("`@("`@(&)R96%K<RX@($5V97)Y=&AI;F<@:7,@8V]N
M<VED97)E9"!T;R!B90`*("`@("`@("`@("`@("`@("`@;VX@<&%G92`Q+B`@
M*&5M8F5D9&5D(&9O<FT@9F5E9',@;W9E<G)I9&4I``H@("`@+U1/4%]32TE0
M/6X@("!,:6YE<R!A="!T;W`@;V8@<&%G92!T;R!S:VEP(&9O<B!R=6YN:6YG
M``H@("`@("`@("`@("`@("`@("!H96%D:6YG<R!A;F0@<&%G92!N=6UB97)S
M+B`@1&5F875L="`]("5D``H@("`@+U1224U?3$E.15,@("!4<FEM('1R86EL
M:6YG('-P86-E<RP@=&%B<RP@<F5T=7)N<RP@86YD``H@("`@("`@("`@("`@
M("`@("!N97=L:6YE<R!F<F]M('1H92!L:6YE<R!B969O<F4@8V]M<&%R:7-O
M;BX`"B`@("`O3D]44DE-7TQ)3D53($1O(&YO="!T<FEM(&QI;F5S(&)E9F]R
M92!C;VUP87)I<V]N+B`@1$5&055,5``*"@!R`$1)1D8Z("!%<G)O<CH@($-A
M;B=T(&]P96X@)7,@9F]R(%)%040A"@!W`$1)1D8Z("!%<G)O<CH@($-A;B=T
M(&]P96X@)7,@9F]R(%=2251%(0H`1$E&1CH@($5R<F]R(&EN(&]P=&EO;B`E
M<RX*`'<`1$E&1CH@($-A;B=T(&]P96X@)7,@9F]R(%=2251%(0H`0D%27T-/
M3`!43U!?4TM)4`!"3U1?4TM)4`!004=%7TQ%3@!.3T5804-4`$5804-4`%)%
M7U-93D,`0DQ!3DM3`$Y/0DQ!3DM3`$Q/3TM!2$5!1`!32TE0,0!32TE0,@!/
M5510550`4T]54D-%7T-/1$4`5%))35],24Y%4P!.3U1224U?3$E.15,`1$E&
M1CH@(%5N<F5C;V=N:7IE9"!/<'1I;VXZ("`E<RX*`$1)1D8Z("!%<G)O<CH@
M(%1O;R!M86YY(&9I;&5S('-P96-I9FEE9"!A="`E<PH`````````````"AM;
M-VT@26YT97)R=7!T(!M;;0H*`````^P````$````!````#0````P````*```
M`"0````````#\@```^L```!W```#\@```^D````+3E;__"\N``A.N0````!8
MCTAN__PO`"U```A.N0````!0CR`N__Q.7DYU``````/L`````0```!D````<
M`````0```!H````*`````````_(```/J`````0```@````/R```#Z@```$$`
M("`@("`@("`@*"@H*"@@("`@("`@("`@("`@("`@("!($!`0$!`0$!`0$!`0
M$!`0A(2$A(2$A(2$A!`0$!`0$!"!@8&!@8$!`0$!`0$!`0$!`0$!`0$!`0$!
M`1`0$!`0$(*"@H*"@@("`@("`@("`@("`@("`@("`@("$!`0$"`@("`@("`@
M("`H*"@H*"`@("`@("`@("`@("`@("`@($@0$!`0$!`0$!`0$!`0$!"$A(2$
MA(2$A(2$$!`0$!`0$(&!@8&!@0$!`0$!`0$!`0$!`0$!`0$!`0$!$!`0$!`0
M@H*"@H*"`@("`@("`@("`@("`@("`@("`@(0$!`0(````````_(```/J````
M`0````````/R```#Z0```!I.5O_\0J[__"`N__P,@````!1L('(83KD`````
M($#1_``````O"$ZY```"6EB/4J[__&#40J[__"`N__RPN0````!L$"\`3KD`
M``.66(]2KO_\8.0O+@`,+RX`"$ZY`````%"/3EY.=0```^P````!````#@``
M`"@````!````$@```$@````!````'P```#X````!````(0```%X````!````
M(@```"`````!````)P```!@````````#\@```^D````H3E;__"\\```P`$*G
M3KD```!$4(\"@```,``M0/_\2H!F!G``3EY.=4JY`````&=B<%XO`$ZY```%
M#EB/#*X``"``__QF!'!$8`)P0R\`3KD```4.6(]P"B\`3KD```4.6(]"KO_\
M("[__+"Y`````&P0+P!.N0```Y98CU*N__Q@Y'``+P`O`$ZY`````%"/8`@@
M+O_\3EY.=4Y>3G4``````^P````!````"P```"H````$````$@```'8```!<
M````4````#8````!````'P```&P````!````(0```(H````!````,P````X`
M```````#\@```^H````!`````````_(```/I````1$Y6__A"KO_\(#D````$
M4X`CP`````1*@&L2<``@>0`````0$%*Y`````&`.2'D`````3KD`````6(\M
M0/_X#(#_____9RP,@`````IF$"!N``C1[O_\4J[__$(08!0@;@`(T>[__%*N
M__P@+O_X$(!@EDJN__QF!G``3EY.=2!N``C1[O_\0A`@+@`(3EY.=4Y6__A"
MKO_\("X`#%.`(B[__+*`;$P@;@`0("@`!%.`(4``!$J`:PHB4%*0<``0$6`,
M+RX`$$ZY`````%B/+4#_^%*`9QP@;@`(T>[__%*N__P@+O_X$(`,@`````IF
MJ$YQ("[__"!N``C1P$(02H!F!G``3EY.=2`N``A.7DYU```#[`````(````4
M````R````#0````%````(@```"X````F````'@```!(````*`````````_(`
M``/J`````0````````/R```#Z0```+).5O_X+7P`````__P@;O_\L?P```'@
M9!(0*``02@!G"@:N````&/_\8.(@;O_\L?P```'@9@9P`$Y>3G4O+O_\+RX`
M#"\N``AA"$_O``Q.7DYU3E;_ZB!N`!!**``09P@O"&$``?98CRUY`````/_T
M+6X`#/_P<``@;O_P$"@``0R`````8F<.#(````!A9A)"KO_T8`@M?```@`#_
M]%*N__`@;O_P$"@``0P``"M7P40!2(%(P7``(&X`#!`0'4'_[PR`````=V<`
M`-`,@````')G``""#(````!A9@`!%"`N__0`@`````@O0```2B[_[V<$<@)@
M`G(!("\``("!`(````$`+SP```&D+P`O+@`(3KD```!D3^\`#"U`__A2@&8&
M<`!.7DYU<`(O`$*G+R[_^$ZY```##D_O``Q*+O_O9P@@/````(!@`G`"+4#_
M_&```*1*+O_O9P1P`F`"<``B+O_T@H`O`2\N``A.N0```&10CRU`__A2@&8&
M<`!.7DYU2B[_[V<((#P```"`8`)P`2U`__Q@7DHN_^]G!'`"8`)P`2(N__2"
M@`"!```!``"!```"`"\\```!I"\!+RX`"$ZY````9$_O``PM0/_X4H!F!G``
M3EY.=4HN_^]G""`\````@&`"<`(M0/_\8`9P`$Y>3G4@+O_X<@9.N0`````@
M0-'\`````$HH``%G&`CN``+__R!N`!#0_``6(FX`$"-(``Q@""!N`!!"J``,
M("[_^"!N`!`10``1(*@`#'``(4``""%```0@+O_\$4``$"`(3EY.=4Y6```@
M;@`($"@`$`@```%G#B\(</\O`$ZY```!(%"/(&X`"!`H`!`"```,2@!F%DJH
M`!)G$"\H`!(O*``,3KD```$*4(^1R")N``@C2``,(T@`$D(I`!!P`!`I`!$O
M`$ZY```#EEB/3EY.=0`````#[`````$````-````:@````4````2```"O```
M`38```'&```!<````10````!````%````G0````!````%P```IH````!````
M(````@@````#````(@```#`````2````!@````$````G```"``````````/R
M```#Z0```%-.5O[L2.<`($'N`!`M2/_L(&X`#!`02@!G``$8<@`2$%*(+4'_
M^"U(``P,@0```"5F``#&$!`,```E9CQT`!004JX`#"!N``@@*``(4X`A0``(
M+4+_^$J`:PPB4%*0$H)P`!`18*HO+@`(+R[_^$ZY```!(%"/8)A(;O_T2&[_
M[$AN_NPO+@`,3KD`````3^\`$"U`__!*@&<`_W9"KO_\+4``#"`N__RPKO_T
M;`#_8B!N``@B*``(4X$A00`(2H%K%")04I!%[O[LU<`0$A*`<@`2$6`<0>[^
M[-'N__QP`!`0+RX`""\`3KD```$@4(\B`%*N__Q@K"!N``@@*``(4X`A0``(
M2H!K$B)04I`@+O_X$H!R`!(18`#^]B\N``@O+O_X3KD```$@4(\B`&``_N`O
M+@`(</\O`$ZY```!(%"/3-\$`$Y>3G4``````^P````$````%````3P```$F
M````Z@```'`````!````(P```(H````````#\@```^D````\3E;__'``(&X`
M"!`04JX`""U`__Q*@&<\(CD````@4X$CP0```"!*@6L4('D````84KD````8
M$(!R`!(08,9(>0```!@O+O_\3KD```$@4(\B`&"P(#D````@4X`CP````"!*
M@&L6('D````84KD````8<`H0@'(`$A!@%$AY````&'`*+P!.N0```2!0CR(`
M(`%.7DYU3E;_^$*N__AP`"!N``@0$%*N``@M0/_\2H!G-B!N``PB*``(4X$A
M00`(2H%K#")04I`2@'(`$A%@$B\N``PO+O_\3KD```$@4(\B`"U!__A@MB`N
M__A.7DYU```#[`````,````4````V@```(@```!*````"@```"(```!^````
M;@```&@```!>````5@```$`````R````+````"(````:`````````_(```/J
M`````0````````/R```#Z0```8).5@``2KD`````9P9.N0````!*K@`(:R0@
M+@`(L+D`````;!AR!DZY`````"!`T?P`````$!`(```'9@YP"2/``````'``
M3EY.=2`N``AR!DZY`````"!`T?P`````(`A.7DYU3E;_]$*N__P@+O_\L+D`
M````;!QR!DZY`````"!`T?P`````$!!*`&<&4J[__&#8("[__+"Y`````&8.
M<!@CP`````!P_TY>3G4@+O_\<@9.N0`````@0-'\`````"`Y``````*```"`
M`"(N``RS@"U```PM2/_T"```#V<$<!!@`G```(````"`(&[_]!"`("X`#`*`
M`````PR``````F<\#(`````!9Q)*@&92(&[_]!`0````0!"`8%@(+@`#``]G
M!'`(8`)P``"`````('(`(&[_]!(0@H`0@6`V""X``P`/9P1P"&`"<```@```
M`&!R`"!N__02$(*`$(%@%"!N__1"$'`6(\``````</].7DYU""X``0`.9PPO
M+@`(3KD```"D6(\@+@`,`H````,`2H!G"BU\```#[O_X8`@M?````^W_^"\N
M__@O+@`(3KD`````4(\@;O_T(4```DJ`9B!.N0```-0CP````!QP`B/`````
M`"!N__1"$'#_3EY.=2`N__Q.7DYU3E8``"`N``P"@```@```@````P$B+@`,
M`H'__W__+P$O`"\N``AA`/Y,3^\`#$Y>3G5.5O_X2JX`$&L2+RX`"&$`_<Y8
MCRU`__A*@&8.<!8CP`````!P_TY>3G4O+@`0+RX`#"!N__@O*``"3KD````P
M3^\`#"U`__Q2@&843KD```#4(\`````<<`4CP``````@+O_\3EY.=4Y6__A*
MK@`0:Q(O+@`(80#]9EB/+4#_^$J`9@YP%B/``````'#_3EY.=2!N__@0$`@`
M``-G$'`"+P!"IR\N``AA0D_O``PO+@`0+RX`#"!N__@O*``"3KD```!,3^\`
M#"U`__Q2@&843KD```#4(\`````<<`4CP``````@+O_\3EY.=4Y6__PO+@`(
M80#\Z%B/+4#__$J`9PH,K@````(`$&,.<!8CP`````!P_TY>3G4@+@`0Y8`@
M0-'\`````"\0+RX`#")N__PO*0`"3KD```"(3^\`#%*`9A1.N0```-0CP```
M`!QP%B/``````'``+P`O`"!N__PO*``"3KD```"(3^\`#$Y>3G5.5O_X+RX`
M"&$`_&!8CRU`__A*@&8&</].7DYU<``@;O_X$A`M0/_\"`$``F<$3EY.=2!N
M__@O*``"3KD````<6(\@;O_X0A`@+O_\3EY.=4Y6```O+@`(3KD```"D6(]*
M@&8:3KD```#4(\`````<<`(CP`````!P_TY>3G5P`$Y>3G5.5@``+RX`"&'"
M6(].7DYU3E8``"\N``PO+@`(3KD```"X4(]*@&8:3KD```#4(\`````<<`4C
MP`````!P_TY>3G5P`$Y>3G4O/````^U(>0````U.N0````!0CR/`````*$YU
M3E;__DJY`````&<&3KD`````2KD````H9@)AR$HY````#&<<$#D````,'4#_
M_T(Y````#'(`$B[__R`!3EY.=7`!+P!(;O__+SD````H3KD````P3^\`#'``
M$"[__TY>3G5.5O_^2CD````,9QH0.0````Q".0````P=0/__`H````#_3EY.
M=6$`_W9.7DYU3E8``$JY`````&<&3KD`````2KD````H9@1A`/\X<`$O`$AN
M``LO.0```"A.N0```$Q/[P`,<``0+@`+3EY.=4Y6``!*.0````QG!G#_3EY.
M=2`N``@3P`````Q.7DYU3E;__$JY`````&<&3KD`````2KD````H9@1A`/[8
M+SP```#_+RX`""\Y````*$ZY````,$_O``PM0/_\2H!J!$*N__P@;@`(T>[_
M_$(0("X`"$Y>3G5.5@``2KD`````9P9.N0````!*N0```"AF!&$`_H(O+@`(
M3KD`````6(\O`"\N``@O.0```"A.N0```$Q/[P`,3EY.=0```^P````/````
M`0``!?8```78```%F```!8(```4V```%(@``!,@```22```$>```!$H```0"
M```#;@```OH```)V```!T`````P````(```$4@``!`H```-V```#,@```P(`
M``*J```"?@```D(```'8```!;@```*0```!`````!0````H```72```%?```
M!1P```2,````#@````4````+```%R@``!70```44```$A`````8````!````
M$0```,0````*````$P``!68```54```$]```!.X```3F```$K@``!*0```2<
M```$:@```T8````!````'@``!>@````#````'P```)H```!R````'@````0`
M```@````O@```(0```!:````,`````0````G````M@```'P```!2````*```
M`!0````R```$.````](```.*```#6@``!?P```4\```"X@``!9X```3.```"
M7@``!$0```/\```#:````O0```)P```!R@``!'````&V```#\````88`````
M```#\@```^H````$_____P`````````!`"H``````_(```/I````_$Y6__@@
M;@`($"@`$`(``#!*`&<&</].7DYU(&X`"$JH`!)F'!`H`!`(```"9A(O"&$`
M`U!8CTJ`9P9P_TY>3G4@;@`($"@`$`@```)G"'`!+4#_^&`J(&X`"!`H`!`(
M```!9P9P_TY>3G4@;@`($"@`$`````$10``0+6@`$O_X<``@;@`($"@`$2\N
M__@O*``,+P!.N0```B)/[P`,+4#__$J`:A`@;@`($"@`$````"`10``02J[_
M_&80(&X`"!`H`!`````0$4``$$JN__QO#B!N``@A;O_\``0@J``,(&X`"!`H
M`!`"```P2@!G!G#_3EY.=2!N``@@*``$4X`A0``$2H!K"B)04I!P`!`18`HO
M+@`(80#^Z%B/3EY.=4Y6__(M;@`(__8@;@`,$"@`$`(``#!*`&<&</].7DYU
M(&X`#$JH`!)F=A`H`!`(```"9FP,KO____\`"&8&<`!.7DYU+RX`#&$``AA8
MCTJ`9P9P_TY>3G4@;@`,$"@`$`````(10``0("@`$B%```A3@"%```A*@&L0
M(E!2D"`N``@2@'(`$A%@$"\N``PO+@`(80#_;%"/(@`@`4Y>3G4@;@`,$"@`
M$`@```)G2`RN_____P`(9@9P`$Y>3G4@+@`('4#__W``(&X`#!`H`!%R`2\!
M2&[__R\`+4'_\DZY```"BD_O``QR_RU!``@M0/_Z8```PB!N``P0*``0"```
M`&<&</].7DYU(&X`#!`H`!`````"$4``$`RN_____P`(9SI*J``(;S0@*``(
M4X`A0``(2H!K$")04I`@+@`($H!R`!(18!`O+@`,+RX`"&$`_JY0CR(`</\M
M0``((FX`#"!1L>D`#&="2JD`"&H(+6D`$O_R8!`@;@`,("@`$I"H``@M0/_R
M<``@;@`,$"@`$2\N__(O*``,+P!.N0```HI/[P`,+4#_^F`*<``M0/_Z+4#_
M\@RN_______Z9A(@;@`,$"@`$````"`10``08!H@+O_ZL*[_\F<0(&X`#!`H
M`!`````0$4``$"!N``P@*``2(4``"")H``P@B2`N``@,@/____]G*B(H``A3
M@2%!``A*@6L,(E!2D!*`<@`2$6`0+RX`#"\N``AA`/W24(\B`"!N``P0*``0
M`@``,$H`9P9P_TY>3G4,KO______]F8&<`!.7DYU("[_]DY>3G5.5@``(&X`
M"$JH`!)G$!`H`!`(```#9@9P`$Y>3G4O.0````!.N0```!!8CR!N``@@@"%`
M``Q*@&8.<`PCP`````!P_TY>3G4@;@`((7D``````!(0*``0`@``\Q%``!!P
M`"%```@A0``$3EY.=0```^P````"````!@```]````.B`````0````@```/`
M`````P```!(```*^```"`````)8````!````%P```Z@````````#\@```^D`
M``!;3E;__"`N``@&@`````Q"IR\`3KD`````4(\M0/_\2H!F!G``3EY.=2!N
M__S!B`)`__[!B"`N``@&@`````PA0``(+R[__$AY`````&$``)I0CR!N__S0
M_``,(`A.7DYU3E;__"\N``AAEEB/+4#__$J`9P1.7DYU('S_____(`A.7DYU
M82YP`"/`````$"/`````""/`````#"/`````""/``````"/`````#"/`````
M!$YU3E;_^"UY`````/_\2J[__&<>(&[__"U0__@O*``(+PA.N0```!A0CRUN
M__C__&#<3EY.=4Y6```B;@`((&D`!")N``PC2``$D<@BB"!N``A*J``$9P8@
M:``$((D@;@`,(FX`""-(``1*D68"(HA.7DYU3E8``"!N``Q*D&8,(FX`""-H
M``0`!&`,(FX`#"!1(6D`!``$(&X`#$JH``1F"")N``@BD&`*(FX`#"!I``0@
MD4Y>3G4``````^P````#`````0```)8```"0````B@````(````6````N@``
M`$@````$````)0```*X```"B````J````)P````"````,P```-8````4````
M`````_(```/K`````P```_(```/I````H4Y6__P@.0````SG@$Y>3G5.5O_\
M("X`""\`+4#__&$&6(].7DYU3E;_[$JN``AN!G``3EY.=2`N``A>@'((3KD`
M````+7P````(__@@;O_X+5#__"U`__!*KO_\9U8@+O_P(&[__"(H``2R@&4V
MLH!F"")N__@BD&`6(&[__"`H``20KO_P(4``!.>`T:[__"`N__"1N0````P@
M;O_\(`A.7DYU+6[__/_X(&[__"U0__Q@I"`N__#G@"(Y````%-"!4X!.N0``
M```B.0```!1.N0`````O`"U`_^Q.N0````!8CRU`__1*@&<8+R[_["\`8190
MCR\N``AA`/\J6(].7DYU<`!.7DYU3E;__"`N``PO`"\N``@M0/_\8090CTY>
M3G5.5O_D2JX`#&X&</].7DYU(&X`",&(`D#__L&(("X`#%Z`<@A.N0`````M
M0/_DYX`M2/_LT<`@+O_DT;D````,+7P````(__0B;O_T+5'__"U(_^A*KO_\
M9P``Z"!N__P@*``$YX#1P"U(__@@;O_\L>[_Z&,8(F[_["*((V[_Y``$(&[_
M]"")<`!.7DYU(&[__+'N_^AF'B)N_^PBD"`N_^30J``$(T``!"!N__0@B7``
M3EY.=2!N_^RQ[O_X9!`@+O_DD;D````,</].7DYU(&[_[+'N__AF4"!N__Q*
MD&<<(&[_Z")N__RQT6,0("[_Y)&Y````#'#_3EY.=2`N_^0@;O_\T:@`!$J0
M9Q8@;O_H(F[__+'19@H@*``$T:D`!"*0<`!.7DYU+6[__/_T+6[_^/_P(&[_
M_"U0__Q@`/\4(&[_]""N_^R1R")N_^PBB"-N_^0`!"`(3EY.=0`````#[```
M``(````!````S````+P````!````%0```-X````'````)0```A@```'J```!
M9@```6````"6````1@````8````#````)@```4H```#&````0`````$````G
M````T@````````/R```#Z0```%E.5O[L0>X`#"U(_^P@;@`($!!*`&<``39R
M`!(04H@M0?_X+4@`"`R!````)68``-H0$`P``"5F1G0`%!!2K@`((#D````@
M4X`CP````"`M0O_X2H!K%"!Y````&%*Y````&!""<``0$&"B2'D````8+R[_
M^$ZY```!(%"/8(Y(;O_T2&[_[$AN_NPO+@`(3KD`````3^\`$"U`__!*@&<`
M_VQ"KO_\+4``""`N__RPKO_T;`#_6"(Y````(%.!(\$````@2H%K'"!Y````
M&%*Y````&$/N_NS3P!`1$(!R`!(08!Y![O[LT>[__'``$!!(>0```!@O`$ZY
M```!(%"/(@!2KO_\8*(@.0```"!3@"/`````($J`:QH@>0```!A2N0```!@@
M+O_X$(!R`!(08`#^VDAY````&"\N__A.N0```2!0CR(`8`#^PDAY````&'#_
M+P!.N0```2!0CTY>3G4``````^P````$````%````5@```%`````^@```'8`
M```0````(@```4X```$V```!(@```1P```$2```!"@```/(```#0````R@``
M`,````"X````;````%X```!8````2@```$(````!````(P```)`````````#
M\@```^D````H3E;_\'``(&X`"!(0+4#__"U`__@M0/_P#`$`+68,<@$M0?_X
M+4'_\&`2(&X`"!`0#```*V8&<`$M0/_X("[_^"!N``C1P'(`$A!2@2!!T?P`
M````$A`(`0`"9RH@+O_\<@I.N0`````@;@`(T>[_^%*N__AR`!(0!($````P
MT($M0/_\8+9*KO_P9P1$KO_\(&X`#""N__P@+O_X3EY.=0```^P````!````
M!P```%`````!````)P```&0````````#\@```^D````+3E8``'``(&X`"!`0
M4H`B0-/\`````!`1"````V<&4JX`"&#@("X`"$Y>3G4```/L`````0````<`
M```2`````````_(```/I````(DY6__PO+@`(3KD`````6(\@;@`(T<`M2/_\
M(&[__%*N__PB;@`,$!$0@%*N``Q*`&;H("X`"$Y>3G5.5O_\+RX`"$ZY````
M`%B/(&X`"-'`+4C__"`N`!!3K@`02H!O&B!N``P0$")N__P2@%*N``Q*`&<&
M4J[__&#:(&[__$(0("X`"$Y>3G4```/L`````@```!X```!$````"@``````
M``/R```#Z0```!!.5@``(&X`"!`0(&X`#!(0L`%F%$H`9@9P`$Y>3G52K@`(
M4JX`#&#<<``@;@`($!!R`"!N``P2$)"!3EY.=0`````#\@```^D````:3E;_
M_"UN``C__"!N__Q2KO_\(FX`#!`1$(!2K@`,2@!FZ"`N``A.7DYU3E;__"UN
M``C__$JN`!!O("!N``P0$")N__P2@%*N``Q*`&<,4J[__$YQ4ZX`$&#:(&[_
M_$(0("X`"$Y>3G4```/R```#Z0````E.5O_\0J[__"!N``C1[O_\$!!*`&<&
M4J[__&#L("[__$Y>3G4```/R```#Z@````$````4```#\@```^L````>```#
M\@```^D````:3E;_^DCG!P`L.0````!^`+Y&;#H@!\'\``8@0-'\`````!H0
M2@5G(B`%"````F8:(`?!_``&($#1_``````O*``"3KD````<6(]21V#"+RX`
M#"\N``A.N0```3I0CTS?`.!.7DYU``````/L`````0````````!8`````0``
M`!\````*`````@```"`````Z````'@````$````R````1`````````/R```#
MZP```'@```/R```#Z0```A].5O^T2.<`('``+4#_Z'+_+4'_Y'(@+4'_X"!N
M``@2$"U`__`M0/_<+4#_[`P!`"UF"G`!4JX`""U`__!P`"!N``@0$"]```12
M@"!`T?P`````$!`(```"9V(,KP```#``!&8&<#`M0/_@<``@;@`($!!2K@`(
M`H`````/+4#_W'``(&X`"!`04H`B0-/\`````!`1"````F<B("[_W'(*3KD`
M````<@`2$%*N``@"@0````_0@2U`_]Q@Q"!N``@0$`P``"YF1%*N``A"KO_D
M<``@;@`($!!2@")`T_P`````$!$(```"9R(@+O_D<@I.N0````!R`!(04JX`
M"`*!````#]"!+4#_Y&#$(&X`"!`0#```;&8*<`%2K@`(+4#_[$*N_]!P`"!N
M``@0$')(!($````(:P`"B+"[&`AF\$[[&`8```!F8``";@```&5@``)@````
M9V```E````!C8``"*@```'-@``'2````;V```5@```!X8```W````'5@```X
M````9&````)*KO_L9PXB;@`0(%%8D2U0_\Q@#")N`!`@45B1+5#_S$JN_\QJ
M*'`!+4#_Z&`@2J[_[&<.(FX`$"!16)$M4/_,8`PB;@`0(%%8D2U0_\QP"RU`
M__P@+O_,<@I.N0`````M0?_X2H%J!$2N__A3KO_\("[_^`:`````,"(N__P=
M@!BX("[_S'(*3KD`````+4#_S$JN_\QFO`RN`````?_H9@Y3KO_\("[__!V\
M`"T(N$'N_[@@+O_\T<!R"Y*`+4'_]"U(_]!@``%V2J[_[&<.(FX`$"!16)$M
M4/_,8`PB;@`0(%%8D2U0_\QP""U`__Q3KO_\("[_S`*`````#R!`T?P`````
M("[__!V0"+@@+O_,Z(`"@`____\M0/_,2J[_S&;,0>[_N"`N__S1P'((DH`M
M0?_T+4C_T&```0)*KO_L9PXB;@`0(%%8D2U0_\Q@#")N`!`@45B1+5#_S'`+
M+4#__%.N__P@+O_,`H`````'!H`````P(B[__!V`&+@@+O_,YH`"@!____\M
M0/_,2J[_S&;.0>[_N"`N__S1P'(+DH`M0?_T+4C_T&```)`,KO______Y&8(
M+7P```#(_^0B;@`0(%%8D2)0+4G_T+/\`````&8(+7P````0_]!"KO_T("[_
M]+"N_^1L4"!N_]#1P!`02@!G1%*N__1@Y$'N_[AP`2U`__0D;@`0(E)8DB`1
M'4#_N"U(_]!@('`"+4#_U&`80J[_U&`2<`$M0/_48`IP`$S?!`!.7DYU2J[_
MT&<``-)*KO_<9PH@+O_<L*[_]&P&+6[_]/_<("[_])&N_]Q"KO_\2J[_\&=(
M("[_]%.`+4#_]$J`:Q@@;@`,T>[__%*N__PB;O_0$)%2KO_08-H@+O_<4X`M
M0/_<2H!K7"!N``S1[O_\4J[__"`N_^`0@&#>("[_W%.`+4#_W$J`:Q0@;@`,
MT>[__%*N__P@+O_@$(!@WB`N__13@"U`__1*@&L8(&X`#-'N__Q2KO_\(F[_
MT!"14J[_T&#:(&X`%""N__P@;@`(4H@@"$S?!`!.7DYU#*[______^1F!G`&
M+4#_Y`RN````%/_D;01P$V`$("[_Y"U`__12@`RN`````?_45\%$`4B!2,%(
M;O^X2&[_Z$AN_]@O`2\`(&X`$"\03KD`````3^\`&"!N`!!0D$'N_[@B+O_8
M+4#_]"U!__PM2/_02H%J!$2N__P,K@````+_U&8:2J[_]&<.#*X````&__QM
M!'``8`)P`2U`_]1*KO_T9P13KO_8<``M0/_\2J[_Z&<$4J[__$JN_]1G*B`N
M_^12@"(N__S0@2U`__Q*KO_8:P@@+O_8T:[__$JN_^1G0%*N__Q@.B`N_^1<
M@-&N__Q*KO_8:@@@+O_81(!@!"`N_]@M0/_X#(````!C;P12KO_\#*X```/G
M__AO!%*N__Q*KO_P9C0@+O_<L*[__&\J("[__)&N_]P@+O_<4X`M0/_<2H!K
M%"!N``Q2K@`,("[_X!"`4J[__&#>2J[_Z&<,(&X`#!"\`"U2K@`,2J[_U&<`
M`09*KO_8:G`@;@`,$+P`,%*($+P`+E*(+4@`#"`N_^13@"U`_^1*@&L``>0@
M+O_84H`M0/_82H!J#B!N``P0O``P4JX`#&#4("[_]%.`+4#_]$J`:Q0@;O_0
M(FX`#!*04J[_T%*N``Q@LB!N``P0O``P4JX`#&"D("[_V%.N_]A*@&LP("[_
M]%.`+4#_]$J`:Q0@;O_0(FX`#!*04J[_T%*N``Q@TB!N``P0O``P4JX`#&#$
M2J[_Y&<,(&X`#!"\`"Y2K@`,("[_Y%.`+4#_Y$J`:P`!.B`N__13@"U`__1*
M@&L4(&[_T")N``P2D%*N_]!2K@`,8,X@;@`,$+P`,%*N``Q@P"`N__13@"U`
M__1*@&L4(&[_T")N``P2D%*N_]!2K@`,8`P@;@`,$+P`,%*N``P@;@`,$+P`
M+E*N``P@+O_D4X`M0/_D2H!K,"`N__13@"U`__1*@&L4(&[_T")N``P2D%*N
M_]!2K@`,8-`@;@`,$+P`,%*N``Q@PB!N``P0O`!%4H@M2``,2J[_V&H.$+P`
M+5*N``Q$KO_88`P@;@`,$+P`*U*N``QP"RU`__13KO_T("[_V'(*3KD`````
M!H$````P("[_]!V!"+@@+O_8<@I.N0`````M0/_8#*X````)__1NR$JN_]AF
MPB`N__0,@`````ML$E*N__0@;@`,$+8(N%*N``Q@X@RN`````?_P9C0@+O_<
ML*[__&\J("[__)&N_]P@+O_<4X`M0/_<2H!K%"!N``Q2K@`,("[_X!"`4J[_
M_&#>(&X`%""N__P@;@`(4H@@"$S?!`!.7DYU``````/L`````P````<```#>
M````C@```$X````"````)````V8```*.````!````"8```?N```'U````A8`
M``'H`````@```"<```#R````H@````$````J```$\@````````/R```#Z@``
M``4P,3(S-#4V-S@Y04)#1$5&`````````_(```/J````!```````````````
M``````````/R```#Z0```!%(YSP`*@%G,FH"1($H`&<H:@)$@$*"=A_C@..2
MM(%E!)2!4H!1R__R(@*YA6H"1("SA&H(1(%@!$*!0H!,WP`\3G4``````_(`
M``/I````$4CG>``H`+.$2H!G,&H"1(`D`$J!9@1"@&`B:@)$@28`QL%(0L3!
M2$)"0M:"2$'`P4A`0D#0@TJ$:@)$@$S?`!Y.=0`````#\@```^D````$3E8`
M`"/N``@````@3EY.=0```^P````!`````0````@````````#\@```^D````V
M)`#`O'____]F"'``<@!T`&`B2$)(PNA"Q+R```?_E'P#_R\"=`KCB>.04<K_
M^@C``!\D'TYU+P,O`(.?9V24?``+2H!F""`!0H&4?``@+P`"G__@``!G)%)"
MXHCBD>*3+P`"G__@``!F[DJ#:@Y2@60*4H!@V%-"XXGCD`@``!1G]-1\`_]O
M'K1\!_]L*,"\``___^E*/P)"0DA"A%](0H"")A].=2\\`````4ZY`````'``
M8!@O/`````).N0`````P/'_P2$*`0DA`0D!/[P`$<@!@S``````#[`````(`
M```H````O@```*X````````#\@```^D```#E3E#_XDY1``!(YW\P)&@`""`:
M(A).N0````!":0`(0FD`!B\`@Y]F#B1H`!PF*``,4X-@``#X4D(S0@`$2$(S
M0@`(0D8T*0`$9UQJ$E9":Q@*0@`#U6D`!&$``0!@2&$``3)2:0`&8!)T!-5I
M``1A``#J80``\E-I``9*@&O$4VD`!..)XY!@\D)"0D8O`(.?9Q1A``#22D9F
M#`Q"``%F!E-I``9@[`8&`#`3AB`*4D*T?``4:]1V`20H``Q*J``09PXH/```
M``'4:0`&4T)K.G@4#$(`$FPR.`(:,2`+!@4`!0P%`#EO(A.\`#`@"U(Q(`H:
M,2@*4T)JZ%)I``930WH`NJ@`$&<"4H0D:``<1_$P"B`$9QY31#8$!$,`%&L"
M>!,4VU',__Q*0VL(%/P`,%'+__HD:``80I)*:0`(9P)3DB1H`!1"@3(I``9(
MP22!3-\,_DY93EA.=>*(XI&4?``!9O9.=7P`2.<P`"0`)@'CB>.0XY;CB>.0
MXY;2@]&"9```!%*&XXGCD..63-\`#$YU+P)T`#\\`$#CB>.0XY(,0@`*;0@$
M@@````I2@5-79NA/[P`")!].=4Y0__1.40``2.=^,'``<@`S0```,T```C-`
M``0S0``&80`!=@P&`#!F"`!I(```!&#N#`8`+68*`&F````$80`!6`P&`#!M
M/@P&`#EN.`!I(```!#-&``H\*0`&G6D``B\``I_P````9P92:0`"8,YA`/\Z
M/"D`"@*&````#]*&0H;1AF"X#`8`+F8,2FD`!F9B4FD`!F"F#`8`16<&#`8`
M969080``\@P&`"MG#`P&`"UF"@!I$```!&$``-P,!@`P;3`,!@`Y;BHZ*0``
MX>D``.'I``#;:0``X>D```)&``_=:0``#&D/_P``;<S@Z0``8/(_*0`$`E\@
M`&8*)&@`%$*28```@C0I```_*0`$`E\0`&<"1$+5:0`"+P"#GV=4,WP`/P``
M2H!K"N.)XY!3:0``8/)*:0`"9R!K%'0$U6D``&$`_EIA`/YB4VD``F#680#^
MA%)I``)@S'0`-"D``#\I``0"7X``9P0(P@`?3KD````V)&@`&"3`)($D:``4
M)+P````!<``P*0`(3-\$?DY93EA.=2PH``AG"B%\```````(3G5(Y_S@)&@`
M$$Z2/`!,WP<_,T8`"%.H``QF"`!I"```!$YU/RD`!`)?"`!G`GS_3G4`````
M`^P````"````*0```RP````6`````````_(```/I````!BYY````/$ZY````
M`"\\````%$ZY`````````^P````!`````0````(````!````"0```!0````!
M````+P````@````````#\@```^D```";3E;_^@RY````(`````!L``$&(&X`
M"!`02(!(P%*`(D#3_``````0$0@```-G!E*N``A@WB!N``@0$$H`9P``V"!N
M``@0$`P``")F<"`Y`````.6`4KD`````(D#3_`````12B"*(+4@`""!N``@0
M$$H`9PP,```B9P92K@`(8.H@;@`($!!*`&8D2'D````H2'D````P3KD`````
M4(]P`2\`3KD`````6(]@`/]8(&X`"$(04JX`"&``_TH@.0````#E@%*Y````
M`"!`T?P````$(*X`""!N``@0$$B`2,!*@&<84H`B0-/\`````!`1"````V8&
M4JX`"&#:(&X`"!`02@!F`F`.(&X`"$(04JX`"&``_O!".0```!%P`1/`````
M$!/`````*7`"$\`````H$\````!!$\````!`2KD`````9@``A")Y````."!I
M`"1P*"\`+R@`!$AY`````$ZY````.D_O``PO/````^Y(>0````!.N0````!0
MCR/``````B/`````"'($$\$````&(\`````.$\$````,Y8!"IR/`````B$ZY
M````,%B/('D```"((D`C:``(`*1"KO_Z(\````"$8#A.N0```&@CP`````).
MN0```'@CP`````@O/````^U(>0```$U.N0````!0CR/`````#G`$+4#_^B`N
M__H`@````,`2.0````!(@4C!@H`3P0`````@+O_Z`(````"@$CD````&2(%(
MP8*`$\$````&$#D````,````H!/`````#$AY````!"\Y`````$ZY`````%"/
M0J=.N0````!8CTY>3G4```/L`````0````$```%*`````0````(```)8````
M`@````<```#J````(@````(````)```"8@```*0````!````#P```)@````!
M````&P```6(````.````(````D8```(\```"-@```BH```(:```"#@```?@`
M``'>```!T@```9H```&4```!C@```88```&`````!P```"(```$Z```!-```
M`2X```$F```!(````1@```"2````!````"T```'J```!<@```5P```",````
M#0```"X```)2```"3````<0```&R```!I````4````#.````Q@```+X```!>
M````5@```$X````*````!````#(```'8```!S````?````%X`````0```#,`
M``&J`````````_(```/J````%&-O;CHQ,"\Q,"\S,C`O.#`O````````````
M``````````````````!%<G)O<CH@;F]N+71E<FUI;F%T960@<75O=&5D('-T
M<FEN9PH`*@`````#\@```^L````C```#\@```^D````60J=(>0```%A.N0``
M`%Q0CR/``````"/Y````3`````QP*"\`+SP```#Z<``O`"\`2'D```!$+P!(
M>0```"HO`$ZY`````$_O`"!P%"\`3KD`````6(].=0```^P````!`````0``
M`!@````!````"0```%`````$````,````#H````R````'`````0````!````
M,0```!(````!````,P````H````!````-````$(````````#\@```^H````;
M__\````.``X````````````````J*B!3=&%C:R!/=F5R9FQO=R`J*@``__\`
M```$``0`````````%`````!%6$E4``#__P````0`!``````````^`````&EN
M='5I=&EO;BYL:6)R87)Y```````#[`````,````P````4````#H````V````
M`````_(```/K`````0```_(```/I````.4CG(`),[P`&``PL>0```#!.KO_B
M3-]`!$YU```O#B(O``@L>0```#!.KO_<+%].=4CG,`),[P`.`!`L>0```#!.
MKO_63-]`#$YU``!(YS`"3.\`#@`0+'D````P3J[_T$S?0`Q.=0``+PXL>0``
M`#!.KO_*+%].=2\.+'D````P3J[_Q"Q?3G5(YS`"3.\`#@`0+'D````P3J[_
MODS?0`Q.=0``+PXB+P`(+'D````P3J[_N"Q?3G5(YR`"3.\`!@`,+'D````P
M3J[_LDS?0`1.=0``+PXL>0```#!.KO]\+%].=0```^P````*`````0```-@`
M``#$````K````)0```!\````;````%@````\````)`````P````````#\@``
M`^D````=+PXL>0```"Q,[P`#``A.KO\Z+%].=0``+PXL>0```"PB;P`(("\`
M#$ZN_RXL7TYU+PXL>0```"PB;P`(3J[^VBQ?3G4O#BQY````+$SO``,`"$ZN
M_LXL7TYU```O#BQY````+")O``@@+P`,3J[]V"Q?3G4```/L````!0````$`
M``!@````2````#0````<````!`````````/R```#Z0````U(YS`R+'D`````
M(&\`&")O`!PD;P`@)F\`)"`O`"@B+P`L)"\`,"8O`#1.KOZD3-],#$YU```#
5[`````$````Q````!@````````/R
`
end