diff options
180 files changed, 50490 insertions, 0 deletions
diff --git a/compat/strftime.c b/compat/strftime.c new file mode 100644 index 0000000..91e7057 --- /dev/null +++ b/compat/strftime.c @@ -0,0 +1,538 @@ +/* + * strftime.c -- + * + * This file contains a modified version of the BSD 4.4 strftime + * function. + * + * This file is a modified version of the strftime.c file from the BSD 4.4 + * source. See the copyright notice below for details on redistribution + * restrictions. The "license.terms" file does not apply to this file. + * + * Changes 2002 Copyright (c) 2002 ActiveState Corporation. + * + * RCS: @(#) $Id: strftime.c,v 1.17 2004/09/08 18:46:18 kennykb Exp $ + */ + +/* + * Copyright (c) 1989 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) +static char *rcsid = "$Id: strftime.c,v 1.17 2004/09/08 18:46:18 kennykb Exp $"; +#endif /* LIBC_SCCS */ + +#include <time.h> +#include <string.h> +#include <locale.h> +#include "tclInt.h" + +#define TM_YEAR_BASE 1900 +#define IsLeapYear(x) ((x % 4 == 0) && (x % 100 != 0 || x % 400 == 0)) + +/* + * Structure type holding the locale-dependent strings for formatting + * times. The strings are all expected to be encoded in UTF-8. + */ + +typedef struct { + const char *abday[7]; /* Abbreviated weekday names */ + const char *day[7]; /* Full weekday names */ + const char *abmon[12]; /* Abbreviated month names */ + const char *mon[12]; /* Full month name */ + const char *am_pm[2]; /* The strings to use for meridian time + * (am, pm) */ + const char *d_t_fmt; /* The locale-dependent date-time format */ + const char *d_fmt; /* The locale-dependent date format */ + const char *t_fmt; /* The locale-dependent 24hr time format */ + const char *t_fmt_ampm; /* The locale-dependent 12hr time format */ +} _TimeLocale; + +/* + * This is the C locale default. On Windows, if we wanted to make this + * localized, we would use GetLocaleInfo to get the correct values. + * It may be acceptable to do localization of month/day names, as the + * numerical values would be considered the locale-independent versions. + */ +static const _TimeLocale _DefaultTimeLocale = +{ + { + "Sun","Mon","Tue","Wed","Thu","Fri","Sat", + }, + { + "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", + "Friday", "Saturday" + }, + { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }, + { + "January", "February", "March", "April", "May", "June", "July", + "August", "September", "October", "November", "December" + }, + { + "AM", "PM" + }, + "%a %b %d %H:%M:%S %Y", + "%m/%d/%y", + "%H:%M:%S", + "%I:%M:%S %p" +}; + +static CONST _TimeLocale *_CurrentTimeLocale = &_DefaultTimeLocale; + +static int isGMT; +static size_t gsize; +static char *pt; +static int _add _ANSI_ARGS_((CONST char* str)); +static int _conv _ANSI_ARGS_((int n, int digits, int pad)); +static int _secs _ANSI_ARGS_((CONST struct tm *t)); +static size_t _fmt _ANSI_ARGS_((CONST char *format, + const struct tm *t)); +static int ISO8601Week _ANSI_ARGS_((CONST struct tm* t, int *year )); + +/* + *---------------------------------------------------------------------- + * + * TclpStrftime -- + * + * Formats a time (in 'struct tm' representation) for use by + * [clock format]. + * + * Results: + * Returns the length of the formatted string. + * + * Side effects: + * Stores the formatted string in the 's' parameter. The + * formatted string is returned in UTF-8 encoding, *not* the + * system encoding. + * + *---------------------------------------------------------------------- + */ + +size_t +TclpStrftime(s, maxsize, format, t, useGMT) + char *s; /* Buffer to hold the formatted string */ + size_t maxsize; /* Size of the passed buffer */ + CONST char *format; /* Format to use (see the user documentation + * for [clock] for details) */ + CONST struct tm *t; /* Time to format */ + int useGMT; /* Flag == 1 if time is to be returned + * in UTC */ +{ + if (format[0] == '%' && format[1] == 'Q') { + /* Format as a stardate */ + sprintf(s, "Stardate %2d%03d.%01d", + (((t->tm_year + TM_YEAR_BASE) + 377) - 2323), + (((t->tm_yday + 1) * 1000) / + (365 + IsLeapYear((t->tm_year + TM_YEAR_BASE)))), + (((t->tm_hour * 60) + t->tm_min)/144)); + return(strlen(s)); + } + + isGMT = useGMT; + /* + * We may be able to skip this for useGMT, but it should be harmless. + * -- hobbs + */ + tzset(); + + pt = s; + if ((gsize = maxsize) < 1) + return(0); + if (_fmt(format, t)) { + *pt = '\0'; + return(maxsize - gsize); + } + return(0); +} + +#define SUN_WEEK(t) (((t)->tm_yday + 7 - \ + ((t)->tm_wday)) / 7) +#define MON_WEEK(t) (((t)->tm_yday + 7 - \ + ((t)->tm_wday ? (t)->tm_wday - 1 : 6)) / 7) + +static size_t +_fmt(format, t) + CONST char *format; + CONST struct tm *t; +{ +#ifdef __WIN32__ +#define BUF_SIZ 256 + TCHAR buf[BUF_SIZ]; + SYSTEMTIME syst; + syst.wYear = t->tm_year + 1900; + syst.wMonth = t->tm_mon + 1; + syst.wDayOfWeek = t->tm_wday; + syst.wDay = t->tm_mday; + syst.wHour = t->tm_hour; + syst.wMinute = t->tm_min; + syst.wSecond = t->tm_sec; + syst.wMilliseconds = 0; +#endif + for (; *format; ++format) { + if (*format == '%') { + ++format; + if (*format == 'E') { + /* Alternate Era */ + ++format; + } else if (*format == 'O') { + /* Alternate numeric symbols */ + ++format; + } + switch(*format) { + case '\0': + --format; + break; + case 'A': + if (t->tm_wday < 0 || t->tm_wday > 6) + return(0); + if (!_add(_CurrentTimeLocale->day[t->tm_wday])) + return(0); + continue; + case 'a': + if (t->tm_wday < 0 || t->tm_wday > 6) + return(0); + if (!_add(_CurrentTimeLocale->abday[t->tm_wday])) + return(0); + continue; + case 'B': + if (t->tm_mon < 0 || t->tm_mon > 11) + return(0); + if (!_add(_CurrentTimeLocale->mon[t->tm_mon])) + return(0); + continue; + case 'b': + case 'h': + if (t->tm_mon < 0 || t->tm_mon > 11) + return(0); + if (!_add(_CurrentTimeLocale->abmon[t->tm_mon])) + return(0); + continue; + case 'C': + if (!_conv((t->tm_year + TM_YEAR_BASE) / 100, + 2, '0')) + return(0); + continue; + case 'D': + if (!_fmt("%m/%d/%y", t)) + return(0); + continue; + case 'd': + if (!_conv(t->tm_mday, 2, '0')) + return(0); + continue; + case 'e': + if (!_conv(t->tm_mday, 2, ' ')) + return(0); + continue; + case 'g': + { + int year; + ISO8601Week( t, &year ); + if ( !_conv( year%100, 2, '0' ) ) { + return( 0 ); + } + continue; + } + case 'G': + { + int year; + ISO8601Week( t, &year ); + if ( !_conv( year, 4, '0' ) ) { + return( 0 ); + } + continue; + } + case 'H': + if (!_conv(t->tm_hour, 2, '0')) + return(0); + continue; + case 'I': + if (!_conv(t->tm_hour % 12 ? + t->tm_hour % 12 : 12, 2, '0')) + return(0); + continue; + case 'j': + if (!_conv(t->tm_yday + 1, 3, '0')) + return(0); + continue; + case 'k': + if (!_conv(t->tm_hour, 2, ' ')) + return(0); + continue; + case 'l': + if (!_conv(t->tm_hour % 12 ? + t->tm_hour % 12: 12, 2, ' ')) + return(0); + continue; + case 'M': + if (!_conv(t->tm_min, 2, '0')) + return(0); + continue; + case 'm': + if (!_conv(t->tm_mon + 1, 2, '0')) + return(0); + continue; + case 'n': + if (!_add("\n")) + return(0); + continue; + case 'p': + if (!_add(_CurrentTimeLocale->am_pm[t->tm_hour >= 12])) + return(0); + continue; + case 'R': + if (!_fmt("%H:%M", t)) + return(0); + continue; + case 'r': + if (!_fmt(_CurrentTimeLocale->t_fmt_ampm, t)) + return(0); + continue; + case 'S': + if (!_conv(t->tm_sec, 2, '0')) + return(0); + continue; + case 's': + if (!_secs(t)) + return(0); + continue; + case 'T': + if (!_fmt("%H:%M:%S", t)) + return(0); + continue; + case 't': + if (!_add("\t")) + return(0); + continue; + case 'U': + if (!_conv(SUN_WEEK(t), 2, '0')) + return(0); + continue; + case 'u': + if (!_conv(t->tm_wday ? t->tm_wday : 7, 1, '0')) + return(0); + continue; + case 'V': + { + int week = ISO8601Week( t, NULL ); + if (!_conv(week, 2, '0')) + return(0); + continue; + } + case 'W': + if (!_conv(MON_WEEK(t), 2, '0')) + return(0); + continue; + case 'w': + if (!_conv(t->tm_wday, 1, '0')) + return(0); + continue; +#ifdef __WIN32__ + /* + * To properly handle the localized time routines on Windows, + * we must make use of the special localized calls. + */ + case 'c': + if (!GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, + &syst, NULL, buf, BUF_SIZ) || !_add(buf) + || !_add(" ")) { + return(0); + } + /* + * %c is created with LONGDATE + " " + TIME on Windows, + * so continue to %X case here. + */ + case 'X': + if (!GetTimeFormat(LOCALE_USER_DEFAULT, 0, + &syst, NULL, buf, BUF_SIZ) || !_add(buf)) { + return(0); + } + continue; + case 'x': + if (!GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, + &syst, NULL, buf, BUF_SIZ) || !_add(buf)) { + return(0); + } + continue; +#else + case 'c': + if (!_fmt(_CurrentTimeLocale->d_t_fmt, t)) + return(0); + continue; + case 'x': + if (!_fmt(_CurrentTimeLocale->d_fmt, t)) + return(0); + continue; + case 'X': + if (!_fmt(_CurrentTimeLocale->t_fmt, t)) + return(0); + continue; +#endif + case 'y': + if (!_conv((t->tm_year + TM_YEAR_BASE) % 100, + 2, '0')) + return(0); + continue; + case 'Y': + if (!_conv((t->tm_year + TM_YEAR_BASE), 4, '0')) + return(0); + continue; + case 'Z': { + char *name = (isGMT ? "GMT" : TclpGetTZName(t->tm_isdst)); + if (name && !_add(name)) { + return 0; + } + continue; + } + case '%': + /* + * X311J/88-090 (4.12.3.5): if conversion char is + * undefined, behavior is undefined. Print out the + * character itself as printf(3) does. + */ + default: + break; + } + } + if (!gsize--) + return(0); + *pt++ = *format; + } + return(gsize); +} + +static int +_secs(t) + CONST struct tm *t; +{ + static char buf[15]; + register time_t s; + register char *p; + struct tm tmp; + + /* Make a copy, mktime(3) modifies the tm struct. */ + tmp = *t; + s = mktime(&tmp); + for (p = buf + sizeof(buf) - 2; s > 0 && p > buf; s /= 10) + *p-- = (char)(s % 10 + '0'); + return(_add(++p)); +} + +static int +_conv(n, digits, pad) + int n, digits; + int pad; +{ + static char buf[10]; + register char *p; + + p = buf + sizeof( buf ) - 1; + *p-- = '\0'; + if ( n == 0 ) { + *p-- = '0'; + } else { + for (; n > 0 && p > buf; n /= 10, --digits) + *p-- = (char)(n % 10 + '0'); + } + while (p > buf && digits-- > 0) + *p-- = (char) pad; + return(_add(++p)); +} + +static int +_add(str) + const char *str; +{ + for (;; ++pt, --gsize) { + if (!gsize) + return(0); + if (!(*pt = *str++)) + return(1); + } +} + +static int +ISO8601Week( t, year ) + CONST struct tm* t; + int* year; +{ + /* Find the day-of-year of the Thursday in + * the week in question. */ + + int ydayThursday; + int week; + if ( t->tm_wday == 0 ) { + ydayThursday = t->tm_yday - 3; + } else { + ydayThursday = t->tm_yday - t->tm_wday + 4; + } + + if ( ydayThursday < 0 ) { + + /* This is the last week of the previous year. */ + if ( IsLeapYear(( t->tm_year + TM_YEAR_BASE - 1 )) ) { + ydayThursday += 366; + } else { + ydayThursday += 365; + } + week = ydayThursday / 7 + 1; + if ( year != NULL ) { + *year = t->tm_year + 1899; + } + + } else if ( ( IsLeapYear(( t -> tm_year + TM_YEAR_BASE )) + && ydayThursday >= 366 ) + || ( !IsLeapYear(( t -> tm_year + + TM_YEAR_BASE )) + && ydayThursday >= 365 ) ) { + + /* This is week 1 of the following year */ + + week = 1; + if ( year != NULL ) { + *year = t->tm_year + 1901; + } + + } else { + + week = ydayThursday / 7 + 1; + if ( year != NULL ) { + *year = t->tm_year + 1900; + } + + } + + return week; + +} diff --git a/compat/strtoll.c b/compat/strtoll.c new file mode 100644 index 0000000..ce1c8a1 --- /dev/null +++ b/compat/strtoll.c @@ -0,0 +1,107 @@ +/* + * strtoll.c -- + * + * Source code for the "strtoll" library procedure. + * + * Copyright (c) 1988 The Regents of the University of California. + * Copyright (c) 1994 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: strtoll.c,v 1.9 2007/04/16 13:36:34 dkf Exp $ + */ + +#include "tclInt.h" +#include <ctype.h> + +#define TCL_WIDEINT_MAX (((Tcl_WideUInt)Tcl_LongAsWide(-1))>>1) + + +/* + *---------------------------------------------------------------------- + * + * strtoll -- + * + * Convert an ASCII string into an integer. + * + * Results: + * The return value is the integer equivalent of string. If endPtr is + * non-NULL, then *endPtr is filled in with the character after the last + * one that was part of the integer. If string doesn't contain a valid + * integer value, then zero is returned and *endPtr is set to string. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +#if TCL_WIDE_INT_IS_LONG +long long +#else +Tcl_WideInt +#endif +strtoll( + CONST char *string, /* String of ASCII digits, possibly preceded + * by white space. For bases greater than 10, + * either lower- or upper-case digits may be + * used. */ + char **endPtr, /* Where to store address of terminating + * character, or NULL. */ + int base) /* Base for conversion. Must be less than 37. + * If 0, then the base is chosen from the + * leading characters of string: "0x" means + * hex, "0" means octal, anything else means + * decimal. */ +{ + register CONST char *p; + Tcl_WideInt result = Tcl_LongAsWide(0); + Tcl_WideUInt uwResult; + + /* + * Skip any leading blanks. + */ + + p = string; + while (isspace(UCHAR(*p))) { + p += 1; + } + + /* + * Check for a sign. + */ + + errno = 0; + if (*p == '-') { + p += 1; + uwResult = strtoull(p, endPtr, base); + if (errno != ERANGE) { + if (uwResult > TCL_WIDEINT_MAX+1) { + errno = ERANGE; + return Tcl_LongAsWide(-1); + } else if (uwResult > TCL_WIDEINT_MAX) { + return ~((Tcl_WideInt)TCL_WIDEINT_MAX); + } else { + result = -((Tcl_WideInt) uwResult); + } + } + } else { + if (*p == '+') { + p += 1; + } + uwResult = strtoull(p, endPtr, base); + if (errno != ERANGE) { + if (uwResult > TCL_WIDEINT_MAX) { + errno = ERANGE; + return Tcl_LongAsWide(-1); + } else { + result = uwResult; + } + } + } + if ((result == 0) && (endPtr != 0) && (*endPtr == p)) { + *endPtr = (char *) string; + } + return result; +} diff --git a/compat/strtoull.c b/compat/strtoull.c new file mode 100644 index 0000000..b31567f --- /dev/null +++ b/compat/strtoull.c @@ -0,0 +1,255 @@ +/* + * strtoull.c -- + * + * Source code for the "strtoull" library procedure. + * + * Copyright (c) 1988 The Regents of the University of California. + * Copyright (c) 1994 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: strtoull.c,v 1.9 2007/04/16 13:36:34 dkf Exp $ + */ + +#include "tclInt.h" +#include <ctype.h> + +/* + * The table below is used to convert from ASCII digits to a numerical + * equivalent. It maps from '0' through 'z' to integers (100 for non-digit + * characters). + */ + +static char cvtIn[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* '0' - '9' */ + 100, 100, 100, 100, 100, 100, 100, /* punctuation */ + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, /* 'A' - 'Z' */ + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, + 100, 100, 100, 100, 100, 100, /* punctuation */ + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, /* 'a' - 'z' */ + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35}; + + +/* + *---------------------------------------------------------------------- + * + * strtoull -- + * + * Convert an ASCII string into an integer. + * + * Results: + * The return value is the integer equivalent of string. If endPtr is + * non-NULL, then *endPtr is filled in with the character after the last + * one that was part of the integer. If string doesn't contain a valid + * integer value, then zero is returned and *endPtr is set to string. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +#if TCL_WIDE_INT_IS_LONG +unsigned long long +#else +Tcl_WideUInt +#endif +strtoull( + CONST char *string, /* String of ASCII digits, possibly preceded + * by white space. For bases greater than 10, + * either lower- or upper-case digits may be + * used. */ + char **endPtr, /* Where to store address of terminating + * character, or NULL. */ + int base) /* Base for conversion. Must be less than 37. + * If 0, then the base is chosen from the + * leading characters of string: "0x" means + * hex, "0" means octal, anything else means + * decimal. */ +{ + register CONST char *p; + register Tcl_WideUInt result = 0; + register unsigned digit; + register Tcl_WideUInt shifted; + int anyDigits = 0, negative = 0; + + /* + * Skip any leading blanks. + */ + + p = string; + while (isspace(UCHAR(*p))) { /* INTL: locale-dependent */ + p += 1; + } + + /* + * Check for a sign. + */ + + if (*p == '-') { + p += 1; + negative = 1; + } else { + if (*p == '+') { + p += 1; + } + } + + /* + * If no base was provided, pick one from the leading characters of the + * string. + */ + + if (base == 0) { + if (*p == '0') { + p += 1; + if (*p == 'x' || *p == 'X') { + p += 1; + base = 16; + } else { + /* + * Must set anyDigits here, otherwise "0" produces a "no + * digits" error. + */ + + anyDigits = 1; + base = 8; + } + } else { + base = 10; + } + } else if (base == 16) { + /* + * Skip a leading "0x" from hex numbers. + */ + + if ((p[0] == '0') && (p[1] == 'x' || *p == 'X')) { + p += 2; + } + } + + /* + * Sorry this code is so messy, but speed seems important. Do different + * things for base 8, 10, 16, and other. + */ + + if (base == 8) { + for ( ; ; p += 1) { + digit = *p - '0'; + if (digit > 7) { + break; + } + shifted = result << 3; + if ((shifted >> 3) != result) { + goto overflow; + } + result = shifted + digit; + if ( result < shifted ) { + goto overflow; + } + anyDigits = 1; + } + } else if (base == 10) { + for ( ; ; p += 1) { + digit = *p - '0'; + if (digit > 9) { + break; + } + shifted = 10 * result; + if ((shifted / 10) != result) { + goto overflow; + } + result = shifted + digit; + if ( result < shifted ) { + goto overflow; + } + anyDigits = 1; + } + } else if (base == 16) { + for ( ; ; p += 1) { + digit = *p - '0'; + if (digit > ('z' - '0')) { + break; + } + digit = cvtIn[digit]; + if (digit > 15) { + break; + } + shifted = result << 4; + if ((shifted >> 4) != result) { + goto overflow; + } + result = shifted + digit; + if ( result < shifted ) { + goto overflow; + } + anyDigits = 1; + } + } else if ( base >= 2 && base <= 36 ) { + for ( ; ; p += 1) { + digit = *p - '0'; + if (digit > ('z' - '0')) { + break; + } + digit = cvtIn[digit]; + if (digit >= (unsigned) base) { + break; + } + shifted = result * base; + if ((shifted/base) != result) { + goto overflow; + } + result = shifted + digit; + if ( result < shifted ) { + goto overflow; + } + anyDigits = 1; + } + } + + /* + * Negate if we found a '-' earlier. + */ + + if (negative) { + result = (Tcl_WideUInt)(-((Tcl_WideInt)result)); + } + + /* + * See if there were any digits at all. + */ + + if (!anyDigits) { + p = string; + } + + if (endPtr != 0) { + *endPtr = (char *) p; + } + + return result; + + /* + * On overflow generate the right output + */ + + overflow: + errno = ERANGE; + if (endPtr != 0) { + for ( ; ; p += 1) { + digit = *p - '0'; + if (digit > ('z' - '0')) { + break; + } + digit = cvtIn[digit]; + if (digit >= (unsigned) base) { + break; + } + } + *endPtr = (char *) p; + } + return (Tcl_WideUInt)Tcl_LongAsWide(-1); +} diff --git a/compat/tclErrno.h b/compat/tclErrno.h new file mode 100644 index 0000000..bcbc984 --- /dev/null +++ b/compat/tclErrno.h @@ -0,0 +1,99 @@ +/* + * tclErrno.h -- + * + * This header file contains the various POSIX errno definitions that + * are used by Tcl. This file is derived from the spec POSIX 2.4 and + * previous implementations for Berkeley UNIX. + * + * Copyright (c) 1982, 1986, 1989 Regents of the University of California. + * Copyright (c) 1996 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclErrno.h,v 1.3 2002/06/07 08:50:22 dkf Exp $ + */ + +extern int errno; /* global error number */ + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* Input/output error */ +#define ENXIO 6 /* Device not configured */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file descriptor */ +#define ECHILD 10 /* No child processes */ +#define EDEADLK 11 /* Resource deadlock avoided */ + /* 11 was EAGAIN */ +#define ENOMEM 12 /* Cannot allocate memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* Operation not supported by device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* Too many open files in system */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Inappropriate ioctl for device */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Numerical argument out of domain */ +#define ERANGE 34 /* Result too large */ +#define EAGAIN 35 /* Resource temporarily unavailable */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define EINPROGRESS 36 /* Operation now in progress */ +#define EALREADY 37 /* Operation already in progress */ +#define ENOTSOCK 38 /* Socket operation on non-socket */ +#define EDESTADDRREQ 39 /* Destination address required */ +#define EMSGSIZE 40 /* Message too long */ +#define EPROTOTYPE 41 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 42 /* Protocol not available */ +#define EPROTONOSUPPORT 43 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 44 /* Socket type not supported */ +#define EOPNOTSUPP 45 /* Operation not supported on socket */ +#define EPFNOSUPPORT 46 /* Protocol family not supported */ +#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */ +#define EADDRINUSE 48 /* Address already in use */ +#define EADDRNOTAVAIL 49 /* Can't assign requested address */ +#define ENETDOWN 50 /* Network is down */ +#define ENETUNREACH 51 /* Network is unreachable */ +#define ENETRESET 52 /* Network dropped connection on reset */ +#define ECONNABORTED 53 /* Software caused connection abort */ +#define ECONNRESET 54 /* Connection reset by peer */ +#define ENOBUFS 55 /* No buffer space available */ +#define EISCONN 56 /* Socket is already connected */ +#define ENOTCONN 57 /* Socket is not connected */ +#define ESHUTDOWN 58 /* Can't send after socket shutdown */ +#define ETOOMANYREFS 59 /* Too many references: can't splice */ +#define ETIMEDOUT 60 /* Connection timed out */ +#define ECONNREFUSED 61 /* Connection refused */ +#define ELOOP 62 /* Too many levels of symbolic links */ +#define ENAMETOOLONG 63 /* File name too long */ +#define EHOSTDOWN 64 /* Host is down */ +#define EHOSTUNREACH 65 /* No route to host */ +#define ENOTEMPTY 66 /* Directory not empty */ +#define EPROCLIM 67 /* Too many processes */ +#define EUSERS 68 /* Too many users */ +#define EDQUOT 69 /* Disc quota exceeded */ +#define ESTALE 70 /* Stale NFS file handle */ +#define EREMOTE 71 /* Too many levels of remote in path */ +#define EBADRPC 72 /* RPC struct is bad */ +#define ERPCMISMATCH 73 /* RPC version wrong */ +#define EPROGUNAVAIL 74 /* RPC prog. not avail */ +#define EPROGMISMATCH 75 /* Program version wrong */ +#define EPROCUNAVAIL 76 /* Bad procedure for program */ +#define ENOLCK 77 /* No locks available */ +#define ENOSYS 78 /* Function not implemented */ +#define EOVERFLOW 79 /* Value too large to be stored in data type */ diff --git a/compat/tmpnam.c b/compat/tmpnam.c new file mode 100644 index 0000000..6faf8de --- /dev/null +++ b/compat/tmpnam.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted provided + * that this notice is preserved and that due credit is given to the + * University of California at Berkeley. The name of the University may not be + * used to endorse or promote products derived from this software without + * specific written prior permission. This software is provided ``as is'' + * without express or implied warranty. + * + * RCS: @(#) $Id: tmpnam.c,v 1.3 2007/04/16 13:36:34 dkf Exp $ + */ + +#include <sys/param.h> +#include <sys/stat.h> +#include <sys/file.h> +#include <stdio.h> + +/* + * Use /tmp instead of /usr/tmp, because L_tmpname is only 14 chars on some + * machines (like NeXT machines) and /usr/tmp will cause buffer overflows. + */ + +#ifdef P_tmpdir +# undef P_tmpdir +#endif +#define P_tmpdir "/tmp" + +char * +tmpnam( + char *s) +{ + static char name[50]; + char *mktemp(char *); + + if (!s) { + s = name; + } + (void) sprintf(s, "%s/XXXXXX", P_tmpdir); + return mktemp(s); +} diff --git a/compat/unicows/license.txt b/compat/unicows/license.txt new file mode 100644 index 0000000..46f4d0b --- /dev/null +++ b/compat/unicows/license.txt @@ -0,0 +1,19 @@ +Copyright (c) 2001-2008 Vaclav Slavik + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +
\ No newline at end of file diff --git a/compat/unicows/readme.txt b/compat/unicows/readme.txt new file mode 100644 index 0000000..00967fc --- /dev/null +++ b/compat/unicows/readme.txt @@ -0,0 +1,163 @@ + + + ============================================= + libunicows + ------------------------------------- + Import library for + Microsoft Layer for Unicode (unicows.dll) + + http://libunicows.sourceforge.net + ============================================= + + + About +======= + +Traditionally, win32 Unicode API was only available on Windows NT or 2000. If +you wanted to take advantage of Unicode in your application and support Windows +95/98 at the same time, your only option was to deploy two executables, one for +NT and one for 9X. + +Fortunately, this changed in 2001 when MS (finally!) released MSLU runtime that +allows Unicode applications to run under Windows 9X. + +See these pages for details: + + http://www.microsoft.com/globaldev/handson/dev/mslu_announce.mspx + http://msdn.microsoft.com/msdnmag/nettop.asp?page=/msdnmag/issues/01/10/MSLU/MSLU.asp&ad=ads.ddj.com/msdnmag/premium.htm + +Less fortunately, this solution requires that you use a special statically +linked import library that decides at runtime whether to load symbols from +system libraries like kernel32.dll or user32.dll (in case of Windows NT) or +from unicows.dll (which provides Unicode emulation layer under 9X). This import +library is only available for Microsoft Visual C++ and is only part of the new +Platform SDK, which is rather huge package. + +This library contains independent implementation of the import library. It can +be used with any C compiler (although it was only tested with Mingw32 and MSVC +so far). + + + + Installing libunicows +======================= + + Mingw32 +--------- + +Simply copy libunicows.a to the lib subdirectory of your Mingw32 installation +(e.g. c:\mingw32\lib). + + + Microsoft Visual C++ +---------------------- + +Copy unicows.lib to C:\Program Files\Visual Studio\VC98\Lib (assuming you +installed MSVC into C:\Program Files\Visual Studio and that you have version +6.0, the path may vary otherwise). + +Note: This was tested only with MSVC++ 6.0, but should work with other versions + as well. + + + Borland C++ +------------- + +Copy unicows.lib to %BORLAND%\lib where %BORLAND% is where you installed BC++ +(this directory should contain import32.lib). + + + Watcom C/C++ +------------- + +Copy unicows.lib to %WATCOM%\lib386\nt where %WATCOM% is where you installed +the compiler. + + + Usage +======= + +1) Add the unicows import library BEFORE other win32 libraries on your command +line. For example, if your command line for Mingw32 was + + c++ foo.o bar.o -o foo -lkernel32 -luser32 -lgdi32 -lcomdlg32 + +change it to + + c++ foo.o bar.o -o foo -lunicows -lkernel32 -luser32 -lgdi32 -lcomdlg32 + +No other change is neccessary, you don't have to include any special headers in +your source files. + + +2) Download Unicows runtime from + + http://www.microsoft.com/downloads/release.asp?releaseid=30039 + +or + + http://download.microsoft.com/download/platformsdk/Redist/1.0/W9XMe/EN-US/unicows.exe + +Extract unicows.dll from the package and distribute it with your application. +Do *not* install it to Windows system directory, always copy the DLL to your +application's directory! (Nobody wants any more of DLL hell...). + +If your application uses Common Controls DLL (very likely) or Rich Edit control, +make sure the installer installs new enough versions that fully support Unicode +(Common Controls DLL version 5.80 and RichEdit 4.0). + + + Compiling from sources +======================== + +1) Download the source package (libunicows-$version-src.tar.gz) + +2) [optional step] Run generate.py to create assembler stubs. You will need + Python (http://www.python.org) to run it. You don't have to do this unless + you modified symbols.txt or src\template.asm, because generated stubs are + already included in source package (in src\gen_asm). + +3) Change to 'src' subdirectory and compile the library. You will need + NASM (http://nasm.sourceforge.net). + + Mingw32: run make -f makefile.mingw32 + MSVC: run nmake -f makefile.vc6 + + If your compiler is not supported, you will have to create a makefile/project + file for it. You can gen inspiration from existing makefiles. If you do so, + please send the makefile (and if possible, compiled unicows.lib) to me, + so that I can include it in the next release of libunicows. Thanks! + + + Compiling and using unicows_wrapper.dll +========================================= + +If precompiled version of libunicows is not available for your compiler, you +can use unicows_wrapper.dll (at the cost of marginally slower calls and +the need to install unicows_wrapper.dll on NT/2k/XP boxes, too). Create +an import library for it in the same way you would do for any other DLL +and same the created import library as unicows.lib (or whatever name convention +your compiler uses, the point is to not name it unicows_wrapper.lib). For +example, this is how to do it with Borland C++ tools: + + implib unicows.lib unicows_wrapper.dll + +That is. Use the library as with other compilers, i.e. put unicows.lib as the +first one on your command line, so that the symbols are found in unicows.lib +and not in e.g. kernel32.lib. + +Unlike with the "native" import libraries, using unicows_wrapper.dll will make +your application depend on unicows_wrapper.dll even when installed on +Windows NT/2000/XP. Therefore, your installer must install following files +in addition to your application's binary and data: + +9x/ME: unicows.dll, unicows_wrapper.dll +NT/2k/XP: unicows_wrapper.dll + + + + Contacting the author +======================= + +I can be reached at this email address: vslavik@fastmail.fm +
\ No newline at end of file diff --git a/compat/unicows/unicows.lib b/compat/unicows/unicows.lib Binary files differnew file mode 100644 index 0000000..e130334 --- /dev/null +++ b/compat/unicows/unicows.lib diff --git a/compat/zlib/algorithm.txt b/compat/zlib/algorithm.txt new file mode 100644 index 0000000..b022dde --- /dev/null +++ b/compat/zlib/algorithm.txt @@ -0,0 +1,209 @@ +1. Compression algorithm (deflate) + +The deflation algorithm used by gzip (also zip and zlib) is a variation of +LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in +the input data. The second occurrence of a string is replaced by a +pointer to the previous string, in the form of a pair (distance, +length). Distances are limited to 32K bytes, and lengths are limited +to 258 bytes. When a string does not occur anywhere in the previous +32K bytes, it is emitted as a sequence of literal bytes. (In this +description, `string' must be taken as an arbitrary sequence of bytes, +and is not restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when deflate() determines that +it would be useful to start another block with fresh trees. (This is +somewhat similar to the behavior of LZW-based _compress_.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (level +parameter of deflateInit). So deflate() does not always find the longest +possible match but generally finds a match which is long enough. + +deflate() also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, deflate() searches for +a longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the process of lazy evaluation begins again. Otherwise, +the original match is kept, and the next match search is attempted only N +steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, deflate() reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, deflate() attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (level parameter 1 to 3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + + +2. Decompression algorithm (inflate) + +2.1 Introduction + +The key question is how to represent a Huffman code (or any prefix code) so +that you can decode fast. The most important characteristic is that shorter +codes are much more common than longer codes, so pay attention to decoding the +short codes fast, and let the long codes take longer to decode. + +inflate() sets up a first level table that covers some number of bits of +input less than the length of longest code. It gets that many bits from the +stream, and looks it up in the table. The table will tell if the next +code is that many bits or less and how many, and if it is, it will tell +the value, else it will point to the next level table for which inflate() +grabs more bits and tries to decode a longer code. + +How many bits to make the first lookup is a tradeoff between the time it +takes to decode and the time it takes to build the table. If building the +table took no time (and if you had infinite memory), then there would only +be a first level table to cover all the way to the longest code. However, +building the table ends up taking a lot longer for more bits since short +codes are replicated many times in such a table. What inflate() does is +simply to make the number of bits in the first table a variable, and then +to set that variable for the maximum speed. + +For inflate, which has 286 possible codes for the literal/length tree, the size +of the first table is nine bits. Also the distance trees have 30 possible +values, and the size of the first table is six bits. Note that for each of +those cases, the table ended up one bit longer than the ``average'' code +length, i.e. the code length of an approximately flat code which would be a +little more than eight bits for 286 symbols and a little less than five bits +for 30 symbols. + + +2.2 More details on the inflate table lookup + +Ok, you want to know what this cleverly obfuscated inflate tree actually +looks like. You are correct that it's not a Huffman tree. It is simply a +lookup table for the first, let's say, nine bits of a Huffman symbol. The +symbol could be as short as one bit or as long as 15 bits. If a particular +symbol is shorter than nine bits, then that symbol's translation is duplicated +in all those entries that start with that symbol's bits. For example, if the +symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a +symbol is nine bits long, it appears in the table once. + +If the symbol is longer than nine bits, then that entry in the table points +to another similar table for the remaining bits. Again, there are duplicated +entries as needed. The idea is that most of the time the symbol will be short +and there will only be one table look up. (That's whole idea behind data +compression in the first place.) For the less frequent long symbols, there +will be two lookups. If you had a compression method with really long +symbols, you could have as many levels of lookups as is efficient. For +inflate, two is enough. + +So a table entry either points to another table (in which case nine bits in +the above example are gobbled), or it contains the translation for the symbol +and the number of bits to gobble. Then you start again with the next +ungobbled bit. + +You may wonder: why not just have one lookup table for how ever many bits the +longest symbol is? The reason is that if you do that, you end up spending +more time filling in duplicate symbol entries than you do actually decoding. +At least for deflate's output that generates new trees every several 10's of +kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code +would take too long if you're only decoding several thousand symbols. At the +other extreme, you could make a new table for every bit in the code. In fact, +that's essentially a Huffman tree. But then you spend two much time +traversing the tree while decoding, even for short symbols. + +So the number of bits for the first lookup table is a trade of the time to +fill out the table vs. the time spent looking at the second level and above of +the table. + +Here is an example, scaled down: + +The code being decoded, with 10 symbols, from 1 to 6 bits long: + +A: 0 +B: 10 +C: 1100 +D: 11010 +E: 11011 +F: 11100 +G: 11101 +H: 11110 +I: 111110 +J: 111111 + +Let's make the first table three bits long (eight entries): + +000: A,1 +001: A,1 +010: A,1 +011: A,1 +100: B,2 +101: B,2 +110: -> table X (gobble 3 bits) +111: -> table Y (gobble 3 bits) + +Each entry is what the bits decode as and how many bits that is, i.e. how +many bits to gobble. Or the entry points to another table, with the number of +bits to gobble implicit in the size of the table. + +Table X is two bits long since the longest code starting with 110 is five bits +long: + +00: C,1 +01: C,1 +10: D,2 +11: E,2 + +Table Y is three bits long since the longest code starting with 111 is six +bits long: + +000: F,2 +001: F,2 +010: G,2 +011: G,2 +100: H,2 +101: H,2 +110: I,3 +111: J,3 + +So what we have here are three tables with a total of 20 entries that had to +be constructed. That's compared to 64 entries for a single table. Or +compared to 16 entries for a Huffman tree (six two entry tables and one four +entry table). Assuming that the code ideally represents the probability of +the symbols, it takes on the average 1.25 lookups per symbol. That's compared +to one lookup for the single table, or 1.66 lookups per symbol for the +Huffman tree. + +There, I think that gives you a picture of what's going on. For inflate, the +meaning of a particular symbol is often more than just a letter. It can be a +byte (a "literal"), or it can be either a length or a distance which +indicates a base value and a number of bits to fetch after the code that is +added to the base value. Or it might be the special end-of-block code. The +data structures created in inftrees.c try to encode all that information +compactly in the tables. + + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu + + +References: + +[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data +Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, +pp. 337-343. + +``DEFLATE Compressed Data Format Specification'' available in +http://www.ietf.org/rfc/rfc1951.txt diff --git a/compat/zlib/as400/bndsrc b/compat/zlib/as400/bndsrc new file mode 100644 index 0000000..9cf94bb --- /dev/null +++ b/compat/zlib/as400/bndsrc @@ -0,0 +1,132 @@ +STRPGMEXP PGMLVL(*CURRENT) SIGNATURE('ZLIB') + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/* Version 1.1.3 entry points. */ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + +/********************************************************************/ +/* *MODULE ADLER32 ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("adler32") + +/********************************************************************/ +/* *MODULE COMPRESS ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("compress") + EXPORT SYMBOL("compress2") + +/********************************************************************/ +/* *MODULE CRC32 ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("crc32") + EXPORT SYMBOL("get_crc_table") + +/********************************************************************/ +/* *MODULE DEFLATE ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("deflate") + EXPORT SYMBOL("deflateEnd") + EXPORT SYMBOL("deflateSetDictionary") + EXPORT SYMBOL("deflateCopy") + EXPORT SYMBOL("deflateReset") + EXPORT SYMBOL("deflateParams") + EXPORT SYMBOL("deflatePrime") + EXPORT SYMBOL("deflateInit_") + EXPORT SYMBOL("deflateInit2_") + +/********************************************************************/ +/* *MODULE GZIO ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("gzopen") + EXPORT SYMBOL("gzdopen") + EXPORT SYMBOL("gzsetparams") + EXPORT SYMBOL("gzread") + EXPORT SYMBOL("gzwrite") + EXPORT SYMBOL("gzprintf") + EXPORT SYMBOL("gzputs") + EXPORT SYMBOL("gzgets") + EXPORT SYMBOL("gzputc") + EXPORT SYMBOL("gzgetc") + EXPORT SYMBOL("gzflush") + EXPORT SYMBOL("gzseek") + EXPORT SYMBOL("gzrewind") + EXPORT SYMBOL("gztell") + EXPORT SYMBOL("gzeof") + EXPORT SYMBOL("gzclose") + EXPORT SYMBOL("gzerror") + +/********************************************************************/ +/* *MODULE INFLATE ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("inflate") + EXPORT SYMBOL("inflateEnd") + EXPORT SYMBOL("inflateSetDictionary") + EXPORT SYMBOL("inflateSync") + EXPORT SYMBOL("inflateReset") + EXPORT SYMBOL("inflateInit_") + EXPORT SYMBOL("inflateInit2_") + EXPORT SYMBOL("inflateSyncPoint") + +/********************************************************************/ +/* *MODULE UNCOMPR ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("uncompress") + +/********************************************************************/ +/* *MODULE ZUTIL ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("zlibVersion") + EXPORT SYMBOL("zError") + +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ +/* Version 1.2.1 additional entry points. */ +/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ + +/********************************************************************/ +/* *MODULE COMPRESS ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("compressBound") + +/********************************************************************/ +/* *MODULE DEFLATE ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("deflateBound") + +/********************************************************************/ +/* *MODULE GZIO ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("gzungetc") + EXPORT SYMBOL("gzclearerr") + +/********************************************************************/ +/* *MODULE INFBACK ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("inflateBack") + EXPORT SYMBOL("inflateBackEnd") + EXPORT SYMBOL("inflateBackInit_") + +/********************************************************************/ +/* *MODULE INFLATE ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("inflateCopy") + +/********************************************************************/ +/* *MODULE ZUTIL ZLIB 01/02/01 00:15:09 */ +/********************************************************************/ + + EXPORT SYMBOL("zlibCompileFlags") + +ENDPGMEXP diff --git a/compat/zlib/as400/compile.clp b/compat/zlib/as400/compile.clp new file mode 100644 index 0000000..8554951 --- /dev/null +++ b/compat/zlib/as400/compile.clp @@ -0,0 +1,123 @@ +/******************************************************************************/ +/* */ +/* ZLIB */ +/* */ +/* Compile sources into modules and link them into a service program. */ +/* */ +/******************************************************************************/ + + PGM + +/* Configuration adjustable parameters. */ + + DCL VAR(&SRCLIB) TYPE(*CHAR) LEN(10) + + VALUE('ZLIB') /* Source library. */ + DCL VAR(&SRCFILE) TYPE(*CHAR) LEN(10) + + VALUE('SOURCES') /* Source member file. */ + DCL VAR(&CTLFILE) TYPE(*CHAR) LEN(10) + + VALUE('TOOLS') /* Control member file. */ + + DCL VAR(&MODLIB) TYPE(*CHAR) LEN(10) + + VALUE('ZLIB') /* Module library. */ + + DCL VAR(&SRVLIB) TYPE(*CHAR) LEN(10) + + VALUE('LGPL') /* Service program library. */ + + DCL VAR(&CFLAGS) TYPE(*CHAR) + + VALUE('OPTIMIZE(40)') /* Compile options. */ + + +/* Working storage. */ + + DCL VAR(&CMDLEN) TYPE(*DEC) LEN(15 5) VALUE(300) /* Command length. */ + DCL VAR(&CMD) TYPE(*CHAR) LEN(512) + + +/* Compile sources into modules. */ + + CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT + + '/ADLER32) SRCFILE(' *TCAT + + &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT + + ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS) + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT + + '/COMPRESS) SRCFILE(' *TCAT + + &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT + + ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS) + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT + + '/CRC32) SRCFILE(' *TCAT + + &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT + + ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS) + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT + + '/DEFLATE) SRCFILE(' *TCAT + + &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT + + ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS) + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT + + '/GZIO) SRCFILE(' *TCAT + + &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT + + ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS) + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT + + '/INFBACK) SRCFILE(' *TCAT + + &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT + + ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS) + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT + + '/INFFAST) SRCFILE(' *TCAT + + &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT + + ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS) + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT + + '/INFLATE) SRCFILE(' *TCAT + + &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT + + ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS) + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT + + '/INFTREES) SRCFILE(' *TCAT + + &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT + + ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS) + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT + + '/TREES) SRCFILE(' *TCAT + + &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT + + ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS) + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT + + '/UNCOMPR) SRCFILE(' *TCAT + + &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT + + ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS) + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + CHGVAR VAR(&CMD) VALUE('CRTCMOD MODULE(' *TCAT &MODLIB *TCAT + + '/ZUTIL) SRCFILE(' *TCAT + + &SRCLIB *TCAT '/' *TCAT &SRCFILE *TCAT + + ') SYSIFCOPT(*IFSIO)' *BCAT &CFLAGS) + CALL PGM(QCMDEXC) PARM(&CMD &CMDLEN) + + +/* Link modules into a service program. */ + + CRTSRVPGM SRVPGM(&SRVLIB/ZLIB) + + MODULE(&MODLIB/ADLER32 &MODLIB/COMPRESS + + &MODLIB/CRC32 &MODLIB/DEFLATE + + &MODLIB/GZIO &MODLIB/INFBACK + + &MODLIB/INFFAST &MODLIB/INFLATE + + &MODLIB/INFTREES &MODLIB/TREES + + &MODLIB/UNCOMPR &MODLIB/ZUTIL) + + SRCFILE(&SRCLIB/&CTLFILE) SRCMBR(BNDSRC) + + TEXT('ZLIB 1.2.3') TGTRLS(V4R4M0) + + ENDPGM diff --git a/compat/zlib/as400/readme.txt b/compat/zlib/as400/readme.txt new file mode 100644 index 0000000..beae13f --- /dev/null +++ b/compat/zlib/as400/readme.txt @@ -0,0 +1,111 @@ + ZLIB version 1.2.3 for AS400 installation instructions + +I) From an AS400 *SAVF file: + +1) Unpacking archive to an AS400 save file + +On the AS400: + +_ Create the ZLIB AS400 library: + + CRTLIB LIB(ZLIB) TYPE(PROD) TEXT('ZLIB compression API library') + +_ Create a work save file, for example: + + CRTSAVF FILE(ZLIB/ZLIBSAVF) + +On a PC connected to the target AS400: + +_ Unpack the save file image to a PC file "ZLIBSAVF" +_ Upload this file into the save file on the AS400, for example + using ftp in BINARY mode. + + +2) Populating the ZLIB AS400 source library + +On the AS400: + +_ Extract the saved objects into the ZLIB AS400 library using: + +RSTOBJ OBJ(*ALL) SAVLIB(ZLIB) DEV(*SAVF) SAVF(ZLIB/ZLIBSAVF) RSTLIB(ZLIB) + + +3) Customize installation: + +_ Edit CL member ZLIB/TOOLS(COMPILE) and change parameters if needed, + according to the comments. + +_ Compile this member with: + + CRTCLPGM PGM(ZLIB/COMPILE) SRCFILE(ZLIB/TOOLS) SRCMBR(COMPILE) + + +4) Compile and generate the service program: + +_ This can now be done by executing: + + CALL PGM(ZLIB/COMPILE) + + + +II) From the original source distribution: + +1) On the AS400, create the source library: + + CRTLIB LIB(ZLIB) TYPE(PROD) TEXT('ZLIB compression API library') + +2) Create the source files: + + CRTSRCPF FILE(ZLIB/SOURCES) RCDLEN(112) TEXT('ZLIB library modules') + CRTSRCPF FILE(ZLIB/H) RCDLEN(112) TEXT('ZLIB library includes') + CRTSRCPF FILE(ZLIB/TOOLS) RCDLEN(112) TEXT('ZLIB library control utilities') + +3) From the machine hosting the distribution files, upload them (with + FTP in text mode, for example) according to the following table: + + Original AS400 AS400 AS400 AS400 + file file member type description + SOURCES Original ZLIB C subprogram sources + adler32.c ADLER32 C ZLIB - Compute the Adler-32 checksum of a dta strm + compress.c COMPRESS C ZLIB - Compress a memory buffer + crc32.c CRC32 C ZLIB - Compute the CRC-32 of a data stream + deflate.c DEFLATE C ZLIB - Compress data using the deflation algorithm + gzio.c GZIO C ZLIB - IO on .gz files + infback.c INFBACK C ZLIB - Inflate using a callback interface + inffast.c INFFAST C ZLIB - Fast proc. literals & length/distance pairs + inflate.c INFLATE C ZLIB - Interface to inflate modules + inftrees.c INFTREES C ZLIB - Generate Huffman trees for efficient decode + trees.c TREES C ZLIB - Output deflated data using Huffman coding + uncompr.c UNCOMPR C ZLIB - Decompress a memory buffer + zutil.c ZUTIL C ZLIB - Target dependent utility functions + H Original ZLIB C and ILE/RPG include files + crc32.h CRC32 C ZLIB - CRC32 tables + deflate.h DEFLATE C ZLIB - Internal compression state + inffast.h INFFAST C ZLIB - Header to use inffast.c + inffixed.h INFFIXED C ZLIB - Table for decoding fixed codes + inflate.h INFLATE C ZLIB - Internal inflate state definitions + inftrees.h INFTREES C ZLIB - Header to use inftrees.c + trees.h TREES C ZLIB - Created automatically with -DGEN_TREES_H + zconf.h ZCONF C ZLIB - Compression library configuration + zlib.h ZLIB C ZLIB - Compression library C user interface + as400/zlib.inc ZLIB.INC RPGLE ZLIB - Compression library ILE RPG user interface + zutil.h ZUTIL C ZLIB - Internal interface and configuration + TOOLS Building source software & AS/400 README + as400/bndsrc BNDSRC Entry point exportation list + as400/compile.clp COMPILE CLP Compile sources & generate service program + as400/readme.txt README TXT Installation instructions + +4) Continue as in I)3). + + + + +Notes: For AS400 ILE RPG programmers, a /copy member defining the ZLIB + API prototypes for ILE RPG can be found in ZLIB/H(ZLIB.INC). + Please read comments in this member for more information. + + Remember that most foreign textual data are ASCII coded: this + implementation does not handle conversion from/to ASCII, so + text data code conversions must be done explicitely. + + Always open zipped files in binary mode. diff --git a/compat/zlib/as400/zlib.inc b/compat/zlib/as400/zlib.inc new file mode 100644 index 0000000..7bbfb7e --- /dev/null +++ b/compat/zlib/as400/zlib.inc @@ -0,0 +1,331 @@ + * ZLIB.INC - Interface to the general purpose compression library + * + * ILE RPG400 version by Patrick Monnerat, DATASPHERE. + * Version 1.2.3 + * + * + * WARNING: + * Procedures inflateInit(), inflateInit2(), deflateInit(), + * deflateInit2() and inflateBackInit() need to be called with + * two additional arguments: + * the package version string and the stream control structure. + * size. This is needed because RPG lacks some macro feature. + * Call these procedures as: + * inflateInit(...: ZLIB_VERSION: %size(z_stream)) + * + /if not defined(ZLIB_H_) + /define ZLIB_H_ + * + ************************************************************************** + * Constants + ************************************************************************** + * + * Versioning information. + * + D ZLIB_VERSION C '1.2.3' + D ZLIB_VERNUM C X'1230' + * + * Other equates. + * + D Z_NO_FLUSH C 0 + D Z_SYNC_FLUSH C 2 + D Z_FULL_FLUSH C 3 + D Z_FINISH C 4 + D Z_BLOCK C 5 + * + D Z_OK C 0 + D Z_STREAM_END C 1 + D Z_NEED_DICT C 2 + D Z_ERRNO C -1 + D Z_STREAM_ERROR C -2 + D Z_DATA_ERROR C -3 + D Z_MEM_ERROR C -4 + D Z_BUF_ERROR C -5 + DZ_VERSION_ERROR C -6 + * + D Z_NO_COMPRESSION... + D C 0 + D Z_BEST_SPEED C 1 + D Z_BEST_COMPRESSION... + D C 9 + D Z_DEFAULT_COMPRESSION... + D C -1 + * + D Z_FILTERED C 1 + D Z_HUFFMAN_ONLY C 2 + D Z_RLE C 3 + D Z_DEFAULT_STRATEGY... + D C 0 + * + D Z_BINARY C 0 + D Z_ASCII C 1 + D Z_UNKNOWN C 2 + * + D Z_DEFLATED C 8 + * + D Z_NULL C 0 + * + ************************************************************************** + * Types + ************************************************************************** + * + D z_streamp S * Stream struct ptr + D gzFile S * File pointer + D z_off_t S 10i 0 Stream offsets + * + ************************************************************************** + * Structures + ************************************************************************** + * + * The GZIP encode/decode stream support structure. + * + D z_stream DS align based(z_streamp) + D zs_next_in * Next input byte + D zs_avail_in 10U 0 Byte cnt at next_in + D zs_total_in 10U 0 Total bytes read + D zs_next_out * Output buffer ptr + D zs_avail_out 10U 0 Room left @ next_out + D zs_total_out 10U 0 Total bytes written + D zs_msg * Last errmsg or null + D zs_state * Internal state + D zs_zalloc * procptr Int. state allocator + D zs_free * procptr Int. state dealloc. + D zs_opaque * Private alloc. data + D zs_data_type 10i 0 ASC/BIN best guess + D zs_adler 10u 0 Uncompr. adler32 val + D 10U 0 Reserved + D 10U 0 Ptr. alignment + * + ************************************************************************** + * Utility function prototypes + ************************************************************************** + * + D compress PR 10I 0 extproc('compress') + D dest 32767 options(*varsize) Destination buffer + D destLen 10U 0 Destination length + D source 32767 const options(*varsize) Source buffer + D sourceLen 10u 0 value Source length + * + D compress2 PR 10I 0 extproc('compress2') + D dest 32767 options(*varsize) Destination buffer + D destLen 10U 0 Destination length + D source 32767 const options(*varsize) Source buffer + D sourceLen 10U 0 value Source length + D level 10I 0 value Compression level + * + D compressBound PR 10U 0 extproc('compressBound') + D sourceLen 10U 0 value + * + D uncompress PR 10I 0 extproc('uncompress') + D dest 32767 options(*varsize) Destination buffer + D destLen 10U 0 Destination length + D source 32767 const options(*varsize) Source buffer + D sourceLen 10U 0 value Source length + * + D gzopen PR extproc('gzopen') + D like(gzFile) + D path * value options(*string) File pathname + D mode * value options(*string) Open mode + * + D gzdopen PR extproc('gzdopen') + D like(gzFile) + D fd 10i 0 value File descriptor + D mode * value options(*string) Open mode + * + D gzsetparams PR 10I 0 extproc('gzsetparams') + D file value like(gzFile) File pointer + D level 10I 0 value + D strategy 10i 0 value + * + D gzread PR 10I 0 extproc('gzread') + D file value like(gzFile) File pointer + D buf 32767 options(*varsize) Buffer + D len 10u 0 value Buffer length + * + D gzwrite PR 10I 0 extproc('gzwrite') + D file value like(gzFile) File pointer + D buf 32767 const options(*varsize) Buffer + D len 10u 0 value Buffer length + * + D gzputs PR 10I 0 extproc('gzputs') + D file value like(gzFile) File pointer + D s * value options(*string) String to output + * + D gzgets PR * extproc('gzgets') + D file value like(gzFile) File pointer + D buf 32767 options(*varsize) Read buffer + D len 10i 0 value Buffer length + * + D gzflush PR 10i 0 extproc('gzflush') + D file value like(gzFile) File pointer + D flush 10I 0 value Type of flush + * + D gzseek PR extproc('gzseek') + D like(z_off_t) + D file value like(gzFile) File pointer + D offset value like(z_off_t) Offset + D whence 10i 0 value Origin + * + D gzrewind PR 10i 0 extproc('gzrewind') + D file value like(gzFile) File pointer + * + D gztell PR extproc('gztell') + D like(z_off_t) + D file value like(gzFile) File pointer + * + D gzeof PR 10i 0 extproc('gzeof') + D file value like(gzFile) File pointer + * + D gzclose PR 10i 0 extproc('gzclose') + D file value like(gzFile) File pointer + * + D gzerror PR * extproc('gzerror') Error string + D file value like(gzFile) File pointer + D errnum 10I 0 Error code + * + D gzclearerr PR extproc('gzclearerr') + D file value like(gzFile) File pointer + * + ************************************************************************** + * Basic function prototypes + ************************************************************************** + * + D zlibVersion PR * extproc('zlibVersion') Version string + * + D deflateInit PR 10I 0 extproc('deflateInit_') Init. compression + D strm like(z_stream) Compression stream + D level 10I 0 value Compression level + D version * value options(*string) Version string + D stream_size 10i 0 value Stream struct. size + * + D deflate PR 10I 0 extproc('deflate') Compress data + D strm like(z_stream) Compression stream + D flush 10I 0 value Flush type required + * + D deflateEnd PR 10I 0 extproc('deflateEnd') Termin. compression + D strm like(z_stream) Compression stream + * + D inflateInit PR 10I 0 extproc('inflateInit_') Init. expansion + D strm like(z_stream) Expansion stream + D version * value options(*string) Version string + D stream_size 10i 0 value Stream struct. size + * + D inflate PR 10I 0 extproc('inflate') Expand data + D strm like(z_stream) Expansion stream + D flush 10I 0 value Flush type required + * + D inflateEnd PR 10I 0 extproc('inflateEnd') Termin. expansion + D strm like(z_stream) Expansion stream + * + ************************************************************************** + * Advanced function prototypes + ************************************************************************** + * + D deflateInit2 PR 10I 0 extproc('deflateInit2_') Init. compression + D strm like(z_stream) Compression stream + D level 10I 0 value Compression level + D method 10I 0 value Compression method + D windowBits 10I 0 value log2(window size) + D memLevel 10I 0 value Mem/cmpress tradeoff + D strategy 10I 0 value Compression stategy + D version * value options(*string) Version string + D stream_size 10i 0 value Stream struct. size + * + D deflateSetDictionary... + D PR 10I 0 extproc('deflateSetDictionary') Init. dictionary + D strm like(z_stream) Compression stream + D dictionary 32767 const options(*varsize) Dictionary bytes + D dictLength 10U 0 value Dictionary length + * + D deflateCopy PR 10I 0 extproc('deflateCopy') Compress strm 2 strm + D dest like(z_stream) Destination stream + D source like(z_stream) Source stream + * + D deflateReset PR 10I 0 extproc('deflateReset') End and init. stream + D strm like(z_stream) Compression stream + * + D deflateParams PR 10I 0 extproc('deflateParams') Change level & strat + D strm like(z_stream) Compression stream + D level 10I 0 value Compression level + D strategy 10I 0 value Compression stategy + * + D deflateBound PR 10U 0 extproc('deflateBound') Change level & strat + D strm like(z_stream) Compression stream + D sourcelen 10U 0 value Compression level + * + D deflatePrime PR 10I 0 extproc('deflatePrime') Change level & strat + D strm like(z_stream) Compression stream + D bits 10I 0 value Number of bits to insert + D value 10I 0 value Bits to insert + * + D inflateInit2 PR 10I 0 extproc('inflateInit2_') Init. expansion + D strm like(z_stream) Expansion stream + D windowBits 10I 0 value log2(window size) + D version * value options(*string) Version string + D stream_size 10i 0 value Stream struct. size + * + D inflateSetDictionary... + D PR 10I 0 extproc('inflateSetDictionary') Init. dictionary + D strm like(z_stream) Expansion stream + D dictionary 32767 const options(*varsize) Dictionary bytes + D dictLength 10U 0 value Dictionary length + * + D inflateSync PR 10I 0 extproc('inflateSync') Sync. expansion + D strm like(z_stream) Expansion stream + * + D inflateCopy PR 10I 0 extproc('inflateCopy') + D dest like(z_stream) Destination stream + D source like(z_stream) Source stream + * + D inflateReset PR 10I 0 extproc('inflateReset') End and init. stream + D strm like(z_stream) Expansion stream + * + D inflateBackInit... + D PR 10I 0 extproc('inflateBackInit_') + D strm like(z_stream) Expansion stream + D windowBits 10I 0 value Log2(buffer size) + D window 32767 options(*varsize) Buffer + D version * value options(*string) Version string + D stream_size 10i 0 value Stream struct. size + * + D inflateBack PR 10I 0 extproc('inflateBack') + D strm like(z_stream) Expansion stream + D in * value procptr Input function + D in_desc * value Input descriptor + D out * value procptr Output function + D out_desc * value Output descriptor + * + D inflateBackEnd PR 10I 0 extproc('inflateBackEnd') + D strm like(z_stream) Expansion stream + * + D zlibCompileFlags... + D PR 10U 0 extproc('zlibCompileFlags') + * + ************************************************************************** + * Checksum function prototypes + ************************************************************************** + * + D adler32 PR 10U 0 extproc('adler32') New checksum + D adler 10U 0 value Old checksum + D buf 32767 const options(*varsize) Bytes to accumulate + D len 10U 0 value Buffer length + * + D crc32 PR 10U 0 extproc('crc32') New checksum + D crc 10U 0 value Old checksum + D buf 32767 const options(*varsize) Bytes to accumulate + D len 10U 0 value Buffer length + * + ************************************************************************** + * Miscellaneous function prototypes + ************************************************************************** + * + D zError PR * extproc('zError') Error string + D err 10I 0 value Error code + * + D inflateSyncPoint... + D PR 10I 0 extproc('inflateSyncPoint') + D strm like(z_stream) Expansion stream + * + D get_crc_table PR * extproc('get_crc_table') Ptr to ulongs + * + /endif diff --git a/compat/zlib/gzio.c b/compat/zlib/gzio.c new file mode 100644 index 0000000..8307498 --- /dev/null +++ b/compat/zlib/gzio.c @@ -0,0 +1,1026 @@ +/* gzio.c -- IO on .gz files + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. + */ + +/* @(#) $Id: gzio.c,v 1.1 2008/12/18 14:14:59 dkf Exp $ */ + +#include <stdio.h> + +#include "zutil.h" + +#ifdef NO_DEFLATE /* for compatibility with old definition */ +# define NO_GZCOMPRESS +#endif + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +#ifndef Z_BUFSIZE +# ifdef MAXSEG_64K +# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ +# else +# define Z_BUFSIZE 16384 +# endif +#endif +#ifndef Z_PRINTF_BUFSIZE +# define Z_PRINTF_BUFSIZE 4096 +#endif + +#ifdef __MVS__ +# pragma map (fdopen , "\174\174FDOPEN") + FILE *fdopen(int, const char *); +#endif + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern void free OF((voidpf ptr)); +#endif + +#define ALLOC(size) malloc(size) +#define TRYFREE(p) {if (p) free(p);} + +static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + +typedef struct gz_stream { + z_stream stream; + int z_err; /* error code for last stream operation */ + int z_eof; /* set if end of input file */ + FILE *file; /* .gz file */ + Byte *inbuf; /* input buffer */ + Byte *outbuf; /* output buffer */ + uLong crc; /* crc32 of uncompressed data */ + char *msg; /* error message */ + char *path; /* path name for debugging only */ + int transparent; /* 1 if input file is not a .gz file */ + char mode; /* 'w' or 'r' */ + z_off_t start; /* start of compressed data in file (header skipped) */ + z_off_t in; /* bytes into deflate or inflate */ + z_off_t out; /* bytes out of deflate or inflate */ + int back; /* one character push-back */ + int last; /* true if push-back is last character */ +} gz_stream; + + +local gzFile gz_open OF((const char *path, const char *mode, int fd)); +local int do_flush OF((gzFile file, int flush)); +local int get_byte OF((gz_stream *s)); +local void check_header OF((gz_stream *s)); +local int destroy OF((gz_stream *s)); +local void putLong OF((FILE *file, uLong x)); +local uLong getLong OF((gz_stream *s)); + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb"). The file is given either by file descriptor + or path name (if fd == -1). + gz_open returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +*/ +local gzFile gz_open (path, mode, fd) + const char *path; + const char *mode; + int fd; +{ + int err; + int level = Z_DEFAULT_COMPRESSION; /* compression level */ + int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ + char *p = (char*)mode; + gz_stream *s; + char fmode[80]; /* copy of mode, without the compression level */ + char *m = fmode; + + if (!path || !mode) return Z_NULL; + + s = (gz_stream *)ALLOC(sizeof(gz_stream)); + if (!s) return Z_NULL; + + s->stream.zalloc = (alloc_func)0; + s->stream.zfree = (free_func)0; + s->stream.opaque = (voidpf)0; + s->stream.next_in = s->inbuf = Z_NULL; + s->stream.next_out = s->outbuf = Z_NULL; + s->stream.avail_in = s->stream.avail_out = 0; + s->file = NULL; + s->z_err = Z_OK; + s->z_eof = 0; + s->in = 0; + s->out = 0; + s->back = EOF; + s->crc = crc32(0L, Z_NULL, 0); + s->msg = NULL; + s->transparent = 0; + + s->path = (char*)ALLOC(strlen(path)+1); + if (s->path == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + strcpy(s->path, path); /* do this early for debugging */ + + s->mode = '\0'; + do { + if (*p == 'r') s->mode = 'r'; + if (*p == 'w' || *p == 'a') s->mode = 'w'; + if (*p >= '0' && *p <= '9') { + level = *p - '0'; + } else if (*p == 'f') { + strategy = Z_FILTERED; + } else if (*p == 'h') { + strategy = Z_HUFFMAN_ONLY; + } else if (*p == 'R') { + strategy = Z_RLE; + } else { + *m++ = *p; /* copy the mode */ + } + } while (*p++ && m != fmode + sizeof(fmode)); + if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + err = Z_STREAM_ERROR; +#else + err = deflateInit2(&(s->stream), level, + Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); + /* windowBits is passed < 0 to suppress zlib header */ + + s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); +#endif + if (err != Z_OK || s->outbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } else { + s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); + + err = inflateInit2(&(s->stream), -MAX_WBITS); + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are + * present after the compressed stream. + */ + if (err != Z_OK || s->inbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } + s->stream.avail_out = Z_BUFSIZE; + + errno = 0; + s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); + + if (s->file == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + if (s->mode == 'w') { + /* Write a very simple .gz header: + */ + fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], + Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); + s->start = 10L; + /* We use 10L instead of ftell(s->file) to because ftell causes an + * fflush on some systems. This version of the library doesn't use + * start anyway in write mode, so this initialization is not + * necessary. + */ + } else { + check_header(s); /* skip the .gz header */ + s->start = ftell(s->file) - s->stream.avail_in; + } + + return (gzFile)s; +} + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. +*/ +gzFile ZEXPORT gzopen (path, mode) + const char *path; + const char *mode; +{ + return gz_open (path, mode, -1); +} + +/* =========================================================================== + Associate a gzFile with the file descriptor fd. fd is not dup'ed here + to mimic the behavio(u)r of fdopen. +*/ +gzFile ZEXPORT gzdopen (fd, mode) + int fd; + const char *mode; +{ + char name[46]; /* allow for up to 128-bit integers */ + + if (fd < 0) return (gzFile)Z_NULL; + sprintf(name, "<fd:%d>", fd); /* for debugging */ + + return gz_open (name, mode, fd); +} + +/* =========================================================================== + * Update the compression level and strategy + */ +int ZEXPORT gzsetparams (file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + /* Make room to allow flushing */ + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + } + s->stream.avail_out = Z_BUFSIZE; + } + + return deflateParams (&(s->stream), level, strategy); +} + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ +local int get_byte(s) + gz_stream *s; +{ + if (s->z_eof) return EOF; + if (s->stream.avail_in == 0) { + errno = 0; + s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) s->z_err = Z_ERRNO; + return EOF; + } + s->stream.next_in = s->inbuf; + } + s->stream.avail_in--; + return *(s->stream.next_in)++; +} + +/* =========================================================================== + Check the gzip header of a gz_stream opened for reading. Set the stream + mode to transparent if the gzip magic header is not present; set s->err + to Z_DATA_ERROR if the magic header is present but the rest of the header + is incorrect. + IN assertion: the stream s has already been created sucessfully; + s->stream.avail_in is zero for the first time, but may be non-zero + for concatenated .gz files. +*/ +local void check_header(s) + gz_stream *s; +{ + int method; /* method byte */ + int flags; /* flags byte */ + uInt len; + int c; + + /* Assure two bytes in the buffer so we can peek ahead -- handle case + where first byte of header is at the end of the buffer after the last + gzip segment */ + len = s->stream.avail_in; + if (len < 2) { + if (len) s->inbuf[0] = s->stream.next_in[0]; + errno = 0; + len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file); + if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO; + s->stream.avail_in += len; + s->stream.next_in = s->inbuf; + if (s->stream.avail_in < 2) { + s->transparent = s->stream.avail_in; + return; + } + } + + /* Peek ahead to check the gzip magic header */ + if (s->stream.next_in[0] != gz_magic[0] || + s->stream.next_in[1] != gz_magic[1]) { + s->transparent = 1; + return; + } + s->stream.avail_in -= 2; + s->stream.next_in += 2; + + /* Check the rest of the gzip header */ + method = get_byte(s); + flags = get_byte(s); + if (method != Z_DEFLATED || (flags & RESERVED) != 0) { + s->z_err = Z_DATA_ERROR; + return; + } + + /* Discard time, xflags and OS code: */ + for (len = 0; len < 6; len++) (void)get_byte(s); + + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ + len = (uInt)get_byte(s); + len += ((uInt)get_byte(s))<<8; + /* len is garbage if EOF but the loop below will quit anyway */ + while (len-- != 0 && get_byte(s) != EOF) ; + } + if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ + for (len = 0; len < 2; len++) (void)get_byte(s); + } + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; +} + + /* =========================================================================== + * Cleanup then free the given gz_stream. Return a zlib error code. + Try freeing in the reverse order of allocations. + */ +local int destroy (s) + gz_stream *s; +{ + int err = Z_OK; + + if (!s) return Z_STREAM_ERROR; + + TRYFREE(s->msg); + + if (s->stream.state != NULL) { + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + err = Z_STREAM_ERROR; +#else + err = deflateEnd(&(s->stream)); +#endif + } else if (s->mode == 'r') { + err = inflateEnd(&(s->stream)); + } + } + if (s->file != NULL && fclose(s->file)) { +#ifdef ESPIPE + if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ +#endif + err = Z_ERRNO; + } + if (s->z_err < 0) err = s->z_err; + + TRYFREE(s->inbuf); + TRYFREE(s->outbuf); + TRYFREE(s->path); + TRYFREE(s); + return err; +} + +/* =========================================================================== + Reads the given number of uncompressed bytes from the compressed file. + gzread returns the number of bytes actually read (0 for end of file). +*/ +int ZEXPORT gzread (file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + Bytef *start = (Bytef*)buf; /* starting point for crc computation */ + Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ + + if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; + + if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; + if (s->z_err == Z_STREAM_END) return 0; /* EOF */ + + next_out = (Byte*)buf; + s->stream.next_out = (Bytef*)buf; + s->stream.avail_out = len; + + if (s->stream.avail_out && s->back != EOF) { + *next_out++ = s->back; + s->stream.next_out++; + s->stream.avail_out--; + s->back = EOF; + s->out++; + start++; + if (s->last) { + s->z_err = Z_STREAM_END; + return 1; + } + } + + while (s->stream.avail_out != 0) { + + if (s->transparent) { + /* Copy first the lookahead bytes: */ + uInt n = s->stream.avail_in; + if (n > s->stream.avail_out) n = s->stream.avail_out; + if (n > 0) { + zmemcpy(s->stream.next_out, s->stream.next_in, n); + next_out += n; + s->stream.next_out = next_out; + s->stream.next_in += n; + s->stream.avail_out -= n; + s->stream.avail_in -= n; + } + if (s->stream.avail_out > 0) { + s->stream.avail_out -= + (uInt)fread(next_out, 1, s->stream.avail_out, s->file); + } + len -= s->stream.avail_out; + s->in += len; + s->out += len; + if (len == 0) s->z_eof = 1; + return (int)len; + } + if (s->stream.avail_in == 0 && !s->z_eof) { + + errno = 0; + s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (ferror(s->file)) { + s->z_err = Z_ERRNO; + break; + } + } + s->stream.next_in = s->inbuf; + } + s->in += s->stream.avail_in; + s->out += s->stream.avail_out; + s->z_err = inflate(&(s->stream), Z_NO_FLUSH); + s->in -= s->stream.avail_in; + s->out -= s->stream.avail_out; + + if (s->z_err == Z_STREAM_END) { + /* Check CRC and original size */ + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + start = s->stream.next_out; + + if (getLong(s) != s->crc) { + s->z_err = Z_DATA_ERROR; + } else { + (void)getLong(s); + /* The uncompressed length returned by above getlong() may be + * different from s->out in case of concatenated .gz files. + * Check for such files: + */ + check_header(s); + if (s->z_err == Z_OK) { + inflateReset(&(s->stream)); + s->crc = crc32(0L, Z_NULL, 0); + } + } + } + if (s->z_err != Z_OK || s->z_eof) break; + } + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + + if (len == s->stream.avail_out && + (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)) + return -1; + return (int)(len - s->stream.avail_out); +} + + +/* =========================================================================== + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ +int ZEXPORT gzgetc(file) + gzFile file; +{ + unsigned char c; + + return gzread(file, &c, 1) == 1 ? c : -1; +} + + +/* =========================================================================== + Push one byte back onto the stream. +*/ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF; + s->back = c; + s->out--; + s->last = (s->z_err == Z_STREAM_END); + if (s->last) s->z_err = Z_OK; + s->z_eof = 0; + return c; +} + + +/* =========================================================================== + Reads bytes from the compressed file until len-1 characters are + read, or a newline character is read and transferred to buf, or an + end-of-file condition is encountered. The string is then terminated + with a null character. + gzgets returns buf, or Z_NULL in case of error. + + The current implementation is not optimized at all. +*/ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + char *b = buf; + if (buf == Z_NULL || len <= 0) return Z_NULL; + + while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; + *buf = '\0'; + return b == buf && len > 0 ? Z_NULL : b; +} + + +#ifndef NO_GZCOMPRESS +/* =========================================================================== + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of bytes actually written (0 in case of error). +*/ +int ZEXPORT gzwrite (file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.next_in = (Bytef*)buf; + s->stream.avail_in = len; + + while (s->stream.avail_in != 0) { + + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + break; + } + s->stream.avail_out = Z_BUFSIZE; + } + s->in += s->stream.avail_in; + s->out += s->stream.avail_out; + s->z_err = deflate(&(s->stream), Z_NO_FLUSH); + s->in -= s->stream.avail_in; + s->out -= s->stream.avail_out; + if (s->z_err != Z_OK) break; + } + s->crc = crc32(s->crc, (const Bytef *)buf, len); + + return (int)(len - s->stream.avail_in); +} + + +/* =========================================================================== + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ +#ifdef STDC +#include <stdarg.h> + +int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) +{ + char buf[Z_PRINTF_BUFSIZE]; + va_list va; + int len; + + buf[sizeof(buf) - 1] = 0; + va_start(va, format); +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf(buf, format, va); + va_end(va); + for (len = 0; len < sizeof(buf); len++) + if (buf[len] == 0) break; +# else + len = vsprintf(buf, format, va); + va_end(va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf(buf, sizeof(buf), format, va); + va_end(va); + len = strlen(buf); +# else + len = vsnprintf(buf, sizeof(buf), format, va); + va_end(va); +# endif +#endif + if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0) + return 0; + return gzwrite(file, buf, (unsigned)len); +} +#else /* not ANSI C */ + +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + char buf[Z_PRINTF_BUFSIZE]; + int len; + + buf[sizeof(buf) - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < sizeof(buf); len++) + if (buf[len] == 0) break; +# else + len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(buf); +# else + len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#endif + if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0) + return 0; + return gzwrite(file, buf, len); +} +#endif + +/* =========================================================================== + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned char cc = (unsigned char) c; /* required for big endian systems */ + + return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; +} + + +/* =========================================================================== + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ +int ZEXPORT gzputs(file, s) + gzFile file; + const char *s; +{ + return gzwrite(file, (char*)s, (unsigned)strlen(s)); +} + + +/* =========================================================================== + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. +*/ +local int do_flush (file, flush) + gzFile file; + int flush; +{ + uInt len; + int done = 0; + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.avail_in = 0; /* should be zero already anyway */ + + for (;;) { + len = Z_BUFSIZE - s->stream.avail_out; + + if (len != 0) { + if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { + s->z_err = Z_ERRNO; + return Z_ERRNO; + } + s->stream.next_out = s->outbuf; + s->stream.avail_out = Z_BUFSIZE; + } + if (done) break; + s->out += s->stream.avail_out; + s->z_err = deflate(&(s->stream), flush); + s->out -= s->stream.avail_out; + + /* Ignore the second of two consecutive flushes: */ + if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; + + /* deflate has finished flushing only when it hasn't used up + * all the available space in the output buffer: + */ + done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); + + if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; + } + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} + +int ZEXPORT gzflush (file, flush) + gzFile file; + int flush; +{ + gz_stream *s = (gz_stream*)file; + int err = do_flush (file, flush); + + if (err) return err; + fflush(s->file); + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} +#endif /* NO_GZCOMPRESS */ + +/* =========================================================================== + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error. + SEEK_END is not implemented, returns error. + In this version of the library, gzseek can be extremely slow. +*/ +z_off_t ZEXPORT gzseek (file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || whence == SEEK_END || + s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { + return -1L; + } + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + return -1L; +#else + if (whence == SEEK_SET) { + offset -= s->in; + } + if (offset < 0) return -1L; + + /* At this point, offset is the number of zero bytes to write. */ + if (s->inbuf == Z_NULL) { + s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ + if (s->inbuf == Z_NULL) return -1L; + zmemzero(s->inbuf, Z_BUFSIZE); + } + while (offset > 0) { + uInt size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (uInt)offset; + + size = gzwrite(file, s->inbuf, size); + if (size == 0) return -1L; + + offset -= size; + } + return s->in; +#endif + } + /* Rest of function is for reading only */ + + /* compute absolute position */ + if (whence == SEEK_CUR) { + offset += s->out; + } + if (offset < 0) return -1L; + + if (s->transparent) { + /* map to fseek */ + s->back = EOF; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; + + s->in = s->out = offset; + return offset; + } + + /* For a negative seek, rewind and use positive seek */ + if (offset >= s->out) { + offset -= s->out; + } else if (gzrewind(file) < 0) { + return -1L; + } + /* offset is now the number of bytes to skip. */ + + if (offset != 0 && s->outbuf == Z_NULL) { + s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); + if (s->outbuf == Z_NULL) return -1L; + } + if (offset && s->back != EOF) { + s->back = EOF; + s->out++; + offset--; + if (s->last) s->z_err = Z_STREAM_END; + } + while (offset > 0) { + int size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (int)offset; + + size = gzread(file, s->outbuf, (uInt)size); + if (size <= 0) return -1L; + offset -= size; + } + return s->out; +} + +/* =========================================================================== + Rewinds input file. +*/ +int ZEXPORT gzrewind (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return -1; + + s->z_err = Z_OK; + s->z_eof = 0; + s->back = EOF; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + s->crc = crc32(0L, Z_NULL, 0); + if (!s->transparent) (void)inflateReset(&s->stream); + s->in = 0; + s->out = 0; + return fseek(s->file, s->start, SEEK_SET); +} + +/* =========================================================================== + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. +*/ +z_off_t ZEXPORT gztell (file) + gzFile file; +{ + return gzseek(file, 0L, SEEK_CUR); +} + +/* =========================================================================== + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ +int ZEXPORT gzeof (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + /* With concatenated compressed files that can have embedded + * crc trailers, z_eof is no longer the only/best indicator of EOF + * on a gz_stream. Handle end-of-stream error explicitly here. + */ + if (s == NULL || s->mode != 'r') return 0; + if (s->z_eof) return 1; + return s->z_err == Z_STREAM_END; +} + +/* =========================================================================== + Returns 1 if reading and doing so transparently, otherwise zero. +*/ +int ZEXPORT gzdirect (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return 0; + return s->transparent; +} + +/* =========================================================================== + Outputs a long in LSB order to the given file +*/ +local void putLong (file, x) + FILE *file; + uLong x; +{ + int n; + for (n = 0; n < 4; n++) { + fputc((int)(x & 0xff), file); + x >>= 8; + } +} + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets z_err in case + of error. +*/ +local uLong getLong (s) + gz_stream *s; +{ + uLong x = (uLong)get_byte(s); + int c; + + x += ((uLong)get_byte(s))<<8; + x += ((uLong)get_byte(s))<<16; + c = get_byte(s); + if (c == EOF) s->z_err = Z_DATA_ERROR; + x += ((uLong)c)<<24; + return x; +} + +/* =========================================================================== + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. +*/ +int ZEXPORT gzclose (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return Z_STREAM_ERROR; + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + return Z_STREAM_ERROR; +#else + if (do_flush (file, Z_FINISH) != Z_OK) + return destroy((gz_stream*)file); + + putLong (s->file, s->crc); + putLong (s->file, (uLong)(s->in & 0xffffffff)); +#endif + } + return destroy((gz_stream*)file); +} + +#ifdef STDC +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +/* =========================================================================== + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ +const char * ZEXPORT gzerror (file, errnum) + gzFile file; + int *errnum; +{ + char *m; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) { + *errnum = Z_STREAM_ERROR; + return (const char*)ERR_MSG(Z_STREAM_ERROR); + } + *errnum = s->z_err; + if (*errnum == Z_OK) return (const char*)""; + + m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); + + if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); + + TRYFREE(s->msg); + s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); + if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR); + strcpy(s->msg, s->path); + strcat(s->msg, ": "); + strcat(s->msg, m); + return (const char*)s->msg; +} + +/* =========================================================================== + Clear the error and end-of-file flags, and do the same for the real file. +*/ +void ZEXPORT gzclearerr (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return; + if (s->z_err != Z_STREAM_END) s->z_err = Z_OK; + s->z_eof = 0; + clearerr(s->file); +} diff --git a/compat/zlib/old/zlib.html b/compat/zlib/old/zlib.html new file mode 100644 index 0000000..8c1b190 --- /dev/null +++ b/compat/zlib/old/zlib.html @@ -0,0 +1,971 @@ +<html> +<head> + <title> + zlib general purpose compression library version 1.1.4 + </title> +</head> +<body bgcolor="White" text="Black" vlink="Red" alink="Navy" link="Red"> +<!-- background="zlibbg.gif" --> + +<h1> zlib 1.1.4 Manual </h1> +<hr> +<a name="Contents"><h2>Contents</h2> +<ol type="I"> +<li> <a href="#Prologue">Prologue</a> +<li> <a href="#Introduction">Introduction</a> +<li> <a href="#Utility functions">Utility functions</a> +<li> <a href="#Basic functions">Basic functions</a> +<li> <a href="#Advanced functions">Advanced functions</a> +<li> <a href="#Constants">Constants</a> +<li> <a href="#struct z_stream_s">struct z_stream_s</a> +<li> <a href="#Checksum functions">Checksum functions</a> +<li> <a href="#Misc">Misc</a> +</ol> +<hr> +<a name="Prologue"><h2> Prologue </h2> + 'zlib' general purpose compression library version 1.1.4, March 11th, 2002 + <p> + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler + <p> + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + <p> + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + <ol> + <li> The origin of this software must not be misrepresented ; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + <li> Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + <li> This notice may not be removed or altered from any source distribution. + </ol> + + <dl> + <dt>Jean-loup Gailly + <dd><a href="mailto:jloup@gzip.org">jloup@gzip.org</a> + <dt>Mark Adler + <dd><a href="mailto:madler@alumni.caltech.edu">madler@alumni.caltech.edu</a> + </dl> + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files + <a href="ftp://ds.internic.net/rfc/rfc1950.txt"> + ftp://ds.internic.net/rfc/rfc1950.txt </a> + (zlib format), + <a href="ftp://ds.internic.net/rfc/rfc1951.txt"> + rfc1951.txt </a> + (<a href="#deflate">deflate</a> format) and + <a href="ftp://ds.internic.net/rfc/rfc1952.txt"> + rfc1952.txt </a> + (gzip format). + <p> + This manual is converted from zlib.h by + <a href="mailto:piaip@csie.ntu.edu.tw"> piaip </a> + <p> + Visit <a href="http://ftp.cdrom.com/pub/infozip/zlib/"> + http://ftp.cdrom.com/pub/infozip/zlib/</a> + for the official zlib web page. + <p> + +<hr> +<a name="Introduction"><h2> Introduction </h2> + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + <p> + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + <p> + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio. + <p> + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. + <p> + +<hr> +<a name="Utility functions"><h2> Utility functions </h2> + The following utility functions are implemented on top of the + <a href="#Basic functions">basic stream-oriented functions</a>. + To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +<h3> Function list </h3> +<ul> +<li> int <a href="#compress">compress</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +<li> int <a href="#compress2">compress2</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level); +<li> int <a href="#uncompress">uncompress</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); +<li> typedef voidp gzFile; +<li> gzFile <a href="#gzopen">gzopen</a> (const char *path, const char *mode); +<li> gzFile <a href="#gzdopen">gzdopen</a> (int fd, const char *mode); +<li> int <a href="#gzsetparams">gzsetparams</a> (gzFile file, int level, int strategy); +<li> int <a href="#gzread">gzread</a> (gzFile file, voidp buf, unsigned len); +<li> int <a href="#gzwrite">gzwrite</a> (gzFile file, const voidp buf, unsigned len); +<li> int VA <a href="#gzprintf">gzprintf</a> (gzFile file, const char *format, ...); +<li> int <a href="#gzputs">gzputs</a> (gzFile file, const char *s); +<li> char * <a href="#gzgets">gzgets</a> (gzFile file, char *buf, int len); +<li> int <a href="#gzputc">gzputc</a> (gzFile file, int c); +<li> int <a href="#gzgetc">gzgetc</a> (gzFile file); +<li> int <a href="#gzflush">gzflush</a> (gzFile file, int flush); +<li> z_off_t <a href="#gzseek">gzseek</a> (gzFile file, z_off_t offset, int whence); +<li> z_off_t <a href="#gztell">gztell</a> (gzFile file); +<li> int <a href="#gzrewind">gzrewind</a> (gzFile file); +<li> int <a href="#gzeof">gzeof</a> (gzFile file); +<li> int <a href="#gzclose">gzclose</a> (gzFile file); +<li> const char * <a href="#gzerror">gzerror</a> (gzFile file, int *errnum); +</ul> +<h3> Function description </h3> +<dl> +<font color="Blue"><dt> int <a name="compress">compress</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);</font> +<dd> + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the + compressed buffer.<p> + This function can be used to <a href="#compress">compress</a> a whole file at once if the + input file is mmap'ed.<p> + <a href="#compress">compress</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not + enough memory, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if there was not enough room in the output + buffer.<p> + +<font color="Blue"><dt> int <a name="compress2">compress2</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level);</font> +<dd> + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in <a href="#deflateInit">deflateInit</a>. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + <p> + + <a href="#compress2">compress2</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not enough + memory, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if there was not enough room in the output buffer, + <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the level parameter is invalid. + <p> + +<font color="Blue"><dt> int <a name="uncompress">uncompress</a> (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);</font> +<dd> + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. <p> + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + <p> + + <a href="#uncompress">uncompress</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not + enough memory, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if there was not enough room in the output + buffer, or <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if the input data was corrupted. + <p> + +<dt> typedef voidp gzFile; +<dd> <p> + +<font color="Blue"><dt> gzFile <a name="gzopen">gzopen</a> (const char *path, const char *mode);</font> +<dd> + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h". (See the description + of <a href="#deflateInit2">deflateInit2</a> for more information about the strategy parameter.) + <p> + + <a href="#gzopen">gzopen</a> can be used to read a file which is not in gzip format ; in this + case <a href="#gzread">gzread</a> will directly read from the file without decompression. + <p> + + <a href="#gzopen">gzopen</a> returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression <a href="#state">state</a> ; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a>). + <p> + +<font color="Blue"><dt> gzFile <a name="gzdopen">gzdopen</a> (int fd, const char *mode);</font> +<dd> + <a href="#gzdopen">gzdopen</a>() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in <a href="#gzopen">gzopen</a>. + <p> + The next call of <a href="#gzclose">gzclose</a> on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use <a href="#gzdopen">gzdopen</a>(dup(fd), mode). + <p> + <a href="#gzdopen">gzdopen</a> returns NULL if there was insufficient memory to allocate + the (de)compression <a href="#state">state</a>. + <p> + +<font color="Blue"><dt> int <a name="gzsetparams">gzsetparams</a> (gzFile file, int level, int strategy);</font> +<dd> + Dynamically update the compression level or strategy. See the description + of <a href="#deflateInit2">deflateInit2</a> for the meaning of these parameters. + <p> + <a href="#gzsetparams">gzsetparams</a> returns <a href="#Z_OK">Z_OK</a> if success, or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the file was not + opened for writing. + <p> + +<font color="Blue"><dt> int <a name="gzread">gzread</a> (gzFile file, voidp buf, unsigned len);</font> +<dd> + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, <a href="#gzread">gzread</a> copies the given number + of bytes into the buffer. + <p> + <a href="#gzread">gzread</a> returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). + <p> + +<font color="Blue"><dt> int <a name="gzwrite">gzwrite</a> (gzFile file, const voidp buf, unsigned len);</font> +<dd> + Writes the given number of uncompressed bytes into the compressed file. + <a href="#gzwrite">gzwrite</a> returns the number of uncompressed bytes actually written + (0 in case of error). + <p> + +<font color="Blue"><dt> int VA <a name="gzprintf">gzprintf</a> (gzFile file, const char *format, ...);</font> +<dd> + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. <a href="#gzprintf">gzprintf</a> returns the number of + uncompressed bytes actually written (0 in case of error). + <p> + +<font color="Blue"><dt> int <a name="gzputs">gzputs</a> (gzFile file, const char *s);</font> +<dd> + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + <p> + <a href="#gzputs">gzputs</a> returns the number of characters written, or -1 in case of error. + <p> + +<font color="Blue"><dt> char * <a name="gzgets">gzgets</a> (gzFile file, char *buf, int len);</font> +<dd> + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + <p> + <a href="#gzgets">gzgets</a> returns buf, or <a href="#Z_NULL">Z_NULL</a> in case of error. + <p> + +<font color="Blue"><dt> int <a name="gzputc">gzputc</a> (gzFile file, int c);</font> +<dd> + Writes c, converted to an unsigned char, into the compressed file. + <a href="#gzputc">gzputc</a> returns the value that was written, or -1 in case of error. + <p> + +<font color="Blue"><dt> int <a name="gzgetc">gzgetc</a> (gzFile file);</font> +<dd> + Reads one byte from the compressed file. <a href="#gzgetc">gzgetc</a> returns this byte + or -1 in case of end of file or error. + <p> + +<font color="Blue"><dt> int <a name="gzflush">gzflush</a> (gzFile file, int flush);</font> +<dd> + Flushes all pending output into the compressed file. The parameter + flush is as in the <a href="#deflate">deflate</a>() function. The return value is the zlib + error number (see function <a href="#gzerror">gzerror</a> below). <a href="#gzflush">gzflush</a> returns <a href="#Z_OK">Z_OK</a> if + the flush parameter is <a href="#Z_FINISH">Z_FINISH</a> and all output could be flushed. + <p> + <a href="#gzflush">gzflush</a> should be called only when strictly necessary because it can + degrade compression. + <p> + +<font color="Blue"><dt> z_off_t <a name="gzseek">gzseek</a> (gzFile file, z_off_t offset, int whence);</font> +<dd> + Sets the starting position for the next <a href="#gzread">gzread</a> or <a href="#gzwrite">gzwrite</a> on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + <p> + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported ; <a href="#gzseek">gzseek</a> then compresses a sequence of zeroes up to the new + starting position. + <p> + <a href="#gzseek">gzseek</a> returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. + <p> + +<font color="Blue"><dt> int <a name="gzrewind">gzrewind</a> (gzFile file);</font> +<dd> + Rewinds the given file. This function is supported only for reading. + <p> + <a href="#gzrewind">gzrewind</a>(file) is equivalent to (int)<a href="#gzseek">gzseek</a>(file, 0L, SEEK_SET) + <p> + +<font color="Blue"><dt> z_off_t <a name="gztell">gztell</a> (gzFile file);</font> +<dd> + Returns the starting position for the next <a href="#gzread">gzread</a> or <a href="#gzwrite">gzwrite</a> on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + <p> + + <a href="#gztell">gztell</a>(file) is equivalent to <a href="#gzseek">gzseek</a>(file, 0L, SEEK_CUR) + <p> + +<font color="Blue"><dt> int <a name="gzeof">gzeof</a> (gzFile file);</font> +<dd> + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. + <p> + +<font color="Blue"><dt> int <a name="gzclose">gzclose</a> (gzFile file);</font> +<dd> + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression <a href="#state">state</a>. The return value is the zlib + error number (see function <a href="#gzerror">gzerror</a> below). + <p> + +<font color="Blue"><dt> const char * <a name="gzerror">gzerror</a> (gzFile file, int *errnum);</font> +<dd> + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to <a href="#Z_ERRNO">Z_ERRNO</a> and the application may consult errno + to get the exact error code. + <p> +</dl> +<hr> +<a name="Basic functions"><h2> Basic functions </h2> +<h3> Function list </h3> +<ul> +<li> const char * <a href="#zlibVersion">zlibVersion</a> (void); +<li> int <a href="#deflateInit">deflateInit</a> (<a href="#z_streamp">z_streamp</a> strm, int level); +<li> int <a href="#deflate">deflate</a> (<a href="#z_streamp">z_streamp</a> strm, int flush); +<li> int <a href="#deflateEnd">deflateEnd</a> (<a href="#z_streamp">z_streamp</a> strm); +<li> int <a href="#inflateInit">inflateInit</a> (<a href="#z_streamp">z_streamp</a> strm); +<li> int <a href="#inflate">inflate</a> (<a href="#z_streamp">z_streamp</a> strm, int flush); +<li> int <a href="#inflateEnd">inflateEnd</a> (<a href="#z_streamp">z_streamp</a> strm); +</ul> + +<h3> Function description </h3> +<dl> +<font color="Blue"><dt> const char * <a name="zlibVersion">zlibVersion</a> (void);</font> +<dd> The application can compare <a href="#zlibVersion">zlibVersion</a> and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by <a href="#deflateInit">deflateInit</a> and <a href="#inflateInit">inflateInit</a>. + <p> + +<font color="Blue"><dt> int <a name="deflateInit">deflateInit</a> (<a href="#z_streamp">z_streamp</a> strm, int level);</font> +<dd> + Initializes the internal stream <a href="#state">state</a> for compression. The fields + <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and <a href="#opaque">opaque</a> must be initialized before by the caller. + If <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> are set to <a href="#Z_NULL">Z_NULL</a>, <a href="#deflateInit">deflateInit</a> updates them to + use default allocation functions. + <p> + + The compression level must be <a href="#Z_DEFAULT_COMPRESSION">Z_DEFAULT_COMPRESSION</a>, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + <p> + + <a href="#Z_DEFAULT_COMPRESSION">Z_DEFAULT_COMPRESSION</a> requests a default compromise between speed and + compression (currently equivalent to level 6). + <p> + + <a href="#deflateInit">deflateInit</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not + enough memory, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if level is not a valid compression level, + <a href="#Z_VERSION_ERROR">Z_VERSION_ERROR</a> if the zlib library version (<a href="#zlib_version">zlib_version</a>) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + <a href="#msg">msg</a> is set to null if there is no error message. <a href="#deflateInit">deflateInit</a> does not + perform any compression: this will be done by <a href="#deflate">deflate</a>(). + <p> + +<font color="Blue"><dt> int <a name="deflate">deflate</a> (<a href="#z_streamp">z_streamp</a> strm, int flush);</font> +<dd> + <a href="#deflate">deflate</a> compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush.<p> + + The detailed semantics are as follows. <a href="#deflate">deflate</a> performs one or both of the + following actions: + + <ul> + <li> Compress more input starting at <a href="#next_in">next_in</a> and update <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a> + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a> are updated and + processing will resume at this point for the next call of <a href="#deflate">deflate</a>(). + + <li> + Provide more output starting at <a href="#next_out">next_out</a> and update <a href="#next_out">next_out</a> and <a href="#avail_out">avail_out</a> + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + </ul> <p> + + Before the call of <a href="#deflate">deflate</a>(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating <a href="#avail_in">avail_in</a> or <a href="#avail_out">avail_out</a> accordingly ; <a href="#avail_out">avail_out</a> + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (<a href="#avail_out">avail_out</a> == 0), or after each call of <a href="#deflate">deflate</a>(). If <a href="#deflate">deflate</a> returns <a href="#Z_OK">Z_OK</a> + and with zero <a href="#avail_out">avail_out</a>, it must be called again after making room in the + output buffer because there might be more output pending. + <p> + + If the parameter flush is set to <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a>, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + <a href="#avail_in">avail_in</a> is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + <p> + + If flush is set to <a href="#Z_FULL_FLUSH">Z_FULL_FLUSH</a>, all output is flushed as with + <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a>, and the compression <a href="#state">state</a> is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using <a href="#Z_FULL_FLUSH">Z_FULL_FLUSH</a> too often can seriously degrade + the compression. + <p> + + If <a href="#deflate">deflate</a> returns with <a href="#avail_out">avail_out</a> == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + <a href="#avail_out">avail_out</a>), until the flush is complete (<a href="#deflate">deflate</a> returns with non-zero + <a href="#avail_out">avail_out</a>). + <p> + + If the parameter flush is set to <a href="#Z_FINISH">Z_FINISH</a>, pending input is processed, + pending output is flushed and <a href="#deflate">deflate</a> returns with <a href="#Z_STREAM_END">Z_STREAM_END</a> if there + was enough output space ; if <a href="#deflate">deflate</a> returns with <a href="#Z_OK">Z_OK</a>, this function must be + called again with <a href="#Z_FINISH">Z_FINISH</a> and more output space (updated <a href="#avail_out">avail_out</a>) but no + more input data, until it returns with <a href="#Z_STREAM_END">Z_STREAM_END</a> or an error. After + <a href="#deflate">deflate</a> has returned <a href="#Z_STREAM_END">Z_STREAM_END</a>, the only possible operations on the + stream are <a href="#deflateReset">deflateReset</a> or <a href="#deflateEnd">deflateEnd</a>. + <p> + + <a href="#Z_FINISH">Z_FINISH</a> can be used immediately after <a href="#deflateInit">deflateInit</a> if all the compression + is to be done in a single step. In this case, <a href="#avail_out">avail_out</a> must be at least + 0.1% larger than <a href="#avail_in">avail_in</a> plus 12 bytes. If <a href="#deflate">deflate</a> does not return + <a href="#Z_STREAM_END">Z_STREAM_END</a>, then it must be called again as described above. + <p> + + <a href="#deflate">deflate</a>() sets strm-> <a href="#adler">adler</a> to the <a href="#adler32">adler32</a> checksum of all input read + so far (that is, <a href="#total_in">total_in</a> bytes). + <p> + + <a href="#deflate">deflate</a>() may update <a href="#data_type">data_type</a> if it can make a good guess about + the input data type (<a href="#Z_ASCII">Z_ASCII</a> or <a href="#Z_BINARY">Z_BINARY</a>). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + <p> + + <a href="#deflate">deflate</a>() returns <a href="#Z_OK">Z_OK</a> if some progress has been made (more input + processed or more output produced), <a href="#Z_STREAM_END">Z_STREAM_END</a> if all input has been + consumed and all output has been produced (only when flush is set to + <a href="#Z_FINISH">Z_FINISH</a>), <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the stream <a href="#state">state</a> was inconsistent (for example + if <a href="#next_in">next_in</a> or <a href="#next_out">next_out</a> was NULL), <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if no progress is possible + (for example <a href="#avail_in">avail_in</a> or <a href="#avail_out">avail_out</a> was zero). + <p> + +<font color="Blue"><dt> int <a name="deflateEnd">deflateEnd</a> (<a href="#z_streamp">z_streamp</a> strm);</font> +<dd> + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + <p> + + <a href="#deflateEnd">deflateEnd</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the + stream <a href="#state">state</a> was inconsistent, <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if the stream was freed + prematurely (some input or output was discarded). In the error case, + <a href="#msg">msg</a> may be set but then points to a static string (which must not be + deallocated). + <p> + +<font color="Blue"><dt> int <a name="inflateInit">inflateInit</a> (<a href="#z_streamp">z_streamp</a> strm);</font> +<dd> + Initializes the internal stream <a href="#state">state</a> for decompression. The fields + <a href="#next_in">next_in</a>, <a href="#avail_in">avail_in</a>, <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and <a href="#opaque">opaque</a> must be initialized before by + the caller. If <a href="#next_in">next_in</a> is not <a href="#Z_NULL">Z_NULL</a> and <a href="#avail_in">avail_in</a> is large enough (the exact + value depends on the compression method), <a href="#inflateInit">inflateInit</a> determines the + compression method from the zlib header and allocates all data structures + accordingly ; otherwise the allocation will be deferred to the first call of + <a href="#inflate">inflate</a>. If <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> are set to <a href="#Z_NULL">Z_NULL</a>, <a href="#inflateInit">inflateInit</a> updates them to + use default allocation functions. + <p> + + <a href="#inflateInit">inflateInit</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not enough + memory, <a href="#Z_VERSION_ERROR">Z_VERSION_ERROR</a> if the zlib library version is incompatible with the + version assumed by the caller. <a href="#msg">msg</a> is set to null if there is no error + message. <a href="#inflateInit">inflateInit</a> does not perform any decompression apart from reading + the zlib header if present: this will be done by <a href="#inflate">inflate</a>(). (So <a href="#next_in">next_in</a> and + <a href="#avail_in">avail_in</a> may be modified, but <a href="#next_out">next_out</a> and <a href="#avail_out">avail_out</a> are unchanged.) + <p> + +<font color="Blue"><dt> int <a name="inflate">inflate</a> (<a href="#z_streamp">z_streamp</a> strm, int flush);</font> +<dd> + <a href="#inflate">inflate</a> decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may some + introduce some output latency (reading input without producing any output) + except when forced to flush. + <p> + + The detailed semantics are as follows. <a href="#inflate">inflate</a> performs one or both of the + following actions: + + <ul> + <li> Decompress more input starting at <a href="#next_in">next_in</a> and update <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a> + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), <a href="#next_in">next_in</a> is updated and processing + will resume at this point for the next call of <a href="#inflate">inflate</a>(). + + <li> Provide more output starting at <a href="#next_out">next_out</a> and update <a href="#next_out">next_out</a> and + <a href="#avail_out">avail_out</a> accordingly. <a href="#inflate">inflate</a>() provides as much output as possible, + until there is no more input data or no more space in the output buffer + (see below about the flush parameter). + </ul> <p> + + Before the call of <a href="#inflate">inflate</a>(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (<a href="#avail_out">avail_out</a> == 0), or after each + call of <a href="#inflate">inflate</a>(). If <a href="#inflate">inflate</a> returns <a href="#Z_OK">Z_OK</a> and with zero <a href="#avail_out">avail_out</a>, it + must be called again after making room in the output buffer because there + might be more output pending. + <p> + + If the parameter flush is set to <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a>, <a href="#inflate">inflate</a> flushes as much + output as possible to the output buffer. The flushing behavior of <a href="#inflate">inflate</a> is + not specified for values of the flush parameter other than <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a> + and <a href="#Z_FINISH">Z_FINISH</a>, but the current implementation actually flushes as much output + as possible anyway. + <p> + + <a href="#inflate">inflate</a>() should normally be called until it returns <a href="#Z_STREAM_END">Z_STREAM_END</a> or an + error. However if all decompression is to be performed in a single step + (a single call of <a href="#inflate">inflate</a>), the parameter flush should be set to + <a href="#Z_FINISH">Z_FINISH</a>. In this case all pending input is processed and all pending + output is flushed ; <a href="#avail_out">avail_out</a> must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be <a href="#inflateEnd">inflateEnd</a> to deallocate the decompression <a href="#state">state</a>. The use of <a href="#Z_FINISH">Z_FINISH</a> + is never required, but can be used to inform <a href="#inflate">inflate</a> that a faster routine + may be used for the single <a href="#inflate">inflate</a>() call. + <p> + + If a preset dictionary is needed at this point (see <a href="#inflateSetDictionary">inflateSetDictionary</a> + below), <a href="#inflate">inflate</a> sets strm-<a href="#adler">adler</a> to the <a href="#adler32">adler32</a> checksum of the + dictionary chosen by the compressor and returns <a href="#Z_NEED_DICT">Z_NEED_DICT</a> ; otherwise + it sets strm-> <a href="#adler">adler</a> to the <a href="#adler32">adler32</a> checksum of all output produced + so far (that is, <a href="#total_out">total_out</a> bytes) and returns <a href="#Z_OK">Z_OK</a>, <a href="#Z_STREAM_END">Z_STREAM_END</a> or + an error code as described below. At the end of the stream, <a href="#inflate">inflate</a>() + checks that its computed <a href="#adler32">adler32</a> checksum is equal to that saved by the + compressor and returns <a href="#Z_STREAM_END">Z_STREAM_END</a> only if the checksum is correct. + <p> + + <a href="#inflate">inflate</a>() returns <a href="#Z_OK">Z_OK</a> if some progress has been made (more input processed + or more output produced), <a href="#Z_STREAM_END">Z_STREAM_END</a> if the end of the compressed data has + been reached and all uncompressed output has been produced, <a href="#Z_NEED_DICT">Z_NEED_DICT</a> if a + preset dictionary is needed at this point, <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if the input data was + corrupted (input stream not conforming to the zlib format or incorrect + <a href="#adler32">adler32</a> checksum), <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the stream structure was inconsistent + (for example if <a href="#next_in">next_in</a> or <a href="#next_out">next_out</a> was NULL), <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not + enough memory, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> if no progress is possible or if there was not + enough room in the output buffer when <a href="#Z_FINISH">Z_FINISH</a> is used. In the <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> + case, the application may then call <a href="#inflateSync">inflateSync</a> to look for a good + compression block. + <p> + +<font color="Blue"><dt> int <a name="inflateEnd">inflateEnd</a> (<a href="#z_streamp">z_streamp</a> strm);</font> +<dd> + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + <p> + + <a href="#inflateEnd">inflateEnd</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the stream <a href="#state">state</a> + was inconsistent. In the error case, <a href="#msg">msg</a> may be set but then points to a + static string (which must not be deallocated). +</dl> +<hr> +<a name="Advanced functions"><h2> Advanced functions </h2> + The following functions are needed only in some special applications. +<h3> Function list </h3> +<ul> +<li> int <a href="#deflateInit2">deflateInit2</a> (<a href="#z_streamp">z_streamp</a> strm, +<li> int <a href="#deflateSetDictionary">deflateSetDictionary</a> (<a href="#z_streamp">z_streamp</a> strm, const Bytef *dictionary, uInt dictLength); +<li> int <a href="#deflateCopy">deflateCopy</a> (<a href="#z_streamp">z_streamp</a> dest, <a href="#z_streamp">z_streamp</a> source); +<li> int <a href="#deflateReset">deflateReset</a> (<a href="#z_streamp">z_streamp</a> strm); +<li> int <a href="#deflateParams">deflateParams</a> (<a href="#z_streamp">z_streamp</a> strm, int level, int strategy); +<li> int <a href="#inflateInit2">inflateInit2</a> (<a href="#z_streamp">z_streamp</a> strm, int windowBits); +<li> int <a href="#inflateSetDictionary">inflateSetDictionary</a> (<a href="#z_streamp">z_streamp</a> strm, const Bytef *dictionary, uInt dictLength); +<li> int <a href="#inflateSync">inflateSync</a> (<a href="#z_streamp">z_streamp</a> strm); +<li> int <a href="#inflateReset">inflateReset</a> (<a href="#z_streamp">z_streamp</a> strm); + +</ul> +<h3> Function description </h3> +<dl> +<font color="Blue"><dt> int <a name="deflateInit2">deflateInit2</a> (<a href="#z_streamp">z_streamp</a> strm, int level, int method, int windowBits, int memLevel, int strategy);</font> + +<dd> This is another version of <a href="#deflateInit">deflateInit</a> with more compression options. The + fields <a href="#next_in">next_in</a>, <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and <a href="#opaque">opaque</a> must be initialized before by + the caller.<p> + + The method parameter is the compression method. It must be <a href="#Z_DEFLATED">Z_DEFLATED</a> in + this version of the library.<p> + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + <a href="#deflateInit">deflateInit</a> is used instead.<p> + + The memLevel parameter specifies how much memory should be allocated + for the internal compression <a href="#state">state</a>. memLevel=1 uses minimum memory but + is slow and reduces compression ratio ; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel.<p> + + The strategy parameter is used to tune the compression algorithm. Use the + value <a href="#Z_DEFAULT_STRATEGY">Z_DEFAULT_STRATEGY</a> for normal data, <a href="#Z_FILTERED">Z_FILTERED</a> for data produced by a + filter (or predictor), or <a href="#Z_HUFFMAN_ONLY">Z_HUFFMAN_ONLY</a> to force Huffman encoding only (no + string match). Filtered data consists mostly of small values with a + somewhat random distribution. In this case, the compression algorithm is + tuned to <a href="#compress">compress</a> them better. The effect of <a href="#Z_FILTERED">Z_FILTERED</a> is to force more + Huffman coding and less string matching ; it is somewhat intermediate + between Z_DEFAULT and <a href="#Z_HUFFMAN_ONLY">Z_HUFFMAN_ONLY</a>. The strategy parameter only affects + the compression ratio but not the correctness of the compressed output even + if it is not set appropriately.<p> + + <a href="#deflateInit2">deflateInit2</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not enough + memory, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if a parameter is invalid (such as an invalid + method). <a href="#msg">msg</a> is set to null if there is no error message. <a href="#deflateInit2">deflateInit2</a> does + not perform any compression: this will be done by <a href="#deflate">deflate</a>().<p> + +<font color="Blue"><dt> int <a name="deflateSetDictionary">deflateSetDictionary</a> (<a href="#z_streamp">z_streamp</a> strm, const Bytef *dictionary, uInt dictLength);</font> +<dd> + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after <a href="#deflateInit">deflateInit</a>, <a href="#deflateInit2">deflateInit2</a> or <a href="#deflateReset">deflateReset</a>, before any + call of <a href="#deflate">deflate</a>. The compressor and decompressor must use exactly the same + dictionary (see <a href="#inflateSetDictionary">inflateSetDictionary</a>).<p> + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy ; the data can then be compressed better than + with the default empty dictionary.<p> + + Depending on the size of the compression data structures selected by + <a href="#deflateInit">deflateInit</a> or <a href="#deflateInit2">deflateInit2</a>, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + <a href="#deflate">deflate</a> or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front.<p> + + Upon return of this function, strm-> <a href="#adler">adler</a> is set to the Adler32 value + of the dictionary ; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.)<p> + + <a href="#deflateSetDictionary">deflateSetDictionary</a> returns <a href="#Z_OK">Z_OK</a> if success, or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if a + parameter is invalid (such as NULL dictionary) or the stream <a href="#state">state</a> is + inconsistent (for example if <a href="#deflate">deflate</a> has already been called for this stream + or if the compression method is bsort). <a href="#deflateSetDictionary">deflateSetDictionary</a> does not + perform any compression: this will be done by <a href="#deflate">deflate</a>().<p> + +<font color="Blue"><dt> int <a name="deflateCopy">deflateCopy</a> (<a href="#z_streamp">z_streamp</a> dest, <a href="#z_streamp">z_streamp</a> source);</font> +<dd> + Sets the destination stream as a complete copy of the source stream.<p> + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling <a href="#deflateEnd">deflateEnd</a>. Note that <a href="#deflateCopy">deflateCopy</a> duplicates the internal + compression <a href="#state">state</a> which can be quite large, so this strategy is slow and + can consume lots of memory.<p> + + <a href="#deflateCopy">deflateCopy</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not + enough memory, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the source stream <a href="#state">state</a> was inconsistent + (such as <a href="#zalloc">zalloc</a> being NULL). <a href="#msg">msg</a> is left unchanged in both source and + destination.<p> + +<font color="Blue"><dt> int <a name="deflateReset">deflateReset</a> (<a href="#z_streamp">z_streamp</a> strm);</font> +<dd> This function is equivalent to <a href="#deflateEnd">deflateEnd</a> followed by <a href="#deflateInit">deflateInit</a>, + but does not free and reallocate all the internal compression <a href="#state">state</a>. + The stream will keep the same compression level and any other attributes + that may have been set by <a href="#deflateInit2">deflateInit2</a>.<p> + + <a href="#deflateReset">deflateReset</a> returns <a href="#Z_OK">Z_OK</a> if success, or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the source + stream <a href="#state">state</a> was inconsistent (such as <a href="#zalloc">zalloc</a> or <a href="#state">state</a> being NULL).<p> + +<font color="Blue"><dt> int <a name="deflateParams">deflateParams</a> (<a href="#z_streamp">z_streamp</a> strm, int level, int strategy);</font> +<dd> + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in <a href="#deflateInit2">deflateInit2</a>. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of <a href="#deflate">deflate</a>().<p> + + Before the call of <a href="#deflateParams">deflateParams</a>, the stream <a href="#state">state</a> must be set as for + a call of <a href="#deflate">deflate</a>(), since the currently available input may have to + be compressed and flushed. In particular, strm-> <a href="#avail_out">avail_out</a> must be + non-zero.<p> + + <a href="#deflateParams">deflateParams</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the source + stream <a href="#state">state</a> was inconsistent or if a parameter was invalid, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> + if strm->avail_out was zero.<p> + +<font color="Blue"><dt> int <a name="inflateInit2">inflateInit2</a> (<a href="#z_streamp">z_streamp</a> strm, int windowBits);</font> + +<dd> This is another version of <a href="#inflateInit">inflateInit</a> with an extra parameter. The + fields <a href="#next_in">next_in</a>, <a href="#avail_in">avail_in</a>, <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and <a href="#opaque">opaque</a> must be initialized + before by the caller.<p> + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if <a href="#inflateInit">inflateInit</a> is used + instead. If a compressed stream with a larger window size is given as + input, <a href="#inflate">inflate</a>() will return with the error code <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> instead of + trying to allocate a larger window.<p> + + <a href="#inflateInit2">inflateInit2</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_MEM_ERROR">Z_MEM_ERROR</a> if there was not enough + memory, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if a parameter is invalid (such as a negative + memLevel). <a href="#msg">msg</a> is set to null if there is no error message. <a href="#inflateInit2">inflateInit2</a> + does not perform any decompression apart from reading the zlib header if + present: this will be done by <a href="#inflate">inflate</a>(). (So <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a> may be + modified, but <a href="#next_out">next_out</a> and <a href="#avail_out">avail_out</a> are unchanged.)<p> + +<font color="Blue"><dt> int <a name="inflateSetDictionary">inflateSetDictionary</a> (<a href="#z_streamp">z_streamp</a> strm, const Bytef *dictionary, uInt dictLength);</font> +<dd> + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of <a href="#inflate">inflate</a> + if this call returned <a href="#Z_NEED_DICT">Z_NEED_DICT</a>. The dictionary chosen by the compressor + can be determined from the Adler32 value returned by this call of + <a href="#inflate">inflate</a>. The compressor and decompressor must use exactly the same + dictionary (see <a href="#deflateSetDictionary">deflateSetDictionary</a>).<p> + + <a href="#inflateSetDictionary">inflateSetDictionary</a> returns <a href="#Z_OK">Z_OK</a> if success, <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if a + parameter is invalid (such as NULL dictionary) or the stream <a href="#state">state</a> is + inconsistent, <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if the given dictionary doesn't match the + expected one (incorrect Adler32 value). <a href="#inflateSetDictionary">inflateSetDictionary</a> does not + perform any decompression: this will be done by subsequent calls of + <a href="#inflate">inflate</a>().<p> + +<font color="Blue"><dt> int <a name="inflateSync">inflateSync</a> (<a href="#z_streamp">z_streamp</a> strm);</font> + +<dd> Skips invalid compressed data until a full flush point (see above the + description of <a href="#deflate">deflate</a> with <a href="#Z_FULL_FLUSH">Z_FULL_FLUSH</a>) can be found, or until all + available input is skipped. No output is provided.<p> + + <a href="#inflateSync">inflateSync</a> returns <a href="#Z_OK">Z_OK</a> if a full flush point has been found, <a href="#Z_BUF_ERROR">Z_BUF_ERROR</a> + if no more input was provided, <a href="#Z_DATA_ERROR">Z_DATA_ERROR</a> if no flush point has been found, + or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the stream structure was inconsistent. In the success + case, the application may save the current current value of <a href="#total_in">total_in</a> which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call <a href="#inflateSync">inflateSync</a>, providing more input each time, + until success or end of the input data.<p> + +<font color="Blue"><dt> int <a name="inflateReset">inflateReset</a> (<a href="#z_streamp">z_streamp</a> strm);</font> +<dd> + This function is equivalent to <a href="#inflateEnd">inflateEnd</a> followed by <a href="#inflateInit">inflateInit</a>, + but does not free and reallocate all the internal decompression <a href="#state">state</a>. + The stream will keep attributes that may have been set by <a href="#inflateInit2">inflateInit2</a>. + <p> + + <a href="#inflateReset">inflateReset</a> returns <a href="#Z_OK">Z_OK</a> if success, or <a href="#Z_STREAM_ERROR">Z_STREAM_ERROR</a> if the source + stream <a href="#state">state</a> was inconsistent (such as <a href="#zalloc">zalloc</a> or <a href="#state">state</a> being NULL). + <p> +</dl> + +<hr> +<a name="Checksum functions"><h2> Checksum functions </h2> + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +<h3> Function list </h3> +<ul> +<li> uLong <a href="#adler32">adler32</a> (uLong <a href="#adler">adler</a>, const Bytef *buf, uInt len); +<li> uLong <a href="#crc32">crc32</a> (uLong crc, const Bytef *buf, uInt len); +</ul> +<h3> Function description </h3> +<dl> +<font color="Blue"><dt> uLong <a name="adler32">adler32</a> (uLong <a href="#adler">adler</a>, const Bytef *buf, uInt len);</font> +<dd> + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + <p> + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + <pre> + + uLong <a href="#adler">adler</a> = <a href="#adler32">adler32</a>(0L, <a href="#Z_NULL">Z_NULL</a>, 0); + + while (read_buffer(buffer, length) != EOF) { + <a href="#adler">adler</a> = <a href="#adler32">adler32</a>(<a href="#adler">adler</a>, buffer, length); + } + if (<a href="#adler">adler</a> != original_adler) error(); + </pre> + +<font color="Blue"><dt> uLong <a name="crc32">crc32</a> (uLong crc, const Bytef *buf, uInt len);</font> +<dd> + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: + <pre> + + uLong crc = <a href="#crc32">crc32</a>(0L, <a href="#Z_NULL">Z_NULL</a>, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = <a href="#crc32">crc32</a>(crc, buffer, length); + } + if (crc != original_crc) error(); + </pre> +</dl> +<hr> +<a name="struct z_stream_s"><h2> struct z_stream_s </h2> +<font color="Blue"> +<a name="z_stream_s"> +<pre> +typedef struct z_stream_s { + Bytef *<a name="next_in">next_in</a>; /* next input byte */ + uInt <a name="avail_in">avail_in</a>; /* number of bytes available at <a href="#next_in">next_in</a> */ + uLong <a name="total_in">total_in</a>; /* total nb of input bytes read so far */ + + Bytef *<a name="next_out">next_out</a>; /* next output byte should be put there */ + uInt <a name="avail_out">avail_out</a>; /* remaining free space at <a href="#next_out">next_out</a> */ + uLong <a name="total_out">total_out</a>; /* total nb of bytes output so far */ + + char *<a name="msg">msg</a>; /* last error message, NULL if no error */ + struct internal_state FAR *<a name="state">state</a>; /* not visible by applications */ + + alloc_func <a name="zalloc">zalloc</a>; /* used to allocate the internal <a href="#state">state</a> */ + free_func <a name="zfree">zfree</a>; /* used to free the internal <a href="#state">state</a> */ + voidpf <a name="opaque">opaque</a>; /* private data object passed to <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> */ + + int <a name="data_type">data_type</a>; /* best guess about the data type: ascii or binary */ + uLong <a name="adler">adler</a>; /* <a href="#adler32">adler32</a> value of the uncompressed data */ + uLong <a name="reserved">reserved</a>; /* <a href="#reserved">reserved</a> for future use */ +} <a href="#z_stream_s">z_stream</a> ; + +typedef <a href="#z_stream_s">z_stream</a> FAR * <a name="z_streamp">z_streamp</a>; ÿ +</pre> +</font> + The application must update <a href="#next_in">next_in</a> and <a href="#avail_in">avail_in</a> when <a href="#avail_in">avail_in</a> has + dropped to zero. It must update <a href="#next_out">next_out</a> and <a href="#avail_out">avail_out</a> when <a href="#avail_out">avail_out</a> + has dropped to zero. The application must initialize <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a> and + <a href="#opaque">opaque</a> before calling the init function. All other fields are set by the + compression library and must not be updated by the application. <p> + + The <a href="#opaque">opaque</a> value provided by the application will be passed as the first + parameter for calls of <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a>. This can be useful for custom + memory management. The compression library attaches no meaning to the + <a href="#opaque">opaque</a> value. <p> + + <a href="#zalloc">zalloc</a> must return <a href="#Z_NULL">Z_NULL</a> if there is not enough memory for the object. + If zlib is used in a multi-threaded application, <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> must be + thread safe. <p> + + On 16-bit systems, the functions <a href="#zalloc">zalloc</a> and <a href="#zfree">zfree</a> must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by <a href="#zalloc">zalloc</a> for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + <p> + + The fields <a href="#total_in">total_in</a> and <a href="#total_out">total_out</a> can be used for statistics or + progress reports. After compression, <a href="#total_in">total_in</a> holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). <p> + +<hr> +<a name="Constants"><h2> Constants </h2> +<font color="Blue"> +<pre> +#define <a name="Z_NO_FLUSH">Z_NO_FLUSH</a> 0 +#define <a name="Z_PARTIAL_FLUSH">Z_PARTIAL_FLUSH</a> 1 + /* will be removed, use <a href="#Z_SYNC_FLUSH">Z_SYNC_FLUSH</a> instead */ +#define <a name="Z_SYNC_FLUSH">Z_SYNC_FLUSH</a> 2 +#define <a name="Z_FULL_FLUSH">Z_FULL_FLUSH</a> 3 +#define <a name="Z_FINISH">Z_FINISH</a> 4 +/* Allowed flush values ; see <a href="#deflate">deflate</a>() below for details */ + +#define <a name="Z_OK">Z_OK</a> 0 +#define <a name="Z_STREAM_END">Z_STREAM_END</a> 1 +#define <a name="Z_NEED_DICT">Z_NEED_DICT</a> 2 +#define <a name="Z_ERRNO">Z_ERRNO</a> (-1) +#define <a name="Z_STREAM_ERROR">Z_STREAM_ERROR</a> (-2) +#define <a name="Z_DATA_ERROR">Z_DATA_ERROR</a> (-3) +#define <a name="Z_MEM_ERROR">Z_MEM_ERROR</a> (-4) +#define <a name="Z_BUF_ERROR">Z_BUF_ERROR</a> (-5) +#define <a name="Z_VERSION_ERROR">Z_VERSION_ERROR</a> (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define <a name="Z_NO_COMPRESSION">Z_NO_COMPRESSION</a> 0 +#define <a name="Z_BEST_SPEED">Z_BEST_SPEED</a> 1 +#define <a name="Z_BEST_COMPRESSION">Z_BEST_COMPRESSION</a> 9 +#define <a name="Z_DEFAULT_COMPRESSION">Z_DEFAULT_COMPRESSION</a> (-1) +/* compression levels */ + +#define <a name="Z_FILTERED">Z_FILTERED</a> 1 +#define <a name="Z_HUFFMAN_ONLY">Z_HUFFMAN_ONLY</a> 2 +#define <a name="Z_DEFAULT_STRATEGY">Z_DEFAULT_STRATEGY</a> 0 +/* compression strategy ; see <a href="#deflateInit2">deflateInit2</a>() below for details */ + +#define <a name="Z_BINARY">Z_BINARY</a> 0 +#define <a name="Z_ASCII">Z_ASCII</a> 1 +#define <a name="Z_UNKNOWN">Z_UNKNOWN</a> 2 +/* Possible values of the <a href="#data_type">data_type</a> field */ + +#define <a name="Z_DEFLATED">Z_DEFLATED</a> 8 +/* The <a href="#deflate">deflate</a> compression method (the only one supported in this version) */ + +#define <a name="Z_NULL">Z_NULL</a> 0 /* for initializing <a href="#zalloc">zalloc</a>, <a href="#zfree">zfree</a>, <a href="#opaque">opaque</a> */ + +#define <a name="zlib_version">zlib_version</a> <a href="#zlibVersion">zlibVersion</a>() +/* for compatibility with versions less than 1.0.2 */ +</pre> +</font> + +<hr> +<a name="Misc"><h2> Misc </h2> + <a href="#deflateInit">deflateInit</a> and <a href="#inflateInit">inflateInit</a> are macros to allow checking the zlib version + and the compiler's view of <a href="#z_stream_s">z_stream</a>. + <p> + Other functions: + <dl> + <font color="Blue"><dt> const char * <a name="zError">zError</a> (int err);</font> + <font color="Blue"><dt> int <a name="inflateSyncPoint">inflateSyncPoint</a> (<a href="#z_streamp">z_streamp</a> z);</font> + <font color="Blue"><dt> const uLongf * <a name="get_crc_table">get_crc_table</a> (void);</font> + </dl> + <hr> + <font size="-1"> + Last update: Wed Oct 13 20:42:34 1999<br> + piapi@csie.ntu.edu.tw + </font> + +</body> +</html> diff --git a/compat/zlib/projects/README.projects b/compat/zlib/projects/README.projects new file mode 100644 index 0000000..1c029e4 --- /dev/null +++ b/compat/zlib/projects/README.projects @@ -0,0 +1,41 @@ +This directory contains project files for building zlib under various +Integrated Development Environments (IDE). + +If you wish to submit a new project to this directory, you should comply +to the following requirements. Otherwise (e.g. if you wish to integrate +a custom piece of code that changes the zlib interface or its behavior), +please consider submitting the project to the contrib directory. + + +Requirements +============ + +- The project must build zlib using the source files from the official + zlib source distribution, exclusively. + +- If the project produces redistributable builds (e.g. shared objects + or DLL files), these builds must be compatible to those produced by + makefiles, if such makefiles exist in the zlib distribution. + In particular, if the project produces a DLL build for the Win32 + platform, this build must comply to the officially-ammended Win32 DLL + Application Binary Interface (ABI), described in win32/DLL_FAQ.txt. + +- The project may provide additional build targets, which depend on + 3rd-party (unofficially-supported) software, present in the contrib + directory. For example, it is possible to provide an "ASM build", + besides the officially-supported build, and have ASM source files + among its dependencies. + +- If there are significant differences between the project files created + by different versions of an IDE (e.g. Visual C++ 6.0 vs. 7.0), the name + of the project directory should contain the version number of the IDE + for which the project is intended (e.g. "visualc6" for Visual C++ 6.0, + or "visualc7" for Visual C++ 7.0 and 7.1). + + +Current projects +================ + +visualc6/ by Simon-Pierre Cadieux <methodex@methodex.ca> + and Cosmin Truta <cosmint@cs.ubbcluj.ro> + Project for Microsoft Visual C++ 6.0 diff --git a/compat/zlib/projects/visualc6/README.txt b/compat/zlib/projects/visualc6/README.txt new file mode 100644 index 0000000..3d0aef0 --- /dev/null +++ b/compat/zlib/projects/visualc6/README.txt @@ -0,0 +1,73 @@ +Microsoft Developer Studio Project Files, Format Version 6.00 for zlib. + +Copyright (C) 2000-2004 Simon-Pierre Cadieux. +Copyright (C) 2004 Cosmin Truta. +For conditions of distribution and use, see copyright notice in zlib.h. + + +This project builds the zlib binaries as follows: + +* Win32_DLL_Release\zlib1.dll DLL build +* Win32_DLL_Debug\zlib1d.dll DLL build (debug version) +* Win32_DLL_ASM_Release\zlib1.dll DLL build using ASM code +* Win32_DLL_ASM_Debug\zlib1d.dll DLL build using ASM code (debug version) +* Win32_LIB_Release\zlib.lib static build +* Win32_LIB_Debug\zlibd.lib static build (debug version) +* Win32_LIB_ASM_Release\zlib.lib static build using ASM code +* Win32_LIB_ASM_Debug\zlibd.lib static build using ASM code (debug version) + + +For more information regarding the DLL builds, please see the DLL FAQ +in ..\..\win32\DLL_FAQ.txt. + + +To build and test: + +1) On the main menu, select "File | Open Workspace". + Open "zlib.dsw". + +2) Select "Build | Set Active Configuration". + Choose the configuration you wish to build. + +3) Select "Build | Clean". + +4) Select "Build | Build ... (F7)". Ignore warning messages about + not being able to find certain include files (e.g. alloc.h). + +5) If you built one of the sample programs (example or minigzip), + select "Build | Execute ... (Ctrl+F5)". + + +To use: + +1) Select "Project | Settings (Alt+F7)". + Make note of the configuration names used in your project. + Usually, these names are "Win32 Release" and "Win32 Debug". + +2) In the Workspace window, select the "FileView" tab. + Right-click on the root item "Workspace '...'". + Select "Insert Project into Workspace". + Switch on the checkbox "Dependency of:", and select the name + of your project. Open "zlib.dsp". + +3) Select "Build | Configurations". + For each configuration of your project: + 3.1) Choose the zlib configuration you wish to use. + 3.2) Click on "Add". + 3.3) Set the new zlib configuration name to the name used by + the configuration from the current iteration. + +4) Select "Build | Set Active Configuration". + Choose the configuration you wish to build. + +5) Select "Build | Build ... (F7)". + +6) If you built an executable program, select + "Build | Execute ... (Ctrl+F5)". + + +Note: + +To build the ASM-enabled code, you need Microsoft Assembler +(ML.EXE). You can get it by downloading and installing the +latest Processor Pack for Visual C++ 6.0. diff --git a/compat/zlib/projects/visualc6/example.dsp b/compat/zlib/projects/visualc6/example.dsp new file mode 100644 index 0000000..2599efd --- /dev/null +++ b/compat/zlib/projects/visualc6/example.dsp @@ -0,0 +1,278 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=example - Win32 LIB Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 LIB Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example - Win32 DLL ASM Release" (based on "Win32 (x86) Console Application") +!MESSAGE "example - Win32 DLL ASM Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "example - Win32 DLL Release" (based on "Win32 (x86) Console Application") +!MESSAGE "example - Win32 DLL Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "example - Win32 LIB ASM Release" (based on "Win32 (x86) Console Application") +!MESSAGE "example - Win32 LIB ASM Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "example - Win32 LIB Release" (based on "Win32 (x86) Console Application") +!MESSAGE "example - Win32 LIB Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example - Win32 DLL ASM Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "example___Win32_DLL_ASM_Release" +# PROP BASE Intermediate_Dir "example___Win32_DLL_ASM_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_DLL_ASM_Release" +# PROP Intermediate_Dir "Win32_DLL_ASM_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "example - Win32 DLL ASM Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "example___Win32_DLL_ASM_Debug" +# PROP BASE Intermediate_Dir "example___Win32_DLL_ASM_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_DLL_ASM_Debug" +# PROP Intermediate_Dir "Win32_DLL_ASM_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ELSEIF "$(CFG)" == "example - Win32 DLL Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "example___Win32_DLL_Release" +# PROP BASE Intermediate_Dir "example___Win32_DLL_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_DLL_Release" +# PROP Intermediate_Dir "Win32_DLL_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "example - Win32 DLL Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "example___Win32_DLL_Debug" +# PROP BASE Intermediate_Dir "example___Win32_DLL_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_DLL_Debug" +# PROP Intermediate_Dir "Win32_DLL_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ELSEIF "$(CFG)" == "example - Win32 LIB ASM Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "example___Win32_LIB_ASM_Release" +# PROP BASE Intermediate_Dir "example___Win32_LIB_ASM_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_LIB_ASM_Release" +# PROP Intermediate_Dir "Win32_LIB_ASM_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "example - Win32 LIB ASM Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "example___Win32_LIB_ASM_Debug" +# PROP BASE Intermediate_Dir "example___Win32_LIB_ASM_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_LIB_ASM_Debug" +# PROP Intermediate_Dir "Win32_LIB_ASM_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ELSEIF "$(CFG)" == "example - Win32 LIB Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "example___Win32_LIB_Release" +# PROP BASE Intermediate_Dir "example___Win32_LIB_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_LIB_Release" +# PROP Intermediate_Dir "Win32_LIB_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "example - Win32 LIB Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "example___Win32_LIB_Debug" +# PROP BASE Intermediate_Dir "example___Win32_LIB_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_LIB_Debug" +# PROP Intermediate_Dir "Win32_LIB_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "example - Win32 DLL ASM Release" +# Name "example - Win32 DLL ASM Debug" +# Name "example - Win32 DLL Release" +# Name "example - Win32 DLL Debug" +# Name "example - Win32 LIB ASM Release" +# Name "example - Win32 LIB ASM Debug" +# Name "example - Win32 LIB Release" +# Name "example - Win32 LIB Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\example.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\zconf.h +# End Source File +# Begin Source File + +SOURCE=..\..\zlib.h +# End Source File +# End Group +# End Target +# End Project diff --git a/compat/zlib/projects/visualc6/minigzip.dsp b/compat/zlib/projects/visualc6/minigzip.dsp new file mode 100644 index 0000000..941582b --- /dev/null +++ b/compat/zlib/projects/visualc6/minigzip.dsp @@ -0,0 +1,278 @@ +# Microsoft Developer Studio Project File - Name="minigzip" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=minigzip - Win32 LIB Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "minigzip.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "minigzip.mak" CFG="minigzip - Win32 LIB Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "minigzip - Win32 DLL ASM Release" (based on "Win32 (x86) Console Application") +!MESSAGE "minigzip - Win32 DLL ASM Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "minigzip - Win32 DLL Release" (based on "Win32 (x86) Console Application") +!MESSAGE "minigzip - Win32 DLL Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "minigzip - Win32 LIB ASM Release" (based on "Win32 (x86) Console Application") +!MESSAGE "minigzip - Win32 LIB ASM Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "minigzip - Win32 LIB Release" (based on "Win32 (x86) Console Application") +!MESSAGE "minigzip - Win32 LIB Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "minigzip - Win32 DLL ASM Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "minigzip___Win32_DLL_ASM_Release" +# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_ASM_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_DLL_ASM_Release" +# PROP Intermediate_Dir "Win32_DLL_ASM_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "minigzip - Win32 DLL ASM Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "minigzip___Win32_DLL_ASM_Debug" +# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_ASM_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_DLL_ASM_Debug" +# PROP Intermediate_Dir "Win32_DLL_ASM_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ELSEIF "$(CFG)" == "minigzip - Win32 DLL Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "minigzip___Win32_DLL_Release" +# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_DLL_Release" +# PROP Intermediate_Dir "Win32_DLL_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "minigzip - Win32 DLL Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "minigzip___Win32_DLL_Debug" +# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_DLL_Debug" +# PROP Intermediate_Dir "Win32_DLL_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ELSEIF "$(CFG)" == "minigzip - Win32 LIB ASM Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "minigzip___Win32_LIB_ASM_Release" +# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_ASM_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_LIB_ASM_Release" +# PROP Intermediate_Dir "Win32_LIB_ASM_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "minigzip - Win32 LIB ASM Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "minigzip___Win32_LIB_ASM_Debug" +# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_ASM_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_LIB_ASM_Debug" +# PROP Intermediate_Dir "Win32_LIB_ASM_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ELSEIF "$(CFG)" == "minigzip - Win32 LIB Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "minigzip___Win32_LIB_Release" +# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_LIB_Release" +# PROP Intermediate_Dir "Win32_LIB_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "minigzip - Win32 LIB Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "minigzip___Win32_LIB_Debug" +# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_LIB_Debug" +# PROP Intermediate_Dir "Win32_LIB_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "minigzip - Win32 DLL ASM Release" +# Name "minigzip - Win32 DLL ASM Debug" +# Name "minigzip - Win32 DLL Release" +# Name "minigzip - Win32 DLL Debug" +# Name "minigzip - Win32 LIB ASM Release" +# Name "minigzip - Win32 LIB ASM Debug" +# Name "minigzip - Win32 LIB Release" +# Name "minigzip - Win32 LIB Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\minigzip.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\zconf.h +# End Source File +# Begin Source File + +SOURCE=..\..\zlib.h +# End Source File +# End Group +# End Target +# End Project diff --git a/compat/zlib/projects/visualc6/zlib.dsp b/compat/zlib/projects/visualc6/zlib.dsp new file mode 100644 index 0000000..34f1f30 --- /dev/null +++ b/compat/zlib/projects/visualc6/zlib.dsp @@ -0,0 +1,621 @@ +# Microsoft Developer Studio Project File - Name="zlib" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=zlib - Win32 LIB Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "zlib.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "zlib.mak" CFG="zlib - Win32 LIB Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "zlib - Win32 DLL ASM Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlib - Win32 DLL ASM Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlib - Win32 DLL Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlib - Win32 DLL Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlib - Win32 LIB ASM Release" (based on "Win32 (x86) Static Library") +!MESSAGE "zlib - Win32 LIB ASM Debug" (based on "Win32 (x86) Static Library") +!MESSAGE "zlib - Win32 LIB Release" (based on "Win32 (x86) Static Library") +!MESSAGE "zlib - Win32 LIB Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "zlib - Win32 DLL ASM Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlib___Win32_DLL_ASM_Release" +# PROP BASE Intermediate_Dir "zlib___Win32_DLL_ASM_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_DLL_ASM_Release" +# PROP Intermediate_Dir "Win32_DLL_ASM_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /D "ASMV" /D "ASMINF" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 /nologo /dll /machine:I386 /out:"Win32_DLL_ASM_Release\zlib1.dll" + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "zlib___Win32_DLL_ASM_Debug" +# PROP BASE Intermediate_Dir "zlib___Win32_DLL_ASM_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_DLL_ASM_Debug" +# PROP Intermediate_Dir "Win32_DLL_ASM_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /D "ASMV" /D "ASMINF" /FR /FD /GZ /c +# SUBTRACT CPP /YX /Yc /Yu +MTL=midl.exe +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Win32_DLL_ASM_Debug\zlib1d.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlib___Win32_DLL_Release" +# PROP BASE Intermediate_Dir "zlib___Win32_DLL_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_DLL_Release" +# PROP Intermediate_Dir "Win32_DLL_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 /nologo /dll /machine:I386 /out:"Win32_DLL_Release\zlib1.dll" + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "zlib___Win32_DLL_Debug" +# PROP BASE Intermediate_Dir "zlib___Win32_DLL_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_DLL_Debug" +# PROP Intermediate_Dir "Win32_DLL_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c +# SUBTRACT CPP /YX /Yc /Yu +MTL=midl.exe +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Win32_DLL_Debug\zlib1d.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlib___Win32_LIB_ASM_Release" +# PROP BASE Intermediate_Dir "zlib___Win32_LIB_ASM_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_LIB_ASM_Release" +# PROP Intermediate_Dir "Win32_LIB_ASM_Release" +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /D "ASMV" /D "ASMINF" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "zlib___Win32_LIB_ASM_Debug" +# PROP BASE Intermediate_Dir "zlib___Win32_LIB_ASM_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_LIB_ASM_Debug" +# PROP Intermediate_Dir "Win32_LIB_ASM_Debug" +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /D "ASMV" /D "ASMINF" /FR /FD /GZ /c +# SUBTRACT CPP /YX /Yc /Yu +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"Win32_LIB_ASM_Debug\zlibd.lib" + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlib___Win32_LIB_Release" +# PROP BASE Intermediate_Dir "zlib___Win32_LIB_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_LIB_Release" +# PROP Intermediate_Dir "Win32_LIB_Release" +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "zlib___Win32_LIB_Debug" +# PROP BASE Intermediate_Dir "zlib___Win32_LIB_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_LIB_Debug" +# PROP Intermediate_Dir "Win32_LIB_Debug" +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "_DEBUG" /FR /FD /GZ /c +# SUBTRACT CPP /YX /Yc /Yu +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"Win32_LIB_Debug\zlibd.lib" + +!ENDIF + +# Begin Target + +# Name "zlib - Win32 DLL ASM Release" +# Name "zlib - Win32 DLL ASM Debug" +# Name "zlib - Win32 DLL Release" +# Name "zlib - Win32 DLL Debug" +# Name "zlib - Win32 LIB ASM Release" +# Name "zlib - Win32 LIB ASM Debug" +# Name "zlib - Win32 LIB Release" +# Name "zlib - Win32 LIB Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\adler32.c +# End Source File +# Begin Source File + +SOURCE=..\..\compress.c +# End Source File +# Begin Source File + +SOURCE=..\..\crc32.c +# End Source File +# Begin Source File + +SOURCE=..\..\deflate.c +# End Source File +# Begin Source File + +SOURCE=..\..\gzclose.c +# End Source File +# Begin Source File + +SOURCE=..\..\gzlib.c +# End Source File +# Begin Source File + +SOURCE=..\..\gzread.c +# End Source File +# Begin Source File + +SOURCE=..\..\gzwrite.c +# End Source File +# Begin Source File + +SOURCE=..\..\infback.c +# End Source File +# Begin Source File + +SOURCE=..\..\inffast.c +# End Source File +# Begin Source File + +SOURCE=..\..\inflate.c +# End Source File +# Begin Source File + +SOURCE=..\..\inftrees.c +# End Source File +# Begin Source File + +SOURCE=..\..\trees.c +# End Source File +# Begin Source File + +SOURCE=..\..\uncompr.c +# End Source File +# Begin Source File + +SOURCE=..\..\win32\zlib.def + +!IF "$(CFG)" == "zlib - Win32 DLL ASM Release" + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug" + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL Release" + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug" + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\zutil.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\crc32.h +# End Source File +# Begin Source File + +SOURCE=..\..\deflate.h +# End Source File +# Begin Source File + +SOURCE=..\..\inffast.h +# End Source File +# Begin Source File + +SOURCE=..\..\inffixed.h +# End Source File +# Begin Source File + +SOURCE=..\..\inflate.h +# End Source File +# Begin Source File + +SOURCE=..\..\inftrees.h +# End Source File +# Begin Source File + +SOURCE=..\..\trees.h +# End Source File +# Begin Source File + +SOURCE=..\..\zconf.h +# End Source File +# Begin Source File + +SOURCE=..\..\zlib.h +# End Source File +# Begin Source File + +SOURCE=..\..\zutil.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=..\..\win32\zlib1.rc +# End Source File +# End Group +# Begin Group "Assembler Files (Unsupported)" + +# PROP Default_Filter "asm;obj;c;cpp;cxx;h;hpp;hxx" +# Begin Source File + +SOURCE=..\..\contrib\masmx86\gvmat32.asm + +!IF "$(CFG)" == "zlib - Win32 DLL ASM Release" + +# Begin Custom Build - Assembling... +IntDir=.\Win32_DLL_ASM_Release +InputPath=..\..\contrib\masmx86\gvmat32.asm +InputName=gvmat32 + +"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)" + +# End Custom Build + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug" + +# Begin Custom Build - Assembling... +IntDir=.\Win32_DLL_ASM_Debug +InputPath=..\..\contrib\masmx86\gvmat32.asm +InputName=gvmat32 + +"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)" + +# End Custom Build + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release" + +# Begin Custom Build - Assembling... +IntDir=.\Win32_LIB_ASM_Release +InputPath=..\..\contrib\masmx86\gvmat32.asm +InputName=gvmat32 + +"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)" + +# End Custom Build + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug" + +# Begin Custom Build - Assembling... +IntDir=.\Win32_LIB_ASM_Debug +InputPath=..\..\contrib\masmx86\gvmat32.asm +InputName=gvmat32 + +"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)" + +# End Custom Build + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\contrib\masmx86\gvmat32c.c + +!IF "$(CFG)" == "zlib - Win32 DLL ASM Release" + +# ADD CPP /I "..\.." + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug" + +# ADD CPP /I "..\.." + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL Release" + +# PROP Exclude_From_Build 1 +# ADD CPP /I "..\.." + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug" + +# PROP Exclude_From_Build 1 +# ADD CPP /I "..\.." + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release" + +# ADD CPP /I "..\.." + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug" + +# ADD CPP /I "..\.." + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release" + +# PROP Exclude_From_Build 1 +# ADD CPP /I "..\.." + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug" + +# PROP Exclude_From_Build 1 +# ADD CPP /I "..\.." + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\contrib\masmx86\inffas32.asm + +!IF "$(CFG)" == "zlib - Win32 DLL ASM Release" + +# Begin Custom Build - Assembling... +IntDir=.\Win32_DLL_ASM_Release +InputPath=..\..\contrib\masmx86\inffas32.asm +InputName=inffas32 + +"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)" + +# End Custom Build + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug" + +# Begin Custom Build - Assembling... +IntDir=.\Win32_DLL_ASM_Debug +InputPath=..\..\contrib\masmx86\inffas32.asm +InputName=inffas32 + +"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)" + +# End Custom Build + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release" + +# Begin Custom Build - Assembling... +IntDir=.\Win32_LIB_ASM_Release +InputPath=..\..\contrib\masmx86\inffas32.asm +InputName=inffas32 + +"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)" + +# End Custom Build + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug" + +# Begin Custom Build - Assembling... +IntDir=.\Win32_LIB_ASM_Debug +InputPath=..\..\contrib\masmx86\inffas32.asm +InputName=inffas32 + +"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)" + +# End Custom Build + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# End Group +# Begin Source File + +SOURCE=.\README.txt +# End Source File +# End Target +# End Project diff --git a/compat/zlib/projects/visualc6/zlib.dsw b/compat/zlib/projects/visualc6/zlib.dsw new file mode 100644 index 0000000..2644856 --- /dev/null +++ b/compat/zlib/projects/visualc6/zlib.dsw @@ -0,0 +1,59 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "example"=.\example.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name zlib + End Project Dependency +}}} + +############################################################################### + +Project: "minigzip"=.\minigzip.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name zlib + End Project Dependency +}}} + +############################################################################### + +Project: "zlib"=.\zlib.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/compat/zlib/zconf.in.h b/compat/zlib/zconf.in.h new file mode 100644 index 0000000..49595cc --- /dev/null +++ b/compat/zlib/zconf.in.h @@ -0,0 +1,332 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2005 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: zconf.in.h,v 1.1 2008/12/18 14:14:59 dkf Exp $ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define deflatePrime z_deflatePrime +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table +# define zError z_zError + +# define alloc_func z_alloc_func +# define free_func z_free_func +# define in_func z_in_func +# define out_func z_out_func +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include <windows.h> + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include <sys/types.h> /* for off_t */ +# include <unistd.h> /* for SEEK_* and off_t */ +# ifdef VMS +# include <unixio.h> /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/doc/Macintosh.3 b/doc/Macintosh.3 new file mode 100644 index 0000000..8bedd30 --- /dev/null +++ b/doc/Macintosh.3 @@ -0,0 +1,111 @@ +'\" +'\" Copyright (c) 1997-1998 Sun Microsystems, Inc. +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +'\" RCS: @(#) $Id: Macintosh.3,v 1.5 2003/07/18 16:56:41 dgp Exp $ +'\" +.so man.macros +.TH Tcl_MacSetEventProc 3 "8.1" Tcl "Tcl Library Procedures" +.BS +.SH NAME +Tcl_MacSetEventProc, Tcl_MacConvertTextResource, Tcl_MacEvalResource, Tcl_MacFindResource, Tcl_GetOSTypeFromObj, Tcl_SetOSTypeObj, Tcl_NewOSTypeObj \- procedures to handle Macintosh resources and other Macintosh specifics +.SH SYNOPSIS +.nf +\fB#include <tcl.h>\fR +.sp +int +\fBTcl_MacEvalResource\fR(\fIinterp, resourceName, resourceNumber, fileName\fR) +.sp +char* +\fBTcl_MacConvertTextResource\fR(\fIresource\fR) +.sp +Handle +\fBTcl_MacFindResource\fR(\fIinterp, resourceType, resourceName, resourceNumber, resFileRef, releaseIt\fR) +.sp +Tcl_Obj* +\fBTcl_NewOSTypeObj\fR(\fInewOSType\fR) +.sp +void +\fBTcl_SetOSTypeObj\fR(\fIobjPtr, newOSType\fR) +.sp +int +\fBTcl_GetOSTypeFromObj\fR(\fIinterp, objPtr, osTypePtr\fR) +.sp +void +\fBTcl_MacSetEventProc\fR(\fIprocPtr\fR) +.SH ARGUMENTS +.AP Tcl_Interp *interp in +Interpreter to use for error reporting, or NULL if no error reporting is +desired. +.AP "CONST char" *resourceName in +Name of TEXT resource to source, NULL if number should be used. +.AP int resourceNumber in +Resource id of source. +.AP "CONST char" *fileName in +Name of file to process. NULL if application resource. +.AP Handle resource in +Handle to TEXT resource. +.AP long resourceType in +Type of resource to load. +.AP "CONST char" *resFileRef in +Registered resource file reference, NULL if searching all open resource files. +.AP int *releaseIt out +Should we release this resource when done. +.AP int newOSType in +Int used to initialize the new object or set the object's value. +.AP Tcl_Obj *objPtr in +Object whose internal representation is to be set or retrieved. +.AP osTypePtr out +Place to store the resulting integer. +.AP Tcl_MacConvertEventPtr procPtr in +Reference to the new function to handle all incoming Mac events. + +.BE +.SH INTRODUCTION +.PP +The described routines are used to implement the Macintosh specific +\fBresource\fR command and the Mac specific notifier.. They manipulate +or use Macintosh resources and provide administration for open +resource file references. + +.SH DESCRIPTION +.PP +\fBTcl_MacEvalResource\fR extends the \fBsource\fR command to +Macintosh resources. It sources Tcl code from a Text resource. +Currently only sources the resource by name, file IDs may be supported +at a later date. +.PP +\fBTcl_MacConvertTextResource\fR converts a TEXT resource into a Tcl +suitable string. It mallocs the returned memory, converts ``\\r'' to +``\\n'', and appends a null. The caller has the responsibility for +freeing the memory. +.PP +\fBTcl_MacFindResource\fR provides a higher level interface for +loading resources. It is used by \fBresource read\fR. +.PP +\fBTcl_NewOSTypeObj\fR is used to create a new resource name type +object. The object type is "ostype". +.PP +\fBTcl_SetOSTypeObj\fR modifies an object to be a resource type and to +have the specified long value. +.PP +\fBTcl_GetOSTypeFromObj\fR attempts to return an int from the Tcl +object "objPtr". If the object is not already an int, an attempt will +be made to convert it to one. +.PP +\fBTcl_MacSetEventProc\fR sets the event handling procedure for the +application. This function will be passed all incoming Mac events. +This function usually controls the console or some other entity like +Tk. + +.SH RESOURCE TYPES +.PP +Resource types are 4-byte values used by the macintosh resource +facility to tag parts of the resource fork in a file so that the OS +knows how to handle them. As all 4 bytes are restricted to printable +characters such a type can be interpreted as a 4 character string too. + +.SH KEYWORDS +macintosh, mac, resource, notifier diff --git a/doc/resource.n b/doc/resource.n new file mode 100644 index 0000000..8be83da --- /dev/null +++ b/doc/resource.n @@ -0,0 +1,155 @@ +'\" +'\" Copyright (c) 1997 Sun Microsystems, Inc. +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" RCS: @(#) $Id: resource.n,v 1.7 2002/07/01 18:24:39 jenglish Exp $ +'\" +.so man.macros +.TH resource n 8.0 Tcl "Tcl Built-In Commands" +.BS +'\" Note: do not modify the .SH NAME line immediately below! +.SH NAME +resource \- Manipulate Macintosh resources +.SH SYNOPSIS +\fBresource \fIoption\fR ?\fIarg arg ...\fR? +.BE + +.SH DESCRIPTION +.PP +The \fBresource\fR command provides some generic operations for +dealing with Macintosh resources. This command is only supported on +the Macintosh platform. Each Macintosh file consists of two +\fIforks\fR: a \fIdata\fR fork and a \fIresource\fR fork. You use the +normal open, puts, close, etc. commands to manipulate the data fork. +You must use this command, however, to interact with the resource +fork. \fIOption\fR indicates what resource command to perform. Any +unique abbreviation for \fIoption\fR is acceptable. The valid options +are: +.TP +\fBresource close \fIrsrcRef\fR +Closes the given resource reference (obtained from \fBresource +open\fR). Resources from that resource file will no longer be +available. +.TP +\fBresource delete\fR ?\fIoptions\fR? \fIresourceType\fR +This command will delete the resource specified by \fIoptions\fR and +type \fIresourceType\fR (see RESOURCE TYPES below). The options +give you several ways to specify the resource to be deleted. +.RS +.TP +\fB\-id\fR \fIresourceId\fR +If the \fB-id\fR option is given the id \fIresourceId\fR (see RESOURCE +IDS below) is used to specify the resource to be deleted. The id must +be a number - to specify a name use the \fB\-name\fR option. +.TP +\fB\-name\fR \fIresourceName\fR +If \fB-name\fR is specified, the resource named +\fIresourceName\fR will be deleted. If the \fB-id\fR is also +provided, then there must be a resource with BOTH this name and +this id. If no name is provided, then the id will be used regardless +of the name of the actual resource. +.TP +\fB\-file\fR \fIresourceRef\fR +If the \fB-file\fR option is specified then the resource will be +deleted from the file pointed to by \fIresourceRef\fR. Otherwise the +first resource with the given \fIresourceName\fR and or +\fIresourceId\fR which is found on the resource file path will be +deleted. To inspect the file path, use the \fIresource files\fR command. +.RE +.TP +\fBresource files ?\fIresourceRef\fR? +If \fIresourceRef\fRis not provided, this command returns a Tcl list +of the resource references for all the currently open resource files. +The list is in the normal Macintosh search order for resources. If +\fIresourceRef\fR is specified, the command will +return the path to the file whose resource fork is represented by that +token. +.TP +\fBresource list \fIresourceType\fR ?\fIresourceRef\fR? +List all of the resources ids of type \fIresourceType\fR (see RESOURCE +TYPES below). If \fIresourceRef\fR is specified then the command will +limit the search to that particular resource file. Otherwise, all +resource files currently opened by the application will be searched. +A Tcl list of either the resource name's or resource id's of the found +resources will be returned. See the RESOURCE IDS section below for +more details about what a resource id is. +.TP +\fBresource open \fIfileName\fR ?\fIaccess\fR? +Open the resource for the file \fIfileName\fR. Standard file access +permissions may also be specified (see the manual entry for \fBopen\fR +for details). A resource reference (\fIresourceRef\fR) is returned +that can be used by the other resource commands. An error can occur +if the file doesn't exist or the file does not have a resource fork. +However, if you open the file with write permissions the file and/or +resource fork will be created instead of generating an error. +.TP +\fBresource read \fIresourceType\fR \fIresourceId\fR ?\fIresourceRef\fR? +Read the entire resource of type \fIresourceType\fR (see RESOURCE +TYPES below) and the name or id of \fIresourceId\fR (see RESOURCE IDS +below) into memory and return the result. If \fIresourceRef\fR is +specified we limit our search to that resource file, otherwise we +search all open resource forks in the application. It is important to +note that most Macintosh resource use a binary format and the data +returned from this command may have embedded NULLs or other non-ASCII +data. +.TP +\fBresource types ?\fIresourceRef\fR? +This command returns a Tcl list of all resource types (see RESOURCE +TYPES below) found in the resource file pointed to by +\fIresourceRef\fR. If \fIresourceRef\fR is not specified it will +return all the resource types found in every resource file currently +opened by the application. +.TP +\fBresource write\fR ?\fIoptions\fR? \fIresourceType\fR \fIdata\fR +This command will write the passed in \fIdata\fR as a new resource of +type \fIresourceType\fR (see RESOURCE TYPES below). Several options +are available that describe where and how the resource is stored. +.RS +.TP +\fB\-id\fR \fIresourceId\fR +If the \fB-id\fR option is given the id \fIresourceId\fR (see RESOURCE +IDS below) is used for the new resource, otherwise a unique id will be +generated that will not conflict with any existing resource. However, +the id must be a number - to specify a name use the \fB\-name\fR option. +.TP +\fB\-name\fR \fIresourceName\fR +If \fB-name\fR is specified the resource will be named +\fIresourceName\fR, otherwise it will have the empty string as the +name. +.TP +\fB\-file\fR \fIresourceRef\fR +If the \fB-file\fR option is specified then the resource will be +written in the file pointed to by \fIresourceRef\fR, otherwise the +most recently open resource will be used. +.TP +\fB\-force\fR +If the target resource already exists, then by default Tcl will not +overwrite it, but raise an error instead. Use the -force flag to +force overwriting the extant resource. +.RE + +.SH "RESOURCE TYPES" +Resource types are defined as a four character string that is then +mapped to an underlying id. For example, \fBTEXT\fR refers to the +Macintosh resource type for text. The type \fBSTR#\fR is a list of +counted strings. All Macintosh resources must be of some type. See +Macintosh documentation for a more complete list of resource types +that are commonly used. + +.SH "RESOURCE IDS" +For this command the notion of a resource id actually refers to two +ideas in Macintosh resources. Every place you can use a resource Id +you can use either the resource name or a resource number. Names are +always searched or returned in preference to numbers. For example, +the \fBresource list\fR command will return names if they exist or +numbers if the name is NULL. + +.SH "PORTABILITY ISSUES" +The resource command is only available on Macintosh. + +.SH "SEE ALSO" +open(n) + +.SH KEYWORDS +open, resource diff --git a/generic/tclInitScript.h b/generic/tclInitScript.h new file mode 100644 index 0000000..18b8cb7 --- /dev/null +++ b/generic/tclInitScript.h @@ -0,0 +1,111 @@ +/* + * tclInitScript.h -- + * + * This file contains Unix & Windows common init script + * + * Copyright (c) 1998 Sun Microsystems, Inc. + * Copyright (c) 1999 by Scriptics Corporation. + * All rights reserved. + * + * RCS: @(#) $Id: tclInitScript.h,v 1.15 2004/03/17 18:14:13 das Exp $ + */ + +/* + * In order to find init.tcl during initialization, the following script + * is invoked by Tcl_Init(). It looks in several different directories: + * + * $tcl_library - can specify a primary location, if set + * no other locations will be checked + * + * $env(TCL_LIBRARY) - highest priority so user can always override + * the search path unless the application has + * specified an exact directory above + * + * $tclDefaultLibrary - this value is initialized by TclPlatformInit + * from a static C variable that was set at + * compile time + * + * $tcl_libPath - this value is initialized by a call to + * TclGetLibraryPath called from Tcl_Init. + * + * The first directory on this path that contains a valid init.tcl script + * will be set as the value of tcl_library. + * + * Note that this entire search mechanism can be bypassed by defining an + * alternate tclInit procedure before calling Tcl_Init(). + */ + +static char initScript[] = "if {[info proc tclInit]==\"\"} {\n\ + proc tclInit {} {\n\ + global tcl_libPath tcl_library errorInfo\n\ + global env tclDefaultLibrary\n\ + rename tclInit {}\n\ + set errors {}\n\ + set dirs {}\n\ + if {[info exists tcl_library]} {\n\ + lappend dirs $tcl_library\n\ + } else {\n\ + if {[info exists env(TCL_LIBRARY)]} {\n\ + lappend dirs $env(TCL_LIBRARY)\n\ + }\n\ + catch {\n\ + lappend dirs $tclDefaultLibrary\n\ + unset tclDefaultLibrary\n\ + }\n\ + set dirs [concat $dirs $tcl_libPath]\n\ + }\n\ + foreach i $dirs {\n\ + set tcl_library $i\n\ + set tclfile [file join $i init.tcl]\n\ + if {[file exists $tclfile]} {\n\ + if {![catch {uplevel #0 [list source $tclfile]} msg]} {\n\ + return\n\ + } else {\n\ + append errors \"$tclfile: $msg\n$errorInfo\n\"\n\ + }\n\ + }\n\ + }\n\ + set msg \"Can't find a usable init.tcl in the following directories: \n\"\n\ + append msg \" $dirs\n\n\"\n\ + append msg \"$errors\n\n\"\n\ + append msg \"This probably means that Tcl wasn't installed properly.\n\"\n\ + error $msg\n\ + }\n\ +}\n\ +tclInit"; + + +/* + * A pointer to a string that holds an initialization script that if non-NULL + * is evaluated in Tcl_Init() prior to the built-in initialization script + * above. This variable can be modified by the procedure below. + */ + +static char * tclPreInitScript = NULL; + + +/* + *---------------------------------------------------------------------- + * + * TclSetPreInitScript -- + * + * This routine is used to change the value of the internal + * variable, tclPreInitScript. + * + * Results: + * Returns the current value of tclPreInitScript. + * + * Side effects: + * Changes the way Tcl_Init() routine behaves. + * + *---------------------------------------------------------------------- + */ + +char * +TclSetPreInitScript (string) + char *string; /* Pointer to a script. */ +{ + char *prevString = tclPreInitScript; + tclPreInitScript = string; + return(prevString); +} diff --git a/generic/tclMath.h b/generic/tclMath.h new file mode 100644 index 0000000..69c0f9f --- /dev/null +++ b/generic/tclMath.h @@ -0,0 +1,20 @@ +/* + * tclMath.h -- + * + * This file used to be necessary on the Macintosh. + * It is only kept for backward compatibility purposes. + * + * Copyright (c) 1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMath.h,v 1.3 2004/03/17 18:14:14 das Exp $ + */ + +#ifndef _TCLMATH +#define _TCLMATH + +#include <math.h> + +#endif /* _TCLMATH */ diff --git a/generic/tclMathOp.c b/generic/tclMathOp.c new file mode 100644 index 0000000..9858c00 --- /dev/null +++ b/generic/tclMathOp.c @@ -0,0 +1,2884 @@ +/* + * tclMathOp.c -- + * + * This file contains normal command versions of the contents of the + * tcl::mathop namespace. + * + * Copyright (c) 2006 by Donal K. Fellows. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMathOp.c,v 1.8 2006/12/12 17:21:42 dgp Exp $ + */ + +/* + * NOTE: None of the routines in this file are currently in use. + * The file itself may be removed, but remains in place for now in + * case its routine may be useful during performance testing. + */ + +#if 0 + +#include "tclInt.h" +#include "tclCompile.h" +#include "tommath.h" +#include <math.h> +#include <float.h> + +/* + * Hack to determine whether we may expect IEEE floating point. The hack is + * formally incorrect in that non-IEEE platforms might have the same precision + * and range, but VAX, IBM, and Cray do not; are there any other floating + * point units that we might care about? + */ + +#if (FLT_RADIX == 2) && (DBL_MANT_DIG == 53) && (DBL_MAX_EXP == 1024) +#define IEEE_FLOATING_POINT +#endif + +/* + * The stuff below is a bit of a hack so that this file can be used in + * environments that include no UNIX. + * TODO: Does this serve any purpose anymore? + */ + +#ifdef TCL_GENERIC_ONLY +# ifndef NO_FLOAT_H +# include <float.h> +# else /* NO_FLOAT_H */ +# ifndef NO_VALUES_H +# include <values.h> +# endif /* !NO_VALUES_H */ +# endif /* !NO_FLOAT_H */ +#endif /* !TCL_GENERIC_ONLY */ + +/* + * Prototypes for helper functions defined in this file: + */ + +static Tcl_Obj * CombineIntFloat(Tcl_Interp *interp, Tcl_Obj *valuePtr, + int opcode, Tcl_Obj *value2Ptr); +static Tcl_Obj * CombineIntOnly(Tcl_Interp *interp, Tcl_Obj *valuePtr, + int opcode, Tcl_Obj *value2Ptr); +static int CompareNumbers(Tcl_Interp *interp, Tcl_Obj *numObj1, + Tcl_Obj *numObj2, int *resultPtr); + +/* + *---------------------------------------------------------------------- + * + * CombineIntFloat -- + * + * Parses and combines two numbers (either entier() or double()) + * according to the specified operation. + * + * Results: + * Returns the resulting number object (or NULL on failure). + * + * Side effects: + * None. + * + * Notes: + * This code originally extracted from tclExecute.c. + * + *---------------------------------------------------------------------- + */ + +static Tcl_Obj * +CombineIntFloat( + Tcl_Interp *interp, /* Place to write error messages. */ + Tcl_Obj *valuePtr, /* First value to combine. */ + int opcode, /* Operation to use to combine the + * values. Must be one of INST_ADD, INST_SUB, + * INST_MULT, INST_DIV or INST_EXPON. */ + Tcl_Obj *value2Ptr) /* Second value to combine. */ +{ + ClientData ptr1, ptr2; + int type1, type2; + Tcl_Obj *errPtr; + + if ((TclGetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK) +#ifndef ACCEPT_NAN + || (type1 == TCL_NUMBER_NAN) +#endif + ) { + errPtr = valuePtr; + goto illegalOperand; + } + +#ifdef ACCEPT_NAN + if (type1 == TCL_NUMBER_NAN) { + /* NaN first argument -> result is also NaN */ + NEXT_INST_F(1, 1, 0); + } +#endif + + if ((TclGetNumberFromObj(NULL, value2Ptr, &ptr2, &type2) != TCL_OK) +#ifndef ACCEPT_NAN + || (type2 == TCL_NUMBER_NAN) +#endif + ) { + errPtr = value2Ptr; + goto illegalOperand; + } + +#ifdef ACCEPT_NAN + if (type2 == TCL_NUMBER_NAN) { + /* NaN second argument -> result is also NaN */ + return value2Ptr; + NEXT_INST_F(1, 2, 1); + } +#endif + + if ((type1 == TCL_NUMBER_DOUBLE) || (type2 == TCL_NUMBER_DOUBLE)) { + /* + * At least one of the values is floating-point, so perform floating + * point calculations. + */ + + double d1, d2, dResult; + Tcl_GetDoubleFromObj(NULL, valuePtr, &d1); + Tcl_GetDoubleFromObj(NULL, value2Ptr, &d2); + + switch (opcode) { + case INST_ADD: + dResult = d1 + d2; + break; + case INST_SUB: + dResult = d1 - d2; + break; + case INST_MULT: + dResult = d1 * d2; + break; + case INST_DIV: +#ifndef IEEE_FLOATING_POINT + if (d2 == 0.0) { + goto divideByZero; + } +#endif + /* + * We presume that we are running with zero-divide unmasked if + * we're on an IEEE box. Otherwise, this statement might cause + * demons to fly out our noses. + */ + + dResult = d1 / d2; + break; + case INST_EXPON: + if (d1==0.0 && d2<0.0) { + goto exponOfZero; + } + dResult = pow(d1, d2); + break; + default: + /* Unused, here to silence compiler warning. */ + dResult = 0; + } + +#ifndef ACCEPT_NAN + /* + * Check now for IEEE floating-point error. + */ + + if (TclIsNaN(dResult)) { + TclExprFloatError(interp, dResult); + return NULL; + } +#endif + if (Tcl_IsShared(valuePtr)) { + return Tcl_NewDoubleObj(dResult); + } + Tcl_SetDoubleObj(valuePtr, dResult); + return valuePtr; + } + + if ((sizeof(long) >= 2*sizeof(int)) && (opcode == INST_MULT) + && (type1 == TCL_NUMBER_LONG) && (type2 == TCL_NUMBER_LONG)) { + long l1 = *((CONST long *)ptr1); + long l2 = *((CONST long *)ptr2); + if ((l1 <= INT_MAX) && (l1 >= INT_MIN) + && (l2 <= INT_MAX) && (l2 >= INT_MIN)) { + long lResult = l1 * l2; + + if (Tcl_IsShared(valuePtr)) { + return Tcl_NewLongObj(lResult); + } + Tcl_SetLongObj(valuePtr, lResult); + return valuePtr; + } + } + + if ((sizeof(Tcl_WideInt) >= 2*sizeof(long)) && (opcode == INST_MULT) + && (type1 == TCL_NUMBER_LONG) && (type2 == TCL_NUMBER_LONG)) { + Tcl_WideInt w1, w2, wResult; + Tcl_GetWideIntFromObj(NULL, valuePtr, &w1); + Tcl_GetWideIntFromObj(NULL, value2Ptr, &w2); + + wResult = w1 * w2; + + if (Tcl_IsShared(valuePtr)) { + return Tcl_NewWideIntObj(wResult); + } + Tcl_SetWideIntObj(valuePtr, wResult); + return valuePtr; + } + + /* TODO: Attempts to re-use unshared operands on stack */ + if (opcode == INST_EXPON) { + long l1, l2 = 0; + int oddExponent = 0, negativeExponent = 0; + if (type2 == TCL_NUMBER_LONG) { + l2 = *((CONST long *)ptr2); + if (l2 == 0) { + /* Anything to the zero power is 1 */ + return Tcl_NewIntObj(1); + } + } + switch (type2) { + case TCL_NUMBER_LONG: { + negativeExponent = (l2 < 0); + oddExponent = (int) (l2 & 1); + break; + } +#ifndef NO_WIDE_TYPE + case TCL_NUMBER_WIDE: { + Tcl_WideInt w2 = *((CONST Tcl_WideInt *)ptr2); + negativeExponent = (w2 < 0); + oddExponent = (int) (w2 & (Tcl_WideInt)1); + break; + } +#endif + case TCL_NUMBER_BIG: { + mp_int big2; + Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2); + negativeExponent = (mp_cmp_d(&big2, 0) == MP_LT); + mp_mod_2d(&big2, 1, &big2); + oddExponent = !mp_iszero(&big2); + mp_clear(&big2); + break; + } + } + + if (negativeExponent) { + if (type1 == TCL_NUMBER_LONG) { + l1 = *((CONST long *)ptr1); + switch (l1) { + case 0: + /* zero to a negative power is div by zero error */ + goto exponOfZero; + case -1: + if (oddExponent) { + return Tcl_NewIntObj(-1); + } else { + return Tcl_NewIntObj(1); + } + case 1: + /* 1 to any power is 1 */ + return Tcl_NewIntObj(1); + } + } + /* + * Integers with magnitude greater than 1 raise to a negative + * power yield the answer zero (see TIP 123) + */ + return Tcl_NewIntObj(0); + } + + if (type1 == TCL_NUMBER_LONG) { + l1 = *((CONST long *)ptr1); + switch (l1) { + case 0: + /* zero to a positive power is zero */ + return Tcl_NewIntObj(0); + case 1: + /* 1 to any power is 1 */ + return Tcl_NewIntObj(1); + case -1: + if (oddExponent) { + return Tcl_NewIntObj(-1); + } else { + return Tcl_NewIntObj(1); + } + } + } + if (type2 == TCL_NUMBER_BIG) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("exponent too large", -1)); + return NULL; + } + /* TODO: Perform those computations that fit in native types */ + goto overflow; + } + + if ((opcode != INST_MULT) + && (type1 != TCL_NUMBER_BIG) && (type2 != TCL_NUMBER_BIG)) { + Tcl_WideInt w1, w2, wResult; + Tcl_GetWideIntFromObj(NULL, valuePtr, &w1); + Tcl_GetWideIntFromObj(NULL, value2Ptr, &w2); + + switch (opcode) { + case INST_ADD: + wResult = w1 + w2; +#ifndef NO_WIDE_TYPE + if ((type1 == TCL_NUMBER_WIDE) || (type2 == TCL_NUMBER_WIDE)) +#endif + { + /* Check for overflow */ + if (((w1 < 0) && (w2 < 0) && (wResult >= 0)) + || ((w1 > 0) && (w2 > 0) && (wResult < 0))) { + goto overflow; + } + } + break; + + case INST_SUB: + wResult = w1 - w2; +#ifndef NO_WIDE_TYPE + if ((type1 == TCL_NUMBER_WIDE) || (type2 == TCL_NUMBER_WIDE)) +#endif + { + /* Must check for overflow */ + if (((w1 < 0) && (w2 > 0) && (wResult > 0)) + || ((w1 >= 0) && (w2 < 0) && (wResult < 0))) { + goto overflow; + } + } + break; + + case INST_DIV: + if (w2 == 0) { + goto divideByZero; + } + + /* Need a bignum to represent (LLONG_MIN / -1) */ + if ((w1 == LLONG_MIN) && (w2 == -1)) { + goto overflow; + } + wResult = w1 / w2; + + /* Force Tcl's integer division rules */ + /* TODO: examine for logic simplification */ + if (((wResult < 0) || ((wResult == 0) && + ((w1 < 0 && w2 > 0) || (w1 > 0 && w2 < 0)))) && + ((wResult * w2) != w1)) { + wResult -= 1; + } + break; + default: + /* Unused, here to silence compiler warning. */ + wResult = 0; + } + + if (Tcl_IsShared(valuePtr)) { + return Tcl_NewWideIntObj(wResult); + } + Tcl_SetWideIntObj(valuePtr, wResult); + return valuePtr; + } + + overflow: + { + mp_int big1, big2, bigResult, bigRemainder; + Tcl_TakeBignumFromObj(NULL, valuePtr, &big1); + Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2); + mp_init(&bigResult); + switch (opcode) { + case INST_ADD: + mp_add(&big1, &big2, &bigResult); + break; + case INST_SUB: + mp_sub(&big1, &big2, &bigResult); + break; + case INST_MULT: + mp_mul(&big1, &big2, &bigResult); + break; + case INST_DIV: + if (mp_iszero(&big2)) { + mp_clear(&big1); + mp_clear(&big2); + goto divideByZero; + } + mp_init(&bigRemainder); + mp_div(&big1, &big2, &bigResult, &bigRemainder); + /* TODO: internals intrusion */ + if (!mp_iszero(&bigRemainder) + && (bigRemainder.sign != big2.sign)) { + /* Convert to Tcl's integer division rules */ + mp_sub_d(&bigResult, 1, &bigResult); + mp_add(&bigRemainder, &big2, &bigRemainder); + } + mp_clear(&bigRemainder); + break; + case INST_EXPON: + if (big2.used > 1) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("exponent too large", -1)); + mp_clear(&big1); + mp_clear(&big2); + return NULL; + } + mp_expt_d(&big1, big2.dp[0], &bigResult); + break; + } + mp_clear(&big1); + mp_clear(&big2); + if (Tcl_IsShared(valuePtr)) { + return Tcl_NewBignumObj(&bigResult); + } + Tcl_SetBignumObj(valuePtr, &bigResult); + return valuePtr; + } + + { + const char *description, *operator; + + illegalOperand: + switch (opcode) { + case INST_ADD: operator = "+"; break; + case INST_SUB: operator = "-"; break; + case INST_MULT: operator = "*"; break; + case INST_DIV: operator = "/"; break; + case INST_EXPON: operator = "**"; break; + default: + operator = "???"; + } + + if (TclGetNumberFromObj(NULL, errPtr, &ptr1, &type1) != TCL_OK) { + int numBytes; + CONST char *bytes = Tcl_GetStringFromObj(errPtr, &numBytes); + if (numBytes == 0) { + description = "empty string"; + } else if (TclCheckBadOctal(NULL, bytes)) { + description = "invalid octal number"; + } else { + description = "non-numeric string"; + } + } else if (type1 == TCL_NUMBER_NAN) { + description = "non-numeric floating-point value"; + } else if (type1 == TCL_NUMBER_DOUBLE) { + description = "floating-point value"; + } else { + /* TODO: No caller needs this. Eliminate? */ + description = "(big) integer"; + } + + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't use %s as operand of \"%s\"", description, operator)); + return NULL; + } + + divideByZero: + Tcl_SetObjResult(interp, Tcl_NewStringObj("divide by zero", -1)); + Tcl_SetErrorCode(interp, "ARITH", "DIVZERO", "divide by zero", NULL); + return NULL; + + exponOfZero: + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "exponentiation of zero by negative power", -1)); + Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", + "exponentiation of zero by negative power", NULL); + return NULL; +} + +/* + *---------------------------------------------------------------------- + * + * CombineIntOnly -- + * + * Parses and combines two numbers (must be entier()) according to the + * specified operation. + * + * Results: + * Returns the resulting number object (or NULL on failure). + * + * Side effects: + * None. + * + * Notes: + * This code originally extracted from tclExecute.c. + * + *---------------------------------------------------------------------- + */ + +static Tcl_Obj * +CombineIntOnly( + Tcl_Interp *interp, /* Place to write error messages. */ + Tcl_Obj *valuePtr, /* First value to combine. */ + int opcode, /* Operation to use to combine the + * values. Must be one of INST_BITAND, + * INST_BITOR or INST_BITXOR. */ + Tcl_Obj *value2Ptr) /* Second value to combine. */ +{ + ClientData ptr1, ptr2; + int type1, type2; + Tcl_Obj *errPtr; + + if ((TclGetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK) + || (type1 == TCL_NUMBER_NAN) || (type1 == TCL_NUMBER_DOUBLE)) { + errPtr = valuePtr; + goto illegalOperand; + } + if ((TclGetNumberFromObj(NULL, value2Ptr, &ptr2, &type2) != TCL_OK) + || (type2 == TCL_NUMBER_NAN) || (type2 == TCL_NUMBER_DOUBLE)) { + errPtr = value2Ptr; + goto illegalOperand; + } + + if ((type1 == TCL_NUMBER_BIG) || (type2 == TCL_NUMBER_BIG)) { + mp_int big1, big2, bigResult; + mp_int *First, *Second; + int numPos; + + + Tcl_TakeBignumFromObj(NULL, valuePtr, &big1); + Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2); + + /* + * Count how many positive arguments we have. If only one of the + * arguments is negative, store it in 'Second'. + */ + + if (mp_cmp_d(&big1, 0) != MP_LT) { + numPos = 1 + (mp_cmp_d(&big2, 0) != MP_LT); + First = &big1; + Second = &big2; + } else { + First = &big2; + Second = &big1; + numPos = (mp_cmp_d(First, 0) != MP_LT); + } + mp_init(&bigResult); + + switch (opcode) { + case INST_BITAND: + switch (numPos) { + case 2: + /* Both arguments positive, base case */ + mp_and(First, Second, &bigResult); + break; + case 1: + /* First is positive; Second negative + * P & N = P & ~~N = P&~(-N-1) = P & (P ^ (-N-1)) */ + mp_neg(Second, Second); + mp_sub_d(Second, 1, Second); + mp_xor(First, Second, &bigResult); + mp_and(First, &bigResult, &bigResult); + break; + case 0: + /* Both arguments negative + * a & b = ~ (~a | ~b) = -(-a-1|-b-1)-1 */ + mp_neg(First, First); + mp_sub_d(First, 1, First); + mp_neg(Second, Second); + mp_sub_d(Second, 1, Second); + mp_or(First, Second, &bigResult); + mp_neg(&bigResult, &bigResult); + mp_sub_d(&bigResult, 1, &bigResult); + break; + } + break; + + case INST_BITOR: + switch (numPos) { + case 2: + /* Both arguments positive, base case */ + mp_or(First, Second, &bigResult); + break; + case 1: + /* First is positive; Second negative + * N|P = ~(~N&~P) = ~((-N-1)&~P) = -((-N-1)&((-N-1)^P))-1 */ + mp_neg(Second, Second); + mp_sub_d(Second, 1, Second); + mp_xor(First, Second, &bigResult); + mp_and(Second, &bigResult, &bigResult); + mp_neg(&bigResult, &bigResult); + mp_sub_d(&bigResult, 1, &bigResult); + break; + case 0: + /* Both arguments negative + * a | b = ~ (~a & ~b) = -(-a-1&-b-1)-1 */ + mp_neg(First, First); + mp_sub_d(First, 1, First); + mp_neg(Second, Second); + mp_sub_d(Second, 1, Second); + mp_and(First, Second, &bigResult); + mp_neg(&bigResult, &bigResult); + mp_sub_d(&bigResult, 1, &bigResult); + break; + } + break; + + case INST_BITXOR: + switch (numPos) { + case 2: + /* Both arguments positive, base case */ + mp_xor(First, Second, &bigResult); + break; + case 1: + /* First is positive; Second negative + * P^N = ~(P^~N) = -(P^(-N-1))-1 */ + mp_neg(Second, Second); + mp_sub_d(Second, 1, Second); + mp_xor(First, Second, &bigResult); + mp_neg(&bigResult, &bigResult); + mp_sub_d(&bigResult, 1, &bigResult); + break; + case 0: + /* Both arguments negative + * a ^ b = (~a ^ ~b) = (-a-1^-b-1) */ + mp_neg(First, First); + mp_sub_d(First, 1, First); + mp_neg(Second, Second); + mp_sub_d(Second, 1, Second); + mp_xor(First, Second, &bigResult); + break; + } + break; + } + + mp_clear(&big1); + mp_clear(&big2); + if (Tcl_IsShared(valuePtr)) { + return Tcl_NewBignumObj(&bigResult); + } + Tcl_SetBignumObj(valuePtr, &bigResult); + return valuePtr; + } +#ifndef NO_WIDE_TYPE + else if ((type1 == TCL_NUMBER_WIDE) || (type2 == TCL_NUMBER_WIDE)) { + Tcl_WideInt wResult, w1, w2; + Tcl_GetWideIntFromObj(NULL, valuePtr, &w1); + Tcl_GetWideIntFromObj(NULL, value2Ptr, &w2); + + switch (opcode) { + case INST_BITAND: + wResult = w1 & w2; + break; + case INST_BITOR: + wResult = w1 | w2; + break; + case INST_BITXOR: + wResult = w1 ^ w2; + break; + default: + /* Unused, here to silence compiler warning. */ + wResult = 0; + } + + if (Tcl_IsShared(valuePtr)) { + return Tcl_NewWideIntObj(wResult); + } + Tcl_SetWideIntObj(valuePtr, wResult); + return valuePtr; + } +#endif + else { + long lResult, l1 = *((const long *)ptr1); + long l2 = *((const long *)ptr2); + + switch (opcode) { + case INST_BITAND: + lResult = l1 & l2; + break; + case INST_BITOR: + lResult = l1 | l2; + break; + case INST_BITXOR: + lResult = l1 ^ l2; + break; + default: + /* Unused, here to silence compiler warning. */ + lResult = 0; + } + + if (Tcl_IsShared(valuePtr)) { + return Tcl_NewLongObj(lResult); + } + TclSetLongObj(valuePtr, lResult); + return valuePtr; + } + + { + const char *description, *operator; + + illegalOperand: + switch (opcode) { + case INST_BITAND: operator = "&"; break; + case INST_BITOR: operator = "|"; break; + case INST_BITXOR: operator = "^"; break; + default: + operator = "???"; + } + + if (TclGetNumberFromObj(NULL, errPtr, &ptr1, &type1) != TCL_OK) { + int numBytes; + CONST char *bytes = Tcl_GetStringFromObj(errPtr, &numBytes); + if (numBytes == 0) { + description = "empty string"; + } else if (TclCheckBadOctal(NULL, bytes)) { + description = "invalid octal number"; + } else { + description = "non-numeric string"; + } + } else if (type1 == TCL_NUMBER_NAN) { + description = "non-numeric floating-point value"; + } else if (type1 == TCL_NUMBER_DOUBLE) { + description = "floating-point value"; + } else { + /* TODO: No caller needs this. Eliminate? */ + description = "(big) integer"; + } + + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't use %s as operand of \"%s\"", description, operator)); + return NULL; + } +} + +/* + *---------------------------------------------------------------------- + * + * CompareNumbers -- + * + * Parses and compares two numbers (may be either entier() or double()). + * + * Results: + * TCL_OK if the numbers parse correctly, TCL_ERROR if one is not numeric + * at all, and TCL_BREAK if one or the other is "NaN". The resultPtr + * argument is used to update a variable with how the numbers relate to + * each other in the TCL_OK case. + * + * Side effects: + * None. + * + * Notes: + * This code originally extracted from tclExecute.c. + * + *---------------------------------------------------------------------- + */ + +static int +CompareNumbers( + Tcl_Interp *interp, /* Where to write error messages if any. */ + Tcl_Obj *numObj1, /* First number to compare. */ + Tcl_Obj *numObj2, /* Second number to compare. */ + int *resultPtr) /* Pointer to a variable to write the outcome + * of the comparison into. Must not be + * NULL. */ +{ + ClientData ptr1, ptr2; + int type1, type2; + double d1, d2, tmp; + long l1, l2; + mp_int big1, big2; +#ifndef NO_WIDE_TYPE + Tcl_WideInt w1, w2; +#endif + + if (TclGetNumberFromObj(interp, numObj1, &ptr1, &type1) != TCL_OK) { + return TCL_ERROR; + } + if (TclGetNumberFromObj(interp, numObj2, &ptr2, &type2) != TCL_OK) { + return TCL_ERROR; + } + + /* + * Selected special cases. NaNs are not equal to *everything*, otherwise + * objects are equal to themselves. + */ + + if (type1 == TCL_NUMBER_NAN) { + /* NaN first arg: NaN != to everything, other compares are false */ + return TCL_BREAK; + } + if (numObj1 == numObj2) { + *resultPtr = MP_EQ; + return TCL_OK; + } + if (type2 == TCL_NUMBER_NAN) { + /* NaN 2nd arg: NaN != to everything, other compares are false */ + return TCL_BREAK; + } + + /* + * Big switch to pick apart the type rules and choose how to compare the + * two numbers. Also handles a few special cases along the way. + */ + + switch (type1) { + case TCL_NUMBER_LONG: + l1 = *((CONST long *)ptr1); + switch (type2) { + case TCL_NUMBER_LONG: + l2 = *((CONST long *)ptr2); + goto longCompare; +#ifndef NO_WIDE_TYPE + case TCL_NUMBER_WIDE: + w2 = *((CONST Tcl_WideInt *)ptr2); + w1 = (Tcl_WideInt)l1; + goto wideCompare; +#endif + case TCL_NUMBER_DOUBLE: + d2 = *((CONST double *)ptr2); + d1 = (double) l1; + + /* + * If the double has a fractional part, or if the long can be + * converted to double without loss of precision, then compare as + * doubles. + */ + + if ((DBL_MANT_DIG > CHAR_BIT*sizeof(long)) + || (l1 == (long) d1) || (modf(d2, &tmp) != 0.0)) { + goto doubleCompare; + } + + /* + * Otherwise, to make comparision based on full precision, need to + * convert the double to a suitably sized integer. + * + * Need this to get comparsions like + * expr 20000000000000003 < 20000000000000004.0 + * right. Converting the first argument to double will yield two + * double values that are equivalent within double precision. + * Converting the double to an integer gets done exactly, then + * integer comparison can tell the difference. + */ + + if (d2 < (double)LONG_MIN) { + *resultPtr = MP_GT; + return TCL_OK; + } + if (d2 > (double)LONG_MAX) { + *resultPtr = MP_LT; + return TCL_OK; + } + l2 = (long) d2; + goto longCompare; + case TCL_NUMBER_BIG: + Tcl_TakeBignumFromObj(NULL, numObj2, &big2); + if (mp_cmp_d(&big2, 0) == MP_LT) { + *resultPtr = MP_GT; + } else { + *resultPtr = MP_LT; + } + mp_clear(&big2); + } + return TCL_OK; + +#ifndef NO_WIDE_TYPE + case TCL_NUMBER_WIDE: + w1 = *((CONST Tcl_WideInt *)ptr1); + switch (type2) { + case TCL_NUMBER_WIDE: + w2 = *((CONST Tcl_WideInt *)ptr2); + goto wideCompare; + case TCL_NUMBER_LONG: + l2 = *((CONST long *)ptr2); + w2 = (Tcl_WideInt)l2; + goto wideCompare; + case TCL_NUMBER_DOUBLE: + d2 = *((CONST double *)ptr2); + d1 = (double) w1; + if ((DBL_MANT_DIG > CHAR_BIT*sizeof(Tcl_WideInt)) + || (w1 == (Tcl_WideInt) d1) || (modf(d2, &tmp) != 0.0)) { + goto doubleCompare; + } + if (d2 < (double)LLONG_MIN) { + *resultPtr = MP_GT; + return TCL_OK; + } + if (d2 > (double)LLONG_MAX) { + *resultPtr = MP_LT; + return TCL_OK; + } + w2 = (Tcl_WideInt) d2; + goto wideCompare; + case TCL_NUMBER_BIG: + Tcl_TakeBignumFromObj(NULL, numObj2, &big2); + if (mp_cmp_d(&big2, 0) == MP_LT) { + *resultPtr = MP_GT; + } else { + *resultPtr = MP_LT; + } + mp_clear(&big2); + } + return TCL_OK; +#endif + + case TCL_NUMBER_DOUBLE: + d1 = *((CONST double *)ptr1); + switch (type2) { + case TCL_NUMBER_DOUBLE: + d2 = *((CONST double *)ptr2); + goto doubleCompare; + case TCL_NUMBER_LONG: + l2 = *((CONST long *)ptr2); + d2 = (double) l2; + + if ((DBL_MANT_DIG > CHAR_BIT*sizeof(long)) + || (l2 == (long) d2) || (modf(d1, &tmp) != 0.0)) { + goto doubleCompare; + } + if (d1 < (double)LONG_MIN) { + *resultPtr = MP_LT; + return TCL_OK; + } + if (d1 > (double)LONG_MAX) { + *resultPtr = MP_GT; + return TCL_OK; + } + l1 = (long) d1; + goto longCompare; +#ifndef NO_WIDE_TYPE + case TCL_NUMBER_WIDE: + w2 = *((CONST Tcl_WideInt *)ptr2); + d2 = (double) w2; + if ((DBL_MANT_DIG > CHAR_BIT*sizeof(Tcl_WideInt)) + || (w2 == (Tcl_WideInt) d2) || (modf(d1, &tmp) != 0.0)) { + goto doubleCompare; + } + if (d1 < (double)LLONG_MIN) { + *resultPtr = MP_LT; + return TCL_OK; + } + if (d1 > (double)LLONG_MAX) { + *resultPtr = MP_GT; + return TCL_OK; + } + w1 = (Tcl_WideInt) d1; + goto wideCompare; +#endif + case TCL_NUMBER_BIG: + if (TclIsInfinite(d1)) { + *resultPtr = (d1 > 0.0) ? MP_GT : MP_LT; + return TCL_OK; + } + Tcl_TakeBignumFromObj(NULL, numObj2, &big2); + if ((d1 < (double)LONG_MAX) && (d1 > (double)LONG_MIN)) { + if (mp_cmp_d(&big2, 0) == MP_LT) { + *resultPtr = MP_GT; + } else { + *resultPtr = MP_LT; + } + mp_clear(&big2); + return TCL_OK; + } + if ((DBL_MANT_DIG > CHAR_BIT*sizeof(long)) + && (modf(d1, &tmp) != 0.0)) { + d2 = TclBignumToDouble(&big2); + mp_clear(&big2); + goto doubleCompare; + } + Tcl_InitBignumFromDouble(NULL, d1, &big1); + goto bigCompare; + } + return TCL_OK; + + case TCL_NUMBER_BIG: + Tcl_TakeBignumFromObj(NULL, numObj1, &big1); + switch (type2) { +#ifndef NO_WIDE_TYPE + case TCL_NUMBER_WIDE: +#endif + case TCL_NUMBER_LONG: + *resultPtr = mp_cmp_d(&big1, 0); + mp_clear(&big1); + return TCL_OK; + case TCL_NUMBER_DOUBLE: + d2 = *((CONST double *)ptr2); + if (TclIsInfinite(d2)) { + *resultPtr = (d2 > 0.0) ? MP_LT : MP_GT; + mp_clear(&big1); + return TCL_OK; + } + if ((d2 < (double)LONG_MAX) && (d2 > (double)LONG_MIN)) { + *resultPtr = mp_cmp_d(&big1, 0); + mp_clear(&big1); + return TCL_OK; + } + if ((DBL_MANT_DIG > CHAR_BIT*sizeof(long)) + && (modf(d2, &tmp) != 0.0)) { + d1 = TclBignumToDouble(&big1); + mp_clear(&big1); + goto doubleCompare; + } + Tcl_InitBignumFromDouble(NULL, d2, &big2); + goto bigCompare; + case TCL_NUMBER_BIG: + Tcl_TakeBignumFromObj(NULL, numObj2, &big2); + goto bigCompare; + } + } + + /* + * Should really be impossible to get here + */ + + return TCL_OK; + + /* + * The real core comparison rules. + */ + + longCompare: + *resultPtr = (l1 < l2) ? MP_LT : ((l1 > l2) ? MP_GT : MP_EQ); + return TCL_OK; +#ifndef NO_WIDE_TYPE + wideCompare: + *resultPtr = (w1 < w2) ? MP_LT : ((w1 > w2) ? MP_GT : MP_EQ); + return TCL_OK; +#endif + doubleCompare: + *resultPtr = (d1 < d2) ? MP_LT : ((d1 > d2) ? MP_GT : MP_EQ); + return TCL_OK; + bigCompare: + *resultPtr = mp_cmp(&big1, &big2); + mp_clear(&big1); + mp_clear(&big2); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclInvertOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::~" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclInvertOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + ClientData val; + int type; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "number"); + return TCL_ERROR; + } + if (TclGetNumberFromObj(NULL, objv[1], &val, &type) != TCL_OK) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't use non-numeric string as operand of \"~\"", -1)); + return TCL_ERROR; + } + switch (type) { + case TCL_NUMBER_NAN: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't use %s as operand of \"~\"", + "non-numeric floating-point value")); + return TCL_ERROR; + case TCL_NUMBER_DOUBLE: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't use %s as operand of \"~\"", "floating-point value")); + return TCL_ERROR; + case TCL_NUMBER_LONG: { + long l = *((const long *) val); + + Tcl_SetLongObj(Tcl_GetObjResult(interp), ~l); + return TCL_OK; + } +#ifndef NO_WIDE_TYPE + case TCL_NUMBER_WIDE: { + Tcl_WideInt w = *((const Tcl_WideInt *) val); + + Tcl_SetWideIntObj(Tcl_GetObjResult(interp), ~w); + return TCL_OK; + } +#endif + default: { + mp_int big; + + Tcl_TakeBignumFromObj(NULL, objv[1], &big); + /* ~a = - a - 1 */ + mp_neg(&big, &big); + mp_sub_d(&big, 1, &big); + if (Tcl_IsShared(objv[1])) { + Tcl_SetObjResult(interp, Tcl_NewBignumObj(&big)); + } else { + Tcl_SetBignumObj(objv[1], &big); + Tcl_SetObjResult(interp, objv[1]); + } + return TCL_OK; + } + } +} + +/* + *---------------------------------------------------------------------- + * + * TclNotOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::!" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclNotOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + int b; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "boolean"); + return TCL_ERROR; + } + if (Tcl_GetBooleanFromObj(NULL, objv[1], &b) != TCL_OK) { + int type; + ClientData val; + if (TclGetNumberFromObj(NULL, objv[1], &val, &type) == TCL_OK) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't use non-numeric floating-point value as operand of \"!\"", -1)); + } else { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't use non-numeric string as operand of \"!\"", -1)); + } + return TCL_ERROR; + } + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), !b); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclAddOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::+" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclAddOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + if (objc < 2) { + Tcl_SetIntObj(Tcl_GetObjResult(interp), 0); + return TCL_OK; + } else if (objc == 2) { + ClientData ptr1; + int type1; + if (TclGetNumberFromObj(NULL, objv[1], &ptr1, &type1) != TCL_OK) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't use non-numeric string as operand of \"+\"",-1)); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, objv[1]); + return TCL_OK; + } else if (objc == 3) { + /* + * This is a special case of the version with the loop that allows for + * better memory management of objects in some cases. + */ + + Tcl_Obj *resPtr = CombineIntFloat(interp, objv[1], INST_ADD, objv[2]); + if (resPtr == NULL) { + return TCL_ERROR; + } + Tcl_SetObjResult(interp, resPtr); + return TCL_OK; + } else { + Tcl_Obj *sumPtr = objv[1]; + int i; + + Tcl_IncrRefCount(sumPtr); + for (i=2 ; i<objc ; i++) { + Tcl_Obj *resPtr = CombineIntFloat(interp, sumPtr, INST_ADD, + objv[i]); + + if (resPtr == NULL) { + TclDecrRefCount(sumPtr); + return TCL_ERROR; + } + Tcl_IncrRefCount(resPtr); + TclDecrRefCount(sumPtr); + sumPtr = resPtr; + } + Tcl_SetObjResult(interp, sumPtr); + Tcl_DecrRefCount(sumPtr); /* Public form since we know we won't + * be freeing this object now. */ + return TCL_OK; + } +} + +/* + *---------------------------------------------------------------------- + * + * TclMulOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::*" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclMulOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + if (objc < 2) { + Tcl_SetIntObj(Tcl_GetObjResult(interp), 1); + return TCL_OK; + } else if (objc == 2) { + ClientData ptr1; + int type1; + if (TclGetNumberFromObj(NULL, objv[1], &ptr1, &type1) != TCL_OK) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't use non-numeric string as operand of \"*\"",-1)); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, objv[1]); + return TCL_OK; + } else if (objc == 3) { + /* + * This is a special case of the version with the loop that allows for + * better memory management of objects in some cases. + */ + + Tcl_Obj *resPtr = CombineIntFloat(interp, objv[1],INST_MULT,objv[2]); + if (resPtr == NULL) { + return TCL_ERROR; + } + Tcl_SetObjResult(interp, resPtr); + return TCL_OK; + } else { + Tcl_Obj *prodPtr = objv[1]; + int i; + + Tcl_IncrRefCount(prodPtr); + for (i=2 ; i<objc ; i++) { + Tcl_Obj *resPtr = CombineIntFloat(interp, prodPtr, INST_MULT, + objv[i]); + + if (resPtr == NULL) { + TclDecrRefCount(prodPtr); + return TCL_ERROR; + } + Tcl_IncrRefCount(resPtr); + TclDecrRefCount(prodPtr); + prodPtr = resPtr; + } + Tcl_SetObjResult(interp, prodPtr); + Tcl_DecrRefCount(prodPtr); /* Public form since we know we won't + * be freeing this object now. */ + return TCL_OK; + } +} + +/* + *---------------------------------------------------------------------- + * + * TclAndOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::&" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclAndOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + if (objc < 2) { + Tcl_SetIntObj(Tcl_GetObjResult(interp), -1); + return TCL_OK; + } else if (objc == 2) { + ClientData ptr1; + int type1; + if (TclGetNumberFromObj(NULL, objv[1], &ptr1, &type1) != TCL_OK) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't use non-numeric string as operand of \"&\"",-1)); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, objv[1]); + return TCL_OK; + } else if (objc == 3) { + /* + * This is a special case of the version with the loop that allows for + * better memory management of objects in some cases. + */ + + Tcl_Obj *resPtr = CombineIntOnly(interp, objv[1],INST_BITAND,objv[2]); + if (resPtr == NULL) { + return TCL_ERROR; + } + Tcl_SetObjResult(interp, resPtr); + return TCL_OK; + } else { + Tcl_Obj *accumPtr = objv[1]; + int i; + + Tcl_IncrRefCount(accumPtr); + for (i=2 ; i<objc ; i++) { + Tcl_Obj *resPtr = CombineIntOnly(interp, accumPtr, INST_BITAND, + objv[i]); + + if (resPtr == NULL) { + TclDecrRefCount(accumPtr); + return TCL_ERROR; + } + Tcl_IncrRefCount(resPtr); + TclDecrRefCount(accumPtr); + accumPtr = resPtr; + } + Tcl_SetObjResult(interp, accumPtr); + Tcl_DecrRefCount(accumPtr); /* Public form since we know we won't + * be freeing this object now. */ + return TCL_OK; + } +} + +/* + *---------------------------------------------------------------------- + * + * TclOrOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::|" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclOrOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + if (objc < 2) { + Tcl_SetIntObj(Tcl_GetObjResult(interp), 0); + return TCL_OK; + } else if (objc == 2) { + ClientData ptr1; + int type1; + if (TclGetNumberFromObj(NULL, objv[1], &ptr1, &type1) != TCL_OK) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't use non-numeric string as operand of \"|\"",-1)); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, objv[1]); + return TCL_OK; + } else if (objc == 3) { + /* + * This is a special case of the version with the loop that allows for + * better memory management of objects in some cases. + */ + + Tcl_Obj *resPtr = CombineIntOnly(interp, objv[1],INST_BITOR,objv[2]); + if (resPtr == NULL) { + return TCL_ERROR; + } + Tcl_SetObjResult(interp, resPtr); + return TCL_OK; + } else { + Tcl_Obj *accumPtr = objv[1]; + int i; + + Tcl_IncrRefCount(accumPtr); + for (i=2 ; i<objc ; i++) { + Tcl_Obj *resPtr = CombineIntOnly(interp, accumPtr, INST_BITOR, + objv[i]); + + if (resPtr == NULL) { + TclDecrRefCount(accumPtr); + return TCL_ERROR; + } + Tcl_IncrRefCount(resPtr); + TclDecrRefCount(accumPtr); + accumPtr = resPtr; + } + Tcl_SetObjResult(interp, accumPtr); + Tcl_DecrRefCount(accumPtr); /* Public form since we know we won't + * be freeing this object now. */ + return TCL_OK; + } +} + +/* + *---------------------------------------------------------------------- + * + * TclXorOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::^" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclXorOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + if (objc < 2) { + Tcl_SetIntObj(Tcl_GetObjResult(interp), 0); + return TCL_OK; + } else if (objc == 2) { + ClientData ptr1; + int type1; + if (TclGetNumberFromObj(NULL, objv[1], &ptr1, &type1) != TCL_OK) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't use non-numeric string as operand of \"^\"",-1)); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, objv[1]); + return TCL_OK; + } else if (objc == 3) { + /* + * This is a special case of the version with the loop that allows for + * better memory management of objects in some cases. + */ + + Tcl_Obj *resPtr = CombineIntOnly(interp, objv[1],INST_BITXOR,objv[2]); + if (resPtr == NULL) { + return TCL_ERROR; + } + Tcl_SetObjResult(interp, resPtr); + return TCL_OK; + } else { + Tcl_Obj *accumPtr = objv[1]; + int i; + + Tcl_IncrRefCount(accumPtr); + for (i=2 ; i<objc ; i++) { + Tcl_Obj *resPtr = CombineIntOnly(interp, accumPtr, INST_BITXOR, + objv[i]); + + if (resPtr == NULL) { + TclDecrRefCount(accumPtr); + return TCL_ERROR; + } + Tcl_IncrRefCount(resPtr); + TclDecrRefCount(accumPtr); + accumPtr = resPtr; + } + Tcl_SetObjResult(interp, accumPtr); + Tcl_DecrRefCount(accumPtr); /* Public form since we know we won't + * be freeing this object now. */ + return TCL_OK; + } +} + +/* + *---------------------------------------------------------------------- + * + * TclPowOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::**" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclPowOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + if (objc < 2) { + Tcl_SetIntObj(Tcl_GetObjResult(interp), 1); + return TCL_OK; + } else if (objc == 2) { + ClientData ptr1; + int type1; + if (TclGetNumberFromObj(NULL, objv[1], &ptr1, &type1) != TCL_OK) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "can't use non-numeric string as operand of \"**\"",-1)); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, objv[1]); + return TCL_OK; + } else if (objc == 3) { + /* + * This is a special case of the version with the loop that allows for + * better memory management of objects in some cases. + */ + + Tcl_Obj *resPtr = CombineIntFloat(interp, objv[1],INST_EXPON,objv[2]); + if (resPtr == NULL) { + return TCL_ERROR; + } + Tcl_SetObjResult(interp, resPtr); + return TCL_OK; + } else { + Tcl_Obj *powPtr = objv[objc-1]; + int i; + + Tcl_IncrRefCount(powPtr); + for (i=objc-2 ; i>=1 ; i--) { + Tcl_Obj *resPtr = CombineIntFloat(interp, objv[i], INST_EXPON, + powPtr); + + if (resPtr == NULL) { + TclDecrRefCount(powPtr); + return TCL_ERROR; + } + Tcl_IncrRefCount(resPtr); + TclDecrRefCount(powPtr); + powPtr = resPtr; + } + Tcl_SetObjResult(interp, powPtr); + Tcl_DecrRefCount(powPtr); /* Public form since we know we won't + * be freeing this object now. */ + return TCL_OK; + } +} + +/* + *---------------------------------------------------------------------- + * + * TclMinusOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::-" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclMinusOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "value ?value ...?"); + return TCL_ERROR; + } else if (objc == 2) { + /* + * Only a single argument, so we compute the negation. + */ + + Tcl_Obj *zeroPtr = Tcl_NewIntObj(0); + Tcl_Obj *resPtr; + + Tcl_IncrRefCount(zeroPtr); + resPtr = CombineIntFloat(interp, zeroPtr, INST_SUB, objv[1]); + if (resPtr == NULL) { + TclDecrRefCount(zeroPtr); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, resPtr); + TclDecrRefCount(zeroPtr); + return TCL_OK; + } else if (objc == 3) { + /* + * This is a special case of the version with the loop that allows for + * better memory management of objects in some cases. + */ + + Tcl_Obj *resPtr = CombineIntFloat(interp, objv[1], INST_SUB, objv[2]); + if (resPtr == NULL) { + return TCL_ERROR; + } + Tcl_SetObjResult(interp, resPtr); + return TCL_OK; + } else { + Tcl_Obj *diffPtr = objv[1]; + int i; + + Tcl_IncrRefCount(diffPtr); + for (i=2 ; i<objc ; i++) { + Tcl_Obj *resPtr = CombineIntFloat(interp, diffPtr, INST_SUB, + objv[i]); + + if (resPtr == NULL) { + TclDecrRefCount(diffPtr); + return TCL_ERROR; + } + Tcl_IncrRefCount(resPtr); + TclDecrRefCount(diffPtr); + diffPtr = resPtr; + } + Tcl_SetObjResult(interp, diffPtr); + Tcl_DecrRefCount(diffPtr); /* Public form since we know we won't + * be freeing this object now. */ + return TCL_OK; + } +} + +/* + *---------------------------------------------------------------------- + * + * TclDivOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::/" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclDivOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "value ?value ...?"); + return TCL_ERROR; + } else if (objc == 2) { + /* + * Only a single argument, so we compute the reciprocal. + */ + + Tcl_Obj *onePtr = Tcl_NewDoubleObj(1.0); + Tcl_Obj *resPtr; + + Tcl_IncrRefCount(onePtr); + resPtr = CombineIntFloat(interp, onePtr, INST_DIV, objv[1]); + if (resPtr == NULL) { + TclDecrRefCount(onePtr); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, resPtr); + TclDecrRefCount(onePtr); + return TCL_OK; + } else if (objc == 3) { + /* + * This is a special case of the version with the loop that allows for + * better memory management of objects in some cases. + */ + + Tcl_Obj *resPtr = CombineIntFloat(interp, objv[1], INST_DIV, objv[2]); + if (resPtr == NULL) { + return TCL_ERROR; + } + Tcl_SetObjResult(interp, resPtr); + return TCL_OK; + } else { + Tcl_Obj *numeratorPtr = objv[1]; + int i; + + Tcl_IncrRefCount(numeratorPtr); + for (i=2 ; i<objc ; i++) { + Tcl_Obj *resPtr = CombineIntFloat(interp, numeratorPtr, INST_DIV, + objv[i]); + + if (resPtr == NULL) { + TclDecrRefCount(numeratorPtr); + return TCL_ERROR; + } + Tcl_IncrRefCount(resPtr); + TclDecrRefCount(numeratorPtr); + numeratorPtr = resPtr; + } + Tcl_SetObjResult(interp, numeratorPtr); + Tcl_DecrRefCount(numeratorPtr); /* Public form since we know we won't + * be freeing this object now. */ + return TCL_OK; + } +} + +/* + *---------------------------------------------------------------------- + * + * TclLshiftOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::<<" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclLshiftOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + ClientData ptr1, ptr2; + int invalid, shift, type1, type2, idx; + const char *description; + long l1; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "value value"); + return TCL_ERROR; + } + + if ((TclGetNumberFromObj(NULL, objv[1], &ptr1, &type1) != TCL_OK) + || (type1 == TCL_NUMBER_DOUBLE) || (type1 == TCL_NUMBER_NAN)) { + idx = 1; + goto illegalOperand; + } + if ((TclGetNumberFromObj(NULL, objv[2], &ptr2, &type2) != TCL_OK) + || (type2 == TCL_NUMBER_DOUBLE) || (type2 == TCL_NUMBER_NAN)) { + idx = 2; + goto illegalOperand; + } + + /* reject negative shift argument */ + switch (type2) { + case TCL_NUMBER_LONG: + invalid = (*((const long *)ptr2) < (long)0); + break; +#ifndef NO_WIDE_TYPE + case TCL_NUMBER_WIDE: + invalid = (*((const Tcl_WideInt *)ptr2) < (Tcl_WideInt)0); + break; +#endif + case TCL_NUMBER_BIG: + /* TODO: const correctness ? */ + invalid = (mp_cmp_d((mp_int *)ptr2, 0) == MP_LT); + break; + default: + /* Unused, here to silence compiler warning */ + invalid = 0; + } + if (invalid) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("negative shift argument", -1)); + return TCL_ERROR; + } + + /* Zero shifted any number of bits is still zero */ + if ((type1 == TCL_NUMBER_LONG) && (*((const long *)ptr1) == (long)0)) { + Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); + return TCL_OK; + } + + /* Large left shifts create integer overflow */ + if ((type2 != TCL_NUMBER_LONG) + || (*((const long *)ptr2) > (long) INT_MAX)) { + /* + * Technically, we could hold the value (1 << (INT_MAX+1)) in an + * mp_int, but since we're using mp_mul_2d() to do the work, and it + * takes only an int argument, that's a good place to draw the line. + */ + + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "integer value too large to represent", -1)); + return TCL_ERROR; + } + shift = (int)(*((const long *)ptr2)); + + /* Handle shifts within the native long range */ + if ((type1 == TCL_NUMBER_LONG) && ((size_t)shift < CHAR_BIT*sizeof(long)) + && (l1 = *((CONST long *)ptr1)) && + !(((l1>0) ? l1 : ~l1) & -(1L<<(CHAR_BIT*sizeof(long)-1-shift)))) { + Tcl_SetObjResult(interp, Tcl_NewLongObj(l1<<shift)); + return TCL_OK; + } + + /* Handle shifts within the native wide range */ + if ((type1 != TCL_NUMBER_BIG) + && ((size_t)shift < CHAR_BIT*sizeof(Tcl_WideInt))) { + Tcl_WideInt w; + + Tcl_GetWideIntFromObj(NULL, objv[1], &w); + if (!(((w>0) ? w : ~w) & -(((Tcl_WideInt)1) + << (CHAR_BIT*sizeof(Tcl_WideInt)-1-shift)))) { + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(w<<shift)); + return TCL_OK; + } + } + + { + mp_int big, bigResult; + + Tcl_TakeBignumFromObj(NULL, objv[1], &big); + + mp_init(&bigResult); + mp_mul_2d(&big, shift, &bigResult); + mp_clear(&big); + + if (!Tcl_IsShared(objv[1])) { + Tcl_SetBignumObj(objv[1], &bigResult); + Tcl_SetObjResult(interp, objv[1]); + } else { + Tcl_SetObjResult(interp, Tcl_NewBignumObj(&bigResult)); + } + } + return TCL_OK; + + illegalOperand: + if (TclGetNumberFromObj(NULL, objv[idx], &ptr1, &type1) != TCL_OK) { + int numBytes; + const char *bytes = Tcl_GetStringFromObj(objv[idx], &numBytes); + if (numBytes == 0) { + description = "empty string"; + } else if (TclCheckBadOctal(NULL, bytes)) { + description = "invalid octal number"; + } else { + description = "non-numeric string"; + } + } else if (type1 == TCL_NUMBER_NAN) { + description = "non-numeric floating-point value"; + } else { + description = "floating-point value"; + } + + Tcl_SetObjResult(interp, + Tcl_ObjPrintf("can't use %s as operand of \"<<\"", description)); + return TCL_ERROR; +} + +/* + *---------------------------------------------------------------------- + * + * TclRshiftOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::>>" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclRshiftOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + ClientData ptr1, ptr2; + int invalid, shift, type1, type2, idx; + const char *description; + long l1; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "value value"); + return TCL_ERROR; + } + + if ((TclGetNumberFromObj(NULL, objv[1], &ptr1, &type1) != TCL_OK) + || (type1 == TCL_NUMBER_DOUBLE) || (type1 == TCL_NUMBER_NAN)) { + idx = 1; + goto illegalOperand; + } + if ((TclGetNumberFromObj(NULL, objv[2], &ptr2, &type2) != TCL_OK) + || (type2 == TCL_NUMBER_DOUBLE) || (type2 == TCL_NUMBER_NAN)) { + idx = 2; + goto illegalOperand; + } + + /* reject negative shift argument */ + switch (type2) { + case TCL_NUMBER_LONG: + invalid = (*((const long *)ptr2) < (long)0); + break; +#ifndef NO_WIDE_TYPE + case TCL_NUMBER_WIDE: + invalid = (*((const Tcl_WideInt *)ptr2) < (Tcl_WideInt)0); + break; +#endif + case TCL_NUMBER_BIG: + /* TODO: const correctness ? */ + invalid = (mp_cmp_d((mp_int *)ptr2, 0) == MP_LT); + break; + default: + /* Unused, here to silence compiler warning */ + invalid = 0; + } + if (invalid) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("negative shift argument", -1)); + return TCL_ERROR; + } + + /* Zero shifted any number of bits is still zero */ + if ((type1 == TCL_NUMBER_LONG) && (*((const long *)ptr1) == (long)0)) { + Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); + return TCL_OK; + } + + /* Quickly force large right shifts to 0 or -1 */ + if ((type2 != TCL_NUMBER_LONG) + || (*((const long *)ptr2) > INT_MAX)) { + /* + * Again, technically, the value to be shifted could be an mp_int so + * huge that a right shift by (INT_MAX+1) bits could not take us to + * the result of 0 or -1, but since we're using mp_div_2d to do the + * work, and it takes only an int argument, we draw the line there. + */ + + int zero; + + switch (type1) { + case TCL_NUMBER_LONG: + zero = (*((const long *)ptr1) > (long)0); + break; +#ifndef NO_WIDE_TYPE + case TCL_NUMBER_WIDE: + zero = (*((const Tcl_WideInt *)ptr1) > (Tcl_WideInt)0); + break; +#endif + case TCL_NUMBER_BIG: + /* TODO: const correctness ? */ + zero = (mp_cmp_d((mp_int *)ptr1, 0) == MP_GT); + break; + default: + /* Unused, here to silence compiler warning. */ + zero = 0; + } + Tcl_SetObjResult(interp, Tcl_NewIntObj(zero ? 0 : -1)); + return TCL_OK; + } + + shift = (int)(*((const long *)ptr2)); + /* Handle shifts within the native long range */ + if (type1 == TCL_NUMBER_LONG) { + l1 = *((const long *)ptr1); + if ((size_t)shift >= CHAR_BIT*sizeof(long)) { + Tcl_SetObjResult(interp, Tcl_NewIntObj(l1 >= (long)0 ? 0 : -1)); + } else { + Tcl_SetObjResult(interp, Tcl_NewIntObj(l1 >> shift)); + } + return TCL_OK; + } + +#ifndef NO_WIDE_TYPE + /* Handle shifts within the native wide range */ + if (type1 == TCL_NUMBER_WIDE) { + Tcl_WideInt w = *((const Tcl_WideInt *)ptr1); + if ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideInt)) { + Tcl_SetObjResult(interp, + Tcl_NewIntObj(w >= (Tcl_WideInt)0 ? 0 : -1)); + } else { + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(w >> shift)); + } + return TCL_OK; + } +#endif + + { + mp_int big, bigResult, bigRemainder; + + Tcl_TakeBignumFromObj(NULL, objv[1], &big); + + mp_init(&bigResult); + mp_init(&bigRemainder); + mp_div_2d(&big, shift, &bigResult, &bigRemainder); + if (mp_cmp_d(&bigRemainder, 0) == MP_LT) { + /* Convert to Tcl's integer division rules */ + mp_sub_d(&bigResult, 1, &bigResult); + } + mp_clear(&bigRemainder); + mp_clear(&big); + + if (!Tcl_IsShared(objv[1])) { + Tcl_SetBignumObj(objv[1], &bigResult); + Tcl_SetObjResult(interp, objv[1]); + } else { + Tcl_SetObjResult(interp, Tcl_NewBignumObj(&bigResult)); + } + } + return TCL_OK; + + illegalOperand: + if (TclGetNumberFromObj(NULL, objv[idx], &ptr1, &type1) != TCL_OK) { + int numBytes; + const char *bytes = Tcl_GetStringFromObj(objv[idx], &numBytes); + if (numBytes == 0) { + description = "empty string"; + } else if (TclCheckBadOctal(NULL, bytes)) { + description = "invalid octal number"; + } else { + description = "non-numeric string"; + } + } else if (type1 == TCL_NUMBER_NAN) { + description = "non-numeric floating-point value"; + } else { + description = "floating-point value"; + } + + Tcl_SetObjResult(interp, + Tcl_ObjPrintf("can't use %s as operand of \">>\"", description)); + return TCL_ERROR; +} + +/* + *---------------------------------------------------------------------- + * + * TclModOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::%" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclModOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + Tcl_Obj *argObj; + ClientData ptr1, ptr2; + int type1, type2; + long l1, l2 = 0; + const char *description; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "value value"); + return TCL_ERROR; + } + + if ((TclGetNumberFromObj(NULL, objv[1], &ptr1, &type1) != TCL_OK) + || (type1 == TCL_NUMBER_DOUBLE) || (type1 == TCL_NUMBER_NAN)) { + argObj = objv[1]; + goto badArg; + } + if ((TclGetNumberFromObj(NULL, objv[2], &ptr2, &type2) != TCL_OK) + || (type2 == TCL_NUMBER_DOUBLE) || (type2 == TCL_NUMBER_NAN)) { + argObj = objv[2]; + goto badArg; + } + + if (type2 == TCL_NUMBER_LONG) { + l2 = *((CONST long *)ptr2); + if (l2 == 0) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("divide by zero", -1)); + Tcl_SetErrorCode(interp, "ARITH", "DIVZERO", "divide by zero", + NULL); + return TCL_ERROR; + } + if ((l2 == 1) || (l2 == -1)) { + Tcl_SetIntObj(Tcl_GetObjResult(interp), 0); + return TCL_OK; + } + } + if (type1 == TCL_NUMBER_LONG) { + l1 = *((CONST long *)ptr1); + if (l1 == 0) { + Tcl_SetIntObj(Tcl_GetObjResult(interp), 0); + return TCL_OK; + } + if (type2 == TCL_NUMBER_LONG) { + /* Both operands are long; do native calculation */ + long lRemainder, lQuotient = l1 / l2; + + /* Force Tcl's integer division rules */ + /* TODO: examine for logic simplification */ + if (((lQuotient < 0) || ((lQuotient == 0) && + ((l1 < 0 && l2 > 0) || (l1 > 0 && l2 < 0)))) && + ((lQuotient * l2) != l1)) { + lQuotient -= 1; + } + lRemainder = l1 - l2*lQuotient; + Tcl_SetLongObj(Tcl_GetObjResult(interp), lRemainder); + return TCL_OK; + } + /* + * First operand fits in long; second does not, so the second has + * greater magnitude than first. No need to divide to determine the + * remainder. + */ +#ifndef NO_WIDE_TYPE + if (type2 == TCL_NUMBER_WIDE) { + Tcl_WideInt w2 = *((CONST Tcl_WideInt *)ptr2); + + if ((l1 > 0) ^ (w2 > (Tcl_WideInt)0)) { + /* Arguments are opposite sign; remainder is sum */ + Tcl_SetObjResult(interp, + Tcl_NewWideIntObj(w2+(Tcl_WideInt)l1)); + return TCL_OK; + } + /* Arguments are same sign; remainder is first operand */ + Tcl_SetObjResult(interp, objv[1]); + return TCL_OK; + } +#endif + { + mp_int big2; + Tcl_TakeBignumFromObj(NULL, objv[2], &big2); + + /* TODO: internals intrusion */ + if ((l1 > 0) ^ (big2.sign == MP_ZPOS)) { + /* Arguments are opposite sign; remainder is sum */ + mp_int big1; + TclBNInitBignumFromLong(&big1, l1); + mp_add(&big2, &big1, &big2); + Tcl_SetObjResult(interp, Tcl_NewBignumObj(&big2)); + } else { + /* Arguments are same sign; remainder is first operand */ + Tcl_SetObjResult(interp, objv[1]); + /* TODO: free big2? */ + } + } + return TCL_OK; + } +#ifndef NO_WIDE_TYPE + if (type1 == TCL_NUMBER_WIDE) { + Tcl_WideInt w1 = *((CONST Tcl_WideInt *)ptr1); + if (type2 != TCL_NUMBER_BIG) { + Tcl_WideInt w2, wQuotient, wRemainder; + + Tcl_GetWideIntFromObj(NULL, objv[2], &w2); + wQuotient = w1 / w2; + + /* Force Tcl's integer division rules */ + /* TODO: examine for logic simplification */ + if (((wQuotient < ((Tcl_WideInt) 0)) + || ((wQuotient == ((Tcl_WideInt) 0)) && ( + (w1 < ((Tcl_WideInt) 0) && w2 > ((Tcl_WideInt) 0)) + || (w1 > ((Tcl_WideInt) 0) && w2 < ((Tcl_WideInt) 0))) + )) && ((wQuotient * w2) != w1)) { + wQuotient -= (Tcl_WideInt) 1; + } + wRemainder = w1 - w2*wQuotient; + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(wRemainder)); + } else { + mp_int big2; + Tcl_TakeBignumFromObj(NULL, objv[2], &big2); + + /* TODO: internals intrusion */ + if ((w1 > ((Tcl_WideInt) 0)) ^ (big2.sign == MP_ZPOS)) { + /* Arguments are opposite sign; remainder is sum */ + mp_int big1; + TclBNInitBignumFromWideInt(&big1, w1); + mp_add(&big2, &big1, &big2); + Tcl_SetObjResult(interp, Tcl_NewBignumObj(&big2)); + } else { + /* Arguments are same sign; remainder is first operand */ + Tcl_SetObjResult(interp, objv[1]); + } + } + return TCL_OK; + } +#endif + { + mp_int big1, big2, bigResult, bigRemainder; + + Tcl_GetBignumFromObj(NULL, objv[1], &big1); + Tcl_GetBignumFromObj(NULL, objv[2], &big2); + mp_init(&bigResult); + mp_init(&bigRemainder); + mp_div(&big1, &big2, &bigResult, &bigRemainder); + if (!mp_iszero(&bigRemainder) && (bigRemainder.sign != big2.sign)) { + /* Convert to Tcl's integer division rules */ + mp_sub_d(&bigResult, 1, &bigResult); + mp_add(&bigRemainder, &big2, &bigRemainder); + } + mp_copy(&bigRemainder, &bigResult); + mp_clear(&bigRemainder); + mp_clear(&big1); + mp_clear(&big2); + if (Tcl_IsShared(objv[1])) { + Tcl_SetObjResult(interp, Tcl_NewBignumObj(&bigResult)); + } else { + Tcl_SetBignumObj(objv[1], &bigResult); + Tcl_SetObjResult(interp, objv[1]); + } + return TCL_OK; + } + + badArg: + if (TclGetNumberFromObj(NULL, argObj, &ptr1, &type1) != TCL_OK) { + int numBytes; + CONST char *bytes = Tcl_GetStringFromObj(argObj, &numBytes); + if (numBytes == 0) { + description = "empty string"; + } else if (TclCheckBadOctal(NULL, bytes)) { + description = "invalid octal number"; + } else { + description = "non-numeric string"; + } + } else if (type1 == TCL_NUMBER_NAN) { + description = "non-numeric floating-point value"; + } else { + description = "floating-point value"; + } + + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't use %s as operand of \"%%\"", description)); + return TCL_ERROR; +} + +/* + *---------------------------------------------------------------------- + * + * TclNeqOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::!=" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclNeqOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + int result = 1, cmp, len1, len2; + const char *str1, *str2; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "value value"); + return TCL_ERROR; + } + + switch (CompareNumbers(NULL, objv[1], objv[2], &cmp)) { + case TCL_ERROR: + /* + * Got a string + */ + str1 = Tcl_GetStringFromObj(objv[1], &len1); + str2 = Tcl_GetStringFromObj(objv[2], &len2); + if (len1 == len2 && !strcmp(str1, str2)) { + result = 0; + } + case TCL_BREAK: /* Deliberate fallthrough */ + break; + case TCL_OK: + /* + * Got proper numbers + */ + if (cmp == MP_EQ) { + result = 0; + } + } + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), result); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclStrneqOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::ne" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclStrneqOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + const char *s1, *s2; + int s1len, s2len; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "value value"); + return TCL_ERROR; + } + + s1 = Tcl_GetStringFromObj(objv[1], &s1len); + s2 = Tcl_GetStringFromObj(objv[2], &s2len); + if (s1len == s2len && !strcmp(s1, s2)) { + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 0); + } else { + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 1); + } + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclInOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::in" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclInOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + const char *s1, *s2; + int s1len, s2len, i, len; + Tcl_Obj **listObj; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "value list"); + return TCL_ERROR; + } + + if (Tcl_ListObjGetElements(interp, objv[2], &len, &listObj) != TCL_OK) { + return TCL_ERROR; + } + s1 = Tcl_GetStringFromObj(objv[1], &s1len); + for (i=0 ; i<len ; i++) { + s2 = Tcl_GetStringFromObj(listObj[i], &s2len); + if (s1len == s2len && !strcmp(s1, s2)) { + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 1); + return TCL_OK; + } + } + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 0); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclNiOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::ni" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclNiOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + const char *s1, *s2; + int s1len, s2len, i, len; + Tcl_Obj **listObj; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 1, objv, "value list"); + return TCL_ERROR; + } + + if (Tcl_ListObjGetElements(interp, objv[2], &len, &listObj) != TCL_OK) { + return TCL_ERROR; + } + s1 = Tcl_GetStringFromObj(objv[1], &s1len); + for (i=0 ; i<len ; i++) { + s2 = Tcl_GetStringFromObj(listObj[i], &s2len); + if (s1len == s2len && !strcmp(s1, s2)) { + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 0); + return TCL_OK; + } + } + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), 1); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclLessOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::<" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclLessOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + int result = 1; + + if (objc > 2) { + int i, cmp, len1, len2; + const char *str1, *str2; + + for (i=1 ; i<objc-1 ; i++) { + switch (CompareNumbers(NULL, objv[i], objv[i+1], &cmp)) { + case TCL_ERROR: + /* + * Got a string + */ + str1 = Tcl_GetStringFromObj(objv[i], &len1); + str2 = Tcl_GetStringFromObj(objv[i+1], &len2); + if (TclpUtfNcmp2(str1, str2, + (size_t) ((len1 < len2) ? len1 : len2)) >= 0) { + result = 0; + i = objc; + } + continue; + case TCL_OK: + /* + * Got proper numbers + */ + if (cmp != MP_LT) { + result = 0; + i = objc; + } + continue; + case TCL_BREAK: + /* + * Got a NaN (which is different from everything, including + * itself) + */ + result = 0; + i = objc; + continue; + } + } + } + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), result); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclLeqOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::<=" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclLeqOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + int result = 1; + + if (objc > 2) { + int i, cmp, len1, len2; + const char *str1, *str2; + + for (i=1 ; i<objc-1 ; i++) { + switch (CompareNumbers(NULL, objv[i], objv[i+1], &cmp)) { + case TCL_ERROR: + /* + * Got a string + */ + str1 = Tcl_GetStringFromObj(objv[i], &len1); + str2 = Tcl_GetStringFromObj(objv[i+1], &len2); + if (TclpUtfNcmp2(str1, str2, + (size_t) ((len1 < len2) ? len1 : len2)) > 0) { + result = 0; + i = objc; + } + continue; + case TCL_OK: + /* + * Got proper numbers + */ + if (cmp == MP_GT) { + result = 0; + i = objc; + } + continue; + case TCL_BREAK: + /* + * Got a NaN (which is different from everything, including + * itself) + */ + result = 0; + i = objc; + continue; + } + } + } + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), result); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclGreaterOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::>" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclGreaterOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + int result = 1; + + if (objc > 2) { + int i, cmp, len1, len2; + const char *str1, *str2; + + for (i=1 ; i<objc-1 ; i++) { + switch (CompareNumbers(NULL, objv[i], objv[i+1], &cmp)) { + case TCL_ERROR: + /* + * Got a string + */ + str1 = Tcl_GetStringFromObj(objv[i], &len1); + str2 = Tcl_GetStringFromObj(objv[i+1], &len2); + if (TclpUtfNcmp2(str1, str2, + (size_t) ((len1 < len2) ? len1 : len2)) <= 0) { + result = 0; + i = objc; + } + continue; + case TCL_OK: + /* + * Got proper numbers + */ + if (cmp != MP_GT) { + result = 0; + i = objc; + } + continue; + case TCL_BREAK: + /* + * Got a NaN (which is different from everything, including + * itself) + */ + result = 0; + i = objc; + continue; + } + } + } + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), result); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclGeqOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::>=" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclGeqOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + int result = 1; + + if (objc > 2) { + int i, cmp, len1, len2; + const char *str1, *str2; + + for (i=1 ; i<objc-1 ; i++) { + switch (CompareNumbers(NULL, objv[i], objv[i+1], &cmp)) { + case TCL_ERROR: + /* + * Got a string + */ + str1 = Tcl_GetStringFromObj(objv[i], &len1); + str2 = Tcl_GetStringFromObj(objv[i+1], &len2); + if (TclpUtfNcmp2(str1, str2, + (size_t) ((len1 < len2) ? len1 : len2)) < 0) { + result = 0; + i = objc; + } + continue; + case TCL_OK: + /* + * Got proper numbers + */ + if (cmp == MP_LT) { + result = 0; + i = objc; + } + continue; + case TCL_BREAK: + /* + * Got a NaN (which is different from everything, including + * itself) + */ + result = 0; + i = objc; + continue; + } + } + } + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), result); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclEqOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::==" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclEqOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + int result = 1; + + if (objc > 2) { + int i, cmp, len1, len2; + const char *str1, *str2; + + for (i=1 ; i<objc-1 ; i++) { + switch (CompareNumbers(NULL, objv[i], objv[i+1], &cmp)) { + case TCL_ERROR: + /* + * Got a string + */ + str1 = Tcl_GetStringFromObj(objv[i], &len1); + str2 = Tcl_GetStringFromObj(objv[i+1], &len2); + if (len1 != len2 || strcmp(str1, str2)) { + result = 0; + i = objc; + } + continue; + case TCL_OK: + /* + * Got proper numbers + */ + if (cmp != MP_EQ) { + result = 0; + i = objc; + } + continue; + case TCL_BREAK: + /* + * Got a NaN (which is different from everything, including + * itself) + */ + result = 0; + i = objc; + continue; + } + } + } + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), result); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclStreqOpCmd -- + * + * This procedure is invoked to process the "::tcl::mathop::eq" Tcl + * command. See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclStreqOpCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + int result = 1; + + if (objc > 2) { + int i, len1, len2; + const char *str1, *str2; + + for (i=1 ; i<objc-1 ; i++) { + str1 = Tcl_GetStringFromObj(objv[i], &len1); + str2 = Tcl_GetStringFromObj(objv[i+1], &len2); + if (len1 != len2 || strcmp(str1, str2)) { + result = 0; + break; + } + } + } + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), result); + return TCL_OK; +} +#endif + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tclNRE.h b/generic/tclNRE.h new file mode 100755 index 0000000..e69de29 --- /dev/null +++ b/generic/tclNRE.h diff --git a/generic/tclParseExpr.c b/generic/tclParseExpr.c new file mode 100644 index 0000000..c6471a2 --- /dev/null +++ b/generic/tclParseExpr.c @@ -0,0 +1,1080 @@ +/* + * tclParseExpr.c -- + * + * This file contains functions that parse Tcl expressions. They do so in + * a general-purpose fashion that can be used for many different + * purposes, including compilation, direct execution, code analysis, etc. + * + * Copyright (c) 1997 Sun Microsystems, Inc. + * Copyright (c) 1998-2000 by Scriptics Corporation. + * Contributions from Don Porter, NIST, 2006. (not subject to US copyright) + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclParseExpr.c,v 1.44 2006/08/30 20:46:20 dgp Exp $ + */ + +#include "tclInt.h" + +/* + * The ExprNode structure represents one node of the parse tree produced + * as an interim structure by the expression parser. + */ + +typedef struct ExprNode { + unsigned char lexeme; /* Code that identifies the type of this node */ + int left; /* Index of the left operand of this operator node */ + int right; /* Index of the right operand of this operator node */ + int parent; /* Index of the operator of this operand node */ + int token; /* Index of the Tcl_Tokens of this leaf node */ +} ExprNode; + +/* + * Set of lexeme codes stored in ExprNode structs to label and categorize + * the lexemes found. + */ + +#define LEAF (1<<7) +#define UNARY (1<<6) +#define BINARY (1<<5) + +#define NODE_TYPE ( LEAF | UNARY | BINARY) + +#define PLUS 1 +#define MINUS 2 +#define BAREWORD 3 +#define INCOMPLETE 4 +#define INVALID 5 + +#define NUMBER ( LEAF | 1) +#define SCRIPT ( LEAF | 2) +#define BOOLEAN ( LEAF | BAREWORD) +#define BRACED ( LEAF | 4) +#define VARIABLE ( LEAF | 5) +#define QUOTED ( LEAF | 6) +#define EMPTY ( LEAF | 7) + +#define UNARY_PLUS ( UNARY | PLUS) +#define UNARY_MINUS ( UNARY | MINUS) +#define FUNCTION ( UNARY | BAREWORD) +#define START ( UNARY | 4) +#define OPEN_PAREN ( UNARY | 5) +#define NOT ( UNARY | 6) +#define BIT_NOT ( UNARY | 7) + +#define BINARY_PLUS ( BINARY | PLUS) +#define BINARY_MINUS ( BINARY | MINUS) +#define COMMA ( BINARY | 3) +#define MULT ( BINARY | 4) +#define DIVIDE ( BINARY | 5) +#define MOD ( BINARY | 6) +#define LESS ( BINARY | 7) +#define GREATER ( BINARY | 8) +#define BIT_AND ( BINARY | 9) +#define BIT_XOR ( BINARY | 10) +#define BIT_OR ( BINARY | 11) +#define QUESTION ( BINARY | 12) +#define COLON ( BINARY | 13) +#define LEFT_SHIFT ( BINARY | 14) +#define RIGHT_SHIFT ( BINARY | 15) +#define LEQ ( BINARY | 16) +#define GEQ ( BINARY | 17) +#define EQUAL ( BINARY | 18) +#define NEQ ( BINARY | 19) +#define AND ( BINARY | 20) +#define OR ( BINARY | 21) +#define STREQ ( BINARY | 22) +#define STRNEQ ( BINARY | 23) +#define EXPON ( BINARY | 24) +#define IN_LIST ( BINARY | 25) +#define NOT_IN_LIST ( BINARY | 26) +#define CLOSE_PAREN ( BINARY | 27) +#define END ( BINARY | 28) + +/* + * Declarations for local functions to this file: + */ + +static void GenerateTokens(ExprNode *nodes, Tcl_Parse *scratchPtr, + Tcl_Parse *parsePtr); +static int ParseLexeme(CONST char *start, int numBytes, + unsigned char *lexemePtr); + + +/* + *---------------------------------------------------------------------- + * + * Tcl_ParseExpr -- + * + * Given a string, the numBytes bytes starting at start, this function + * parses it as a Tcl expression and stores information about the + * structure of the expression in the Tcl_Parse struct indicated by the + * caller. + * + * Results: + * If the string is successfully parsed as a valid Tcl expression, + * TCL_OK is returned, and data about the expression structure is + * written to *parsePtr. If the string cannot be parsed as a valid + * Tcl expression, TCL_ERROR is returned, and if interp is non-NULL, + * an error message is written to interp. + * + * Side effects: + * If there is insufficient space in parsePtr to hold all the information + * about the expression, then additional space is malloc-ed. If the + * function returns TCL_OK then the caller must eventually invoke + * Tcl_FreeParse to release any additional space that was allocated. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_ParseExpr( + Tcl_Interp *interp, /* Used for error reporting. */ + CONST char *start, /* Start of source string to parse. */ + int numBytes, /* Number of bytes in string. If < 0, the + * string consists of all bytes up to the + * first null character. */ + Tcl_Parse *parsePtr) /* Structure to fill with information about + * the parsed expression; any previous + * information in the structure is ignored. */ +{ +#define NUM_STATIC_NODES 64 + ExprNode staticNodes[NUM_STATIC_NODES]; + ExprNode *lastOrphanPtr, *nodes = staticNodes; + int nodesAvailable = NUM_STATIC_NODES; + int nodesUsed = 0; + Tcl_Parse scratch; /* Parsing scratch space */ + Tcl_Obj *msg = NULL, *post = NULL; + int scanned = 0, code = TCL_OK, insertMark = 0; + CONST char *mark = "_@_"; + CONST int limit = 25; + static CONST unsigned char prec[80] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 15, 15, 5, 16, 16, 16, 13, 13, 11, 10, 9, 6, 6, 14, 14, + 13, 13, 12, 12, 8, 7, 12, 12, 17, 12, 12, 3, 1, 0, 0, 0, + 0, 18, 18, 18, 2, 4, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, + }; + + if (numBytes < 0) { + numBytes = (start ? strlen(start) : 0); + } + + TclParseInit(interp, start, numBytes, &scratch); + TclParseInit(interp, start, numBytes, parsePtr); + + /* Initialize the parse tree with the special "START" node */ + + nodes->lexeme = START; + nodes->left = -1; + nodes->right = -1; + nodes->parent = -1; + nodes->token = -1; + lastOrphanPtr = nodes; + nodesUsed++; + + while ((code == TCL_OK) && (lastOrphanPtr->lexeme != END)) { + ExprNode *nodePtr, *lastNodePtr; + Tcl_Token *tokenPtr; + + /* + * Each pass through this loop adds one more ExprNode. + * Allocate space for one if required. + */ + if (nodesUsed >= nodesAvailable) { + int lastOrphanIdx = lastOrphanPtr - nodes; + int size = nodesUsed * 2; + ExprNode *newPtr; + + if (nodes == staticNodes) { + nodes = NULL; + } + do { + newPtr = (ExprNode *) attemptckrealloc( (char *) nodes, + (unsigned int) (size * sizeof(ExprNode)) ); + } while ((newPtr == NULL) + && ((size -= (size - nodesUsed) / 2) > nodesUsed)); + if (newPtr == NULL) { + msg = Tcl_NewStringObj( + "not enough memory to parse expression", -1); + code = TCL_ERROR; + continue; + } + nodesAvailable = size; + if (nodes == NULL) { + memcpy((VOID *) newPtr, (VOID *) staticNodes, + (size_t) (nodesUsed * sizeof(ExprNode))); + } + nodes = newPtr; + lastOrphanPtr = nodes + lastOrphanIdx; + } + nodePtr = nodes + nodesUsed; + lastNodePtr = nodePtr - 1; + + /* Skip white space between lexemes */ + + scanned = TclParseAllWhiteSpace(start, numBytes); + start += scanned; + numBytes -= scanned; + + scanned = ParseLexeme(start, numBytes, &(nodePtr->lexeme)); + + /* Use context to categorize the lexemes that are ambiguous */ + + if ((NODE_TYPE & nodePtr->lexeme) == 0) { + switch (nodePtr->lexeme) { + case INVALID: + msg = Tcl_NewObj(); + TclObjPrintf(NULL, msg, + "invalid character \"%.*s\"", scanned, start); + code = TCL_ERROR; + continue; + case INCOMPLETE: + msg = Tcl_NewObj(); + TclObjPrintf(NULL, msg, + "incomplete operator \"%.*s\"", scanned, start); + code = TCL_ERROR; + continue; + case BAREWORD: + if (start[scanned+TclParseAllWhiteSpace( + start+scanned, numBytes-scanned)] == '(') { + nodePtr->lexeme = FUNCTION; + } else { + Tcl_Obj *objPtr = Tcl_NewStringObj(start, scanned); + Tcl_IncrRefCount(objPtr); + code = Tcl_ConvertToType(NULL, objPtr, &tclBooleanType); + Tcl_DecrRefCount(objPtr); + if (code == TCL_OK) { + nodePtr->lexeme = BOOLEAN; + } else { + msg = Tcl_NewObj(); + TclObjPrintf(NULL, msg, "invalid bareword \"%.*s%s\"", + (scanned < limit) ? scanned : limit - 3, start, + (scanned < limit) ? "" : "..."); + post = Tcl_NewObj(); + TclObjPrintf(NULL, post, + "should be \"$%.*s%s\" or \"{%.*s%s}\"", + (scanned < limit) ? scanned : limit - 3, + start, (scanned < limit) ? "" : "...", + (scanned < limit) ? scanned : limit - 3, + start, (scanned < limit) ? "" : "..."); + TclObjPrintf(NULL, post, " or \"%.*s%s(...)\" or ...", + (scanned < limit) ? scanned : limit - 3, + start, (scanned < limit) ? "" : "..."); + continue; + } + } + break; + case PLUS: + case MINUS: + if ((NODE_TYPE & lastNodePtr->lexeme) == LEAF) { + nodePtr->lexeme |= BINARY; + } else { + nodePtr->lexeme |= UNARY; + } + } + } + + /* Add node to parse tree based on category */ + + switch (NODE_TYPE & nodePtr->lexeme) { + case LEAF: { + CONST char *end; + + if ((NODE_TYPE & lastNodePtr->lexeme) == LEAF) { + CONST char *operand = + scratch.tokenPtr[lastNodePtr->token].start; + + msg = Tcl_NewObj(); + TclObjPrintf(NULL, msg, "missing operator at %s", mark); + if (operand[0] == '0') { + Tcl_Obj *copy = Tcl_NewStringObj(operand, + start + scanned - operand); + if (TclCheckBadOctal(NULL, Tcl_GetString(copy))) { + post = Tcl_NewStringObj( + "looks like invalid octal number", -1); + } + Tcl_DecrRefCount(copy); + } + scanned = 0; + insertMark = 1; + code = TCL_ERROR; + continue; + } + + if (scratch.numTokens+1 >= scratch.tokensAvailable) { + TclExpandTokenArray(&scratch); + } + nodePtr->token = scratch.numTokens; + tokenPtr = scratch.tokenPtr + nodePtr->token; + tokenPtr->type = TCL_TOKEN_SUB_EXPR; + tokenPtr->start = start; + scratch.numTokens++; + + switch (nodePtr->lexeme) { + case NUMBER: + case BOOLEAN: + tokenPtr = scratch.tokenPtr + scratch.numTokens; + tokenPtr->type = TCL_TOKEN_TEXT; + tokenPtr->start = start; + tokenPtr->size = scanned; + tokenPtr->numComponents = 0; + scratch.numTokens++; + + break; + + case QUOTED: + code = Tcl_ParseQuotedString(interp, start, numBytes, + &scratch, 1, &end); + if (code != TCL_OK) { + scanned = scratch.term - start; + scanned += (scanned < numBytes); + continue; + } + scanned = end - start; + break; + + case BRACED: + code = Tcl_ParseBraces(interp, start, numBytes, + &scratch, 1, &end); + if (code != TCL_OK) { + continue; + } + scanned = end - start; + break; + + case VARIABLE: + code = Tcl_ParseVarName(interp, start, numBytes, &scratch, 1); + if (code != TCL_OK) { + scanned = scratch.term - start; + scanned += (scanned < numBytes); + continue; + } + tokenPtr = scratch.tokenPtr + nodePtr->token + 1; + if (tokenPtr->type != TCL_TOKEN_VARIABLE) { + msg = Tcl_NewStringObj("invalid character \"$\"", -1); + code = TCL_ERROR; + continue; + } + scanned = tokenPtr->size; + break; + + case SCRIPT: + tokenPtr = scratch.tokenPtr + scratch.numTokens; + tokenPtr->type = TCL_TOKEN_COMMAND; + tokenPtr->start = start; + tokenPtr->numComponents = 0; + + end = start + numBytes; + start++; + while (1) { + Tcl_Parse nested; + code = Tcl_ParseCommand(interp, + start, (end - start), 1, &nested); + if (code != TCL_OK) { + parsePtr->term = nested.term; + parsePtr->errorType = nested.errorType; + parsePtr->incomplete = nested.incomplete; + break; + } + start = (nested.commandStart + nested.commandSize); + Tcl_FreeParse(&nested); + if ((nested.term < end) && (*nested.term == ']') + && !nested.incomplete) { + break; + } + + if (start == end) { + msg = Tcl_NewStringObj("missing close-bracket", -1); + parsePtr->term = tokenPtr->start; + parsePtr->errorType = TCL_PARSE_MISSING_BRACKET; + parsePtr->incomplete = 1; + code = TCL_ERROR; + break; + } + } + end = start; + start = tokenPtr->start; + if (code != TCL_OK) { + scanned = parsePtr->term - start; + scanned += (scanned < numBytes); + continue; + } + scanned = end - start; + tokenPtr->size = scanned; + scratch.numTokens++; + break; + } + + tokenPtr = scratch.tokenPtr + nodePtr->token; + tokenPtr->size = scanned; + tokenPtr->numComponents = scratch.numTokens - nodePtr->token - 1; + + nodePtr->left = -1; + nodePtr->right = -1; + nodePtr->parent = -1; + lastOrphanPtr = nodePtr; + nodesUsed++; + break; + } + + case UNARY: + if ((NODE_TYPE & lastNodePtr->lexeme) == LEAF) { + msg = Tcl_NewObj(); + TclObjPrintf(NULL, msg, "missing operator at %s", mark); + scanned = 0; + insertMark = 1; + code = TCL_ERROR; + continue; + } + nodePtr->left = -1; + nodePtr->right = -1; + nodePtr->parent = -1; + + if (scratch.numTokens >= scratch.tokensAvailable) { + TclExpandTokenArray(&scratch); + } + nodePtr->token = scratch.numTokens; + tokenPtr = scratch.tokenPtr + nodePtr->token; + tokenPtr->type = TCL_TOKEN_OPERATOR; + tokenPtr->start = start; + tokenPtr->size = scanned; + tokenPtr->numComponents = 0; + scratch.numTokens++; + + lastOrphanPtr = nodePtr; + nodesUsed++; + break; + + case BINARY: { + ExprNode *otherPtr = NULL; + unsigned char precedence = prec[nodePtr->lexeme]; + + if ((nodePtr->lexeme == CLOSE_PAREN) + && (lastNodePtr->lexeme == OPEN_PAREN)) { + if (lastNodePtr[-1].lexeme == FUNCTION) { + /* Normally, "()" is a syntax error, but as a special + * case accept it as an argument list for a function */ + scanned = 0; + nodePtr->lexeme = EMPTY; + nodePtr->left = -1; + nodePtr->right = -1; + nodePtr->parent = -1; + nodePtr->token = -1; + + lastOrphanPtr = nodePtr; + nodesUsed++; + break; + + } + msg = Tcl_NewObj(); + TclObjPrintf(NULL, msg, "empty subexpression at %s", mark); + scanned = 0; + insertMark = 1; + code = TCL_ERROR; + continue; + } + + + if ((NODE_TYPE & lastNodePtr->lexeme) != LEAF) { + if (prec[lastNodePtr->lexeme] > precedence) { + if (lastNodePtr->lexeme == OPEN_PAREN) { + msg = Tcl_NewStringObj("unbalanced open paren", -1); + } else if (lastNodePtr->lexeme == COMMA) { + msg = Tcl_NewObj(); + TclObjPrintf(NULL, msg, + "missing function argument at %s", mark); + scanned = 0; + insertMark = 1; + } else if (lastNodePtr->lexeme == START) { + msg = Tcl_NewStringObj("empty expression", -1); + } + } else { + if (nodePtr->lexeme == CLOSE_PAREN) { + msg = Tcl_NewStringObj("unbalanced close paren", -1); + } else if ((nodePtr->lexeme == COMMA) + && (lastNodePtr->lexeme == OPEN_PAREN) + && (lastNodePtr[-1].lexeme == FUNCTION)) { + msg = Tcl_NewObj(); + TclObjPrintf(NULL, msg, + "missing function argument at %s", mark); + scanned = 0; + insertMark = 1; + } + } + if (msg == NULL) { + msg = Tcl_NewObj(); + TclObjPrintf(NULL, msg, "missing operand at %s", mark); + scanned = 0; + insertMark = 1; + } + code = TCL_ERROR; + continue; + } + + while (1) { + + if (lastOrphanPtr->parent >= 0) { + otherPtr = nodes + lastOrphanPtr->parent; + } else if (lastOrphanPtr->left >= 0) { + Tcl_Panic("Tcl_ParseExpr: left closure programming error"); + } else { + lastOrphanPtr->parent = lastOrphanPtr - nodes; + otherPtr = lastOrphanPtr; + } + otherPtr--; + + if (prec[otherPtr->lexeme] < precedence) { + break; + } + + /* Special association rules for the ternary operators */ + if (prec[otherPtr->lexeme] == precedence) { + if ((otherPtr->lexeme == QUESTION) + && (lastOrphanPtr->lexeme != COLON)) { + break; + } + if ((otherPtr->lexeme == COLON) + && (nodePtr->lexeme == QUESTION)) { + break; + } + } + + /* Some checks before linking */ + if ((otherPtr->lexeme == OPEN_PAREN) + && (nodePtr->lexeme != CLOSE_PAREN)) { + lastOrphanPtr = otherPtr; + msg = Tcl_NewStringObj("unbalanced open paren", -1); + code = TCL_ERROR; + break; + } + if ((otherPtr->lexeme == QUESTION) + && (lastOrphanPtr->lexeme != COLON)) { + msg = Tcl_NewObj(); + TclObjPrintf(NULL, msg, + "missing operator \":\" at %s", mark); + scanned = 0; + insertMark = 1; + code = TCL_ERROR; + break; + } + if ((lastOrphanPtr->lexeme == COLON) + && (otherPtr->lexeme != QUESTION)) { + msg = Tcl_NewStringObj( + "unexpected operator \":\" without preceding \"?\"", + -1); + code = TCL_ERROR; + break; + } + + /* Link orphan as right operand of otherPtr */ + otherPtr->right = lastOrphanPtr - nodes; + lastOrphanPtr->parent = otherPtr - nodes; + lastOrphanPtr = otherPtr; + + if (otherPtr->lexeme == OPEN_PAREN) { + /* CLOSE_PAREN can only close one OPEN_PAREN */ + tokenPtr = scratch.tokenPtr + otherPtr->token; + tokenPtr->size = start + scanned - tokenPtr->start; + break; + } + if (otherPtr->lexeme == START) { + /* Don't backtrack beyond the start */ + break; + } + } + if (code != TCL_OK) { + continue; + } + + if (nodePtr->lexeme == CLOSE_PAREN) { + if (otherPtr->lexeme == START) { + msg = Tcl_NewStringObj("unbalanced close paren", -1); + code = TCL_ERROR; + continue; + } + /* Create no node for a CLOSE_PAREN lexeme */ + break; + } + + if ((nodePtr->lexeme == COMMA) && ((otherPtr->lexeme != OPEN_PAREN) + || (otherPtr[-1].lexeme != FUNCTION))) { + msg = Tcl_NewStringObj( + "unexpected \",\" outside function argument list", -1); + code = TCL_ERROR; + continue; + } + + if (lastOrphanPtr->lexeme == COLON) { + msg = Tcl_NewStringObj( + "unexpected operator \":\" without preceding \"?\"", + -1); + code = TCL_ERROR; + continue; + } + + /* Link orphan as left operand of new node */ + nodePtr->right = -1; + + if (scratch.numTokens >= scratch.tokensAvailable) { + TclExpandTokenArray(&scratch); + } + nodePtr->token = scratch.numTokens; + tokenPtr = scratch.tokenPtr + nodePtr->token; + tokenPtr->type = TCL_TOKEN_OPERATOR; + tokenPtr->start = start; + tokenPtr->size = scanned; + tokenPtr->numComponents = 0; + scratch.numTokens++; + + nodePtr->left = lastOrphanPtr - nodes; + nodePtr->parent = lastOrphanPtr->parent; + lastOrphanPtr->parent = nodePtr - nodes; + lastOrphanPtr = nodePtr; + nodesUsed++; + break; + } + } + + start += scanned; + numBytes -= scanned; + } + + if (code == TCL_OK) { + /* Shift tokens from scratch space to caller space */ + GenerateTokens(nodes, &scratch, parsePtr); + } else { + if (parsePtr->errorType == TCL_PARSE_SUCCESS) { + parsePtr->errorType = TCL_PARSE_SYNTAX; + parsePtr->term = start; + } + if (interp == NULL) { + if (msg) { + Tcl_DecrRefCount(msg); + } + } else { + if (msg == NULL) { + msg = Tcl_GetObjResult(interp); + } + TclObjPrintf(NULL, msg, "\nin expression \"%s%.*s%.*s%s%s%.*s%s\"", + ((start - limit) < scratch.string) ? "" : "...", + ((start - limit) < scratch.string) + ? (start - scratch.string) : limit - 3, + ((start - limit) < scratch.string) + ? scratch.string : start - limit + 3, + (scanned < limit) ? scanned : limit - 3, start, + (scanned < limit) ? "" : "...", + insertMark ? mark : "", + (start + scanned + limit > scratch.end) + ? scratch.end - (start + scanned) : limit-3, + start + scanned, + (start + scanned + limit > scratch.end) ? "" : "..." + ); + if (post != NULL) { + Tcl_AppendToObj(msg, ";\n", -1); + Tcl_AppendObjToObj(msg, post); + Tcl_DecrRefCount(post); + } + Tcl_SetObjResult(interp, msg); + numBytes = scratch.end - scratch.string; + TclFormatToErrorInfo(interp, + "\n (parsing expression \"%.*s%s\")", + (numBytes < limit) ? numBytes : limit - 3, + scratch.string, (numBytes < limit) ? "" : "..."); + } + } + + if (nodes != staticNodes) { + ckfree((char *)nodes); + } + Tcl_FreeParse(&scratch); + return code; +} + +/* + *---------------------------------------------------------------------- + * + * GenerateTokens -- + * + * Routine that generates Tcl_Tokens that represent a Tcl expression + * and writes them to *parsePtr. The parse tree of the expression + * is in the array of ExprNodes, nodes. Some of the Tcl_Tokens are + * copied from scratch space at *scratchPtr, where the parsing pass + * that constructed the parse tree left them. + * + *---------------------------------------------------------------------- + */ + +static void +GenerateTokens( + ExprNode *nodes, + Tcl_Parse *scratchPtr, + Tcl_Parse *parsePtr) +{ + ExprNode *nodePtr = nodes + nodes->right; + Tcl_Token *sourcePtr, *destPtr, *tokenPtr = scratchPtr->tokenPtr; + int toCopy; + CONST char *end = tokenPtr->start + tokenPtr->size; + + while (nodePtr->lexeme != START) { + switch (NODE_TYPE & nodePtr->lexeme) { + case BINARY: + if (nodePtr->left >= 0) { + if ((nodePtr->lexeme != COMMA) && (nodePtr->lexeme != COLON)) { + sourcePtr = scratchPtr->tokenPtr + nodePtr->token; + if (parsePtr->numTokens + 1 >= parsePtr->tokensAvailable) { + TclExpandTokenArray(parsePtr); + } + destPtr = parsePtr->tokenPtr + parsePtr->numTokens; + nodePtr->token = parsePtr->numTokens; + destPtr->type = TCL_TOKEN_SUB_EXPR; + destPtr->start = tokenPtr->start; + destPtr++; + *destPtr = *sourcePtr; + parsePtr->numTokens += 2; + } + nodePtr = nodes + nodePtr->left; + nodes[nodePtr->parent].left = -1; + } else if (nodePtr->right >= 0) { + tokenPtr += tokenPtr->numComponents + 1; + nodePtr = nodes + nodePtr->right; + nodes[nodePtr->parent].right = -1; + } else { + if ((nodePtr->lexeme != COMMA) && (nodePtr->lexeme != COLON)) { + destPtr = parsePtr->tokenPtr + nodePtr->token; + destPtr->size = end - destPtr->start; + destPtr->numComponents = + parsePtr->numTokens - nodePtr->token - 1; + } + nodePtr = nodes + nodePtr->parent; + } + break; + + case UNARY: + if (nodePtr->right >= 0) { + sourcePtr = scratchPtr->tokenPtr + nodePtr->token; + if (nodePtr->lexeme != OPEN_PAREN) { + if (parsePtr->numTokens + 1 >= parsePtr->tokensAvailable) { + TclExpandTokenArray(parsePtr); + } + destPtr = parsePtr->tokenPtr + parsePtr->numTokens; + nodePtr->token = parsePtr->numTokens; + destPtr->type = TCL_TOKEN_SUB_EXPR; + destPtr->start = tokenPtr->start; + destPtr++; + *destPtr = *sourcePtr; + parsePtr->numTokens += 2; + } + if (tokenPtr == sourcePtr) { + tokenPtr += tokenPtr->numComponents + 1; + } + nodePtr = nodes + nodePtr->right; + nodes[nodePtr->parent].right = -1; + } else { + if (nodePtr->lexeme != OPEN_PAREN) { + destPtr = parsePtr->tokenPtr + nodePtr->token; + destPtr->size = end - destPtr->start; + destPtr->numComponents = + parsePtr->numTokens - nodePtr->token - 1; + } else { + sourcePtr = scratchPtr->tokenPtr + nodePtr->token; + end = sourcePtr->start + sourcePtr->size; + } + nodePtr = nodes + nodePtr->parent; + } + break; + + case LEAF: + switch (nodePtr->lexeme) { + case EMPTY: + break; + + case BRACED: + case QUOTED: + sourcePtr = scratchPtr->tokenPtr + nodePtr->token; + end = sourcePtr->start + sourcePtr->size; + if (sourcePtr->numComponents > 1) { + toCopy = sourcePtr->numComponents; + if (tokenPtr == sourcePtr) { + tokenPtr += toCopy + 1; + } + sourcePtr->numComponents++; + while (parsePtr->numTokens + toCopy + 1 + >= parsePtr->tokensAvailable) { + TclExpandTokenArray(parsePtr); + } + destPtr = parsePtr->tokenPtr + parsePtr->numTokens; + *destPtr++ = *sourcePtr; + *destPtr = *sourcePtr++; + destPtr->type = TCL_TOKEN_WORD; + destPtr->numComponents = toCopy; + destPtr++; + memcpy((VOID *) destPtr, (VOID *) sourcePtr, + (size_t) (toCopy * sizeof(Tcl_Token))); + parsePtr->numTokens += toCopy + 2; + break; + } + + default: + sourcePtr = scratchPtr->tokenPtr + nodePtr->token; + end = sourcePtr->start + sourcePtr->size; + toCopy = sourcePtr->numComponents + 1; + if (tokenPtr == sourcePtr) { + tokenPtr += toCopy; + } + while (parsePtr->numTokens + toCopy - 1 + >= parsePtr->tokensAvailable) { + TclExpandTokenArray(parsePtr); + } + destPtr = parsePtr->tokenPtr + parsePtr->numTokens; + memcpy((VOID *) destPtr, (VOID *) sourcePtr, + (size_t) (toCopy * sizeof(Tcl_Token))); + parsePtr->numTokens += toCopy; + break; + + } + nodePtr = nodes + nodePtr->parent; + break; + + } + } +} + +/* + *---------------------------------------------------------------------- + * + * ParseLexeme -- + * + * Parse a single lexeme from the start of a string, scanning no + * more than numBytes bytes. + * + * Results: + * Returns the number of bytes scanned to produce the lexeme. + * + * Side effects: + * Code identifying lexeme parsed is writen to *lexemePtr. + * + *---------------------------------------------------------------------- + */ + +static int +ParseLexeme( + CONST char *start, /* Start of lexeme to parse. */ + int numBytes, /* Number of bytes in string. */ + unsigned char *lexemePtr) /* Write code of parsed lexeme to this + * storage. */ +{ + CONST char *end; + int scanned; + Tcl_UniChar ch; + + if (numBytes == 0) { + *lexemePtr = END; + return 0; + } + switch (*start) { + case '[': + *lexemePtr = SCRIPT; + return 1; + + case '{': + *lexemePtr = BRACED; + return 1; + + case '(': + *lexemePtr = OPEN_PAREN; + return 1; + + case ')': + *lexemePtr = CLOSE_PAREN; + return 1; + + case '$': + *lexemePtr = VARIABLE; + return 1; + + case '\"': + *lexemePtr = QUOTED; + return 1; + + case ',': + *lexemePtr = COMMA; + return 1; + + case '/': + *lexemePtr = DIVIDE; + return 1; + + case '%': + *lexemePtr = MOD; + return 1; + + case '+': + *lexemePtr = PLUS; + return 1; + + case '-': + *lexemePtr = MINUS; + return 1; + + case '?': + *lexemePtr = QUESTION; + return 1; + + case ':': + *lexemePtr = COLON; + return 1; + + case '^': + *lexemePtr = BIT_XOR; + return 1; + + case '~': + *lexemePtr = BIT_NOT; + return 1; + + case '*': + if ((numBytes > 1) && (start[1] == '*')) { + *lexemePtr = EXPON; + return 2; + } + *lexemePtr = MULT; + return 1; + + case '=': + if ((numBytes > 1) && (start[1] == '=')) { + *lexemePtr = EQUAL; + return 2; + } + *lexemePtr = INCOMPLETE; + return 1; + + case '!': + if ((numBytes > 1) && (start[1] == '=')) { + *lexemePtr = NEQ; + return 2; + } + *lexemePtr = NOT; + return 1; + + case '&': + if ((numBytes > 1) && (start[1] == '&')) { + *lexemePtr = AND; + return 2; + } + *lexemePtr = BIT_AND; + return 1; + + case '|': + if ((numBytes > 1) && (start[1] == '|')) { + *lexemePtr = OR; + return 2; + } + *lexemePtr = BIT_OR; + return 1; + + case '<': + if (numBytes > 1) { + switch (start[1]) { + case '<': + *lexemePtr = LEFT_SHIFT; + return 2; + case '=': + *lexemePtr = LEQ; + return 2; + } + } + *lexemePtr = LESS; + return 1; + + case '>': + if (numBytes > 1) { + switch (start[1]) { + case '>': + *lexemePtr = RIGHT_SHIFT; + return 2; + case '=': + *lexemePtr = GEQ; + return 2; + } + } + *lexemePtr = GREATER; + return 1; + + case 'i': + if ((numBytes > 1) && (start[1] == 'n') + && ((numBytes == 2) || !isalpha(UCHAR(start[2])))) { + /* + * Must make this check so we can tell the difference between + * the "in" operator and the "int" function name and the + * "infinity" numeric value. + */ + *lexemePtr = IN_LIST; + return 2; + } + break; + + case 'e': + if ((numBytes > 1) && (start[1] == 'q') + && ((numBytes == 2) || !isalpha(UCHAR(start[2])))) { + *lexemePtr = STREQ; + return 2; + } + break; + + case 'n': + if ((numBytes > 1) && ((numBytes == 2) || !isalpha(UCHAR(start[2])))) { + switch (start[1]) { + case 'e': + *lexemePtr = STRNEQ; + return 2; + case 'i': + *lexemePtr = NOT_IN_LIST; + return 2; + } + } + } + + if (TclParseNumber(NULL, NULL, NULL, start, numBytes, &end, + TCL_PARSE_NO_WHITESPACE) == TCL_OK) { + *lexemePtr = NUMBER; + return (end-start); + } + + if (Tcl_UtfCharComplete(start, numBytes)) { + scanned = Tcl_UtfToUniChar(start, &ch); + } else { + char utfBytes[TCL_UTF_MAX]; + memcpy(utfBytes, start, (size_t) numBytes); + utfBytes[numBytes] = '\0'; + scanned = Tcl_UtfToUniChar(utfBytes, &ch); + } + if (!isalpha(UCHAR(ch))) { + *lexemePtr = INVALID; + return scanned; + } + end = start; + while (isalnum(UCHAR(ch)) || (UCHAR(ch) == '_')) { + end += scanned; + numBytes -= scanned; + if (Tcl_UtfCharComplete(end, numBytes)) { + scanned = Tcl_UtfToUniChar(end, &ch); + } else { + char utfBytes[TCL_UTF_MAX]; + memcpy(utfBytes, end, (size_t) numBytes); + utfBytes[numBytes] = '\0'; + scanned = Tcl_UtfToUniChar(utfBytes, &ch); + } + } + *lexemePtr = BAREWORD; + return (end-start); +} + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/library/ldAout.tcl b/library/ldAout.tcl new file mode 100644 index 0000000..c32f174 --- /dev/null +++ b/library/ldAout.tcl @@ -0,0 +1,233 @@ +# ldAout.tcl -- +# +# This "tclldAout" procedure in this script acts as a replacement +# for the "ld" command when linking an object file that will be +# loaded dynamically into Tcl or Tk using pseudo-static linking. +# +# Parameters: +# The arguments to the script are the command line options for +# an "ld" command. +# +# Results: +# The "ld" command is parsed, and the "-o" option determines the +# module name. ".a" and ".o" options are accumulated. +# The input archives and object files are examined with the "nm" +# command to determine whether the modules initialization +# entry and safe initialization entry are present. A trivial +# C function that locates the entries is composed, compiled, and +# its .o file placed before all others in the command; then +# "ld" is executed to bind the objects together. +# +# RCS: @(#) $Id: ldAout.tcl,v 1.6 2003/03/19 21:57:42 dgp Exp $ +# +# Copyright (c) 1995, by General Electric Company. All rights reserved. +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# +# This work was supported in part by the ARPA Manufacturing Automation +# and Design Engineering (MADE) Initiative through ARPA contract +# F33615-94-C-4400. + +proc tclLdAout {{cc {}} {shlib_suffix {}} {shlib_cflags none}} { + global env + global argv + + if {[string equal $cc ""]} { + set cc $env(CC) + } + + # if only two parameters are supplied there is assumed that the + # only shlib_suffix is missing. This parameter is anyway available + # as "info sharedlibextension" too, so there is no need to transfer + # 3 parameters to the function tclLdAout. For compatibility, this + # function now accepts both 2 and 3 parameters. + + if {[string equal $shlib_suffix ""]} { + set shlib_cflags $env(SHLIB_CFLAGS) + } elseif {[string equal $shlib_cflags "none"]} { + set shlib_cflags $shlib_suffix + } + + # seenDotO is nonzero if a .o or .a file has been seen + set seenDotO 0 + + # minusO is nonzero if the last command line argument was "-o". + set minusO 0 + + # head has command line arguments up to but not including the first + # .o or .a file. tail has the rest of the arguments. + set head {} + set tail {} + + # nmCommand is the "nm" command that lists global symbols from the + # object files. + set nmCommand {|nm -g} + + # entryProtos is the table of _Init and _SafeInit prototypes found in the + # module. + set entryProtos {} + + # entryPoints is the table of _Init and _SafeInit entries found in the + # module. + set entryPoints {} + + # libraries is the list of -L and -l flags to the linker. + set libraries {} + set libdirs {} + + # Process command line arguments + foreach a $argv { + if {!$minusO && [regexp {\.[ao]$} $a]} { + set seenDotO 1 + lappend nmCommand $a + } + if {$minusO} { + set outputFile $a + set minusO 0 + } elseif {![string compare $a -o]} { + set minusO 1 + } + if {[string match -nocase "-l*" $a]} { + lappend libraries $a + if {[string match "-L*" $a]} { + lappend libdirs [string range $a 2 end] + } + } elseif {$seenDotO} { + lappend tail $a + } else { + lappend head $a + } + } + lappend libdirs /lib /usr/lib + + # MIPS -- If there are corresponding G0 libraries, replace the + # ordinary ones with the G0 ones. + + set libs {} + foreach lib $libraries { + if {[string match "-l*" $lib]} { + set lname [string range $lib 2 end] + foreach dir $libdirs { + if {[file exists [file join $dir lib${lname}_G0.a]]} { + set lname ${lname}_G0 + break + } + } + lappend libs -l$lname + } else { + lappend libs $lib + } + } + set libraries $libs + + # Extract the module name from the "-o" option + + if {![info exists outputFile]} { + error "-o option must be supplied to link a Tcl load module" + } + set m [file tail $outputFile] + if {[regexp {\.a$} $outputFile]} { + set shlib_suffix .a + } else { + set shlib_suffix "" + } + if {[regexp {\..*$} $outputFile match]} { + set l [expr {[string length $m] - [string length $match]}] + } else { + error "Output file does not appear to have a suffix" + } + set modName [string tolower $m 0 [expr {$l-1}]] + if {[string match "lib*" $modName]} { + set modName [string range $modName 3 end] + } + if {[regexp {[0-9\.]*(_g0)?$} $modName match]} { + set modName [string range $modName 0 [expr {[string length $modName]-[string length $match]-1}]] + } + set modName [string totitle $modName] + + # Catalog initialization entry points found in the module + + set f [open $nmCommand r] + while {[gets $f l] >= 0} { + if {[regexp {T[ ]*_?([A-Z][a-z0-9_]*_(Safe)?Init(__FP10Tcl_Interp)?)$} $l trash symbol]} { + if {![regexp {_?([A-Z][a-z0-9_]*_(Safe)?Init)} $symbol trash s]} { + set s $symbol + } + append entryProtos {extern int } $symbol { (); } \n + append entryPoints { } \{ { "} $s {", } $symbol { } \} , \n + } + } + close $f + + if {[string equal $entryPoints ""]} { + error "No entry point found in objects" + } + + # Compose a C function that resolves the initialization entry points and + # embeds the required libraries in the object code. + + set C {#include <string.h>} + append C \n + append C {char TclLoadLibraries_} $modName { [] =} \n + append C { "@LIBS: } $libraries {";} \n + append C $entryProtos + append C {static struct } \{ \n + append C { char * name;} \n + append C { int (*value)();} \n + append C \} {dictionary [] = } \{ \n + append C $entryPoints + append C { 0, 0 } \n \} \; \n + append C {typedef struct Tcl_Interp Tcl_Interp;} \n + append C {typedef int Tcl_PackageInitProc (Tcl_Interp *);} \n + append C {Tcl_PackageInitProc *} \n + append C TclLoadDictionary_ $modName { (symbol)} \n + append C { CONST char * symbol;} \n + append C { + { + int i; + for (i = 0; dictionary [i] . name != 0; ++i) { + if (!strcmp (symbol, dictionary [i] . name)) { + return dictionary [i].value; + } + } + return 0; + } + } + append C \n + + + # Write the C module and compile it + + set cFile tcl$modName.c + set f [open $cFile w] + puts -nonewline $f $C + close $f + set ccCommand "$cc -c $shlib_cflags $cFile" + puts stderr $ccCommand + eval exec $ccCommand + + # Now compose and execute the ld command that packages the module + + if {[string equal $shlib_suffix ".a"]} { + set ldCommand "ar cr $outputFile" + regsub { -o} $tail {} tail + } else { + set ldCommand ld + foreach item $head { + lappend ldCommand $item + } + } + lappend ldCommand tcl$modName.o + foreach item $tail { + lappend ldCommand $item + } + puts stderr $ldCommand + eval exec $ldCommand + if {[string equal $shlib_suffix ".a"]} { + exec ranlib $outputFile + } + + # Clean up working files + exec /bin/rm $cFile [file rootname $cFile].o +} diff --git a/library/msgs/af_ZA.msg b/library/msgs/af_ZA.msg new file mode 100755 index 0000000..fef48ad --- /dev/null +++ b/library/msgs/af_ZA.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset af_ZA DATE_FORMAT "%d %B %Y" + ::msgcat::mcset af_ZA TIME_FORMAT_12 "%l:%M:%S %P" + ::msgcat::mcset af_ZA DATE_TIME_FORMAT "%d %B %Y %l:%M:%S %P %z" +} diff --git a/library/msgs/ar_IN.msg b/library/msgs/ar_IN.msg new file mode 100755 index 0000000..185e49c --- /dev/null +++ b/library/msgs/ar_IN.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset ar_IN DATE_FORMAT "%A %d %B %Y" + ::msgcat::mcset ar_IN TIME_FORMAT_12 "%I:%M:%S %z" + ::msgcat::mcset ar_IN DATE_TIME_FORMAT "%A %d %B %Y %I:%M:%S %z %z" +} diff --git a/library/msgs/ar_JO.msg b/library/msgs/ar_JO.msg new file mode 100755 index 0000000..0f5e269 --- /dev/null +++ b/library/msgs/ar_JO.msg @@ -0,0 +1,39 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset ar_JO DAYS_OF_WEEK_ABBREV [list \ + "\u0627\u0644\u0623\u062d\u062f"\ + "\u0627\u0644\u0627\u062b\u0646\u064a\u0646"\ + "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621"\ + "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621"\ + "\u0627\u0644\u062e\u0645\u064a\u0633"\ + "\u0627\u0644\u062c\u0645\u0639\u0629"\ + "\u0627\u0644\u0633\u0628\u062a"] + ::msgcat::mcset ar_JO MONTHS_ABBREV [list \ + "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ + "\u0634\u0628\u0627\u0637"\ + "\u0622\u0630\u0627\u0631"\ + "\u0646\u064a\u0633\u0627\u0646"\ + "\u0646\u0648\u0627\u0631"\ + "\u062d\u0632\u064a\u0631\u0627\u0646"\ + "\u062a\u0645\u0648\u0632"\ + "\u0622\u0628"\ + "\u0623\u064a\u0644\u0648\u0644"\ + "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644"\ + "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ + "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"\ + ""] + ::msgcat::mcset ar_JO MONTHS_FULL [list \ + "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ + "\u0634\u0628\u0627\u0637"\ + "\u0622\u0630\u0627\u0631"\ + "\u0646\u064a\u0633\u0627\u0646"\ + "\u0646\u0648\u0627\u0631"\ + "\u062d\u0632\u064a\u0631\u0627\u0646"\ + "\u062a\u0645\u0648\u0632"\ + "\u0622\u0628"\ + "\u0623\u064a\u0644\u0648\u0644"\ + "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644"\ + "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ + "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"\ + ""] +} diff --git a/library/msgs/ar_LB.msg b/library/msgs/ar_LB.msg new file mode 100755 index 0000000..e62acd3 --- /dev/null +++ b/library/msgs/ar_LB.msg @@ -0,0 +1,39 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset ar_LB DAYS_OF_WEEK_ABBREV [list \ + "\u0627\u0644\u0623\u062d\u062f"\ + "\u0627\u0644\u0627\u062b\u0646\u064a\u0646"\ + "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621"\ + "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621"\ + "\u0627\u0644\u062e\u0645\u064a\u0633"\ + "\u0627\u0644\u062c\u0645\u0639\u0629"\ + "\u0627\u0644\u0633\u0628\u062a"] + ::msgcat::mcset ar_LB MONTHS_ABBREV [list \ + "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ + "\u0634\u0628\u0627\u0637"\ + "\u0622\u0630\u0627\u0631"\ + "\u0646\u064a\u0633\u0627\u0646"\ + "\u0646\u0648\u0627\u0631"\ + "\u062d\u0632\u064a\u0631\u0627\u0646"\ + "\u062a\u0645\u0648\u0632"\ + "\u0622\u0628"\ + "\u0623\u064a\u0644\u0648\u0644"\ + "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644"\ + "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ + "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"\ + ""] + ::msgcat::mcset ar_LB MONTHS_FULL [list \ + "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ + "\u0634\u0628\u0627\u0637"\ + "\u0622\u0630\u0627\u0631"\ + "\u0646\u064a\u0633\u0627\u0646"\ + "\u0646\u0648\u0627\u0631"\ + "\u062d\u0632\u064a\u0631\u0627\u0646"\ + "\u062a\u0645\u0648\u0632"\ + "\u0622\u0628"\ + "\u0623\u064a\u0644\u0648\u0644"\ + "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644"\ + "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ + "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"\ + ""] +} diff --git a/library/msgs/ar_SY.msg b/library/msgs/ar_SY.msg new file mode 100755 index 0000000..d5e1c87 --- /dev/null +++ b/library/msgs/ar_SY.msg @@ -0,0 +1,39 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset ar_SY DAYS_OF_WEEK_ABBREV [list \ + "\u0627\u0644\u0623\u062d\u062f"\ + "\u0627\u0644\u0627\u062b\u0646\u064a\u0646"\ + "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621"\ + "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621"\ + "\u0627\u0644\u062e\u0645\u064a\u0633"\ + "\u0627\u0644\u062c\u0645\u0639\u0629"\ + "\u0627\u0644\u0633\u0628\u062a"] + ::msgcat::mcset ar_SY MONTHS_ABBREV [list \ + "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ + "\u0634\u0628\u0627\u0637"\ + "\u0622\u0630\u0627\u0631"\ + "\u0646\u064a\u0633\u0627\u0646"\ + "\u0646\u0648\u0627\u0631"\ + "\u062d\u0632\u064a\u0631\u0627\u0646"\ + "\u062a\u0645\u0648\u0632"\ + "\u0622\u0628"\ + "\u0623\u064a\u0644\u0648\u0644"\ + "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644"\ + "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ + "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"\ + ""] + ::msgcat::mcset ar_SY MONTHS_FULL [list \ + "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ + "\u0634\u0628\u0627\u0637"\ + "\u0622\u0630\u0627\u0631"\ + "\u0646\u064a\u0633\u0627\u0646"\ + "\u0646\u0648\u0627\u0631\u0627\u0646"\ + "\u062d\u0632\u064a\u0631"\ + "\u062a\u0645\u0648\u0632"\ + "\u0622\u0628"\ + "\u0623\u064a\u0644\u0648\u0644"\ + "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644"\ + "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\ + "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"\ + ""] +} diff --git a/library/msgs/bn_IN.msg b/library/msgs/bn_IN.msg new file mode 100755 index 0000000..28c000f --- /dev/null +++ b/library/msgs/bn_IN.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset bn_IN DATE_FORMAT "%A %d %b %Y" + ::msgcat::mcset bn_IN TIME_FORMAT_12 "%I:%M:%S %z" + ::msgcat::mcset bn_IN DATE_TIME_FORMAT "%A %d %b %Y %I:%M:%S %z %z" +} diff --git a/library/msgs/de_AT.msg b/library/msgs/de_AT.msg new file mode 100755 index 0000000..61bc266 --- /dev/null +++ b/library/msgs/de_AT.msg @@ -0,0 +1,35 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset de_AT MONTHS_ABBREV [list \ + "J\u00e4n"\ + "Feb"\ + "M\u00e4r"\ + "Apr"\ + "Mai"\ + "Jun"\ + "Jul"\ + "Aug"\ + "Sep"\ + "Okt"\ + "Nov"\ + "Dez"\ + ""] + ::msgcat::mcset de_AT MONTHS_FULL [list \ + "J\u00e4nner"\ + "Februar"\ + "M\u00e4rz"\ + "April"\ + "Mai"\ + "Juni"\ + "Juli"\ + "August"\ + "September"\ + "Oktober"\ + "November"\ + "Dezember"\ + ""] + ::msgcat::mcset de_AT DATE_FORMAT "%Y-%m-%d" + ::msgcat::mcset de_AT TIME_FORMAT "%T" + ::msgcat::mcset de_AT TIME_FORMAT_12 "%T" + ::msgcat::mcset de_AT DATE_TIME_FORMAT "%a %d %b %Y %T %z" +} diff --git a/library/msgs/de_BE.msg b/library/msgs/de_BE.msg new file mode 100755 index 0000000..3614763 --- /dev/null +++ b/library/msgs/de_BE.msg @@ -0,0 +1,53 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset de_BE DAYS_OF_WEEK_ABBREV [list \ + "Son"\ + "Mon"\ + "Die"\ + "Mit"\ + "Don"\ + "Fre"\ + "Sam"] + ::msgcat::mcset de_BE DAYS_OF_WEEK_FULL [list \ + "Sonntag"\ + "Montag"\ + "Dienstag"\ + "Mittwoch"\ + "Donnerstag"\ + "Freitag"\ + "Samstag"] + ::msgcat::mcset de_BE MONTHS_ABBREV [list \ + "Jan"\ + "Feb"\ + "M\u00e4r"\ + "Apr"\ + "Mai"\ + "Jun"\ + "Jul"\ + "Aug"\ + "Sep"\ + "Okt"\ + "Nov"\ + "Dez"\ + ""] + ::msgcat::mcset de_BE MONTHS_FULL [list \ + "Januar"\ + "Februar"\ + "M\u00e4rz"\ + "April"\ + "Mai"\ + "Juni"\ + "Juli"\ + "August"\ + "September"\ + "Oktober"\ + "November"\ + "Dezember"\ + ""] + ::msgcat::mcset de_BE AM "vorm" + ::msgcat::mcset de_BE PM "nachm" + ::msgcat::mcset de_BE DATE_FORMAT "%Y-%m-%d" + ::msgcat::mcset de_BE TIME_FORMAT "%T" + ::msgcat::mcset de_BE TIME_FORMAT_12 "%T" + ::msgcat::mcset de_BE DATE_TIME_FORMAT "%a %d %b %Y %T %z" +} diff --git a/library/msgs/en_AU.msg b/library/msgs/en_AU.msg new file mode 100755 index 0000000..7f9870c --- /dev/null +++ b/library/msgs/en_AU.msg @@ -0,0 +1,7 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset en_AU DATE_FORMAT "%e/%m/%Y" + ::msgcat::mcset en_AU TIME_FORMAT "%H:%M:%S" + ::msgcat::mcset en_AU TIME_FORMAT_12 "%I:%M:%S %P %z" + ::msgcat::mcset en_AU DATE_TIME_FORMAT "%e/%m/%Y %H:%M:%S %z" +} diff --git a/library/msgs/en_BE.msg b/library/msgs/en_BE.msg new file mode 100755 index 0000000..5072986 --- /dev/null +++ b/library/msgs/en_BE.msg @@ -0,0 +1,7 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset en_BE DATE_FORMAT "%d %b %Y" + ::msgcat::mcset en_BE TIME_FORMAT "%k:%M:%S" + ::msgcat::mcset en_BE TIME_FORMAT_12 "%k h %M min %S s %z" + ::msgcat::mcset en_BE DATE_TIME_FORMAT "%d %b %Y %k:%M:%S %z" +} diff --git a/library/msgs/en_BW.msg b/library/msgs/en_BW.msg new file mode 100755 index 0000000..8fd20c7 --- /dev/null +++ b/library/msgs/en_BW.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset en_BW DATE_FORMAT "%d %B %Y" + ::msgcat::mcset en_BW TIME_FORMAT_12 "%l:%M:%S %P" + ::msgcat::mcset en_BW DATE_TIME_FORMAT "%d %B %Y %l:%M:%S %P %z" +} diff --git a/library/msgs/en_CA.msg b/library/msgs/en_CA.msg new file mode 100755 index 0000000..278efe7 --- /dev/null +++ b/library/msgs/en_CA.msg @@ -0,0 +1,7 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset en_CA DATE_FORMAT "%d/%m/%y" + ::msgcat::mcset en_CA TIME_FORMAT "%r" + ::msgcat::mcset en_CA TIME_FORMAT_12 "%I:%M:%S %p" + ::msgcat::mcset en_CA DATE_TIME_FORMAT "%a %d %b %Y %r %z" +} diff --git a/library/msgs/en_GB.msg b/library/msgs/en_GB.msg new file mode 100755 index 0000000..5c61c43 --- /dev/null +++ b/library/msgs/en_GB.msg @@ -0,0 +1,7 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset en_GB DATE_FORMAT "%d/%m/%y" + ::msgcat::mcset en_GB TIME_FORMAT "%T" + ::msgcat::mcset en_GB TIME_FORMAT_12 "%T" + ::msgcat::mcset en_GB DATE_TIME_FORMAT "%a %d %b %Y %T %z" +} diff --git a/library/msgs/en_HK.msg b/library/msgs/en_HK.msg new file mode 100755 index 0000000..8b33bc0 --- /dev/null +++ b/library/msgs/en_HK.msg @@ -0,0 +1,8 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset en_HK AM "AM" + ::msgcat::mcset en_HK PM "PM" + ::msgcat::mcset en_HK DATE_FORMAT "%B %e, %Y" + ::msgcat::mcset en_HK TIME_FORMAT_12 "%l:%M:%S %P" + ::msgcat::mcset en_HK DATE_TIME_FORMAT "%B %e, %Y %l:%M:%S %P %z" +} diff --git a/library/msgs/en_IE.msg b/library/msgs/en_IE.msg new file mode 100755 index 0000000..ba621cf --- /dev/null +++ b/library/msgs/en_IE.msg @@ -0,0 +1,7 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset en_IE DATE_FORMAT "%d/%m/%y" + ::msgcat::mcset en_IE TIME_FORMAT "%T" + ::msgcat::mcset en_IE TIME_FORMAT_12 "%T" + ::msgcat::mcset en_IE DATE_TIME_FORMAT "%a %d %b %Y %T %z" +} diff --git a/library/msgs/en_IN.msg b/library/msgs/en_IN.msg new file mode 100755 index 0000000..a1f155d --- /dev/null +++ b/library/msgs/en_IN.msg @@ -0,0 +1,8 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset en_IN AM "AM" + ::msgcat::mcset en_IN PM "PM" + ::msgcat::mcset en_IN DATE_FORMAT "%d %B %Y" + ::msgcat::mcset en_IN TIME_FORMAT "%H:%M:%S" + ::msgcat::mcset en_IN DATE_TIME_FORMAT "%d %B %Y %H:%M:%S %z" +} diff --git a/library/msgs/en_NZ.msg b/library/msgs/en_NZ.msg new file mode 100755 index 0000000..b419017 --- /dev/null +++ b/library/msgs/en_NZ.msg @@ -0,0 +1,7 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset en_NZ DATE_FORMAT "%e/%m/%Y" + ::msgcat::mcset en_NZ TIME_FORMAT "%H:%M:%S" + ::msgcat::mcset en_NZ TIME_FORMAT_12 "%I:%M:%S %P %z" + ::msgcat::mcset en_NZ DATE_TIME_FORMAT "%e/%m/%Y %H:%M:%S %z" +} diff --git a/library/msgs/en_PH.msg b/library/msgs/en_PH.msg new file mode 100755 index 0000000..682666d --- /dev/null +++ b/library/msgs/en_PH.msg @@ -0,0 +1,8 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset en_PH AM "AM" + ::msgcat::mcset en_PH PM "PM" + ::msgcat::mcset en_PH DATE_FORMAT "%B %e, %Y" + ::msgcat::mcset en_PH TIME_FORMAT_12 "%l:%M:%S %P" + ::msgcat::mcset en_PH DATE_TIME_FORMAT "%B %e, %Y %l:%M:%S %P %z" +} diff --git a/library/msgs/en_SG.msg b/library/msgs/en_SG.msg new file mode 100755 index 0000000..4dc5b1d --- /dev/null +++ b/library/msgs/en_SG.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset en_SG DATE_FORMAT "%d %b %Y" + ::msgcat::mcset en_SG TIME_FORMAT_12 "%P %I:%M:%S" + ::msgcat::mcset en_SG DATE_TIME_FORMAT "%d %b %Y %P %I:%M:%S %z" +} diff --git a/library/msgs/en_ZA.msg b/library/msgs/en_ZA.msg new file mode 100755 index 0000000..fe43797 --- /dev/null +++ b/library/msgs/en_ZA.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset en_ZA DATE_FORMAT "%Y/%m/%d" + ::msgcat::mcset en_ZA TIME_FORMAT_12 "%I:%M:%S" + ::msgcat::mcset en_ZA DATE_TIME_FORMAT "%Y/%m/%d %I:%M:%S %z" +} diff --git a/library/msgs/en_ZW.msg b/library/msgs/en_ZW.msg new file mode 100755 index 0000000..2a5804f --- /dev/null +++ b/library/msgs/en_ZW.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset en_ZW DATE_FORMAT "%d %B %Y" + ::msgcat::mcset en_ZW TIME_FORMAT_12 "%l:%M:%S %P" + ::msgcat::mcset en_ZW DATE_TIME_FORMAT "%d %B %Y %l:%M:%S %P %z" +} diff --git a/library/msgs/es_AR.msg b/library/msgs/es_AR.msg new file mode 100755 index 0000000..7d35027 --- /dev/null +++ b/library/msgs/es_AR.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset es_AR DATE_FORMAT "%d/%m/%Y" + ::msgcat::mcset es_AR TIME_FORMAT "%H:%M:%S" + ::msgcat::mcset es_AR DATE_TIME_FORMAT "%d/%m/%Y %H:%M:%S %z" +} diff --git a/library/msgs/es_BO.msg b/library/msgs/es_BO.msg new file mode 100755 index 0000000..498ad0d --- /dev/null +++ b/library/msgs/es_BO.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset es_BO DATE_FORMAT "%d-%m-%Y" + ::msgcat::mcset es_BO TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset es_BO DATE_TIME_FORMAT "%d-%m-%Y %I:%M:%S %P %z" +} diff --git a/library/msgs/es_CL.msg b/library/msgs/es_CL.msg new file mode 100755 index 0000000..31d465c --- /dev/null +++ b/library/msgs/es_CL.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset es_CL DATE_FORMAT "%d-%m-%Y" + ::msgcat::mcset es_CL TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset es_CL DATE_TIME_FORMAT "%d-%m-%Y %I:%M:%S %P %z" +} diff --git a/library/msgs/es_CO.msg b/library/msgs/es_CO.msg new file mode 100755 index 0000000..77e57f0 --- /dev/null +++ b/library/msgs/es_CO.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset es_CO DATE_FORMAT "%e/%m/%Y" + ::msgcat::mcset es_CO TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset es_CO DATE_TIME_FORMAT "%e/%m/%Y %I:%M:%S %P %z" +} diff --git a/library/msgs/es_CR.msg b/library/msgs/es_CR.msg new file mode 100755 index 0000000..7a652fa --- /dev/null +++ b/library/msgs/es_CR.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset es_CR DATE_FORMAT "%d/%m/%Y" + ::msgcat::mcset es_CR TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset es_CR DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z" +} diff --git a/library/msgs/es_DO.msg b/library/msgs/es_DO.msg new file mode 100755 index 0000000..0e283da --- /dev/null +++ b/library/msgs/es_DO.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset es_DO DATE_FORMAT "%m/%d/%Y" + ::msgcat::mcset es_DO TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset es_DO DATE_TIME_FORMAT "%m/%d/%Y %I:%M:%S %P %z" +} diff --git a/library/msgs/es_EC.msg b/library/msgs/es_EC.msg new file mode 100755 index 0000000..9e921e0 --- /dev/null +++ b/library/msgs/es_EC.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset es_EC DATE_FORMAT "%d/%m/%Y" + ::msgcat::mcset es_EC TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset es_EC DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z" +} diff --git a/library/msgs/es_GT.msg b/library/msgs/es_GT.msg new file mode 100755 index 0000000..ecd6faf --- /dev/null +++ b/library/msgs/es_GT.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset es_GT DATE_FORMAT "%e/%m/%Y" + ::msgcat::mcset es_GT TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset es_GT DATE_TIME_FORMAT "%e/%m/%Y %I:%M:%S %P %z" +} diff --git a/library/msgs/es_HN.msg b/library/msgs/es_HN.msg new file mode 100755 index 0000000..a758ca2 --- /dev/null +++ b/library/msgs/es_HN.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset es_HN DATE_FORMAT "%m-%d-%Y" + ::msgcat::mcset es_HN TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset es_HN DATE_TIME_FORMAT "%m-%d-%Y %I:%M:%S %P %z" +} diff --git a/library/msgs/es_MX.msg b/library/msgs/es_MX.msg new file mode 100755 index 0000000..7cfb545 --- /dev/null +++ b/library/msgs/es_MX.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset es_MX DATE_FORMAT "%e/%m/%Y" + ::msgcat::mcset es_MX TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset es_MX DATE_TIME_FORMAT "%e/%m/%Y %I:%M:%S %P %z" +} diff --git a/library/msgs/es_NI.msg b/library/msgs/es_NI.msg new file mode 100755 index 0000000..7c39495 --- /dev/null +++ b/library/msgs/es_NI.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset es_NI DATE_FORMAT "%m-%d-%Y" + ::msgcat::mcset es_NI TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset es_NI DATE_TIME_FORMAT "%m-%d-%Y %I:%M:%S %P %z" +} diff --git a/library/msgs/es_PA.msg b/library/msgs/es_PA.msg new file mode 100755 index 0000000..cecacdc --- /dev/null +++ b/library/msgs/es_PA.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset es_PA DATE_FORMAT "%m/%d/%Y" + ::msgcat::mcset es_PA TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset es_PA DATE_TIME_FORMAT "%m/%d/%Y %I:%M:%S %P %z" +} diff --git a/library/msgs/es_PE.msg b/library/msgs/es_PE.msg new file mode 100755 index 0000000..9f90595 --- /dev/null +++ b/library/msgs/es_PE.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset es_PE DATE_FORMAT "%d/%m/%Y" + ::msgcat::mcset es_PE TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset es_PE DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z" +} diff --git a/library/msgs/es_PR.msg b/library/msgs/es_PR.msg new file mode 100755 index 0000000..8511b12 --- /dev/null +++ b/library/msgs/es_PR.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset es_PR DATE_FORMAT "%m-%d-%Y" + ::msgcat::mcset es_PR TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset es_PR DATE_TIME_FORMAT "%m-%d-%Y %I:%M:%S %P %z" +} diff --git a/library/msgs/es_PY.msg b/library/msgs/es_PY.msg new file mode 100755 index 0000000..aa93d36 --- /dev/null +++ b/library/msgs/es_PY.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset es_PY DATE_FORMAT "%d/%m/%Y" + ::msgcat::mcset es_PY TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset es_PY DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z" +} diff --git a/library/msgs/es_SV.msg b/library/msgs/es_SV.msg new file mode 100755 index 0000000..fc7954d --- /dev/null +++ b/library/msgs/es_SV.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset es_SV DATE_FORMAT "%m-%d-%Y" + ::msgcat::mcset es_SV TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset es_SV DATE_TIME_FORMAT "%m-%d-%Y %I:%M:%S %P %z" +} diff --git a/library/msgs/es_UY.msg b/library/msgs/es_UY.msg new file mode 100755 index 0000000..b33525c --- /dev/null +++ b/library/msgs/es_UY.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset es_UY DATE_FORMAT "%d/%m/%Y" + ::msgcat::mcset es_UY TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset es_UY DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z" +} diff --git a/library/msgs/es_VE.msg b/library/msgs/es_VE.msg new file mode 100755 index 0000000..7c2a7b0 --- /dev/null +++ b/library/msgs/es_VE.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset es_VE DATE_FORMAT "%d/%m/%Y" + ::msgcat::mcset es_VE TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset es_VE DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z" +} diff --git a/library/msgs/eu_ES.msg b/library/msgs/eu_ES.msg new file mode 100755 index 0000000..2694418 --- /dev/null +++ b/library/msgs/eu_ES.msg @@ -0,0 +1,7 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset eu_ES DATE_FORMAT "%a, %Yeko %bren %da" + ::msgcat::mcset eu_ES TIME_FORMAT "%T" + ::msgcat::mcset eu_ES TIME_FORMAT_12 "%T" + ::msgcat::mcset eu_ES DATE_TIME_FORMAT "%y-%m-%d %T %z" +} diff --git a/library/msgs/fa_IN.msg b/library/msgs/fa_IN.msg new file mode 100755 index 0000000..adc9e91 --- /dev/null +++ b/library/msgs/fa_IN.msg @@ -0,0 +1,52 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset fa_IN DAYS_OF_WEEK_ABBREV [list \ + "\u06cc\u2214"\ + "\u062f\u2214"\ + "\u0633\u2214"\ + "\u0686\u2214"\ + "\u067e\u2214"\ + "\u062c\u2214"\ + "\u0634\u2214"] + ::msgcat::mcset fa_IN DAYS_OF_WEEK_FULL [list \ + "\u06cc\u06cc\u200c\u0634\u0646\u0628\u0647"\ + "\u062f\u0648\u0634\u0646\u0628\u0647"\ + "\u0633\u0647\u200c\u0634\u0646\u0628\u0647"\ + "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647"\ + "\u067e\u0646\u062c\u200c\u0634\u0646\u0628\u0647"\ + "\u062c\u0645\u0639\u0647"\ + "\u0634\u0646\u0628\u0647"] + ::msgcat::mcset fa_IN MONTHS_ABBREV [list \ + "\u0698\u0627\u0646"\ + "\u0641\u0648\u0631"\ + "\u0645\u0627\u0631"\ + "\u0622\u0648\u0631"\ + "\u0645\u0640\u0647"\ + "\u0698\u0648\u0646"\ + "\u0698\u0648\u06cc"\ + "\u0627\u0648\u062a"\ + "\u0633\u067e\u062a"\ + "\u0627\u0643\u062a"\ + "\u0646\u0648\u0627"\ + "\u062f\u0633\u0627"\ + ""] + ::msgcat::mcset fa_IN MONTHS_FULL [list \ + "\u0698\u0627\u0646\u0648\u06cc\u0647"\ + "\u0641\u0648\u0631\u0648\u06cc\u0647"\ + "\u0645\u0627\u0631\u0633"\ + "\u0622\u0648\u0631\u06cc\u0644"\ + "\u0645\u0647"\ + "\u0698\u0648\u0626\u0646"\ + "\u0698\u0648\u0626\u06cc\u0647"\ + "\u0627\u0648\u062a"\ + "\u0633\u067e\u062a\u0627\u0645\u0628\u0631"\ + "\u0627\u0643\u062a\u0628\u0631"\ + "\u0646\u0648\u0627\u0645\u0628\u0631"\ + "\u062f\u0633\u0627\u0645\u0628\u0631"\ + ""] + ::msgcat::mcset fa_IN AM "\u0635\u0628\u062d" + ::msgcat::mcset fa_IN PM "\u0639\u0635\u0631" + ::msgcat::mcset fa_IN DATE_FORMAT "%A %d %B %Y" + ::msgcat::mcset fa_IN TIME_FORMAT_12 "%I:%M:%S %z" + ::msgcat::mcset fa_IN DATE_TIME_FORMAT "%A %d %B %Y %I:%M:%S %z %z" +} diff --git a/library/msgs/fa_IR.msg b/library/msgs/fa_IR.msg new file mode 100755 index 0000000..597ce9d --- /dev/null +++ b/library/msgs/fa_IR.msg @@ -0,0 +1,9 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset fa_IR AM "\u0635\u0628\u062d" + ::msgcat::mcset fa_IR PM "\u0639\u0635\u0631" + ::msgcat::mcset fa_IR DATE_FORMAT "%d\u2044%m\u2044%Y" + ::msgcat::mcset fa_IR TIME_FORMAT "%S:%M:%H" + ::msgcat::mcset fa_IR TIME_FORMAT_12 "%S:%M:%l %P" + ::msgcat::mcset fa_IR DATE_TIME_FORMAT "%d\u2044%m\u2044%Y %S:%M:%H %z" +} diff --git a/library/msgs/fo_FO.msg b/library/msgs/fo_FO.msg new file mode 100755 index 0000000..2392b8e --- /dev/null +++ b/library/msgs/fo_FO.msg @@ -0,0 +1,7 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset fo_FO DATE_FORMAT "%d/%m-%Y" + ::msgcat::mcset fo_FO TIME_FORMAT "%T" + ::msgcat::mcset fo_FO TIME_FORMAT_12 "%T" + ::msgcat::mcset fo_FO DATE_TIME_FORMAT "%a %d %b %Y %T %z" +} diff --git a/library/msgs/fr_BE.msg b/library/msgs/fr_BE.msg new file mode 100755 index 0000000..cdb13bd --- /dev/null +++ b/library/msgs/fr_BE.msg @@ -0,0 +1,7 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset fr_BE DATE_FORMAT "%d/%m/%y" + ::msgcat::mcset fr_BE TIME_FORMAT "%T" + ::msgcat::mcset fr_BE TIME_FORMAT_12 "%T" + ::msgcat::mcset fr_BE DATE_TIME_FORMAT "%a %d %b %Y %T %z" +} diff --git a/library/msgs/fr_CA.msg b/library/msgs/fr_CA.msg new file mode 100755 index 0000000..00ccfff --- /dev/null +++ b/library/msgs/fr_CA.msg @@ -0,0 +1,7 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset fr_CA DATE_FORMAT "%Y-%m-%d" + ::msgcat::mcset fr_CA TIME_FORMAT "%T" + ::msgcat::mcset fr_CA TIME_FORMAT_12 "%T" + ::msgcat::mcset fr_CA DATE_TIME_FORMAT "%a %d %b %Y %T %z" +} diff --git a/library/msgs/fr_CH.msg b/library/msgs/fr_CH.msg new file mode 100755 index 0000000..7e2bac7 --- /dev/null +++ b/library/msgs/fr_CH.msg @@ -0,0 +1,7 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset fr_CH DATE_FORMAT "%d. %m. %y" + ::msgcat::mcset fr_CH TIME_FORMAT "%T" + ::msgcat::mcset fr_CH TIME_FORMAT_12 "%T" + ::msgcat::mcset fr_CH DATE_TIME_FORMAT "%a %d %b %Y %T %z" +} diff --git a/library/msgs/ga_IE.msg b/library/msgs/ga_IE.msg new file mode 100755 index 0000000..b6acbbc --- /dev/null +++ b/library/msgs/ga_IE.msg @@ -0,0 +1,7 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset ga_IE DATE_FORMAT "%d.%m.%y" + ::msgcat::mcset ga_IE TIME_FORMAT "%T" + ::msgcat::mcset ga_IE TIME_FORMAT_12 "%T" + ::msgcat::mcset ga_IE DATE_TIME_FORMAT "%a %d %b %Y %T %z" +} diff --git a/library/msgs/gl_ES.msg b/library/msgs/gl_ES.msg new file mode 100755 index 0000000..d4ed270 --- /dev/null +++ b/library/msgs/gl_ES.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset gl_ES DATE_FORMAT "%d %B %Y" + ::msgcat::mcset gl_ES TIME_FORMAT_12 "%l:%M:%S %P" + ::msgcat::mcset gl_ES DATE_TIME_FORMAT "%d %B %Y %l:%M:%S %P %z" +} diff --git a/library/msgs/gv_GB.msg b/library/msgs/gv_GB.msg new file mode 100755 index 0000000..5e96e6f --- /dev/null +++ b/library/msgs/gv_GB.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset gv_GB DATE_FORMAT "%d %B %Y" + ::msgcat::mcset gv_GB TIME_FORMAT_12 "%l:%M:%S %P" + ::msgcat::mcset gv_GB DATE_TIME_FORMAT "%d %B %Y %l:%M:%S %P %z" +} diff --git a/library/msgs/hi_IN.msg b/library/msgs/hi_IN.msg new file mode 100755 index 0000000..239793f --- /dev/null +++ b/library/msgs/hi_IN.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset hi_IN DATE_FORMAT "%d %M %Y" + ::msgcat::mcset hi_IN TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset hi_IN DATE_TIME_FORMAT "%d %M %Y %I:%M:%S %P %z" +} diff --git a/library/msgs/id_ID.msg b/library/msgs/id_ID.msg new file mode 100755 index 0000000..bb672c1 --- /dev/null +++ b/library/msgs/id_ID.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset id_ID DATE_FORMAT "%d %B %Y" + ::msgcat::mcset id_ID TIME_FORMAT_12 "%l:%M:%S %P" + ::msgcat::mcset id_ID DATE_TIME_FORMAT "%d %B %Y %l:%M:%S %P %z" +} diff --git a/library/msgs/it_CH.msg b/library/msgs/it_CH.msg new file mode 100755 index 0000000..b36ed36 --- /dev/null +++ b/library/msgs/it_CH.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset it_CH DATE_FORMAT "%e. %B %Y" + ::msgcat::mcset it_CH TIME_FORMAT "%H:%M:%S" + ::msgcat::mcset it_CH DATE_TIME_FORMAT "%e. %B %Y %H:%M:%S %z" +} diff --git a/library/msgs/kl_GL.msg b/library/msgs/kl_GL.msg new file mode 100755 index 0000000..403aa10 --- /dev/null +++ b/library/msgs/kl_GL.msg @@ -0,0 +1,7 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset kl_GL DATE_FORMAT "%d %b %Y" + ::msgcat::mcset kl_GL TIME_FORMAT "%T" + ::msgcat::mcset kl_GL TIME_FORMAT_12 "%T" + ::msgcat::mcset kl_GL DATE_TIME_FORMAT "%a %d %b %Y %T %z" +} diff --git a/library/msgs/ko_KR.msg b/library/msgs/ko_KR.msg new file mode 100755 index 0000000..ea5bbd7 --- /dev/null +++ b/library/msgs/ko_KR.msg @@ -0,0 +1,8 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset ko_KR BCE "\uae30\uc6d0\uc804" + ::msgcat::mcset ko_KR CE "\uc11c\uae30" + ::msgcat::mcset ko_KR DATE_FORMAT "%Y.%m.%d" + ::msgcat::mcset ko_KR TIME_FORMAT_12 "%P %l:%M:%S" + ::msgcat::mcset ko_KR DATE_TIME_FORMAT "%Y.%m.%d %P %l:%M:%S %z" +} diff --git a/library/msgs/kok_IN.msg b/library/msgs/kok_IN.msg new file mode 100755 index 0000000..abcb1ff --- /dev/null +++ b/library/msgs/kok_IN.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset kok_IN DATE_FORMAT "%d %M %Y" + ::msgcat::mcset kok_IN TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset kok_IN DATE_TIME_FORMAT "%d %M %Y %I:%M:%S %P %z" +} diff --git a/library/msgs/kw_GB.msg b/library/msgs/kw_GB.msg new file mode 100755 index 0000000..2967680 --- /dev/null +++ b/library/msgs/kw_GB.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset kw_GB DATE_FORMAT "%d %B %Y" + ::msgcat::mcset kw_GB TIME_FORMAT_12 "%l:%M:%S %P" + ::msgcat::mcset kw_GB DATE_TIME_FORMAT "%d %B %Y %l:%M:%S %P %z" +} diff --git a/library/msgs/mr_IN.msg b/library/msgs/mr_IN.msg new file mode 100755 index 0000000..1889da5 --- /dev/null +++ b/library/msgs/mr_IN.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset mr_IN DATE_FORMAT "%d %M %Y" + ::msgcat::mcset mr_IN TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset mr_IN DATE_TIME_FORMAT "%d %M %Y %I:%M:%S %P %z" +} diff --git a/library/msgs/ms_MY.msg b/library/msgs/ms_MY.msg new file mode 100755 index 0000000..c1f93d4 --- /dev/null +++ b/library/msgs/ms_MY.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset ms_MY DATE_FORMAT "%A %d %b %Y" + ::msgcat::mcset ms_MY TIME_FORMAT_12 "%I:%M:%S %z" + ::msgcat::mcset ms_MY DATE_TIME_FORMAT "%A %d %b %Y %I:%M:%S %z %z" +} diff --git a/library/msgs/nl_BE.msg b/library/msgs/nl_BE.msg new file mode 100755 index 0000000..4b19670 --- /dev/null +++ b/library/msgs/nl_BE.msg @@ -0,0 +1,7 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset nl_BE DATE_FORMAT "%d-%m-%y" + ::msgcat::mcset nl_BE TIME_FORMAT "%T" + ::msgcat::mcset nl_BE TIME_FORMAT_12 "%T" + ::msgcat::mcset nl_BE DATE_TIME_FORMAT "%a %d %b %Y %T %z" +} diff --git a/library/msgs/pt_BR.msg b/library/msgs/pt_BR.msg new file mode 100755 index 0000000..8684327 --- /dev/null +++ b/library/msgs/pt_BR.msg @@ -0,0 +1,7 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset pt_BR DATE_FORMAT "%d-%m-%Y" + ::msgcat::mcset pt_BR TIME_FORMAT "%T" + ::msgcat::mcset pt_BR TIME_FORMAT_12 "%T" + ::msgcat::mcset pt_BR DATE_TIME_FORMAT "%a %d %b %Y %T %z" +} diff --git a/library/msgs/ru_UA.msg b/library/msgs/ru_UA.msg new file mode 100755 index 0000000..6e1f8a8 --- /dev/null +++ b/library/msgs/ru_UA.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset ru_UA DATE_FORMAT "%d.%m.%Y" + ::msgcat::mcset ru_UA TIME_FORMAT "%k:%M:%S" + ::msgcat::mcset ru_UA DATE_TIME_FORMAT "%d.%m.%Y %k:%M:%S %z" +} diff --git a/library/msgs/ta_IN.msg b/library/msgs/ta_IN.msg new file mode 100755 index 0000000..24590ac --- /dev/null +++ b/library/msgs/ta_IN.msg @@ -0,0 +1,6 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset ta_IN DATE_FORMAT "%d %M %Y" + ::msgcat::mcset ta_IN TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset ta_IN DATE_TIME_FORMAT "%d %M %Y %I:%M:%S %P %z" +} diff --git a/library/msgs/te_IN.msg b/library/msgs/te_IN.msg new file mode 100755 index 0000000..61638b5 --- /dev/null +++ b/library/msgs/te_IN.msg @@ -0,0 +1,8 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset te_IN AM "\u0c2a\u0c42\u0c30\u0c4d\u0c35\u0c3e\u0c39\u0c4d\u0c28" + ::msgcat::mcset te_IN PM "\u0c05\u0c2a\u0c30\u0c3e\u0c39\u0c4d\u0c28" + ::msgcat::mcset te_IN DATE_FORMAT "%d/%m/%Y" + ::msgcat::mcset te_IN TIME_FORMAT_12 "%I:%M:%S %P" + ::msgcat::mcset te_IN DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z" +} diff --git a/library/msgs/zh_CN.msg b/library/msgs/zh_CN.msg new file mode 100755 index 0000000..d62ce77 --- /dev/null +++ b/library/msgs/zh_CN.msg @@ -0,0 +1,7 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset zh_CN DATE_FORMAT "%Y-%m-%e" + ::msgcat::mcset zh_CN TIME_FORMAT "%k:%M:%S" + ::msgcat::mcset zh_CN TIME_FORMAT_12 "%P%I\u65f6%M\u5206%S\u79d2" + ::msgcat::mcset zh_CN DATE_TIME_FORMAT "%Y-%m-%e %k:%M:%S %z" +} diff --git a/library/msgs/zh_HK.msg b/library/msgs/zh_HK.msg new file mode 100755 index 0000000..badb1dd --- /dev/null +++ b/library/msgs/zh_HK.msg @@ -0,0 +1,28 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset zh_HK DAYS_OF_WEEK_ABBREV [list \ + "\u65e5"\ + "\u4e00"\ + "\u4e8c"\ + "\u4e09"\ + "\u56db"\ + "\u4e94"\ + "\u516d"] + ::msgcat::mcset zh_HK MONTHS_ABBREV [list \ + "1\u6708"\ + "2\u6708"\ + "3\u6708"\ + "4\u6708"\ + "5\u6708"\ + "6\u6708"\ + "7\u6708"\ + "8\u6708"\ + "9\u6708"\ + "10\u6708"\ + "11\u6708"\ + "12\u6708"\ + ""] + ::msgcat::mcset zh_HK DATE_FORMAT "%Y\u5e74%m\u6708%e\u65e5" + ::msgcat::mcset zh_HK TIME_FORMAT_12 "%P%I:%M:%S" + ::msgcat::mcset zh_HK DATE_TIME_FORMAT "%Y\u5e74%m\u6708%e\u65e5 %P%I:%M:%S %z" +} diff --git a/library/msgs/zh_SG.msg b/library/msgs/zh_SG.msg new file mode 100755 index 0000000..a2f3e39 --- /dev/null +++ b/library/msgs/zh_SG.msg @@ -0,0 +1,8 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset zh_SG AM "\u4e0a\u5348" + ::msgcat::mcset zh_SG PM "\u4e2d\u5348" + ::msgcat::mcset zh_SG DATE_FORMAT "%d %B %Y" + ::msgcat::mcset zh_SG TIME_FORMAT_12 "%P %I:%M:%S" + ::msgcat::mcset zh_SG DATE_TIME_FORMAT "%d %B %Y %P %I:%M:%S %z" +} diff --git a/library/msgs/zh_TW.msg b/library/msgs/zh_TW.msg new file mode 100755 index 0000000..e0796b1 --- /dev/null +++ b/library/msgs/zh_TW.msg @@ -0,0 +1,8 @@ +# created by tools/loadICU.tcl -- do not edit +namespace eval ::tcl::clock { + ::msgcat::mcset zh_TW BCE "\u6c11\u570b\u524d" + ::msgcat::mcset zh_TW CE "\u6c11\u570b" + ::msgcat::mcset zh_TW DATE_FORMAT "%Y/%m/%e" + ::msgcat::mcset zh_TW TIME_FORMAT_12 "%P %I:%M:%S" + ::msgcat::mcset zh_TW DATE_TIME_FORMAT "%Y/%m/%e %P %I:%M:%S %z" +} diff --git a/libtommath/TODO b/libtommath/TODO new file mode 100644 index 0000000..deffba1 --- /dev/null +++ b/libtommath/TODO @@ -0,0 +1,16 @@ +things for book in order of importance... + +- Fix up pseudo-code [only] for combas that are not consistent with source +- Start in chapter 3 [basics] and work up... + - re-write to prose [less abrupt] + - clean up pseudo code [spacing] + - more examples where appropriate and figures + +Goal: + - Get sync done by mid January [roughly 8-12 hours work] + - Finish ch3-6 by end of January [roughly 12-16 hours of work] + - Finish ch7-end by mid Feb [roughly 20-24 hours of work]. + +Goal isn't "first edition" but merely cleaner to read. + + diff --git a/libtommath/logs/invmod.log b/libtommath/logs/invmod.log index e69de29..e69de29 100644..100755 --- a/libtommath/logs/invmod.log +++ b/libtommath/logs/invmod.log diff --git a/libtommath/poster.out b/libtommath/poster.out index e69de29..e69de29 100644..100755 --- a/libtommath/poster.out +++ b/libtommath/poster.out diff --git a/mac/AppleScript.html b/mac/AppleScript.html new file mode 100644 index 0000000..32b2e9f --- /dev/null +++ b/mac/AppleScript.html @@ -0,0 +1,312 @@ +<HTML> + +<HEAD> + +<TITLE>tclOSAScript -- OSA</TITLE> + +</HEAD> + +<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#FF0000" ALINK="#00FF00"> + +<H2 ALIGN="CENTER">TclAppleScript Extension Command</H2> + +<H3>NAME</H3> +<DL> +<DT> +AppleScript - Communicate with the AppleScript OSA component to run + AppleScripts from Tcl. +</DL> +<H3>SYNOPSIS</H3> +<DL><DT> +<B>AppleScript <A NAME="compile">compile</A> </B><I>?-flag value?</I> <I>scriptData1 + ?ScriptData2 ...?</I><I>componentName</I> +<BR> +<B>AppleScript <A NAME="decompile">decompile</A></B> <I>scriptName</I> +<BR> +<B>AppleScript <A NAME="delete">delete</A> </B><I>what scriptName</I> +<BR> +<B>AppleScript <A NAME="execute">execute</A> </B><I>?flags value?</I> <I>scriptData1 + ?scriptData2 ...?</I> +<BR> +<B>AppleScript <A NAME="info">info</A> </B><I>what</I> +<BR> +<B>AppleScript <A NAME="load">load</A></B> <I>?flag value? fileName</I> +<BR> +<B>AppleScript <A NAME="run">run</A></B> <I>?flag value?</I> + <I>scriptName</I> +<BR> +<B>AppleScript <A NAME="store">store</A></B> <I>?flag value? scriptName fileName</I> +<BR> +</DL> + +<H3>DESCRIPTION</H3> +<DL> +<DT> + + +This command is used to communicate with the AppleScript OSA component. +You can <A HREF="#compile"><B>compile</B></A> scripts, <A +HREF="#run"><B>run</B></A> compiled scripts, <A +HREF="#execute"><B>execute</B></A> script data (i.e. compile and run at a +blow). You can get script data from a compiled script (<A +HREF="#decompile"><B>decompile</B></A> it), and you can <A +HREF="#load"><B>load</B></A> a compiled script from the scpt resource of a +file, or <A HREF="store"><B>store</B></A> one to a scpt resource. You can +also get <A HREF="#info"><B>info</B></A> on the currently available scripts +and contexts. It has the general form + +<DL> +<DT> +<P> +<I>AppleScript option ?arg arg ...?</I> +<P> +</DL> +The possible sub-commands are: +<P> +<DL> + <DT> + <I>AppleScript</I> <A NAME="compile"><B>compile</A> </B><I>?-flag value?</I> <I>scriptData1 + ?ScriptData2 ...?</I> + <BR> + + <DD> + The scriptData + elements are concatenated (with a space between each), and + sent to AppleScript + for compilation. There is no limitation on the size of + the scriptData, beyond the available memory of the Wish interpreter. + <P> + If the compilation is successful, then the command will return a token + that you can pass to the <A HREF="#run">"run"</A> subcommand. If the + compilation fails, then the return value will be the error message from + AppleScript, and the pertinent line of code, with an "_" to indicate + the place where it thinks the error occured. + <P> + The + compilation is controlled by flag value pairs. The available flags + are: + <P> + <DL> + <DT> + <A NAME="first compile switch"><B>-augment Boolean</B></A> + <DD> + To be used in concert with the <A HREF="#-context">-context</A> flag. + If augment is yes, + then the scriptData augments the handlers and data already in the + script context. If augment is no, then the scriptData replaces the + data and handlers already in the context. The default is yes. + <P> + <!-- I'm leaving this flag out for now, since I can't seem to get the + AE manager to obey it. Even when I hard code the value, applications + still switch to the foreground. Oh, well... + + <DT> + <B>-canswitch Boolean </B> + <DD> + If yes, then applications activated by the code in scriptData will + be allowed to switch to the foreground. If no, then they will use + the notification manager to indicate they need attention (this + usually means they blink the Finder icon, and put a check in the + application's entry in the Finder menu). + --> + + <DT> + <B><A NAME="-context">-context</A> Boolean</B> + <DD> + This flag causes the code given in the scriptData to be compiled + into a "context". In AppleScript, this is the equivalent of creating an Tcl + Namespace. The command in this case returns the name of the context as + the its result, rather than a compiled script name. + <P> + You can store data and procedures (aka + handlers) in a script context. Then later, you can + run other scripts in this context, and they will see all the data and + handlers that were set up with this command. You do this by passing the + name of this context to the -context flag of the run or execute subcommands. + <P> + Unlike the straight compile command, the code compiled into a + script context is run immediatly, when it is compiled, to set up the context. + <DT> + <P> + <B>-name string</B> + <DD> + Use <I>string</I> as the name of the script or script context. If there is + already a script + of this name, it will be discarded. The same is true with script + contexts, unless the <I>-augment</I> flag is true. If no name is provided, then a + unique name will be created for you. + <DT> + <P> + <B>-parent contextName </B> + <DD> + This flag is also to be used in conjunction with the <A HREF="#-context">-context</A> flag. + <I>contextName</I> must be the name of a compiled script context. Then + the new script context will inherit the data and handlers from the + parent context. + </DL> + <P> + <DT> + <I>AppleScript</I> <B><A NAME="decompile">decompile</A></B> <I>scriptName</I> + <BR> + <DD> + This decompiles the script data compiled into the script scriptName, + and returns the source code. + <P> + <DT> + <I>AppleScript</I> <B><A NAME="delete">delete</A> </B><I>what scriptName</I> + <BR> + <DD> + This deletes contexts or script data. The allowed values for "what" are: + <P> + <DL> + <DT> + <P> + <B>context</B> + <DD> + This deletes the context scriptName, + and frees up all the resources associated with it. + <DT> + <P> + <B>script</B> + <DD> + This deletes the script data compiled into the script scriptName, + and frees up all the resources associated with it. + </DL> + <P> + <DT> + <I>AppleScript</I> <B><A NAME="execute">execute</A> </B><I>?flags value?</I> <I>scriptData1 + ?scriptData2 ...?</I> + <BR> + <DD> + This compiles and runs the script in scriptData (concatenating first), and + returns the results of the script execution. It is the same as doing + <I>compile</I> and then <I>run</I>, except that the compiled script is + immediately discarded. + <P> + <DT> + <I>AppleScript</I> <B><A NAME="info">info</A> </B><I>what</I> + <DD> + This gives info on the connection. The allowed values for "what" are: + <P> + <DL> + <DT> + <P> + <B>contexts </B> <I>?pattern?</I> + <DD> + This gives the list of the script contexts that have been. + If <I>pattern</I> is given, it only reports the contexts + that match this pattern. + <DT> + <!-- <P> + <B>language</B> + <DD> + Returns the language of this OSA component + <DT> + --> + <P> + <B>scripts</B> <I>?pattern?</I> + <DD> + This returns a list of the scripts that have been compiled in the + current connection. If <I>pattern</I> is given, it only reports the + script names that match this pattern. + </DL> + <P> + <DT> + <I>AppleScript</I> <B><A NAME="load">load</A></B> <I>?flag value? fileName</I> + <DD> + This loads compiled script data from a resource of type 'scpt' in the + file fileName, and returns a token for the script data. As with the + <I>compile</I> command, the script is not actually executed. Note that all + scripts compiled with Apple's "Script Editor" are stored as script + contexts. However, unlike with the "<I>compile -context</I>" command, the <I>load</I> + command does not run these scripts automatically. If you want to set up + the handlers contained in the loaded script, you must run it manually. + <P> + <I>load</I> takes the following flags: + <P> + <DL> + <DT> + <B>-rsrcname string</B> + <DD> + load a named resource of type 'scpt' using the rsrcname + flag. + <DT> + <P> + <B>-rsrcid integer</B> + <DD> + load a resource by number with the rsrcid flag. + </DL> + <DD> + <P> + If neither the <I>rsrcname</I> nor the <I>rsrcid</I> flag is provided, then the load + command defaults to -rsrcid = 128. This is the resource in which + Apple's Script Editor puts the script data when it writes out a + compiled script. + <P> + <DT> + <I>AppleScript</I> <B><A NAME="run">run</A></B> <I>?flag value?</I> <I>scriptName</I> + <DD> + This runs the script which was previously compiled into <I>scriptName</I>. If the script + runs successfully, the command returns the return value for this command, + coerced to a text string. + If there is an error in + the script execution, then it returns the error result from the + scripting component. It accepts the following flag: + + <DL> + <DT> + <P> + <B>-context contextName</B> + <DD> + <I>contextName</I> must be a context created by a previous call to <I>compile</I> with + the -<I>context</I> flag set. This flag causes the code given in the + <I>scriptData</I> to be run in this "context". It will see all the data and + handlers that were set up previously. + <!-- <DT> + <B>-canswitch Boolean </B> + <DD> + If yes, then applications activated by the code + in scriptData will be allowed to switch to the foreground. If no, then + they will use the notification manager to indicate they need attention + (this usually means they blink the Finder icon, and put a check in the + application's entry in the Finder menu). --> + </DL> + <P> + <DT> + <I>AppleScript </I> <B> <A NAME="store">store</A></B> <I>?flag value? scriptName fileName</I> + <DD> + This stores a compiled script or script context into a resource of type 'scpt' in the + file fileName. + <P> + store takes the following flags: + <P> + <DL> + <DT> + <B>-rsrcname string</B> + <DD> + store to a named resource of type 'scpt' using the rsrcname + flag. + <DT> + <P> + <B>-rsrcid integer</B> + <DD> + store to a numbered resource with the rsrcid flag. + </DL> + <P> + <DD> + If neither the rsrcname nor the rsrcid flag is provided, then the load + command defaults to -rsrcid = 128. Apple's Script Editor can read in files written by + tclOSAScript with this setting of the <I>-rsrcid</I> flag. +</DL> +</DL> +<H2>Notes:</H2> + +The AppleScript command is a stopgap command to fill the place of exec + on the Mac. It is not a supported command, and will likely change + as we broaden it to allow communication with other OSA languages. +<H2>See Also:</H2> + + +</BODY> + +</HTML> diff --git a/mac/Background.doc b/mac/Background.doc new file mode 100644 index 0000000..d23235a --- /dev/null +++ b/mac/Background.doc @@ -0,0 +1,92 @@ +Notes about the Background Only application template +==================================================== + +RCS: @(#) $Id: Background.doc,v 1.2 1998/09/14 18:40:03 stanton Exp $ + +We have included sample code and project files for making a Background-Only + application (BOA) in Tcl. This could be used for server processes (like the +Tcl Web-Server). + +Files: +------ + +* BOA_TclShells.¼ - This is the project file. +* tclMacBOAAppInit.c - This is the AppInit file for the BOA App. +* tclMacBOAMain - This is a replacement for the Tcl_Main for BOA's. + +Caveat: +------- + +This is an unsupported addition to MacTcl. The main feature that will certainly +change is how we handle AppleEvents. Currently, all the AppleEvent handling is +done on the Tk side, which is not really right. Also, there is no way to +register your own AppleEvent handlers, which is obviously something that would be +useful in a BOA App. We will address these issues in Tcl8.1. If you need to +register your own AppleEvent Handlers in the meantime, be aware that your code +will probably break in Tcl8.1. + +I will also improve the basic code here based on feedback that I recieve. This +is to be considered a first cut only at writing a BOA in Tcl. + +Introduction: +------------- + +This project makes a double-clickable BOA application. It obviously needs +some Tcl code to get it started. It will look for this code first in a +'TEXT' resource in the application shell whose name is "bgScript.tcl". If +it does not find any such resource, it will look for a file called +bgScript.tcl in the application's folder. Otherwise it will quit with an +error. + +It creates three files in the application folder to store stdin, stdout & +stderr. They are imaginatively called temp.in, temp.out & temp.err. They +will be opened append, so you do not need to erase them after each use of +the BOA. + +The app does understand the "quit", and the "doScript" AppleEvents, so you can +kill it with the former, and instruct it with the latter. It also has an +aete, so you can target it with Apple's "Script Editor". + +For more information on Macintosh BOA's, see the Apple TechNote: 1070. + +Notifications: +-------------- + +BOA's are not supposed to have direct contact with the outside world. They +are, however, allowed to go through the Notification Manager to post +alerts. To this end, I have added a Tcl command called "bgnotify" to the +shell, that simply posts a notification through the notification manager. + +To use it, say: + +bgnotify "Hi, there little buddy" + +It will make the system beep, and pop up an annoying message box with the +text of the first argument to the command. While the message is up, Tcl +is yielding processor time, but not processing any events. + +Errors: +------- + +Usually a Tcl background application will have some startup code, opening +up a server socket, or whatever, and at the end of this, will use the +vwait command to kick off the event loop. If an error occurs in the +startup code, it will kill the application, and a notification of the error +will be posted through the Notification Manager. + +If an error occurs in the event handling code after the +vwait, the error message will be written to the file temp.err. However, +if you would like to have these errors post a notification as well, just +define a proc called bgerror that takes one argument, the error message, +and passes that off to "bgnotify", thusly: + +proc bgerror {mssg} { + bgnotify "A background error has occured\n $mssg" +} + +Support: +-------- + +If you have any questions, contact me at: + +jim.ingham@eng.sun.com diff --git a/mac/MW_TclAppleScriptHeader.h b/mac/MW_TclAppleScriptHeader.h new file mode 100755 index 0000000..6ce3853 --- /dev/null +++ b/mac/MW_TclAppleScriptHeader.h @@ -0,0 +1,7 @@ +#if __POWERPC__ +#include "MW_TclAppleScriptHeaderPPC" +#elif __CFM68K__ +#include "MW_TclAppleScriptHeaderCFM68K" +#else +#include "MW_TclAppleScriptHeader68K" +#endif diff --git a/mac/MW_TclAppleScriptHeader.pch b/mac/MW_TclAppleScriptHeader.pch new file mode 100644 index 0000000..12fec3f --- /dev/null +++ b/mac/MW_TclAppleScriptHeader.pch @@ -0,0 +1,36 @@ +/* + * MW_TclAppleScriptHeader.pch -- + * + * This file is the source for a pre-compilied header that gets used + * for TclAppleScript. This make compilies go a bit + * faster. This file is only intended to be used in the MetroWerks + * CodeWarrior environment. It essentially acts as a place to set + * compiler flags. See MetroWerks documention for more details. + * + * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: MW_TclAppleScriptHeader.pch,v 1.5 2001/11/23 01:26:17 das Exp $ + */ + +/* + * To use the compilied header you need to set the "Prefix file" in + * the "C/C++ Language" preference panel to point to the created + * compilied header. The name of the header depends on the + * architecture we are compiling for (see the code below). For + * example, for a 68k app the prefix file should be: MW_TclHeader68K. + */ + +#if __POWERPC__ +#pragma precompile_target "MW_TclAppleScriptHeaderPPC" +#elif __CFM68K__ +#pragma precompile_target "MW_TclAppleScriptHeaderCFM68K" +#else +#pragma precompile_target "MW_TclAppleScriptHeader68K" +#endif + +#include "tclMacCommonPch.h" + +#define USE_TCL_STUBS diff --git a/mac/MW_TclBuildLibHeader.h b/mac/MW_TclBuildLibHeader.h new file mode 100644 index 0000000..f6a6f61 --- /dev/null +++ b/mac/MW_TclBuildLibHeader.h @@ -0,0 +1,7 @@ +#if __POWERPC__ +#include "MW_TclBuildLibHeaderPPC" +#elif __CFM68K__ +#include "MW_TclBuildLibHeaderCFM68K" +#else +#include "MW_TclBuildLibHeader68K" +#endif diff --git a/mac/MW_TclBuildLibHeader.pch b/mac/MW_TclBuildLibHeader.pch new file mode 100644 index 0000000..a727451 --- /dev/null +++ b/mac/MW_TclBuildLibHeader.pch @@ -0,0 +1,35 @@ +/* + * MW_TclBuildLibHeader.pch -- + * + * This file is the source for a pre-compilied header that gets used + * for all files in the Tcl projects. This make compilies go a bit + * faster. This file is only intended to be used in the MetroWerks + * CodeWarrior environment. It essentially acts as a place to set + * compiler flags. See MetroWerks documention for more details. + * + * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id$ + */ + +/* + * To use the compilied header you need to set the "Prefix file" in + * the "C/C++ Language" preference panel to point to the created + * compilied header. The name of the header depends on the + * architecture we are compiling for (see the code below). For + * example, for a 68k app the prefix file should be: MW_TclHeader68K. + */ +#if __POWERPC__ +#pragma precompile_target "MW_TclBuildLibHeaderPPC" +#elif __CFM68K__ +#pragma precompile_target "MW_TclBuildLibHeaderCFM68K" +#else +#pragma precompile_target "MW_TclBuildLibHeader68K" +#endif + +#define BUILD_tcl 1 + +#include "MW_TclHeaderCommon.h" diff --git a/mac/MW_TclHeader.h b/mac/MW_TclHeader.h new file mode 100755 index 0000000..43a9029 --- /dev/null +++ b/mac/MW_TclHeader.h @@ -0,0 +1,7 @@ +#if __POWERPC__ +#include "MW_TclHeaderPPC" +#elif __CFM68K__ +#include "MW_TclHeaderCFM68K" +#else +#include "MW_TclHeader68K" +#endif diff --git a/mac/MW_TclHeader.pch b/mac/MW_TclHeader.pch new file mode 100644 index 0000000..14bf41a --- /dev/null +++ b/mac/MW_TclHeader.pch @@ -0,0 +1,33 @@ +/* + * MW_TclHeader.pch -- + * + * This file is the source for a pre-compilied header that gets used + * for all files in the Tcl projects. This make compilies go a bit + * faster. This file is only intended to be used in the MetroWerks + * CodeWarrior environment. It essentially acts as a place to set + * compiler flags. See MetroWerks documention for more details. + * + * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: MW_TclHeader.pch,v 1.8 2001/11/23 01:26:20 das Exp $ + */ + +/* + * To use the compilied header you need to set the "Prefix file" in + * the "C/C++ Language" preference panel to point to the created + * compilied header. The name of the header depends on the + * architecture we are compiling for (see the code below). For + * example, for a 68k app the prefix file should be: MW_TclHeader68K. + */ +#if __POWERPC__ +#pragma precompile_target "MW_TclHeaderPPC" +#elif __CFM68K__ +#pragma precompile_target "MW_TclHeaderCFM68K" +#else +#pragma precompile_target "MW_TclHeader68K" +#endif + +#include "MW_TclHeaderCommon.h" diff --git a/mac/MW_TclHeaderCommon.h b/mac/MW_TclHeaderCommon.h new file mode 100644 index 0000000..56ea59c --- /dev/null +++ b/mac/MW_TclHeaderCommon.h @@ -0,0 +1,54 @@ +/* + * MW_TclHeaderCommon.h -- + * + * Common includes for precompiled headers + * + * Copyright (c) 1998 by Scriptics Corporation. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id$ + */ + +#pragma once + +#include "tclMacCommonPch.h" + +/* + * Place any includes below that will are needed by the majority of the + * and is OK to be in any file in the system. + */ + +#include "tcl.h" + +#ifdef BUILD_tcl +# undef TCL_STORAGE_CLASS +# define TCL_STORAGE_CLASS DLLEXPORT +#endif +#include "tclMac.h" +#undef TCL_STORAGE_CLASS +#define TCL_STORAGE_CLASS DLLIMPORT + +#include "tclInt.h" + + +#if PRAGMA_IMPORT +#pragma import on +#endif + +#include <MoreFiles.h> +#include <MoreFilesExtras.h> +#include <FSpCompat.h> +#include <FileCopy.h> +#include <FullPath.h> +#include <IterateDirectory.h> +#include <MoreDesktopMgr.h> +#include <DirectoryCopy.h> +#include <Search.h> + +#ifdef PRAGMA_IMPORT_OFF +#pragma import off +#elif PRAGMA_IMPORT +#pragma import reset +#endif diff --git a/mac/MW_TclStaticHeader.h b/mac/MW_TclStaticHeader.h new file mode 100644 index 0000000..0c1abc2 --- /dev/null +++ b/mac/MW_TclStaticHeader.h @@ -0,0 +1,7 @@ +#if __POWERPC__ +#include "MW_TclStaticHeaderPPC" +#elif __CFM68K__ +#include "MW_TclStaticHeaderCFM68K" +#else +#include "MW_TclStaticHeader68K" +#endif diff --git a/mac/MW_TclStaticHeader.pch b/mac/MW_TclStaticHeader.pch new file mode 100644 index 0000000..f23021f --- /dev/null +++ b/mac/MW_TclStaticHeader.pch @@ -0,0 +1,35 @@ +/* + * MW_TclStaticHeader.pch -- + * + * This file is the source for a pre-compilied header that gets used + * for all files in the Tcl projects. This make compilies go a bit + * faster. This file is only intended to be used in the MetroWerks + * CodeWarrior environment. It essentially acts as a place to set + * compiler flags. See MetroWerks documention for more details. + * + * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id$ + */ + +/* + * To use the compilied header you need to set the "Prefix file" in + * the "C/C++ Language" preference panel to point to the created + * compilied header. The name of the header depends on the + * architecture we are compiling for (see the code below). For + * example, for a 68k app the prefix file should be: MW_TclHeader68K. + */ +#if __POWERPC__ +#pragma precompile_target "MW_TclStaticHeaderPPC" +#elif __CFM68K__ +#pragma precompile_target "MW_TclStaticHeaderCFM68K" +#else +#pragma precompile_target "MW_TclStaticHeader68K" +#endif + +#define STATIC_BUILD 1 + +#include "MW_TclHeaderCommon.h" diff --git a/mac/MW_TclTestHeader.h b/mac/MW_TclTestHeader.h new file mode 100755 index 0000000..c47bb97 --- /dev/null +++ b/mac/MW_TclTestHeader.h @@ -0,0 +1,7 @@ +#if __POWERPC__ +#include "MW_TclTestHeaderPPC" +#elif __CFM68K__ +#include "MW_TclTestHeaderCFM68K" +#else +#include "MW_TclTestHeader68K" +#endif diff --git a/mac/MW_TclTestHeader.pch b/mac/MW_TclTestHeader.pch new file mode 100755 index 0000000..dbb297a --- /dev/null +++ b/mac/MW_TclTestHeader.pch @@ -0,0 +1,41 @@ +/* + * MW_TclTestHeader.pch -- + * + * This file is the source for a pre-compilied header that gets used + * for all files in the Tcl projects. This make compilies go a bit + * faster. This file is only intended to be used in the MetroWerks + * CodeWarrior environment. It essentially acts as a place to set + * compiler flags. See MetroWerks documention for more details. + * + * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: MW_TclTestHeader.pch,v 1.2 2001/11/23 01:26:23 das Exp $ + */ + +/* + * To use the compilied header you need to set the "Prefix file" in + * the "C/C++ Language" preference panel to point to the created + * compilied header. The name of the header depends on the + * architecture we are compiling for (see the code below). For + * example, for a 68k app the prefix file should be: MW_TclHeader68K. + */ +#if __POWERPC__ +#pragma precompile_target "MW_TclTestHeaderPPC" +#elif __CFM68K__ +#pragma precompile_target "MW_TclTestHeaderCFM68K" +#else +#pragma precompile_target "MW_TclTestHeader68K" +#endif + +#define BUILD_tcl 1 + +#define STATIC_BUILD 1 + +#define TCL_DEBUG 1 + +#define TCL_THREADS 1 + +#include "MW_TclHeaderCommon.h" diff --git a/mac/README b/mac/README new file mode 100644 index 0000000..99dc71d --- /dev/null +++ b/mac/README @@ -0,0 +1,69 @@ +Tcl 8.5 for Macintosh + +RCS: @(#) $Id: README,v 1.18 2003/03/04 23:46:08 dgp Exp $ + +1. Introduction +--------------- + +This is the README file for the Macintosh version of the Tcl +scripting language. The home page for the Mac/Tcl info is + http://www.tcl.tk/software/mac/ + +A summary of what's new in this release is at + http://www.tcl.tk/software/tcltk/8.5.html + +A summary of Macintosh-specific features is at + http://www.tcl.tk/software/mac/features.html + +2. The Distribution +------------------- + +Macintosh Tcl is distributed in three different forms. This should +make it easier to only download what you need. Substitute <version> +with the version you wish to use. The packages are as follows: + +mactk<version>.sea.hqx + + This distribution is a "binary" only release. It contains an + installer program that will install a 68k, PowerPC, or Fat + version of the "Tcl Shell" and "Wish" applications. In addition, + it installs the Tcl & Tk libraries in the Extensions folder inside + your System Folder. + +mactcltk-full-<version>.sea.hqx + + This release contains the full release of Tcl and Tk for the + Macintosh plus the More Files packages which Macintosh Tcl and Tk + rely on. + +mactcl-source-<version>.sea.hqx + + This release contains the complete source for Tcl. In + addition, Metrowerks CodeWarrior libraries and project files + are included. However, you must already have the More Files + package to compile this code. + +The "html" subdirectory contains reference documentation in +in the HTML format. You may also find these pages at: + + http://www.tcl.tk/man/ + +3. Compiling Tcl +---------------- + +In order to compile Macintosh Tcl you must have the +following items: + + CodeWarrior Pro 5+ + Mac Tcl (sources) + More Files 1.4.9 + +The included project files should work fine. However, for +current release notes please check this page: + + http://www.tcl.tk/doc/howto/compile.html#mac + +If you have comments or Bug reports, please use the SourceForge +Bug tracker to report them: + + http://tcl.sourceforge.net/ diff --git a/mac/bugs.doc b/mac/bugs.doc new file mode 100644 index 0000000..730f115 --- /dev/null +++ b/mac/bugs.doc @@ -0,0 +1,44 @@ +Known bug list for Tcl 8.0 for Macintosh + +by Ray Johnson +Sun Microsystems Laboratories +rjohnson@eng.sun.com + +RCS: @(#) $Id: bugs.doc,v 1.4 2000/02/10 08:39:37 jingham Exp $ + +This was a new feature as of Tcl7.6b1 and as such I'll started with +a clean slate. I currently know of no reproducable bugs. I often +get vague reports - but nothing I've been able to confirm. Let +me know what bugs you find! + +The Macintosh version of Tcl passes most all tests in the Tcl +test suite. Slower Macs may fail some tests in event.test whose +timing constraints are too tight. If other tests fail please report +them. + +Ray + +Known bugs in the current release. + +* With the socket code you can't use the "localhost" host name. This + is actually a known bug in Apple's MacTcp stack. However, you can + use [info hostname] whereever you would have used "localhost" to + achive the same effect. + +* Most socket bugs have been fixed. We do have a couple of test cases + that will hang the Mac, however, and we are still working on them. + If you find additional test cases that show crashes please let us + know! + +* In Tcl 8.2, the new Regexp code seems to be more deeply recursive than +the older version in Tcl8.0. As a result, I have had to increase the Stack +size of Tcl to 1Meg. If you are not doing regexps with many subexpressions, +this is probably more stack than you will need. You can relink with the +stack set to 512K, and you will be fine for most purposes. +* This regexp problem is fixed in Tcl8.3. If you are going to do complex +regexp's, it is probably a good idea to keep the stack size big. But normal +regexps will not cause crashes. + +* The "clock scan -base" command does not work. The epoch is wrong. +* The file mtime command does not work when setting the time, it is off +by 4 years. diff --git a/mac/libmoto.doc b/mac/libmoto.doc new file mode 100644 index 0000000..2183651 --- /dev/null +++ b/mac/libmoto.doc @@ -0,0 +1,39 @@ +Notes about the use of libmoto +------------------------------ + +RCS: @(#) $Id: libmoto.doc,v 1.2 1998/09/14 18:40:04 stanton Exp $ + +First of all, libmoto is not required! If you don't have it, you +can simply remove the library reference from the project file and +everything should compile just fine. + +The libmoto library replaces certain functions in the MathLib and +ANSI libraries. Motorola has optimized the functions in the library +to run very fast on the PowerPC. As I said above, you don't need +this library, but it does make things faster. + +Obtaining Libmoto: + + For more information about Libmoto and how to doanload + it, visit the following URL: + + http://www.mot.com/SPS/PowerPC/library/fact_sheet/libmoto.html + + You will need to register for the library. However, the + library is free and you can use it in any commercial product + you might have. + +Installing Libmoto: + + Just follow the instructions provided by the Motorola + README file. You need to make sure that the Libmoto + library is before the ANSI and MathLib libraries in + link order. Also, you will get several warnings stateing + that certain functions have already been defined in + Libmoto. (These can safely be ignored.) + +Finally, you can thank Kate Stewart of Motorola for twisting my +arm at the Tcl/Tk Conference to provide some support for Libmoto. + +Ray Johnson + diff --git a/mac/morefiles.doc b/mac/morefiles.doc new file mode 100644 index 0000000..58f0929 --- /dev/null +++ b/mac/morefiles.doc @@ -0,0 +1,74 @@ +Notes about MoreFiles, dnr.c & other non-Tcl source files +--------------------------------------------------------- + +RCS: @(#) $Id: morefiles.doc,v 1.2 1998/09/14 18:40:04 stanton Exp $ + +The Macintosh distribution uses several source files that don't +actually ship with Tcl. This sometimes causes problems or confusion +to developers. This document should help clear up a few things. + +dnr.c +----- + +We have found a way to work around some bugs in dnr.c that +Apple has never fixed even though we sent in numerous bug reports. +The file tclMacDNR.c simply set's some #pragma's and the includes +the Apple dnr.c file. This should work the problems that many of +you have reported with dnr.c. + +More Files +---------- + +Macintosh Tcl/Tk also uses Jim Luther's very useful package called +More Files. More Files fixes many of the broken or underfunctional +parts of the file system. + +More Files can be found on the MetroWerks CD and Developer CD from +Apple. You can also down load the latest version from: + + ftp://members.aol.com/JumpLong/ + +The package can also be found at the home of Tcl/Tk for the mac: + + ftp://ftp.sunlabs.com/pub/tcl/mac/ + +I used to just link the More Files library in the Tcl projects. +However, this caused problems when libraries wern't matched correctly. +I'm now including the files in the Tcl project directly. This +solves the problem of missmatched libraries - but may not always +compile. + +If you get a compiliation error in MoreFiles you need to contact +Jim Luther. His email address: + + JumpLong@aol.com + +The version of More Files that we use with Tcl/Tk is 1.4.3. Early +version may work as well.. + +Unfortunantly, there is one bug in his library (in 1.4.3). The bug is +in the function FSpGetFullPath found in the file FullPath.c. After +the call to PBGetCatInfoSync you need to change the line: + + if ( result == noErr ) + + to: + + if ( (result == noErr) || (result == fnfErr) ) + + +The latest version of More Files is 1.4.6. Unfortunantly, this +version has a bug that keeps it from working with shared libraries +right out of the box. If you want to use 1.4.6 you can but you will +need to make the following fix: + + In the file "Opimization.h" in the More Files package you + need to remove the line "#pragma internal on". And in the + file "OptimazationEnd.h" you need to remove the line + "#pragma internal reset". + +Note: the version of MoreFile downloaded from the Sun Tcl/Tk site +will have the fix included. (If you want you can send email to +Jim Luther suggesting that he use Tcl for regression testing!) + +Ray Johnson diff --git a/mac/porting.notes b/mac/porting.notes new file mode 100644 index 0000000..5e71969 --- /dev/null +++ b/mac/porting.notes @@ -0,0 +1,23 @@ +Porting Notes +------------- + +RCS: @(#) $Id: porting.notes,v 1.2 1998/09/14 18:40:04 stanton Exp $ + +Currently, the Macintosh version Tcl only compilies with the +CodeWarrior C compilier from MetroWerks. It should be straight +forward to port the Tcl source to MPW. + +Tcl on the Mac no longer requires the use of GUSI. It should now +be easier to port Tcl/Tk to other compiliers such as Symantic C +and MPW C. + +If you attempt to port Tcl to other Macintosh compiliers please +let me know. I would be glad to help with advice and encouragement. +If your efforts are succesfull I wold also be interested in puting +those changes into the core distribution. Furthermore, please feel +free to send me any notes you might make about your porting +experience so I may include them in this file for others to reference. + +Ray Johnson +ray.johnson@eng.sun.com + diff --git a/mac/tclMac.h b/mac/tclMac.h new file mode 100644 index 0000000..b937342 --- /dev/null +++ b/mac/tclMac.h @@ -0,0 +1,28 @@ +/* + * tclMac.h -- + * + * Declarations of Macintosh specific public variables and procedures. + * + * Copyright (c) 1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMac.h,v 1.5 2001/11/23 01:27:05 das Exp $ + */ + +#ifndef _TCLMAC +#define _TCLMAC + +#ifndef _TCL +# include "tcl.h" +#endif +#include <Types.h> +#include <Files.h> +#include <Events.h> + +typedef int (*Tcl_MacConvertEventPtr) _ANSI_ARGS_((EventRecord *eventPtr)); + +#include "tclPlatDecls.h" + +#endif /* _TCLMAC */ diff --git a/mac/tclMacAETE.r b/mac/tclMacAETE.r new file mode 100644 index 0000000..be9dd11 --- /dev/null +++ b/mac/tclMacAETE.r @@ -0,0 +1,58 @@ +/* + * tclMacAETE.r -- + * + * This file creates the Apple Event Terminology resources + * for use Tcl and Tk. It is not used in the Simple Tcl shell + * since SIOUX does not support AppleEvents. An example of its + * use in Tcl is the TclBGOnly project. And it is used in all the + * Tk Shells. + * + * Copyright (c) 1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacAETE.r,v 1.2 1998/09/14 18:40:04 stanton Exp $ + */ + +#define SystemSevenOrLater 1 + +#include <Types.r> +#include <SysTypes.r> +#include <AEUserTermTypes.r> + +/* + * The following resources defines the Apple Events that Tk can be + * sent from Apple Script. + */ + +resource 'aete' (0, "Wish Suite") { + 0x01, 0x00, english, roman, + { + "Required Suite", + "Events that every application should support", + 'reqd', 1, 1, + {}, + {}, + {}, + {}, + + "Wish Suite", "Events for the Wish application", 'WIsH', 1, 1, + { + "do script", "Execute a Tcl script", 'misc', 'dosc', + 'TEXT', "Result", replyOptional, singleItem, + notEnumerated, reserved, reserved, reserved, reserved, + reserved, reserved, reserved, reserved, reserved, + reserved, reserved, reserved, reserved, + 'TEXT', "Script to execute", directParamRequired, + singleItem, notEnumerated, changesState, reserved, + reserved, reserved, reserved, reserved, reserved, + reserved, reserved, reserved, reserved, reserved, + reserved, + {}, + }, + {}, + {}, + {}, + } +}; diff --git a/mac/tclMacAlloc.c b/mac/tclMacAlloc.c new file mode 100644 index 0000000..3e6a948 --- /dev/null +++ b/mac/tclMacAlloc.c @@ -0,0 +1,412 @@ +/* + * tclMacAlloc.c -- + * + * This is a very fast storage allocator. It allocates blocks of a + * small number of different sizes, and keeps free lists of each size. + * Blocks that don't exactly fit are passed up to the next larger size. + * Blocks over a certain size are directly allocated by calling NewPtr. + * + * Copyright (c) 1983 Regents of the University of California. + * Copyright (c) 1996-1997 Sun Microsystems, Inc. + * + * Portions contributed by Chris Kingsley, Jack Jansen and Ray Johnson + *. + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacAlloc.c,v 1.5 2001/11/23 01:27:09 das Exp $ + */ + +#include "tclInt.h" +#include "tclMacInt.h" +#include <Memory.h> +#include <Gestalt.h> +#include <stdlib.h> +#include <string.h> + + +/* + * Flags that are used by ConfigureMemory to define how the allocator + * should work. They can be or'd together. + */ +#define MEMORY_ALL_SYS 1 /* All memory should come from the system +heap. */ +#define MEMORY_DONT_USE_TEMPMEM 2 /* Don't use temporary memory but system memory. */ + +/* + * Amount of space to leave in the application heap for the Toolbox to work. + */ + +#define TOOLBOX_SPACE (512 * 1024) + +static int memoryFlags = 0; +static Handle toolGuardHandle = NULL; + /* This handle must be around so that we don't + * have NewGWorld failures. This handle is + * purgeable. Before we allocate any blocks, + * we see if this handle is still around. + * If it is not, then we try to get it again. + * If we can get it, we lock it and try + * to do the normal allocation, unlocking on + * the way out. If we can't, we go to the + * system heap directly. */ + +static int tclUseMemTracking = 0; /* Are we tracking memory allocations? + * On recent versions of the MacOS this + * is no longer necessary, as we can use + * temporary memory which is freed by the + * OS after a quit or crash. */ + +static size_t tclExtraHdlSize = 0; /* Size of extra memory allocated at the start + * of each block when using memory tracking + * ( == 0 otherwise) */ + +/* + * The following typedef and variable are used to keep track of memory + * blocks that are allocated directly from the System Heap. These chunks + * of memory must always be freed - even if we crash. + */ + +typedef struct listEl { + Handle memoryHandle; + struct listEl * next; + struct listEl * prec; +} ListEl; + +static ListEl * systemMemory = NULL; +static ListEl * appMemory = NULL; + +/* + * Prototypes for functions used only in this file. + */ + +static pascal void CleanUpExitProc _ANSI_ARGS_((void)); +void ConfigureMemory _ANSI_ARGS_((int flags)); +void FreeAllMemory _ANSI_ARGS_((void)); + +/* + *---------------------------------------------------------------------- + * + * TclpSysRealloc -- + * + * This function reallocates a chunk of system memory. If the + * chunk is already big enough to hold the new block, then no + * allocation happens. + * + * Results: + * Returns a pointer to the newly allocated block. + * + * Side effects: + * May copy the contents of the original block to the new block + * and deallocate the original block. + * + *---------------------------------------------------------------------- + */ + +VOID * +TclpSysRealloc( + VOID *oldPtr, /* Original block */ + unsigned int size) /* New size of block. */ +{ + Handle hand; + void *newPtr; + int maxsize; + OSErr err; + + if (tclUseMemTracking) { + hand = ((ListEl *) ((Ptr) oldPtr - tclExtraHdlSize))->memoryHandle; + } else { + hand = RecoverHandle((Ptr) oldPtr); + } + maxsize = GetHandleSize(hand) - sizeof(Handle); + if (maxsize < size) { + HUnlock(hand); + SetHandleSize(hand,size + tclExtraHdlSize); + err = MemError(); + HLock(hand); + if(err==noErr){ + newPtr=(*hand + tclExtraHdlSize); + } else { + newPtr = TclpSysAlloc(size, 1); + if(newPtr!=NULL) { + memmove(newPtr, oldPtr, maxsize); + TclpSysFree(oldPtr); + } + } + } else { + newPtr = oldPtr; + } + return newPtr; +} + +/* + *---------------------------------------------------------------------- + * + * TclpSysAlloc -- + * + * Allocate a new block of memory free from the System. + * + * Results: + * Returns a pointer to a new block of memory. + * + * Side effects: + * May obtain memory from app or sys space. Info is added to + * overhead lists etc. + * + *---------------------------------------------------------------------- + */ + +VOID * +TclpSysAlloc( + long size, /* Size of block to allocate. */ + int isBin) /* Is this a bin allocation? */ +{ + Handle hand = NULL; + ListEl * newMemoryRecord; + int isSysMem = 0; + static int initialized=0; + + if (!initialized) { + long response = 0; + OSErr err = noErr; + int useTempMem = 0; + + /* Check if we can use temporary memory */ + initialized=1; + err = Gestalt(gestaltOSAttr, &response); + if (err == noErr) { + useTempMem = response & (1 << gestaltRealTempMemory); + } + tclUseMemTracking = !useTempMem || (memoryFlags & MEMORY_DONT_USE_TEMPMEM); + if(tclUseMemTracking) { + tclExtraHdlSize = sizeof(ListEl); + /* + * We are allocating memory directly from the system + * heap. We need to install an exit handle + * to ensure the memory is cleaned up. + */ + TclMacInstallExitToShellPatch(CleanUpExitProc); + } + } + + if (!(memoryFlags & MEMORY_ALL_SYS)) { + + /* + * If the guard handle has been purged, throw it away and try + * to allocate it again. + */ + + if ((toolGuardHandle != NULL) && (*toolGuardHandle == NULL)) { + DisposeHandle(toolGuardHandle); + toolGuardHandle = NULL; + } + + /* + * If we have never allocated the guard handle, or it was purged + * and thrown away, then try to allocate it again. + */ + + if (toolGuardHandle == NULL) { + toolGuardHandle = NewHandle(TOOLBOX_SPACE); + if (toolGuardHandle != NULL) { + HLock(toolGuardHandle); + HPurge(toolGuardHandle); + } + } + + /* + * If we got the handle, lock it and do our allocation. + */ + + if (toolGuardHandle != NULL) { + HLock(toolGuardHandle); + hand = NewHandle(size + tclExtraHdlSize); + HUnlock(toolGuardHandle); + } + } + if (hand == NULL) { + /* + * Ran out of memory in application space. Lets try to get + * more memory from system. Otherwise, we return NULL to + * denote failure. + */ + if(!tclUseMemTracking) { + /* Use Temporary Memory instead of System Heap when available */ + OSErr err; + isBin = 1; /* always HLockHi TempMemHandles */ + hand = TempNewHandle(size + tclExtraHdlSize,&err); + if(err!=noErr) { hand=NULL; } + } else { + /* Use system heap when tracking memory */ + isSysMem=1; + isBin = 0; + hand = NewHandleSys(size + tclExtraHdlSize); + } + } + if (hand == NULL) { + return NULL; + } + if (isBin) { + HLockHi(hand); + } else { + HLock(hand); + } + if(tclUseMemTracking) { + /* Only need to do this when tracking memory */ + newMemoryRecord = (ListEl *) *hand; + newMemoryRecord->memoryHandle = hand; + newMemoryRecord->prec = NULL; + if(isSysMem) { + newMemoryRecord->next = systemMemory; + systemMemory = newMemoryRecord; + } else { + newMemoryRecord->next = appMemory; + appMemory = newMemoryRecord; + } + if(newMemoryRecord->next!=NULL) { + newMemoryRecord->next->prec=newMemoryRecord; + } + } + + return (*hand + tclExtraHdlSize); +} + +/* + *---------------------------------------------------------------------- + * + * TclpSysFree -- + * + * Free memory that we allocated back to the system. + * + * Results: + * None. + * + * Side effects: + * Memory is freed. + * + *---------------------------------------------------------------------- + */ + +void +TclpSysFree( + void * ptr) /* Free this system memory. */ +{ + if(tclUseMemTracking) { + /* Only need to do this when tracking memory */ + ListEl *memRecord; + + memRecord = (ListEl *) ((Ptr) ptr - tclExtraHdlSize); + /* Remove current record from linked list */ + if(memRecord->next!=NULL) { + memRecord->next->prec=memRecord->prec; + } + if(memRecord->prec!=NULL) { + memRecord->prec->next=memRecord->next; + } + if(memRecord==appMemory) { + appMemory=memRecord->next; + } else if(memRecord==systemMemory) { + systemMemory=memRecord->next; + } + DisposeHandle(memRecord->memoryHandle); + } else { + DisposeHandle(RecoverHandle((Ptr) ptr)); + } +} + +/* + *---------------------------------------------------------------------- + * + * CleanUpExitProc -- + * + * This procedure is invoked as an exit handler when ExitToShell + * is called. It removes any memory that was allocated directly + * from the system heap. This must be called when the application + * quits or the memory will never be freed. + * + * Results: + * None. + * + * Side effects: + * May free memory in the system heap. + * + *---------------------------------------------------------------------- + */ + +static pascal void +CleanUpExitProc() +{ + ListEl * memRecord; + + if(tclUseMemTracking) { + /* Only need to do this when tracking memory */ + while (systemMemory != NULL) { + memRecord = systemMemory; + systemMemory = memRecord->next; + DisposeHandle(memRecord->memoryHandle); + } + } +} + +/* + *---------------------------------------------------------------------- + * + * FreeAllMemory -- + * + * This procedure frees all memory blocks allocated by the memory + * sub-system. Make sure you don't have any code that references + * any malloced data! + * + * Results: + * None. + * + * Side effects: + * Frees all memory allocated by TclpAlloc. + * + *---------------------------------------------------------------------- + */ + +void +FreeAllMemory() +{ + ListEl * memRecord; + + if(tclUseMemTracking) { + /* Only need to do this when tracking memory */ + while (systemMemory != NULL) { + memRecord = systemMemory; + systemMemory = memRecord->next; + DisposeHandle(memRecord->memoryHandle); + } + while (appMemory != NULL) { + memRecord = appMemory; + appMemory = memRecord->next; + DisposeHandle(memRecord->memoryHandle); + } + } +} + +/* + *---------------------------------------------------------------------- + * + * ConfigureMemory -- + * + * This procedure sets certain flags in this file that control + * how memory is allocated and managed. This call must be made + * before any call to TclpAlloc is made. + * + * Results: + * None. + * + * Side effects: + * Certain state will be changed. + * + *---------------------------------------------------------------------- + */ + +void +ConfigureMemory( + int flags) /* Flags that control memory alloc scheme. */ +{ + memoryFlags = flags; +} diff --git a/mac/tclMacAppInit.c b/mac/tclMacAppInit.c new file mode 100644 index 0000000..65f79e8 --- /dev/null +++ b/mac/tclMacAppInit.c @@ -0,0 +1,213 @@ +/* + * tclMacAppInit.c -- + * + * Provides a version of the Tcl_AppInit procedure for the example shell. + * + * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center + * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacAppInit.c,v 1.9 2001/11/23 01:27:13 das Exp $ + */ + +#include "tcl.h" +#include "tclInt.h" +#include "tclPort.h" +#include "tclMac.h" +#include "tclMacInt.h" + +#if defined(THINK_C) +# include <console.h> +#elif defined(__MWERKS__) +# include <SIOUX.h> +EXTERN short InstallConsole _ANSI_ARGS_((short fd)); +#endif + +#ifdef TCL_TEST +extern int Procbodytest_Init _ANSI_ARGS_((Tcl_Interp *interp)); +extern int Procbodytest_SafeInit _ANSI_ARGS_((Tcl_Interp *interp)); +extern int TclObjTest_Init _ANSI_ARGS_((Tcl_Interp *interp)); +extern int Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp)); +#endif /* TCL_TEST */ + +/* + * Forward declarations for procedures defined later in this file: + */ + +static int MacintoshInit _ANSI_ARGS_((void)); + +/* + *---------------------------------------------------------------------- + * + * main -- + * + * Main program for tclsh. This file can be used as a prototype + * for other applications using the Tcl library. + * + * Results: + * None. This procedure never returns (it exits the process when + * it's done. + * + * Side effects: + * This procedure initializes the Macintosh world and then + * calls Tcl_Main. Tcl_Main will never return except to exit. + * + *---------------------------------------------------------------------- + */ + +void +main( + int argc, /* Number of arguments. */ + char **argv) /* Array of argument strings. */ +{ + char *newArgv[2]; + + if (MacintoshInit() != TCL_OK) { + Tcl_Exit(1); + } + + argc = 1; + newArgv[0] = "tclsh"; + newArgv[1] = NULL; + Tcl_Main(argc, newArgv, Tcl_AppInit); +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_AppInit -- + * + * This procedure performs application-specific initialization. + * Most applications, especially those that incorporate additional + * packages, will have their own version of this procedure. + * + * Results: + * Returns a standard Tcl completion code, and leaves an error + * message in the interp's result if an error occurs. + * + * Side effects: + * Depends on the startup script. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_AppInit( + Tcl_Interp *interp) /* Interpreter for application. */ +{ + if (Tcl_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + +#ifdef TCL_TEST + if (Tcltest_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, + (Tcl_PackageInitProc *) NULL); + if (TclObjTest_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + if (Procbodytest_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + Tcl_StaticPackage(interp, "procbodytest", Procbodytest_Init, + Procbodytest_SafeInit); +#endif /* TCL_TEST */ + + /* + * Call the init procedures for included packages. Each call should + * look like this: + * + * if (Mod_Init(interp) == TCL_ERROR) { + * return TCL_ERROR; + * } + * + * where "Mod" is the name of the module. + */ + + /* + * Call Tcl_CreateCommand for application-specific commands, if + * they weren't already created by the init procedures called above. + * Each call would loo like this: + * + * Tcl_CreateCommand(interp, "tclName", CFuncCmd, NULL, NULL); + */ + + /* + * Specify a user-specific startup script to invoke if the application + * is run interactively. On the Mac we can specifiy either a TEXT resource + * which contains the script or the more UNIX like file location + * may also used. (I highly recommend using the resource method.) + */ + + Tcl_SetVar(interp, "tcl_rcRsrcName", "tclshrc", TCL_GLOBAL_ONLY); + /* Tcl_SetVar(interp, "tcl_rcFileName", "~/.tclshrc", TCL_GLOBAL_ONLY); */ + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * MacintoshInit -- + * + * This procedure calls initalization routines to set up a simple + * console on a Macintosh. This is necessary as the Mac doesn't + * have a stdout & stderr by default. + * + * Results: + * Returns TCL_OK if everything went fine. If it didn't the + * application should probably fail. + * + * Side effects: + * Inits the appropiate console package. + * + *---------------------------------------------------------------------- + */ + +static int +MacintoshInit() +{ +#if GENERATING68K && !GENERATINGCFM + SetApplLimit(GetApplLimit() - (TCL_MAC_68K_STACK_GROWTH)); +#endif + MaxApplZone(); + +#if defined(THINK_C) + + /* Set options for Think C console package */ + /* The console package calls the Mac init calls */ + console_options.pause_atexit = 0; + console_options.title = "\pTcl Interpreter"; + +#elif defined(__MWERKS__) + + /* Set options for CodeWarrior SIOUX package */ + SIOUXSettings.autocloseonquit = true; + SIOUXSettings.showstatusline = true; + SIOUXSettings.asktosaveonclose = false; + SIOUXSettings.wasteusetempmemory = true; + InstallConsole(0); + SIOUXSetTitle("\pTcl Interpreter"); + +#elif defined(applec) + + /* Init packages used by MPW SIOW package */ + InitGraf((Ptr)&qd.thePort); + InitFonts(); + InitWindows(); + InitMenus(); + TEInit(); + InitDialogs(nil); + InitCursor(); + +#endif + + Tcl_MacSetEventProc((Tcl_MacConvertEventPtr) SIOUXHandleOneEvent); + + /* No problems with initialization */ + return TCL_OK; +} diff --git a/mac/tclMacApplication.r b/mac/tclMacApplication.r new file mode 100644 index 0000000..280c4ad --- /dev/null +++ b/mac/tclMacApplication.r @@ -0,0 +1,115 @@ +/* + * tclMacApplication.r -- + * + * This file creates resources for use Tcl Shell application. + * It should be viewed as an example of how to create a new + * Tcl application using the shared Tcl libraries. + * + * Copyright (c) 1996-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacApplication.r,v 1.6 2002/09/12 17:33:20 das Exp $ + */ + +#include <Types.r> +#include <SysTypes.r> + +/* + * The folowing include and defines help construct + * the version string for Tcl. + */ + +#define RC_INVOKED +#include "tcl.h" + +#if (TCL_RELEASE_LEVEL == 0) +# define RELEASE_LEVEL alpha +#elif (TCL_RELEASE_LEVEL == 1) +# define RELEASE_LEVEL beta +#elif (TCL_RELEASE_LEVEL == 2) +# define RELEASE_LEVEL final +#endif + +#if (TCL_RELEASE_LEVEL == 2) +# define MINOR_VERSION (TCL_MINOR_VERSION * 16) + TCL_RELEASE_SERIAL +# define RELEASE_CODE 0x00 +#else +# define MINOR_VERSION TCL_MINOR_VERSION * 16 +# define RELEASE_CODE TCL_RELEASE_SERIAL +#endif + +resource 'vers' (1) { + TCL_MAJOR_VERSION, MINOR_VERSION, + RELEASE_LEVEL, RELEASE_CODE, verUS, + TCL_PATCH_LEVEL, + TCL_PATCH_LEVEL ", by Ray Johnson & Jim Ingham" "\n" "© 2001 Tcl Core Team" +}; + +resource 'vers' (2) { + TCL_MAJOR_VERSION, MINOR_VERSION, + RELEASE_LEVEL, RELEASE_CODE, verUS, + TCL_PATCH_LEVEL, + "Tcl Shell " TCL_PATCH_LEVEL " © 1993-2001" +}; + +#define TCL_APP_CREATOR 'Tcl ' + +type TCL_APP_CREATOR as 'STR '; +resource TCL_APP_CREATOR (0, purgeable) { + "Tcl Shell " TCL_PATCH_LEVEL " © 1993-2001" +}; + +/* + * The 'kind' resource works with a 'BNDL' in Macintosh Easy Open + * to affect the text the Finder displays in the "kind" column and + * file info dialog. This information will be applied to all files + * with the listed creator and type. + */ + +resource 'kind' (128, "Tcl kind", purgeable) { + TCL_APP_CREATOR, + 0, /* region = USA */ + { + 'APPL', "Tcl Shell", + } +}; + +/* + * The following resource is used when creating the 'env' variable in + * the Macintosh environment. The creation mechanisim looks for the + * 'STR#' resource named "Tcl Environment Variables" rather than a + * specific resource number. (In other words, feel free to change the + * resource id if it conflicts with your application.) Each string in + * the resource must be of the form "KEYWORD=SOME STRING". See Tcl + * documentation for futher information about the env variable. + * + * A good example of something you may want to set is: "TCL_LIBRARY=My + * disk:etc." + */ + +resource 'STR#' (128, "Tcl Environment Variables") { + { + /* + "SCHEDULE_NAME=Agent Controller Schedule", + "SCHEDULE_PATH=Lozoya:System Folder:Tcl Lib:Tcl-Scheduler" + */ + }; +}; + +data 'alis' (1000, "Library Folder") { + $"0000 0000 00BA 0002 0001 012F 0000 0000" /* .....†...../.... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 985C FB00 4244 0000 0000" /* ......ò\š.BD.... */ + $"0002 1328 5375 7070 6F72 7420 4C69 6272" /* ...(Support Libr */ + $"6172 6965 7329 0000 0000 0000 0000 0000" /* aries).......... */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0000 0000 0000 0000 0000 0000 0000" /* ................ */ + $"0000 0076 8504 B617 A796 003D 0027 025B" /* ...vÖ..ßñ.=.'.[ */ + $"01E4 0001 0001 0000 0000 0000 0000 0000" /* .”.............. */ + $"0000 0000 0000 0000 0001 2F00 0002 0015" /* ........../..... */ + $"2F3A 2853 7570 706F 7274 204C 6962 7261" /* /:(Support Libra */ + $"7269 6573 2900 FFFF 0000" /* ries)... */ +}; + diff --git a/mac/tclMacBOAAppInit.c b/mac/tclMacBOAAppInit.c new file mode 100644 index 0000000..0f7687b --- /dev/null +++ b/mac/tclMacBOAAppInit.c @@ -0,0 +1,257 @@ +/* + * tclMacBOAAppInit.c -- + * + * Provides a version of the Tcl_AppInit procedure for a + * Macintosh Background Only Application. + * + * Copyright (c) 1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacBOAAppInit.c,v 1.5 2001/06/14 00:48:51 dgp Exp $ + */ + +#include "tcl.h" +#include "tclInt.h" +#include "tclPort.h" +#include "tclMac.h" +#include "tclMacInt.h" +#include <Fonts.h> +#include <Windows.h> +#include <Dialogs.h> +#include <Menus.h> +#include <Aliases.h> +#include <LowMem.h> + +#include <AppleEvents.h> +#include <SegLoad.h> +#include <ToolUtils.h> + +#if defined(THINK_C) +# include <console.h> +#elif defined(__MWERKS__) +# include <SIOUX.h> +short InstallConsole _ANSI_ARGS_((short fd)); +#endif + +void TkMacInitAppleEvents(Tcl_Interp *interp); +int HandleHighLevelEvents(EventRecord *eventPtr); + +#ifdef TCL_TEST +EXTERN int TclObjTest_Init _ANSI_ARGS_((Tcl_Interp *interp)); +EXTERN int Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp)); +#endif /* TCL_TEST */ + +/* + * Forward declarations for procedures defined later in this file: + */ + +static int MacintoshInit _ANSI_ARGS_((void)); + +/* + *---------------------------------------------------------------------- + * + * main -- + * + * Main program for tclsh. This file can be used as a prototype + * for other applications using the Tcl library. + * + * Results: + * None. This procedure never returns (it exits the process when + * it's done. + * + * Side effects: + * This procedure initializes the Macintosh world and then + * calls Tcl_Main. Tcl_Main will never return except to exit. + * + *---------------------------------------------------------------------- + */ + +void +main( + int argc, /* Number of arguments. */ + char **argv) /* Array of argument strings. */ +{ + char *newArgv[3]; + + if (MacintoshInit() != TCL_OK) { + Tcl_Exit(1); + } + + argc = 2; + newArgv[0] = "tclsh"; + newArgv[1] = "bgScript.tcl"; + newArgv[2] = NULL; + Tcl_Main(argc, newArgv, Tcl_AppInit); +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_AppInit -- + * + * This procedure performs application-specific initialization. + * Most applications, especially those that incorporate additional + * packages, will have their own version of this procedure. + * + * Results: + * Returns a standard Tcl completion code, and leaves an error + * message in the interp's result if an error occurs. + * + * Side effects: + * Depends on the startup script. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_AppInit( + Tcl_Interp *interp) /* Interpreter for application. */ +{ + Tcl_Channel tempChan; + + if (Tcl_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + +#ifdef TCL_TEST + if (Tcltest_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, + (Tcl_PackageInitProc *) NULL); + if (TclObjTest_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } +#endif /* TCL_TEST */ + + /* + * Call the init procedures for included packages. Each call should + * look like this: + * + * if (Mod_Init(interp) == TCL_ERROR) { + * return TCL_ERROR; + * } + * + * where "Mod" is the name of the module. + */ + + /* + * Call Tcl_CreateCommand for application-specific commands, if + * they weren't already created by the init procedures called above. + * Each call would loo like this: + * + * Tcl_CreateCommand(interp, "tclName", CFuncCmd, NULL, NULL); + */ + + /* + * Specify a user-specific startup script to invoke if the application + * is run interactively. On the Mac we can specifiy either a TEXT resource + * which contains the script or the more UNIX like file location + * may also used. (I highly recommend using the resource method.) + */ + + Tcl_SetVar(interp, "tcl_rcRsrcName", "tclshrc", TCL_GLOBAL_ONLY); + + /* Tcl_SetVar(interp, "tcl_rcFileName", "~/.tclshrc", TCL_GLOBAL_ONLY); */ + + /* + * We have to support at least the quit Apple Event. + */ + + TkMacInitAppleEvents(interp); + + /* + * Open a file channel to put stderr, stdin, stdout... + */ + + tempChan = Tcl_OpenFileChannel(interp, ":temp.in", "a+", 0); + Tcl_SetStdChannel(tempChan,TCL_STDIN); + Tcl_RegisterChannel(interp, tempChan); + Tcl_SetChannelOption(NULL, tempChan, "-translation", "cr"); + Tcl_SetChannelOption(NULL, tempChan, "-buffering", "line"); + + tempChan = Tcl_OpenFileChannel(interp, ":temp.out", "a+", 0); + Tcl_SetStdChannel(tempChan,TCL_STDOUT); + Tcl_RegisterChannel(interp, tempChan); + Tcl_SetChannelOption(NULL, tempChan, "-translation", "cr"); + Tcl_SetChannelOption(NULL, tempChan, "-buffering", "line"); + + tempChan = Tcl_OpenFileChannel(interp, ":temp.err", "a+", 0); + Tcl_SetStdChannel(tempChan,TCL_STDERR); + Tcl_RegisterChannel(interp, tempChan); + Tcl_SetChannelOption(NULL, tempChan, "-translation", "cr"); + Tcl_SetChannelOption(NULL, tempChan, "-buffering", "none"); + + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * MacintoshInit -- + * + * This procedure calls initalization routines to set up a simple + * console on a Macintosh. This is necessary as the Mac doesn't + * have a stdout & stderr by default. + * + * Results: + * Returns TCL_OK if everything went fine. If it didn't the + * application should probably fail. + * + * Side effects: + * Inits the appropiate console package. + * + *---------------------------------------------------------------------- + */ + +static int +MacintoshInit() +{ + THz theZone = GetZone(); + SysEnvRec sys; + + + /* + * There is a bug in systems earlier that 7.5.5, where a second BOA will + * get a corrupted heap. This is the fix from TechNote 1070 + */ + + SysEnvirons(1, &sys); + + if (sys.systemVersion < 0x0755) + { + if ( LMGetHeapEnd() != theZone->bkLim) { + LMSetHeapEnd(theZone->bkLim); + } + } + +#if GENERATING68K && !GENERATINGCFM + SetApplLimit(GetApplLimit() - (TCL_MAC_68K_STACK_GROWTH)); +#endif + MaxApplZone(); + + InitGraf((Ptr)&qd.thePort); + + /* No problems with initialization */ + Tcl_MacSetEventProc(HandleHighLevelEvents); + + return TCL_OK; +} + +int +HandleHighLevelEvents( + EventRecord *eventPtr) +{ + int eventFound = false; + + if (eventPtr->what == kHighLevelEvent) { + AEProcessAppleEvent(eventPtr); + eventFound = true; + } else if (eventPtr->what == nullEvent) { + eventFound = true; + } + return eventFound; +} diff --git a/mac/tclMacBOAMain.c b/mac/tclMacBOAMain.c new file mode 100644 index 0000000..ff1a943 --- /dev/null +++ b/mac/tclMacBOAMain.c @@ -0,0 +1,304 @@ +/* + * tclMacBGMain.c -- + * + * Main program for Macintosh Background Only Application shells. + * + * Copyright (c) 1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacBOAMain.c,v 1.4 2001/12/28 23:36:31 dgp Exp $ + */ + +#include "tcl.h" +#include "tclInt.h" +#include "tclMacInt.h" +#include <Resources.h> +#include <Notification.h> +#include <Strings.h> + +/* + * This variable is used to get out of the modal loop of the + * notification manager. + */ + +int NotificationIsDone = 0; + +/* + * The following code ensures that tclLink.c is linked whenever + * Tcl is linked. Without this code there's no reference to the + * code in that file from anywhere in Tcl, so it may not be + * linked into the application. + */ + +EXTERN int Tcl_LinkVar(); +int (*tclDummyLinkVarPtr)() = Tcl_LinkVar; + +/* + * Declarations for various library procedures and variables (don't want + * to include tclPort.h here, because people might copy this file out of + * the Tcl source directory to make their own modified versions). + * Note: "exit" should really be declared here, but there's no way to + * declare it without causing conflicts with other definitions elsewher + * on some systems, so it's better just to leave it out. + */ + +extern int isatty _ANSI_ARGS_((int fd)); +extern char * strcpy _ANSI_ARGS_((char *dst, CONST char *src)); + +static Tcl_Interp *interp; /* Interpreter for application. */ + +/* + * Forward references for procedures defined later in this file: + */ + +void TclMacDoNotification(char *mssg); +void TclMacNotificationResponse(NMRecPtr nmRec); +int Tcl_MacBGNotifyObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); + + +/* + *---------------------------------------------------------------------- + * + * Tcl_Main -- + * + * Main program for tclsh and most other Tcl-based applications. + * + * Results: + * None. This procedure never returns (it exits the process when + * it's done. + * + * Side effects: + * This procedure initializes the Tk world and then starts + * interpreting commands; almost anything could happen, depending + * on the script being interpreted. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_Main(argc, argv, appInitProc) + int argc; /* Number of arguments. */ + char **argv; /* Array of argument strings. */ + Tcl_AppInitProc *appInitProc; + /* Application-specific initialization + * procedure to call after most + * initialization but before starting to + * execute commands. */ +{ + Tcl_Obj *prompt1NamePtr = NULL; + Tcl_Obj *prompt2NamePtr = NULL; + Tcl_Obj *commandPtr = NULL; + char buffer[1000], *args, *fileName; + int code, tty; + int exitCode = 0; + + Tcl_FindExecutable(argv[0]); + interp = Tcl_CreateInterp(); + Tcl_InitMemory(interp); + + /* + * Make command-line arguments available in the Tcl variables "argc" + * and "argv". If the first argument doesn't start with a "-" then + * strip it off and use it as the name of a script file to process. + */ + + fileName = NULL; + if ((argc > 1) && (argv[1][0] != '-')) { + fileName = argv[1]; + argc--; + argv++; + } + args = Tcl_Merge(argc-1, argv+1); + Tcl_SetVar(interp, "argv", args, TCL_GLOBAL_ONLY); + ckfree(args); + TclFormatInt(buffer, argc-1); + Tcl_SetVar(interp, "argc", buffer, TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "argv0", (fileName != NULL) ? fileName : argv[0], + TCL_GLOBAL_ONLY); + + /* + * Set the "tcl_interactive" variable. + */ + + tty = isatty(0); + Tcl_SetVar(interp, "tcl_interactive", + ((fileName == NULL) && tty) ? "1" : "0", TCL_GLOBAL_ONLY); + + /* + * Invoke application-specific initialization. + */ + + if ((*appInitProc)(interp) != TCL_OK) { + Tcl_DString errStr; + + Tcl_DStringInit(&errStr); + Tcl_DStringAppend(&errStr, + "application-specific initialization failed: \n", -1); + Tcl_DStringAppend(&errStr, Tcl_GetStringResult(interp), -1); + Tcl_DStringAppend(&errStr, "\n", 1); + TclMacDoNotification(Tcl_DStringValue(&errStr)); + Tcl_DStringFree(&errStr); + goto done; + } + + /* + * Install the BGNotify command: + */ + + if ( Tcl_CreateObjCommand(interp, "bgnotify", Tcl_MacBGNotifyObjCmd, NULL, + (Tcl_CmdDeleteProc *) NULL) == NULL) { + goto done; + } + + /* + * If a script file was specified then just source that file + * and quit. In this Mac BG Application version, we will try the + * resource fork first, then the file system second... + */ + + if (fileName != NULL) { + Str255 resName; + Handle resource; + + strcpy((char *) resName + 1, fileName); + resName[0] = strlen(fileName); + resource = GetNamedResource('TEXT',resName); + if (resource != NULL) { + code = Tcl_MacEvalResource(interp, fileName, -1, NULL); + } else { + code = Tcl_EvalFile(interp, fileName); + } + + if (code != TCL_OK) { + Tcl_DString errStr; + + Tcl_DStringInit(&errStr); + Tcl_DStringAppend(&errStr, " Error sourcing resource or file: ", -1); + Tcl_DStringAppend(&errStr, fileName, -1); + Tcl_DStringAppend(&errStr, "\n\nError was: ", -1); + Tcl_DStringAppend(&errStr, Tcl_GetStringResult(interp), -1); + TclMacDoNotification(Tcl_DStringValue(&errStr)); + Tcl_DStringFree(&errStr); + } + goto done; + } + + + /* + * Rather than calling exit, invoke the "exit" command so that + * users can replace "exit" with some other command to do additional + * cleanup on exit. The Tcl_Eval call should never return. + */ + + done: + if (commandPtr != NULL) { + Tcl_DecrRefCount(commandPtr); + } + if (prompt1NamePtr != NULL) { + Tcl_DecrRefCount(prompt1NamePtr); + } + if (prompt2NamePtr != NULL) { + Tcl_DecrRefCount(prompt2NamePtr); + } + sprintf(buffer, "exit %d", exitCode); + Tcl_Eval(interp, buffer); +} + +/*---------------------------------------------------------------------- + * + * TclMacDoNotification -- + * + * This posts an error message using the Notification manager. + * + * Results: + * Post a Notification Manager dialog. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +void +TclMacDoNotification(mssg) + char *mssg; +{ + NMRec errorNot; + EventRecord *theEvent = NULL; + OSErr err; + char *ptr; + + errorNot.qType = nmType; + errorNot.nmMark = 0; + errorNot.nmIcon = 0; + errorNot.nmSound = (Handle) -1; + + for ( ptr = mssg; *ptr != '\0'; ptr++) { + if (*ptr == '\n') { + *ptr = '\r'; + } + } + + c2pstr(mssg); + errorNot.nmStr = (StringPtr) mssg; + + errorNot.nmResp = NewNMProc(TclMacNotificationResponse); + errorNot.nmRefCon = SetCurrentA5(); + + NotificationIsDone = 0; + + /* + * Cycle while waiting for the user to click on the + * notification box. Don't take any events off the event queue, + * since we want Tcl to do this but we want to block till the notification + * has been handled... + */ + + err = NMInstall(&errorNot); + if (err == noErr) { + while (!NotificationIsDone) { + WaitNextEvent(0, theEvent, 20, NULL); + } + NMRemove(&errorNot); + } + + p2cstr((unsigned char *) mssg); +} + +void +TclMacNotificationResponse(nmRec) + NMRecPtr nmRec; +{ + int curA5; + + curA5 = SetCurrentA5(); + SetA5(nmRec->nmRefCon); + + NotificationIsDone = 1; + + SetA5(curA5); + +} + +int +Tcl_MacBGNotifyObjCmd(clientData, interp, objc, objv) + ClientData clientData; + Tcl_Interp *interp; + int objc; + Tcl_Obj **objv; +{ + Tcl_Obj *resultPtr; + + resultPtr = Tcl_GetObjResult(interp); + + if ( objc != 2 ) { + Tcl_WrongNumArgs(interp, 1, objv, "message"); + return TCL_ERROR; + } + + TclMacDoNotification(Tcl_GetString(objv[1])); + return TCL_OK; + +} + diff --git a/mac/tclMacChan.c b/mac/tclMacChan.c new file mode 100644 index 0000000..8986e6c --- /dev/null +++ b/mac/tclMacChan.c @@ -0,0 +1,1300 @@ +/* + * tclMacChan.c + * + * Channel drivers for Macintosh channels for the + * console fds. + * + * Copyright (c) 1996-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacChan.c,v 1.22 2003/12/24 04:18:21 davygrvy Exp $ + */ + +#include "tclInt.h" +#include "tclPort.h" +#include "tclMacInt.h" +#include <Aliases.h> +#include <Errors.h> +#include <Files.h> +#include <Gestalt.h> +#include <Processes.h> +#include <Strings.h> +#include <FSpCompat.h> +#include <MoreFiles.h> +#include <MoreFilesExtras.h> +#include "tclIO.h" + +#ifdef __MSL__ +#include <unix.mac.h> +#define TCL_FILE_CREATOR (__getcreator(0)) +#else +#define TCL_FILE_CREATOR 'MPW ' +#endif + +/* + * This structure describes per-instance state of a + * macintosh file based channel. + */ + +typedef struct FileState { + short fileRef; /* Macintosh file reference number. */ + Tcl_Channel fileChan; /* Pointer to the channel for this file. */ + int watchMask; /* OR'ed set of flags indicating which events + * are being watched. */ + int appendMode; /* Flag to tell if in O_APPEND mode or not. */ + int volumeRef; /* Flag to tell if in O_APPEND mode or not. */ + int pending; /* 1 if message is pending on queue. */ + struct FileState *nextPtr; /* Pointer to next registered file. */ +} FileState; + +typedef struct ThreadSpecificData { + int initialized; /* True after the thread initializes */ + FileState *firstFilePtr; /* the head of the list of files managed + * that are being watched for file events. */ + Tcl_Channel stdinChannel; + Tcl_Channel stdoutChannel; /* Note - these seem unused */ + Tcl_Channel stderrChannel; +} ThreadSpecificData; + +static Tcl_ThreadDataKey dataKey; + +/* + * The following structure is what is added to the Tcl event queue when + * file events are generated. + */ + +typedef struct FileEvent { + Tcl_Event header; /* Information that is standard for + * all events. */ + FileState *infoPtr; /* Pointer to file info structure. Note + * that we still have to verify that the + * file exists before dereferencing this + * pointer. */ +} FileEvent; + + +/* + * Static routines for this file: + */ + +static int CommonGetHandle _ANSI_ARGS_((ClientData instanceData, + int direction, ClientData *handlePtr)); +static void CommonWatch _ANSI_ARGS_((ClientData instanceData, + int mask)); +static int FileBlockMode _ANSI_ARGS_((ClientData instanceData, + int mode)); +static void FileChannelExitHandler _ANSI_ARGS_(( + ClientData clientData)); +static void FileCheckProc _ANSI_ARGS_((ClientData clientData, + int flags)); +static int FileClose _ANSI_ARGS_((ClientData instanceData, + Tcl_Interp *interp)); +static int FileEventProc _ANSI_ARGS_((Tcl_Event *evPtr, + int flags)); +static ThreadSpecificData *FileInit _ANSI_ARGS_((void)); +static int FileInput _ANSI_ARGS_((ClientData instanceData, + char *buf, int toRead, int *errorCode)); +static int FileOutput _ANSI_ARGS_((ClientData instanceData, + CONST char *buf, int toWrite, int *errorCode)); +static int FileSeek _ANSI_ARGS_((ClientData instanceData, + long offset, int mode, int *errorCode)); +static void FileSetupProc _ANSI_ARGS_((ClientData clientData, + int flags)); +static Tcl_Channel OpenFileChannel _ANSI_ARGS_((CONST char *fileName, + int mode, int permissions, int *errorCodePtr)); +static int StdIOBlockMode _ANSI_ARGS_((ClientData instanceData, + int mode)); +static int StdIOClose _ANSI_ARGS_((ClientData instanceData, + Tcl_Interp *interp)); +static int StdIOInput _ANSI_ARGS_((ClientData instanceData, + char *buf, int toRead, int *errorCode)); +static int StdIOOutput _ANSI_ARGS_((ClientData instanceData, + CONST char *buf, int toWrite, int *errorCode)); +static int StdIOSeek _ANSI_ARGS_((ClientData instanceData, + long offset, int mode, int *errorCode)); +static int StdReady _ANSI_ARGS_((ClientData instanceData, + int mask)); + +/* + * This structure describes the channel type structure for file based IO: + */ + +static Tcl_ChannelType consoleChannelType = { + "file", /* Type name. */ + (Tcl_ChannelTypeVersion)StdIOBlockMode, /* Set blocking/nonblocking mode.*/ + StdIOClose, /* Close proc. */ + StdIOInput, /* Input proc. */ + StdIOOutput, /* Output proc. */ + StdIOSeek, /* Seek proc. */ + NULL, /* Set option proc. */ + NULL, /* Get option proc. */ + CommonWatch, /* Initialize notifier. */ + CommonGetHandle /* Get OS handles out of channel. */ +}; + +/* + * This variable describes the channel type structure for file based IO. + */ + +static Tcl_ChannelType fileChannelType = { + "file", /* Type name. */ + (Tcl_ChannelTypeVersion)FileBlockMode, /* Set blocking or + * non-blocking mode.*/ + FileClose, /* Close proc. */ + FileInput, /* Input proc. */ + FileOutput, /* Output proc. */ + FileSeek, /* Seek proc. */ + NULL, /* Set option proc. */ + NULL, /* Get option proc. */ + CommonWatch, /* Initialize notifier. */ + CommonGetHandle /* Get OS handles out of channel. */ +}; + + +/* + * Hack to allow Mac Tk to override the TclGetStdChannels function. + */ + +typedef void (*TclGetStdChannelsProc) _ANSI_ARGS_((Tcl_Channel *stdinPtr, + Tcl_Channel *stdoutPtr, Tcl_Channel *stderrPtr)); + +TclGetStdChannelsProc getStdChannelsProc = NULL; + + +/* + *---------------------------------------------------------------------- + * + * FileInit -- + * + * This function initializes the file channel event source. + * + * Results: + * None. + * + * Side effects: + * Creates a new event source. + * + *---------------------------------------------------------------------- + */ + +static ThreadSpecificData * +FileInit() +{ + ThreadSpecificData *tsdPtr = + (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey); + if (tsdPtr == NULL) { + tsdPtr = TCL_TSD_INIT(&dataKey); + tsdPtr->firstFilePtr = NULL; + Tcl_CreateEventSource(FileSetupProc, FileCheckProc, NULL); + Tcl_CreateThreadExitHandler(FileChannelExitHandler, NULL); + } + return tsdPtr; +} + +/* + *---------------------------------------------------------------------- + * + * FileChannelExitHandler -- + * + * This function is called to cleanup the channel driver before + * Tcl is unloaded. + * + * Results: + * None. + * + * Side effects: + * Destroys the communication window. + * + *---------------------------------------------------------------------- + */ + +static void +FileChannelExitHandler( + ClientData clientData) /* Old window proc */ +{ + Tcl_DeleteEventSource(FileSetupProc, FileCheckProc, NULL); +} + +/* + *---------------------------------------------------------------------- + * + * FileSetupProc -- + * + * This procedure is invoked before Tcl_DoOneEvent blocks waiting + * for an event. + * + * Results: + * None. + * + * Side effects: + * Adjusts the block time if needed. + * + *---------------------------------------------------------------------- + */ + +void +FileSetupProc( + ClientData data, /* Not used. */ + int flags) /* Event flags as passed to Tcl_DoOneEvent. */ +{ + FileState *infoPtr; + Tcl_Time blockTime = { 0, 0 }; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + if (!(flags & TCL_FILE_EVENTS)) { + return; + } + + /* + * Check to see if there is a ready file. If so, poll. + */ + + for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL; + infoPtr = infoPtr->nextPtr) { + if (infoPtr->watchMask) { + Tcl_SetMaxBlockTime(&blockTime); + break; + } + } +} + +/* + *---------------------------------------------------------------------- + * + * FileCheckProc -- + * + * This procedure is called by Tcl_DoOneEvent to check the file + * event source for events. + * + * Results: + * None. + * + * Side effects: + * May queue an event. + * + *---------------------------------------------------------------------- + */ + +static void +FileCheckProc( + ClientData data, /* Not used. */ + int flags) /* Event flags as passed to Tcl_DoOneEvent. */ +{ + FileEvent *evPtr; + FileState *infoPtr; + int sentMsg = 0; + Tcl_Time blockTime = { 0, 0 }; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + if (!(flags & TCL_FILE_EVENTS)) { + return; + } + + /* + * Queue events for any ready files that don't already have events + * queued (caused by persistent states that won't generate WinSock + * events). + */ + + for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL; + infoPtr = infoPtr->nextPtr) { + if (infoPtr->watchMask && !infoPtr->pending) { + infoPtr->pending = 1; + evPtr = (FileEvent *) ckalloc(sizeof(FileEvent)); + evPtr->header.proc = FileEventProc; + evPtr->infoPtr = infoPtr; + Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL); + } + } +} + +/*---------------------------------------------------------------------- + * + * FileEventProc -- + * + * This function is invoked by Tcl_ServiceEvent when a file event + * reaches the front of the event queue. This procedure invokes + * Tcl_NotifyChannel on the file. + * + * Results: + * Returns 1 if the event was handled, meaning it should be removed + * from the queue. Returns 0 if the event was not handled, meaning + * it should stay on the queue. The only time the event isn't + * handled is if the TCL_FILE_EVENTS flag bit isn't set. + * + * Side effects: + * Whatever the notifier callback does. + * + *---------------------------------------------------------------------- + */ + +static int +FileEventProc( + Tcl_Event *evPtr, /* Event to service. */ + int flags) /* Flags that indicate what events to + * handle, such as TCL_FILE_EVENTS. */ +{ + FileEvent *fileEvPtr = (FileEvent *)evPtr; + FileState *infoPtr; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + if (!(flags & TCL_FILE_EVENTS)) { + return 0; + } + + /* + * Search through the list of watched files for the one whose handle + * matches the event. We do this rather than simply dereferencing + * the handle in the event so that files can be deleted while the + * event is in the queue. + */ + + for (infoPtr = tsdPtr->firstFilePtr; infoPtr != NULL; + infoPtr = infoPtr->nextPtr) { + if (fileEvPtr->infoPtr == infoPtr) { + infoPtr->pending = 0; + Tcl_NotifyChannel(infoPtr->fileChan, infoPtr->watchMask); + break; + } + } + return 1; +} + +/* + *---------------------------------------------------------------------- + * + * StdIOBlockMode -- + * + * Set blocking or non-blocking mode on channel. + * + * Results: + * 0 if successful, errno when failed. + * + * Side effects: + * Sets the device into blocking or non-blocking mode. + * + *---------------------------------------------------------------------- + */ + +static int +StdIOBlockMode( + ClientData instanceData, /* Unused. */ + int mode) /* The mode to set. */ +{ + /* + * Do not allow putting stdin, stdout or stderr into nonblocking mode. + */ + + if (mode == TCL_MODE_NONBLOCKING) { + return EFAULT; + } + + return 0; +} + +/* + *---------------------------------------------------------------------- + * + * StdIOClose -- + * + * Closes the IO channel. + * + * Results: + * 0 if successful, the value of errno if failed. + * + * Side effects: + * Closes the physical channel + * + *---------------------------------------------------------------------- + */ + +static int +StdIOClose( + ClientData instanceData, /* Unused. */ + Tcl_Interp *interp) /* Unused. */ +{ + int fd, errorCode = 0; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + /* + * Invalidate the stdio cache if necessary. Note that we assume that + * the stdio file and channel pointers will become invalid at the same + * time. + * Do not close standard channels while in thread-exit. + */ + + fd = (int) ((FileState*)instanceData)->fileRef; + if (!TclInThreadExit()) { + if (fd == 0) { + tsdPtr->stdinChannel = NULL; + } else if (fd == 1) { + tsdPtr->stdoutChannel = NULL; + } else if (fd == 2) { + tsdPtr->stderrChannel = NULL; + } else { + Tcl_Panic("recieved invalid std file"); + } + + if (close(fd) < 0) { + errorCode = errno; + } + } + return errorCode; +} + +/* + *---------------------------------------------------------------------- + * + * CommonGetHandle -- + * + * Called from Tcl_GetChannelHandle to retrieve OS handles from inside + * a file based channel. + * + * Results: + * The appropriate handle or NULL if not present. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +CommonGetHandle( + ClientData instanceData, /* The file state. */ + int direction, /* Which handle to retrieve? */ + ClientData *handlePtr) +{ + if ((direction == TCL_READABLE) || (direction == TCL_WRITABLE)) { + *handlePtr = (ClientData) ((FileState*)instanceData)->fileRef; + return TCL_OK; + } + return TCL_ERROR; +} + +/* + *---------------------------------------------------------------------- + * + * StdIOInput -- + * + * Reads input from the IO channel into the buffer given. Returns + * count of how many bytes were actually read, and an error indication. + * + * Results: + * A count of how many bytes were read is returned and an error + * indication is returned in an output argument. + * + * Side effects: + * Reads input from the actual channel. + * + *---------------------------------------------------------------------- + */ + +int +StdIOInput( + ClientData instanceData, /* Unused. */ + char *buf, /* Where to store data read. */ + int bufSize, /* How much space is available + * in the buffer? */ + int *errorCode) /* Where to store error code. */ +{ + int fd; + int bytesRead; /* How many bytes were read? */ + + *errorCode = 0; + errno = 0; + fd = (int) ((FileState*)instanceData)->fileRef; + bytesRead = read(fd, buf, (size_t) bufSize); + if (bytesRead > -1) { + return bytesRead; + } + *errorCode = errno; + return -1; +} + +/* + *---------------------------------------------------------------------- + * + * StdIOOutput-- + * + * Writes the given output on the IO channel. Returns count of how + * many characters were actually written, and an error indication. + * + * Results: + * A count of how many characters were written is returned and an + * error indication is returned in an output argument. + * + * Side effects: + * Writes output on the actual channel. + * + *---------------------------------------------------------------------- + */ + +static int +StdIOOutput( + ClientData instanceData, /* Unused. */ + CONST char *buf, /* The data buffer. */ + int toWrite, /* How many bytes to write? */ + int *errorCode) /* Where to store error code. */ +{ + int written; + int fd; + + *errorCode = 0; + errno = 0; + fd = (int) ((FileState*)instanceData)->fileRef; + written = write(fd, (void*)buf, (size_t) toWrite); + if (written > -1) { + return written; + } + *errorCode = errno; + return -1; +} + +/* + *---------------------------------------------------------------------- + * + * StdIOSeek -- + * + * Seeks on an IO channel. Returns the new position. + * + * Results: + * -1 if failed, the new position if successful. If failed, it + * also sets *errorCodePtr to the error code. + * + * Side effects: + * Moves the location at which the channel will be accessed in + * future operations. + * + *---------------------------------------------------------------------- + */ + +static int +StdIOSeek( + ClientData instanceData, /* Unused. */ + long offset, /* Offset to seek to. */ + int mode, /* Relative to where should we seek? */ + int *errorCodePtr) /* To store error code. */ +{ + int newLoc; + int fd; + + *errorCodePtr = 0; + fd = (int) ((FileState*)instanceData)->fileRef; + newLoc = lseek(fd, offset, mode); + if (newLoc > -1) { + return newLoc; + } + *errorCodePtr = errno; + return -1; +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_PidObjCmd -- + * + * This procedure is invoked to process the "pid" Tcl command. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + + /* ARGSUSED */ +int +Tcl_PidObjCmd(dummy, interp, objc, objv) + ClientData dummy; /* Not used. */ + Tcl_Interp *interp; /* Current interpreter. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST *objv; /* Argument strings. */ +{ + ProcessSerialNumber psn; + char buf[20]; + Tcl_Channel chan; + Tcl_Obj *resultPtr; + + if (objc > 2) { + Tcl_WrongNumArgs(interp, 1, objv, "?channelId?"); + return TCL_ERROR; + } + if (objc == 1) { + resultPtr = Tcl_GetObjResult(interp); + GetCurrentProcess(&psn); + sprintf(buf, "0x%08x%08x", psn.highLongOfPSN, psn.lowLongOfPSN); + Tcl_SetStringObj(resultPtr, buf, -1); + } else { + chan = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), + NULL); + if (chan == (Tcl_Channel) NULL) { + return TCL_ERROR; + } + /* + * We can't create pipelines on the Mac so + * this will always return an empty list. + */ + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclpGetDefaultStdChannel -- + * + * Constructs a channel for the specified standard OS handle. + * + * Results: + * Returns the specified default standard channel, or NULL. + * + * Side effects: + * May cause the creation of a standard channel and the underlying + * file. + * + *---------------------------------------------------------------------- + */ + +Tcl_Channel +TclpGetDefaultStdChannel( + int type) /* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */ +{ + Tcl_Channel channel = NULL; + int fd = 0; /* Initializations needed to prevent */ + int mode = 0; /* compiler warning (used before set). */ + char *bufMode = NULL; + char channelName[16 + TCL_INTEGER_SPACE]; + int channelPermissions; + FileState *fileState; + + /* + * If the channels were not created yet, create them now and + * store them in the static variables. + */ + + switch (type) { + case TCL_STDIN: + fd = 0; + channelPermissions = TCL_READABLE; + bufMode = "line"; + break; + case TCL_STDOUT: + fd = 1; + channelPermissions = TCL_WRITABLE; + bufMode = "line"; + break; + case TCL_STDERR: + fd = 2; + channelPermissions = TCL_WRITABLE; + bufMode = "none"; + break; + default: + Tcl_Panic("TclGetDefaultStdChannel: Unexpected channel type"); + break; + } + + sprintf(channelName, "console%d", (int) fd); + fileState = (FileState *) ckalloc((unsigned) sizeof(FileState)); + channel = Tcl_CreateChannel(&consoleChannelType, channelName, + (ClientData) fileState, channelPermissions); + fileState->fileChan = channel; + fileState->fileRef = fd; + + /* + * Set up the normal channel options for stdio handles. + */ + + Tcl_SetChannelOption(NULL, channel, "-translation", "cr"); + Tcl_SetChannelOption(NULL, channel, "-buffering", bufMode); + + return channel; +} + +/* + *---------------------------------------------------------------------- + * + * TclpOpenFileChannel -- + * + * Open a File based channel on MacOS systems. + * + * Results: + * The new channel or NULL. If NULL, the output argument + * errorCodePtr is set to a POSIX error. + * + * Side effects: + * May open the channel and may cause creation of a file on the + * file system. + * + *---------------------------------------------------------------------- + */ + +Tcl_Channel +TclpOpenFileChannel( + Tcl_Interp *interp, /* Interpreter for error reporting; + * can be NULL. */ + Tcl_Obj *pathPtr, /* Name of file to open. */ + int mode, /* POSIX open mode. */ + int permissions) /* If the open involves creating a + * file, with what modes to create + * it? */ +{ + Tcl_Channel chan; + CONST char *native; + int errorCode; + + native = Tcl_FSGetNativePath(pathPtr); + if (native == NULL) { + return NULL; + } + chan = OpenFileChannel(native, mode, permissions, &errorCode); + + if (chan == NULL) { + Tcl_SetErrno(errorCode); + if (interp != (Tcl_Interp *) NULL) { + Tcl_AppendResult(interp, "couldn't open \"", + Tcl_GetString(pathPtr), "\": ", + Tcl_PosixError(interp), (char *) NULL); + } + return NULL; + } + + return chan; +} + +/* + *---------------------------------------------------------------------- + * + * OpenFileChannel-- + * + * Opens a Macintosh file and creates a Tcl channel to control it. + * + * Results: + * A Tcl channel. + * + * Side effects: + * Will open a Macintosh file. + * + *---------------------------------------------------------------------- + */ + +static Tcl_Channel +OpenFileChannel( + CONST char *fileName, /* Name of file to open (native). */ + int mode, /* Mode for opening file. */ + int permissions, /* If the open involves creating a + * file, with what modes to create + * it? */ + int *errorCodePtr) /* Where to store error code. */ +{ + int channelPermissions; + Tcl_Channel chan; + char macPermision; + FSSpec fileSpec; + OSErr err; + short fileRef; + FileState *fileState; + char channelName[16 + TCL_INTEGER_SPACE]; + ThreadSpecificData *tsdPtr; + + tsdPtr = FileInit(); + + /* + * Note we use fsRdWrShPerm instead of fsRdWrPerm which allows shared + * writes on a file. This isn't common on a mac but is common with + * Windows and UNIX and the feature is used by Tcl. + */ + + switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) { + case O_RDWR: + channelPermissions = (TCL_READABLE | TCL_WRITABLE); + macPermision = fsRdWrShPerm; + break; + case O_WRONLY: + /* + * Mac's fsRdPerm permission actually defaults to fsRdWrPerm because + * the Mac OS doesn't realy support write only access. We explicitly + * set the permission fsRdWrShPerm so that we can have shared write + * access. + */ + channelPermissions = TCL_WRITABLE; + macPermision = fsRdWrShPerm; + break; + case O_RDONLY: + default: + channelPermissions = TCL_READABLE; + macPermision = fsRdPerm; + break; + } + + err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec); + if ((err != noErr) && (err != fnfErr)) { + *errorCodePtr = errno = TclMacOSErrorToPosixError(err); + Tcl_SetErrno(errno); + return NULL; + } + + if ((err == fnfErr) && (mode & O_CREAT)) { + err = HCreate(fileSpec.vRefNum, fileSpec.parID, fileSpec.name, TCL_FILE_CREATOR, 'TEXT'); + if (err != noErr) { + *errorCodePtr = errno = TclMacOSErrorToPosixError(err); + Tcl_SetErrno(errno); + return NULL; + } + } else if ((mode & O_CREAT) && (mode & O_EXCL)) { + *errorCodePtr = errno = EEXIST; + Tcl_SetErrno(errno); + return NULL; + } + + err = HOpenDF(fileSpec.vRefNum, fileSpec.parID, fileSpec.name, macPermision, &fileRef); + if (err != noErr) { + *errorCodePtr = errno = TclMacOSErrorToPosixError(err); + Tcl_SetErrno(errno); + return NULL; + } + + if (mode & O_TRUNC) { + SetEOF(fileRef, 0); + } + + sprintf(channelName, "file%d", (int) fileRef); + fileState = (FileState *) ckalloc((unsigned) sizeof(FileState)); + chan = Tcl_CreateChannel(&fileChannelType, channelName, + (ClientData) fileState, channelPermissions); + if (chan == (Tcl_Channel) NULL) { + *errorCodePtr = errno = EFAULT; + Tcl_SetErrno(errno); + FSClose(fileRef); + ckfree((char *) fileState); + return NULL; + } + + fileState->fileChan = chan; + fileState->nextPtr = tsdPtr->firstFilePtr; + tsdPtr->firstFilePtr = fileState; + fileState->volumeRef = fileSpec.vRefNum; + fileState->fileRef = fileRef; + fileState->pending = 0; + fileState->watchMask = 0; + if (mode & O_APPEND) { + fileState->appendMode = true; + } else { + fileState->appendMode = false; + } + + if ((mode & O_APPEND) || (mode & O_APPEND)) { + if (Tcl_Seek(chan, 0, SEEK_END) < 0) { + *errorCodePtr = errno = EFAULT; + Tcl_SetErrno(errno); + Tcl_Close(NULL, chan); + FSClose(fileRef); + ckfree((char *) fileState); + return NULL; + } + } + + return chan; +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_MakeFileChannel -- + * + * Makes a Tcl_Channel from an existing OS level file handle. + * + * Results: + * The Tcl_Channel created around the preexisting OS level file handle. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_Channel +Tcl_MakeFileChannel(handle, mode) + ClientData handle; /* OS level handle. */ + int mode; /* ORed combination of TCL_READABLE and + * TCL_WRITABLE to indicate file mode. */ +{ + /* + * Not implemented yet. + */ + + return NULL; +} + +/* + *---------------------------------------------------------------------- + * + * FileBlockMode -- + * + * Set blocking or non-blocking mode on channel. Macintosh files + * can never really be set to blocking or non-blocking modes. + * However, we don't generate an error - we just return success. + * + * Results: + * 0 if successful, errno when failed. + * + * Side effects: + * Sets the device into blocking or non-blocking mode. + * + *---------------------------------------------------------------------- + */ + +static int +FileBlockMode( + ClientData instanceData, /* Unused. */ + int mode) /* The mode to set. */ +{ + return 0; +} + +/* + *---------------------------------------------------------------------- + * + * FileClose -- + * + * Closes the IO channel. + * + * Results: + * 0 if successful, the value of errno if failed. + * + * Side effects: + * Closes the physical channel + * + *---------------------------------------------------------------------- + */ + +static int +FileClose( + ClientData instanceData, /* Unused. */ + Tcl_Interp *interp) /* Unused. */ +{ + FileState *fileState = (FileState *) instanceData; + int errorCode = 0; + OSErr err; + + err = FSClose(fileState->fileRef); + FlushVol(NULL, fileState->volumeRef); + if (err != noErr) { + errorCode = errno = TclMacOSErrorToPosixError(err); + Tcl_Panic("error during file close"); + } + + ckfree((char *) fileState); + Tcl_SetErrno(errorCode); + return errorCode; +} + +/* + *---------------------------------------------------------------------- + * + * FileInput -- + * + * Reads input from the IO channel into the buffer given. Returns + * count of how many bytes were actually read, and an error indication. + * + * Results: + * A count of how many bytes were read is returned and an error + * indication is returned in an output argument. + * + * Side effects: + * Reads input from the actual channel. + * + *---------------------------------------------------------------------- + */ + +int +FileInput( + ClientData instanceData, /* Unused. */ + char *buffer, /* Where to store data read. */ + int bufSize, /* How much space is available + * in the buffer? */ + int *errorCodePtr) /* Where to store error code. */ +{ + FileState *fileState = (FileState *) instanceData; + OSErr err; + long length = bufSize; + + *errorCodePtr = 0; + errno = 0; + err = FSRead(fileState->fileRef, &length, buffer); + if ((err == noErr) || (err == eofErr)) { + return length; + } else { + switch (err) { + case ioErr: + *errorCodePtr = errno = EIO; + case afpAccessDenied: + *errorCodePtr = errno = EACCES; + default: + *errorCodePtr = errno = EINVAL; + } + return -1; + } + *errorCodePtr = errno; + return -1; +} + +/* + *---------------------------------------------------------------------- + * + * FileOutput-- + * + * Writes the given output on the IO channel. Returns count of how + * many characters were actually written, and an error indication. + * + * Results: + * A count of how many characters were written is returned and an + * error indication is returned in an output argument. + * + * Side effects: + * Writes output on the actual channel. + * + *---------------------------------------------------------------------- + */ + +static int +FileOutput( + ClientData instanceData, /* Unused. */ + CONST char *buffer, /* The data buffer. */ + int toWrite, /* How many bytes to write? */ + int *errorCodePtr) /* Where to store error code. */ +{ + FileState *fileState = (FileState *) instanceData; + long length = toWrite; + OSErr err; + + *errorCodePtr = 0; + errno = 0; + + if (fileState->appendMode == true) { + FileSeek(instanceData, 0, SEEK_END, errorCodePtr); + *errorCodePtr = 0; + } + + err = FSWrite(fileState->fileRef, &length, buffer); + if (err == noErr) { + err = FlushFile(fileState->fileRef); + } else { + *errorCodePtr = errno = TclMacOSErrorToPosixError(err); + return -1; + } + return length; +} + +/* + *---------------------------------------------------------------------- + * + * FileSeek -- + * + * Seeks on an IO channel. Returns the new position. + * + * Results: + * -1 if failed, the new position if successful. If failed, it + * also sets *errorCodePtr to the error code. + * + * Side effects: + * Moves the location at which the channel will be accessed in + * future operations. + * + *---------------------------------------------------------------------- + */ + +static int +FileSeek( + ClientData instanceData, /* Unused. */ + long offset, /* Offset to seek to. */ + int mode, /* Relative to where should we seek? */ + int *errorCodePtr) /* To store error code. */ +{ + FileState *fileState = (FileState *) instanceData; + IOParam pb; + OSErr err; + + *errorCodePtr = 0; + pb.ioCompletion = NULL; + pb.ioRefNum = fileState->fileRef; + if (mode == SEEK_SET) { + pb.ioPosMode = fsFromStart; + } else if (mode == SEEK_END) { + pb.ioPosMode = fsFromLEOF; + } else if (mode == SEEK_CUR) { + err = PBGetFPosSync((ParmBlkPtr) &pb); + if (pb.ioResult == noErr) { + if (offset == 0) { + return pb.ioPosOffset; + } + offset += pb.ioPosOffset; + } + pb.ioPosMode = fsFromStart; + } + pb.ioPosOffset = offset; + err = PBSetFPosSync((ParmBlkPtr) &pb); + if (pb.ioResult == noErr){ + return pb.ioPosOffset; + } else if (pb.ioResult == eofErr) { + long currentEOF, newEOF; + long buffer, i, length; + + err = PBGetEOFSync((ParmBlkPtr) &pb); + currentEOF = (long) pb.ioMisc; + if (mode == SEEK_SET) { + newEOF = offset; + } else if (mode == SEEK_END) { + newEOF = offset + currentEOF; + } else if (mode == SEEK_CUR) { + err = PBGetFPosSync((ParmBlkPtr) &pb); + newEOF = offset + pb.ioPosOffset; + } + + /* + * Write 0's to the new EOF. + */ + pb.ioPosOffset = 0; + pb.ioPosMode = fsFromLEOF; + err = PBGetFPosSync((ParmBlkPtr) &pb); + length = 1; + buffer = 0; + for (i = 0; i < (newEOF - currentEOF); i++) { + err = FSWrite(fileState->fileRef, &length, &buffer); + } + err = PBGetFPosSync((ParmBlkPtr) &pb); + if (pb.ioResult == noErr){ + return pb.ioPosOffset; + } + } + *errorCodePtr = errno = TclMacOSErrorToPosixError(err); + return -1; +} + +/* + *---------------------------------------------------------------------- + * + * CommonWatch -- + * + * Initialize the notifier to watch handles from this channel. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static void +CommonWatch( + ClientData instanceData, /* The file state. */ + int mask) /* Events of interest; an OR-ed + * combination of TCL_READABLE, + * TCL_WRITABLE and TCL_EXCEPTION. */ +{ + FileState *infoPtr = (FileState *) instanceData; + Tcl_Time blockTime = { 0, 0 }; + + infoPtr->watchMask = mask; + if (infoPtr->watchMask) { + Tcl_SetMaxBlockTime(&blockTime); + } +} + +/* + *---------------------------------------------------------------------- + * + * TclpCutFileChannel -- + * + * Remove any thread local refs to this channel. See + * Tcl_CutChannel for more info. + * + * Results: + * None. + * + * Side effects: + * Changes thread local list of valid channels. + * + *---------------------------------------------------------------------- + */ + +void +TclpCutFileChannel(chan) + Tcl_Channel chan; /* The channel being removed. Must + * not be referenced in any + * interpreter. */ +{ + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + Channel *chanPtr = (Channel *) chan; + FileState *infoPtr; + FileState **nextPtrPtr; + int removed = 0; + + if (chanPtr->typePtr != &fileChannelType) + return; + + infoPtr = (FileState *) chanPtr->instanceData; + + for (nextPtrPtr = &(tsdPtr->firstFilePtr); (*nextPtrPtr) != NULL; + nextPtrPtr = &((*nextPtrPtr)->nextPtr)) { + if ((*nextPtrPtr) == infoPtr) { + (*nextPtrPtr) = infoPtr->nextPtr; + removed = 1; + break; + } + } + + /* + * This could happen if the channel was created in one thread + * and then moved to another without updating the thread + * local data in each thread. + */ + + if (!removed) { + Tcl_Panic("file info ptr not on thread channel list"); + } +} + +/* + *---------------------------------------------------------------------- + * + * TclpSpliceFileChannel -- + * + * Insert thread local ref for this channel. + * Tcl_SpliceChannel for more info. + * + * Results: + * None. + * + * Side effects: + * Changes thread local list of valid channels. + * + *---------------------------------------------------------------------- + */ + +void +TclpSpliceFileChannel(chan) + Tcl_Channel chan; /* The channel being removed. Must + * not be referenced in any + * interpreter. */ +{ + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + Channel *chanPtr = (Channel *) chan; + FileState *infoPtr; + + if (chanPtr->typePtr != &fileChannelType) + return; + + infoPtr = (FileState *) chanPtr->instanceData; + + infoPtr->nextPtr = tsdPtr->firstFilePtr; + tsdPtr->firstFilePtr = infoPtr; +} diff --git a/mac/tclMacCommonPch.h b/mac/tclMacCommonPch.h new file mode 100755 index 0000000..c0deb9d --- /dev/null +++ b/mac/tclMacCommonPch.h @@ -0,0 +1,71 @@ +/* + * tclMacCommonPch.h -- + * + * Macintosh Tcl must be compiled with certain compiler options to + * ensure that it will work correctly. The following pragmas are + * used to ensure that those options are set correctly. An error + * will occur at compile time if they are not set correctly. + * + * Copyright (c) 1998 by Scriptics Corporation. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacCommonPch.h,v 1.3 2001/11/23 01:27:24 das Exp $ + */ + +#if !__option(enumsalwaysint) +#error Tcl requires the Metrowerks setting "Enums always ints". +#endif + + +#if !defined(__POWERPC__) +#if !__option(far_data) +#error Tcl requires the Metrowerks setting "Far data". +#endif +#endif + + +#if !defined(__POWERPC__) +#if !__option(fourbyteints) +#error Tcl requires the Metrowerks setting "4 byte ints". +#endif +#endif + + +#if !defined(__POWERPC__) +#if !__option(IEEEdoubles) +#error Tcl requires the Metrowerks setting "8 byte doubles". +#endif +#endif + + +/* +* The define is used most everywhere to tell Tcl (or any Tcl +* extensions) that we are compiling for the Macintosh platform. +*/ + + +#define MAC_TCL + + +/* +* Define the following symbol if you want +* comprehensive debugging turned on. +*/ + + +/* #define TCL_DEBUG */ + + +#ifdef TCL_DEBUG +# define TCL_MEM_DEBUG +# define TCL_TEST +#endif + + +/* +* for Metrowerks Pro 6 MSL +*/ + +#include <UseDLLPrefix.h> diff --git a/mac/tclMacDNR.c b/mac/tclMacDNR.c new file mode 100644 index 0000000..fa7058b --- /dev/null +++ b/mac/tclMacDNR.c @@ -0,0 +1,23 @@ +/* + * tclMacDNR.c + * + * This file actually just includes the file "dnr.c" provided by + * Apple Computer and redistributed by MetroWerks (and other compiler + * vendors.) Unfortunantly, despite various bug reports, dnr.c uses + * C++ style comments and will not compile under the "ANSI Strict" + * mode that the rest of Tcl compiles under. Furthermore, the Apple + * license prohibits me from redistributing a corrected version of + * dnr.c. This file uses a pragma to turn off the Strict ANSI option + * and then includes the dnr.c file. + * + * Copyright (c) 1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacDNR.c,v 1.2 1998/09/14 18:40:04 stanton Exp $ + */ + +#pragma ANSI_strict off +#include <dnr.c> +#pragma ANSI_strict reset diff --git a/mac/tclMacEnv.c b/mac/tclMacEnv.c new file mode 100644 index 0000000..8f6b58f --- /dev/null +++ b/mac/tclMacEnv.c @@ -0,0 +1,536 @@ +/* + * tclMacEnv.c -- + * + * Implements the "environment" on a Macintosh. + * + * Copyright (c) 1995-1996 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacEnv.c,v 1.2 1998/09/14 18:40:04 stanton Exp $ + */ + +#include <Gestalt.h> +#include <Folders.h> +#include <TextUtils.h> +#include <Resources.h> +#include <string.h> + +#include "tcl.h" +#include "tclInt.h" +#include "tclMacInt.h" +#include "tclPort.h" + +#define kMaxEnvStringSize 255 +#define kMaxEnvVarSize 100 +#define kLoginnameTag "LOGIN=" +#define kUsernameTag "USER=" +#define kDefaultDirTag "HOME=" + +/* + * The following specifies a text file where additional environment variables + * can be set. The file must reside in the preferences folder. If the file + * doesn't exist NO error will occur. Commet out the difinition if you do + * NOT want to use an environment variables file. + */ +#define kPrefsFile "Tcl Environment Variables" + +/* + * The following specifies the Name of a 'STR#' resource in the application + * where additional environment variables may be set. If the resource doesn't + * exist no errors will occur. Commet it out if you don't want it. + */ +#define REZ_ENV "\pTcl Environment Variables" + +/* Globals */ +char **environ = NULL; + +/* + * Declarations for local procedures defined in this file: + */ +static char ** RezRCVariables _ANSI_ARGS_((void)); +static char ** FileRCVariables _ANSI_ARGS_((void)); +static char ** PathVariables _ANSI_ARGS_((void)); +static char ** SystemVariables _ANSI_ARGS_((void)); +static char * MakeFolderEnvVar _ANSI_ARGS_((char * prefixTag, + long whichFolder)); +static char * GetUserName _ANSI_ARGS_((void)); + +/* + *---------------------------------------------------------------------- + * + * RezRCVariables -- + * + * Creates environment variables from the applications resource fork. + * The function looks for the 'STR#' resource with the name defined + * in the #define REZ_ENV. If the define is not defined this code + * will not be included. If the resource doesn't exist or no strings + * reside in the resource nothing will happen. + * + * Results: + * ptr to value on success, NULL if error. + * + * Side effects: + * Memory is allocated and returned to the caller. + * + *---------------------------------------------------------------------- + */ + +#ifdef REZ_ENV +static char ** +RezRCVariables() +{ + Handle envStrs = NULL; + char** rezEnv = NULL; + short int numStrs; + + envStrs = GetNamedResource('STR#', REZ_ENV); + if (envStrs == NULL) return NULL; + numStrs = *((short *) (*envStrs)); + + rezEnv = (char **) ckalloc((numStrs + 1) * sizeof(char *)); + + if (envStrs != NULL) { + ResType theType; + Str255 theName; + short theID, index = 1; + int i = 0; + char* string; + + GetResInfo(envStrs, &theID, &theType, theName); + for(;;) { + GetIndString(theName, theID, index++); + if (theName[0] == '\0') break; + string = (char *) ckalloc(theName[0] + 2); + strncpy(string, (char *) theName + 1, theName[0]); + string[theName[0]] = '\0'; + rezEnv[i++] = string; + } + ReleaseResource(envStrs); + + rezEnv[i] = NULL; + return rezEnv; + } + + return NULL; +} +#endif + +/* + *---------------------------------------------------------------------- + * + * FileRCVariables -- + * + * Creates environment variables from a file in the system preferences + * folder. The function looks for a file in the preferences folder + * a name defined in the #define kPrefsFile. If the define is not + * defined this code will not be included. If the resource doesn't exist or + * no strings reside in the resource nothing will happen. + * + * Results: + * ptr to value on success, NULL if error. + * + * Side effects: + * Memory is allocated and returned to the caller. + * + *---------------------------------------------------------------------- + */ + +#ifdef kPrefsFile +static char ** +FileRCVariables() +{ + char *prefsFolder = NULL; + char *tempPtr = NULL; + char **fileEnv = NULL; + FILE *thePrefsFile = NULL; + int i; + FSSpec prefDir; + OSErr err; + Handle theString = NULL; + Tcl_Channel chan; + int size; + Tcl_DString lineRead; + + err = FSpFindFolder(kOnSystemDisk, kPreferencesFolderType, + kDontCreateFolder, &prefDir); + if (err != noErr) { + return NULL; + } + err = FSpPathFromLocation(&prefDir, &size, &theString); + if (err != noErr) { + return NULL; + } + (void) Munger(theString, size, NULL, 0, kPrefsFile, strlen(kPrefsFile)); + + HLock(theString); + chan = Tcl_OpenFileChannel(NULL, *theString, "r", 0); + HUnlock(theString); + DisposeHandle(theString); + if (chan == NULL) { + return NULL; + } + + /* + * We found a env file. Let start parsing it. + */ + fileEnv = (char **) ckalloc((kMaxEnvVarSize + 1) * sizeof(char *)); + + i = 0; + Tcl_DStringInit(&lineRead); + while (Tcl_Gets(chan, &lineRead) != -1) { + /* + * First strip off new line char + */ + if (lineRead.string[lineRead.length-1] == '\n') { + lineRead.string[lineRead.length-1] = '\0'; + } + if (lineRead.string[0] == '\0' || lineRead.string[0] == '#') { + /* + * skip empty lines or commented lines + */ + Tcl_DStringSetLength(&lineRead, 0); + continue; + } + + tempPtr = (char *) ckalloc(lineRead.length + 1); + strcpy(tempPtr, lineRead.string); + fileEnv[i++] = tempPtr; + Tcl_DStringSetLength(&lineRead, 0); + } + + fileEnv[i] = NULL; + Tcl_Close(NULL, chan); + Tcl_DStringFree(&lineRead); + + return fileEnv; +} +#endif + +/* + *---------------------------------------------------------------------- + * + * MakeFolderEnvVar -- + * + * This function creates "environment" variable by taking a prefix and + * appending a folder path to a directory. The directory is specified + * by a integer value acceptable by the FindFolder function. + * + * Results: + * The function returns an *allocated* string. If the folder doesn't + * exist the return string is still allocated and just contains the + * given prefix. + * + * Side effects: + * Memory is allocated and returned to the caller. + * + *---------------------------------------------------------------------- + */ + +static char * +MakeFolderEnvVar( + char * prefixTag, /* Prefix added before result. */ + long whichFolder) /* Constant for FSpFindFolder. */ +{ + char * thePath = NULL; + char * result = NULL; + OSErr theErr = noErr; + Handle theString = NULL; + FSSpec theFolder; + int size; + Tcl_DString pathStr; + Tcl_DString tagPathStr; + + Tcl_DStringInit(&pathStr); + theErr = FSpFindFolder(kOnSystemDisk, whichFolder, + kDontCreateFolder, &theFolder); + if (theErr == noErr) { + theErr = FSpPathFromLocation(&theFolder, &size, &theString); + + HLock(theString); + tclPlatform = TCL_PLATFORM_MAC; + Tcl_DStringAppend(&pathStr, *theString, -1); + HUnlock(theString); + DisposeHandle(theString); + + Tcl_DStringInit(&tagPathStr); + Tcl_DStringAppend(&tagPathStr, prefixTag, strlen(prefixTag)); + Tcl_DStringAppend(&tagPathStr, pathStr.string, pathStr.length); + Tcl_DStringFree(&pathStr); + + /* + * Make sure the path ends with a ':' + */ + if (tagPathStr.string[tagPathStr.length - 1] != ':') { + Tcl_DStringAppend(&tagPathStr, ":", 1); + } + + /* + * Don't free tagPathStr - rather make sure it's allocated + * and return it as the result. + */ + if (tagPathStr.string == tagPathStr.staticSpace) { + result = (char *) ckalloc(tagPathStr.length + 1); + strcpy(result, tagPathStr.string); + } else { + result = tagPathStr.string; + } + } else { + result = (char *) ckalloc(strlen(prefixTag) + 1); + strcpy(result, prefixTag); + } + + return result; +} + +/* + *---------------------------------------------------------------------- + * + * PathVariables -- + * + * Creates environment variables from the system call FSpFindFolder. + * The function generates environment variables for many of the + * commonly used paths on the Macintosh. + * + * Results: + * ptr to value on success, NULL if error. + * + * Side effects: + * Memory is allocated and returned to the caller. + * + *---------------------------------------------------------------------- + */ + +static char ** +PathVariables() +{ + int i = 0; + char **sysEnv; + char *thePath = NULL; + + sysEnv = (char **) ckalloc((12) * sizeof(char *)); + + sysEnv[i++] = MakeFolderEnvVar("PREF_FOLDER=", kPreferencesFolderType); + sysEnv[i++] = MakeFolderEnvVar("SYS_FOLDER=", kSystemFolderType); + sysEnv[i++] = MakeFolderEnvVar("TEMP=", kTemporaryFolderType); + sysEnv[i++] = MakeFolderEnvVar("APPLE_M_FOLDER=", kAppleMenuFolderType); + sysEnv[i++] = MakeFolderEnvVar("CP_FOLDER=", kControlPanelFolderType); + sysEnv[i++] = MakeFolderEnvVar("DESK_FOLDER=", kDesktopFolderType); + sysEnv[i++] = MakeFolderEnvVar("EXT_FOLDER=", kExtensionFolderType); + sysEnv[i++] = MakeFolderEnvVar("PRINT_MON_FOLDER=", + kPrintMonitorDocsFolderType); + sysEnv[i++] = MakeFolderEnvVar("SHARED_TRASH_FOLDER=", + kWhereToEmptyTrashFolderType); + sysEnv[i++] = MakeFolderEnvVar("TRASH_FOLDER=", kTrashFolderType); + sysEnv[i++] = MakeFolderEnvVar("START_UP_FOLDER=", kStartupFolderType); + sysEnv[i++] = NULL; + + return sysEnv; +} + +/* + *---------------------------------------------------------------------- + * + * SystemVariables -- + * + * Creates environment variables from various Mac system calls. + * + * Results: + * ptr to value on success, NULL if error. + * + * Side effects: + * Memory is allocated and returned to the caller. + * + *---------------------------------------------------------------------- + */ + +static char ** +SystemVariables() +{ + int i = 0; + char ** sysEnv; + char * thePath = NULL; + Handle theString = NULL; + FSSpec currentDir; + int size; + + sysEnv = (char **) ckalloc((4) * sizeof(char *)); + + /* + * Get user name from chooser. It will be assigned to both + * the USER and LOGIN environment variables. + */ + thePath = GetUserName(); + if (thePath != NULL) { + sysEnv[i] = (char *) ckalloc(strlen(kLoginnameTag) + strlen(thePath) + 1); + strcpy(sysEnv[i], kLoginnameTag); + strcpy(sysEnv[i]+strlen(kLoginnameTag), thePath); + i++; + sysEnv[i] = (char *) ckalloc(strlen(kUsernameTag) + strlen(thePath) + 1); + strcpy(sysEnv[i], kUsernameTag); + strcpy(sysEnv[i]+strlen(kUsernameTag), thePath); + i++; + } + + /* + * Get 'home' directory + */ +#ifdef kDefaultDirTag + FSpGetDefaultDir(¤tDir); + FSpPathFromLocation(¤tDir, &size, &theString); + HLock(theString); + sysEnv[i] = (char *) ckalloc(strlen(kDefaultDirTag) + size + 4); + strcpy(sysEnv[i], kDefaultDirTag); + strncpy(sysEnv[i]+strlen(kDefaultDirTag) , *theString, size); + if (sysEnv[i][strlen(kDefaultDirTag) + size - 1] != ':') { + sysEnv[i][strlen(kDefaultDirTag) + size] = ':'; + sysEnv[i][strlen(kDefaultDirTag) + size + 1] = '\0'; + } else { + sysEnv[i][strlen(kDefaultDirTag) + size] = '\0'; + } + HUnlock(theString); + DisposeHandle(theString); + i++; +#endif + + sysEnv[i++] = NULL; + return sysEnv; +} + +/* + *---------------------------------------------------------------------- + * + * TclMacCreateEnv -- + * + * This function allocates and populates the global "environ" + * variable. Entries are in traditional Unix format but variables + * are, hopefully, a bit more relevant for the Macintosh. + * + * Results: + * The number of elements in the newly created environ array. + * + * Side effects: + * Memory is allocated and pointed too by the environ variable. + * + *---------------------------------------------------------------------- + */ + +int +TclMacCreateEnv() +{ + char ** sysEnv = NULL; + char ** pathEnv = NULL; + char ** fileEnv = NULL; + char ** rezEnv = NULL; + int count = 0; + int i, j; + + sysEnv = SystemVariables(); + if (sysEnv != NULL) { + for (i = 0; sysEnv[i] != NULL; count++, i++) { + /* Empty Loop */ + } + } + + pathEnv = PathVariables(); + if (pathEnv != NULL) { + for (i = 0; pathEnv[i] != NULL; count++, i++) { + /* Empty Loop */ + } + } + +#ifdef kPrefsFile + fileEnv = FileRCVariables(); + if (fileEnv != NULL) { + for (i = 0; fileEnv[i] != NULL; count++, i++) { + /* Empty Loop */ + } + } +#endif + +#ifdef REZ_ENV + rezEnv = RezRCVariables(); + if (rezEnv != NULL) { + for (i = 0; rezEnv[i] != NULL; count++, i++) { + /* Empty Loop */ + } + } +#endif + + /* + * Create environ variable + */ + environ = (char **) ckalloc((count + 1) * sizeof(char *)); + j = 0; + + if (sysEnv != NULL) { + for (i = 0; sysEnv[i] != NULL;) + environ[j++] = sysEnv[i++]; + ckfree((char *) sysEnv); + } + + if (pathEnv != NULL) { + for (i = 0; pathEnv[i] != NULL;) + environ[j++] = pathEnv[i++]; + ckfree((char *) pathEnv); + } + +#ifdef kPrefsFile + if (fileEnv != NULL) { + for (i = 0; fileEnv[i] != NULL;) + environ[j++] = fileEnv[i++]; + ckfree((char *) fileEnv); + } +#endif + +#ifdef REZ_ENV + if (rezEnv != NULL) { + for (i = 0; rezEnv[i] != NULL;) + environ[j++] = rezEnv[i++]; + ckfree((char *) rezEnv); + } +#endif + + environ[j] = NULL; + return j; +} + +/* + *---------------------------------------------------------------------- + * + * GetUserName -- + * + * Get the user login name. + * + * Results: + * ptr to static string, NULL if error. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static char * +GetUserName() +{ + static char buf[33]; + short refnum; + Handle h; + + refnum = CurResFile(); + UseResFile(0); + h = GetResource('STR ', -16096); + UseResFile(refnum); + if (h == NULL) { + return NULL; + } + + HLock(h); + strncpy(buf, (*h)+1, **h); + buf[**h] = '\0'; + HUnlock(h); + ReleaseResource(h); + return(buf[0] ? buf : NULL); +} diff --git a/mac/tclMacExit.c b/mac/tclMacExit.c new file mode 100644 index 0000000..347ff4e --- /dev/null +++ b/mac/tclMacExit.c @@ -0,0 +1,333 @@ +/* + * tclMacExit.c -- + * + * This file contains routines that deal with cleaning up various state + * when Tcl/Tk applications quit. Unfortunantly, not all state is cleaned + * up by the process when an application quites or crashes. Also you + * need to do different things depending on wether you are running as + * 68k code, PowerPC, or a code resource. The Exit handler code was + * adapted from code posted on alt.sources.mac by Dave Nebinger. + * + * Copyright (c) 1995 Dave Nebinger. + * Copyright (c) 1995-1996 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacExit.c,v 1.4 1999/04/16 00:47:19 stanton Exp $ + */ + +#include "tclInt.h" +#include "tclMacInt.h" +#include <SegLoad.h> +#include <Traps.h> +#include <Processes.h> + +/* + * Various typedefs and defines needed to patch ExitToShell. + */ + +enum { + uppExitToShellProcInfo = kPascalStackBased +}; + +#if GENERATINGCFM +typedef UniversalProcPtr ExitToShellUPP; + +#define CallExitToShellProc(userRoutine) \ + CallUniversalProc((UniversalProcPtr)(userRoutine),uppExitToShellProcInfo) +#define NewExitToShellProc(userRoutine) \ + (ExitToShellUPP)NewRoutineDescriptor((ProcPtr)(userRoutine), \ + uppExitToShellProcInfo, GetCurrentArchitecture()) + +#else +typedef ExitToShellProcPtr ExitToShellUPP; + +#define CallExitToShellProc(userRoutine) \ + (*(userRoutine))() +#define NewExitToShellProc(userRoutine) \ + (ExitToShellUPP)(userRoutine) +#endif + +#define DisposeExitToShellProc(userRoutine) \ + DisposeRoutineDescriptor(userRoutine) + +#if defined(powerc)||defined(__powerc) +#pragma options align=mac68k +#endif +struct ExitToShellUPPList{ + struct ExitToShellUPPList* nextProc; + ExitToShellUPP userProc; +}; +#if defined(powerc)||defined(__powerc) +#pragma options align=reset +#endif + +typedef struct ExitToShellDataStruct ExitToShellDataRec,* ExitToShellDataPtr,** ExitToShellDataHdl; + +typedef struct ExitToShellUPPList ExitToShellUPPList,* ExitToShellUPPListPtr,** ExitToShellUPPHdl; + +#if defined(powerc)||defined(__powerc) +#pragma options align=mac68k +#endif +struct ExitToShellDataStruct{ + unsigned long a5; + ExitToShellUPPList* userProcs; + ExitToShellUPP oldProc; +}; +#if defined(powerc)||defined(__powerc) +#pragma options align=reset +#endif + +/* + * Static globals used within this file. + */ +static ExitToShellDataPtr gExitToShellData = (ExitToShellDataPtr) NULL; + + +/* + *---------------------------------------------------------------------- + * + * TclPlatformExit -- + * + * This procedure implements the Macintosh specific exit routine. + * We explicitly callthe ExitHandler function to do various clean + * up. + * + * Results: + * None. + * + * Side effects: + * We exit the process. + * + *---------------------------------------------------------------------- + */ + +void +TclpExit( + int status) /* Ignored. */ +{ + TclMacExitHandler(); + +/* + * If we are using the Metrowerks Standard Library, then we will call its exit so that it + * will get a chance to clean up temp files, and so forth. It always calls the standard + * ExitToShell, so the Tcl handlers will also get called. + * + * If you have another exit, make sure that it does not patch ExitToShell, and does + * call it. If so, it will probably work as well. + * + */ + +#ifdef __MSL__ + exit(status); +#else + ExitToShell(); +#endif + +} + +/* + *---------------------------------------------------------------------- + * + * TclMacExitHandler -- + * + * This procedure is invoked after Tcl at the last possible moment + * to clean up any state Tcl has left around that may cause other + * applications to crash. For example, this function can be used + * as the termination routine for CFM applications. + * + * Results: + * None. + * + * Side effects: + * Various cleanup occurs. + * + *---------------------------------------------------------------------- + */ + +void +TclMacExitHandler() +{ + ExitToShellUPPListPtr curProc; + + /* + * Loop through all installed Exit handlers + * and call them. Always make sure we are in + * a clean state in case we are recursivly called. + */ + if ((gExitToShellData) != NULL && (gExitToShellData->userProcs != NULL)){ + + /* + * Call the installed exit to shell routines. + */ + curProc = gExitToShellData->userProcs; + do { + gExitToShellData->userProcs = curProc->nextProc; + CallExitToShellProc(curProc->userProc); + DisposeExitToShellProc(curProc->userProc); + DisposePtr((Ptr) curProc); + curProc = gExitToShellData->userProcs; + } while (curProc != (ExitToShellUPPListPtr) NULL); + } + + return; +} + +/* + *---------------------------------------------------------------------- + * + * TclMacInstallExitToShellPatch -- + * + * This procedure installs a way to clean up state at the latest + * possible moment before we exit. These are things that must + * be cleaned up or the system will crash. The exact way in which + * this is implemented depends on the architecture in which we are + * running. For 68k applications we patch the ExitToShell call. + * For PowerPC applications we just create a list of procs to call. + * The function ExitHandler should be installed in the Code + * Fragments terminiation routine. + * + * Results: + * None. + * + * Side effects: + * Installs the new routine. + * + *---------------------------------------------------------------------- + */ + +OSErr +TclMacInstallExitToShellPatch( + ExitToShellProcPtr newProc) /* Function pointer. */ +{ + ExitToShellUPP exitHandler; + ExitToShellUPPListPtr listPtr; + + if (gExitToShellData == (ExitToShellDataPtr) NULL){ + TclMacInitExitToShell(true); + } + + /* + * Add the passed in function pointer to the list of functions + * to be called when ExitToShell is called. + */ + exitHandler = NewExitToShellProc(newProc); + listPtr = (ExitToShellUPPListPtr) NewPtrClear(sizeof(ExitToShellUPPList)); + listPtr->userProc = exitHandler; + listPtr->nextProc = gExitToShellData->userProcs; + gExitToShellData->userProcs = listPtr; + + return noErr; +} + +/* + *---------------------------------------------------------------------- + * + * ExitToShellPatchRoutine -- + * + * This procedure is invoked when someone calls ExitToShell for + * this application. This function performs some last miniute + * clean up and then calls the real ExitToShell routine. + * + * Results: + * None. + * + * Side effects: + * Various cleanup occurs. + * + *---------------------------------------------------------------------- + */ + +static pascal void +ExitToShellPatchRoutine() +{ + ExitToShellUPP oldETS; + long oldA5; + + /* + * Set up our A5 world. This allows us to have + * access to our global variables in the 68k world. + */ + oldA5 = SetCurrentA5(); + SetA5(gExitToShellData->a5); + + /* + * Call the function that invokes all + * of the handlers. + */ + TclMacExitHandler(); + + /* + * Call the origional ExitToShell routine. + */ + oldETS = gExitToShellData->oldProc; + DisposePtr((Ptr) gExitToShellData); + SetA5(oldA5); + CallExitToShellProc(oldETS); + return; +} + +/* + *---------------------------------------------------------------------- + * + * TclMacInitExitToShell -- + * + * This procedure initializes the ExitToShell clean up machanism. + * Generally, this is handled automatically when users make a call + * to InstallExitToShellPatch. However, it can be called + * explicitly at startup time to turn off the patching mechanism. + * This can be used by code resources which could be removed from + * the application before ExitToShell is called. + * + * Note, if we are running from CFM code we never install the + * patch. Instead, the function ExitHandler should be installed + * as the terminiation routine for the code fragment. + * + * Results: + * None. + * + * Side effects: + * Creates global state. + * + *---------------------------------------------------------------------- + */ + +void +TclMacInitExitToShell( + int usePatch) /* True if on 68k. */ +{ + if (gExitToShellData == (ExitToShellDataPtr) NULL){ +#if GENERATINGCFM + gExitToShellData = (ExitToShellDataPtr) + NewPtr(sizeof(ExitToShellDataRec)); + gExitToShellData->a5 = SetCurrentA5(); + gExitToShellData->userProcs = (ExitToShellUPPList*) NULL; +#else + ExitToShellUPP oldExitToShell, newExitToShellPatch; + short exitToShellTrap; + + /* + * Initialize patch mechanism. + */ + + gExitToShellData = (ExitToShellDataPtr) NewPtr(sizeof(ExitToShellDataRec)); + gExitToShellData->a5 = SetCurrentA5(); + gExitToShellData->userProcs = (ExitToShellUPPList*) NULL; + + /* + * Save state needed to call origional ExitToShell routine. Install + * the new ExitToShell code in it's place. + */ + if (usePatch) { + exitToShellTrap = _ExitToShell & 0x3ff; + newExitToShellPatch = NewExitToShellProc(ExitToShellPatchRoutine); + oldExitToShell = (ExitToShellUPP) + NGetTrapAddress(exitToShellTrap, ToolTrap); + NSetTrapAddress((UniversalProcPtr) newExitToShellPatch, + exitToShellTrap, ToolTrap); + gExitToShellData->oldProc = oldExitToShell; + } +#endif + } +} diff --git a/mac/tclMacFCmd.c b/mac/tclMacFCmd.c new file mode 100644 index 0000000..a1307b4 --- /dev/null +++ b/mac/tclMacFCmd.c @@ -0,0 +1,1721 @@ +/* + * tclMacFCmd.c -- + * + * Implements the Macintosh specific portions of the file manipulation + * subcommands of the "file" command. + * + * Copyright (c) 1996-1998 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacFCmd.c,v 1.20 2003/05/14 19:21:23 das Exp $ + */ + +#include "tclInt.h" +#include "tclMac.h" +#include "tclMacInt.h" +#include "tclPort.h" +#include <FSpCompat.h> +#include <MoreFilesExtras.h> +#include <Strings.h> +#include <Errors.h> +#include <FileCopy.h> +#include <DirectoryCopy.h> +#include <Script.h> +#include <string.h> +#include <Finder.h> +#include <Aliases.h> +#include <Resources.h> + +/* + * Callback for the file attributes code. + */ + +static int GetFileFinderAttributes _ANSI_ARGS_((Tcl_Interp *interp, + int objIndex, Tcl_Obj *fileName, + Tcl_Obj **attributePtrPtr)); +static int GetFileReadOnly _ANSI_ARGS_((Tcl_Interp *interp, + int objIndex, Tcl_Obj *fileName, + Tcl_Obj **readOnlyPtrPtr)); +static int SetFileFinderAttributes _ANSI_ARGS_((Tcl_Interp *interp, + int objIndex, Tcl_Obj *fileName, + Tcl_Obj *attributePtr)); +static int SetFileReadOnly _ANSI_ARGS_((Tcl_Interp *interp, + int objIndex, Tcl_Obj *fileName, + Tcl_Obj *readOnlyPtr)); + +/* + * These are indeces into the tclpFileAttrsStrings table below. + */ + +#define MAC_CREATOR_ATTRIBUTE 0 +#define MAC_HIDDEN_ATTRIBUTE 1 +#define MAC_READONLY_ATTRIBUTE 2 +#define MAC_TYPE_ATTRIBUTE 3 +#define MAC_RSRCLENGTH_ATTRIBUTE 4 + +/* + * Global variables for the file attributes code. + */ + +CONST char *tclpFileAttrStrings[] = {"-creator", "-hidden", "-readonly", + "-type", "-rsrclength", (char *) NULL}; +CONST TclFileAttrProcs tclpFileAttrProcs[] = { + {GetFileFinderAttributes, SetFileFinderAttributes}, + {GetFileFinderAttributes, SetFileFinderAttributes}, + {GetFileReadOnly, SetFileReadOnly}, + {GetFileFinderAttributes, SetFileFinderAttributes}, + {GetFileFinderAttributes, SetFileFinderAttributes}}; + +/* + * File specific static data + */ + +static long startSeed = 248923489; + +/* + * Prototypes for procedure only used in this file + */ + +static pascal Boolean CopyErrHandler _ANSI_ARGS_((OSErr error, + short failedOperation, + short srcVRefNum, long srcDirID, + ConstStr255Param srcName, short dstVRefNum, + long dstDirID,ConstStr255Param dstName)); +static int DoCopyDirectory _ANSI_ARGS_((CONST char *src, + CONST char *dst, Tcl_DString *errorPtr)); +static int DoCopyFile _ANSI_ARGS_((CONST char *src, + CONST char *dst)); +static int DoCreateDirectory _ANSI_ARGS_((CONST char *path)); +static int DoRemoveDirectory _ANSI_ARGS_((CONST char *path, + int recursive, Tcl_DString *errorPtr)); +static int DoRenameFile _ANSI_ARGS_((CONST char *src, + CONST char *dst)); +OSErr FSpGetFLockCompat _ANSI_ARGS_((const FSSpec *specPtr, + Boolean *lockedPtr)); +static OSErr GetFileSpecs _ANSI_ARGS_((CONST char *path, + FSSpec *pathSpecPtr, FSSpec *dirSpecPtr, + Boolean *pathExistsPtr, + Boolean *pathIsDirectoryPtr)); +static OSErr MoveRename _ANSI_ARGS_((const FSSpec *srcSpecPtr, + const FSSpec *dstSpecPtr, StringPtr copyName)); +static int Pstrequal _ANSI_ARGS_((ConstStr255Param stringA, + ConstStr255Param stringB)); + +/* + *--------------------------------------------------------------------------- + * + * TclpObjRenameFile, DoRenameFile -- + * + * Changes the name of an existing file or directory, from src to dst. + * If src and dst refer to the same file or directory, does nothing + * and returns success. Otherwise if dst already exists, it will be + * deleted and replaced by src subject to the following conditions: + * If src is a directory, dst may be an empty directory. + * If src is a file, dst may be a file. + * In any other situation where dst already exists, the rename will + * fail. + * + * Results: + * If the directory was successfully created, returns TCL_OK. + * Otherwise the return value is TCL_ERROR and errno is set to + * indicate the error. Some possible values for errno are: + * + * EACCES: src or dst parent directory can't be read and/or written. + * EEXIST: dst is a non-empty directory. + * EINVAL: src is a root directory or dst is a subdirectory of src. + * EISDIR: dst is a directory, but src is not. + * ENOENT: src doesn't exist. src or dst is "". + * ENOTDIR: src is a directory, but dst is not. + * EXDEV: src and dst are on different filesystems. + * + * Side effects: + * The implementation of rename may allow cross-filesystem renames, + * but the caller should be prepared to emulate it with copy and + * delete if errno is EXDEV. + * + *--------------------------------------------------------------------------- + */ + +int +TclpObjRenameFile(srcPathPtr, destPathPtr) + Tcl_Obj *srcPathPtr; + Tcl_Obj *destPathPtr; +{ + return DoRenameFile(Tcl_FSGetNativePath(srcPathPtr), + Tcl_FSGetNativePath(destPathPtr)); +} + +static int +DoRenameFile( + CONST char *src, /* Pathname of file or dir to be renamed + * (native). */ + CONST char *dst) /* New pathname of file or directory + * (native). */ +{ + FSSpec srcFileSpec, dstFileSpec, dstDirSpec; + OSErr err; + long srcID, dummy; + Boolean srcIsDirectory, dstIsDirectory, dstExists, dstLocked; + + err = FSpLLocationFromPath(strlen(src), src, &srcFileSpec); + if (err == noErr) { + FSpGetDirectoryID(&srcFileSpec, &srcID, &srcIsDirectory); + } + if (err == noErr) { + err = GetFileSpecs(dst, &dstFileSpec, &dstDirSpec, &dstExists, + &dstIsDirectory); + } + if (err == noErr) { + if (dstExists == 0) { + err = MoveRename(&srcFileSpec, &dstDirSpec, dstFileSpec.name); + goto end; + } + err = FSpGetFLockCompat(&dstFileSpec, &dstLocked); + if (dstLocked) { + FSpRstFLockCompat(&dstFileSpec); + } + } + if (err == noErr) { + if (srcIsDirectory) { + if (dstIsDirectory) { + /* + * The following call will remove an empty directory. If it + * fails, it's because it wasn't empty. + */ + + if (DoRemoveDirectory(dst, 0, NULL) != TCL_OK) { + return TCL_ERROR; + } + + /* + * Now that that empty directory is gone, we can try + * renaming src. If that fails, we'll put this empty + * directory back, for completeness. + */ + + err = MoveRename(&srcFileSpec, &dstDirSpec, dstFileSpec.name); + if (err != noErr) { + FSpDirCreateCompat(&dstFileSpec, smSystemScript, &dummy); + if (dstLocked) { + FSpSetFLockCompat(&dstFileSpec); + } + } + } else { + errno = ENOTDIR; + return TCL_ERROR; + } + } else { + if (dstIsDirectory) { + errno = EISDIR; + return TCL_ERROR; + } else { + /* + * Overwrite existing file by: + * + * 1. Rename existing file to temp name. + * 2. Rename old file to new name. + * 3. If success, delete temp file. If failure, + * put temp file back to old name. + */ + + Str31 tmpName; + FSSpec tmpFileSpec; + + err = GenerateUniqueName(dstFileSpec.vRefNum, &startSeed, + dstFileSpec.parID, dstFileSpec.parID, tmpName); + if (err == noErr) { + err = FSpRenameCompat(&dstFileSpec, tmpName); + } + if (err == noErr) { + err = FSMakeFSSpecCompat(dstFileSpec.vRefNum, + dstFileSpec.parID, tmpName, &tmpFileSpec); + } + if (err == noErr) { + err = MoveRename(&srcFileSpec, &dstDirSpec, + dstFileSpec.name); + } + if (err == noErr) { + FSpDeleteCompat(&tmpFileSpec); + } else { + FSpDeleteCompat(&dstFileSpec); + FSpRenameCompat(&tmpFileSpec, dstFileSpec.name); + if (dstLocked) { + FSpSetFLockCompat(&dstFileSpec); + } + } + } + } + } + + end: + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + return TCL_ERROR; + } + return TCL_OK; +} + +/* + *-------------------------------------------------------------------------- + * + * MoveRename -- + * + * Helper function for TclpRenameFile. Renames a file or directory + * into the same directory or another directory. The target name + * must not already exist in the destination directory. + * + * Don't use FSpMoveRenameCompat because it doesn't work with + * directories or with locked files. + * + * Results: + * Returns a mac error indicating the cause of the failure. + * + * Side effects: + * Creates a temp file in the target directory to handle a rename + * between directories. + * + *-------------------------------------------------------------------------- + */ + +static OSErr +MoveRename( + const FSSpec *srcFileSpecPtr, /* Source object. */ + const FSSpec *dstDirSpecPtr, /* Destination directory. */ + StringPtr copyName) /* New name for object in destination + * directory. */ +{ + OSErr err; + long srcID, dstID; + Boolean srcIsDir, dstIsDir; + Str31 tmpName; + FSSpec dstFileSpec, srcDirSpec, tmpSrcFileSpec, tmpDstFileSpec; + Boolean locked; + + if (srcFileSpecPtr->parID == 1) { + /* + * Trying to rename a volume. + */ + + return badMovErr; + } + if (srcFileSpecPtr->vRefNum != dstDirSpecPtr->vRefNum) { + /* + * Renaming across volumes. + */ + + return diffVolErr; + } + err = FSpGetFLockCompat(srcFileSpecPtr, &locked); + if (locked) { + FSpRstFLockCompat(srcFileSpecPtr); + } + if (err == noErr) { + err = FSpGetDirectoryID(dstDirSpecPtr, &dstID, &dstIsDir); + } + if (err == noErr) { + if (srcFileSpecPtr->parID == dstID) { + /* + * Renaming object within directory. + */ + + err = FSpRenameCompat(srcFileSpecPtr, copyName); + goto done; + } + if (Pstrequal(srcFileSpecPtr->name, copyName)) { + /* + * Moving object to another directory (under same name). + */ + + err = FSpCatMoveCompat(srcFileSpecPtr, dstDirSpecPtr); + goto done; + } + err = FSpGetDirectoryID(srcFileSpecPtr, &srcID, &srcIsDir); + } + if (err == noErr) { + /* + * Fullblown: rename source object to temp name, move temp to + * dest directory, and rename temp to target. + */ + + err = GenerateUniqueName(srcFileSpecPtr->vRefNum, &startSeed, + srcFileSpecPtr->parID, dstID, tmpName); + FSMakeFSSpecCompat(srcFileSpecPtr->vRefNum, srcFileSpecPtr->parID, + tmpName, &tmpSrcFileSpec); + FSMakeFSSpecCompat(dstDirSpecPtr->vRefNum, dstID, tmpName, + &tmpDstFileSpec); + } + if (err == noErr) { + err = FSpRenameCompat(srcFileSpecPtr, tmpName); + } + if (err == noErr) { + err = FSpCatMoveCompat(&tmpSrcFileSpec, dstDirSpecPtr); + if (err == noErr) { + err = FSpRenameCompat(&tmpDstFileSpec, copyName); + if (err == noErr) { + goto done; + } + FSMakeFSSpecCompat(srcFileSpecPtr->vRefNum, srcFileSpecPtr->parID, + NULL, &srcDirSpec); + FSpCatMoveCompat(&tmpDstFileSpec, &srcDirSpec); + } + FSpRenameCompat(&tmpSrcFileSpec, srcFileSpecPtr->name); + } + + done: + if (locked != false) { + if (err == noErr) { + FSMakeFSSpecCompat(dstDirSpecPtr->vRefNum, + dstID, copyName, &dstFileSpec); + FSpSetFLockCompat(&dstFileSpec); + } else { + FSpSetFLockCompat(srcFileSpecPtr); + } + } + return err; +} + +/* + *--------------------------------------------------------------------------- + * + * TclpObjCopyFile, DoCopyFile -- + * + * Copy a single file (not a directory). If dst already exists and + * is not a directory, it is removed. + * + * Results: + * If the file was successfully copied, returns TCL_OK. Otherwise + * the return value is TCL_ERROR and errno is set to indicate the + * error. Some possible values for errno are: + * + * EACCES: src or dst parent directory can't be read and/or written. + * EISDIR: src or dst is a directory. + * ENOENT: src doesn't exist. src or dst is "". + * + * Side effects: + * This procedure will also copy symbolic links, block, and + * character devices, and fifos. For symbolic links, the links + * themselves will be copied and not what they point to. For the + * other special file types, the directory entry will be copied and + * not the contents of the device that it refers to. + * + *--------------------------------------------------------------------------- + */ + +int +TclpObjCopyFile(srcPathPtr, destPathPtr) + Tcl_Obj *srcPathPtr; + Tcl_Obj *destPathPtr; +{ + return DoCopyFile(Tcl_FSGetNativePath(srcPathPtr), + Tcl_FSGetNativePath(destPathPtr)); +} + +static int +DoCopyFile( + CONST char *src, /* Pathname of file to be copied (native). */ + CONST char *dst) /* Pathname of file to copy to (native). */ +{ + OSErr err, dstErr; + Boolean dstExists, dstIsDirectory, dstLocked; + FSSpec srcFileSpec, dstFileSpec, dstDirSpec, tmpFileSpec; + Str31 tmpName; + + err = FSpLLocationFromPath(strlen(src), src, &srcFileSpec); + if (err == noErr) { + err = GetFileSpecs(dst, &dstFileSpec, &dstDirSpec, &dstExists, + &dstIsDirectory); + } + if (dstExists) { + if (dstIsDirectory) { + errno = EISDIR; + return TCL_ERROR; + } + err = FSpGetFLockCompat(&dstFileSpec, &dstLocked); + if (dstLocked) { + FSpRstFLockCompat(&dstFileSpec); + } + + /* + * Backup dest file. + */ + + dstErr = GenerateUniqueName(dstFileSpec.vRefNum, &startSeed, dstFileSpec.parID, + dstFileSpec.parID, tmpName); + if (dstErr == noErr) { + dstErr = FSpRenameCompat(&dstFileSpec, tmpName); + } + } + if (err == noErr) { + err = FSpFileCopy(&srcFileSpec, &dstDirSpec, + (StringPtr) dstFileSpec.name, NULL, 0, true); + } + if ((dstExists != false) && (dstErr == noErr)) { + FSMakeFSSpecCompat(dstFileSpec.vRefNum, dstFileSpec.parID, + tmpName, &tmpFileSpec); + if (err == noErr) { + /* + * Delete backup file. + */ + + FSpDeleteCompat(&tmpFileSpec); + } else { + + /* + * Restore backup file. + */ + + FSpDeleteCompat(&dstFileSpec); + FSpRenameCompat(&tmpFileSpec, dstFileSpec.name); + if (dstLocked) { + FSpSetFLockCompat(&dstFileSpec); + } + } + } + + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + return TCL_ERROR; + } + return TCL_OK; +} + +/* + *--------------------------------------------------------------------------- + * + * TclpObjDeleteFile, TclpDeleteFile -- + * + * Removes a single file (not a directory). + * + * Results: + * If the file was successfully deleted, returns TCL_OK. Otherwise + * the return value is TCL_ERROR and errno is set to indicate the + * error. Some possible values for errno are: + * + * EACCES: a parent directory can't be read and/or written. + * EISDIR: path is a directory. + * ENOENT: path doesn't exist or is "". + * + * Side effects: + * The file is deleted, even if it is read-only. + * + *--------------------------------------------------------------------------- + */ + +int +TclpObjDeleteFile(pathPtr) + Tcl_Obj *pathPtr; +{ + return TclpDeleteFile(Tcl_FSGetNativePath(pathPtr)); +} + +int +TclpDeleteFile( + CONST char *path) /* Pathname of file to be removed (native). */ +{ + OSErr err; + FSSpec fileSpec; + Boolean isDirectory; + long dirID; + + err = FSpLLocationFromPath(strlen(path), path, &fileSpec); + if (err == noErr) { + /* + * Since FSpDeleteCompat will delete an empty directory, make sure + * that this isn't a directory first. + */ + + FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); + if (isDirectory == true) { + errno = EISDIR; + return TCL_ERROR; + } + } + err = FSpDeleteCompat(&fileSpec); + if (err == fLckdErr) { + FSpRstFLockCompat(&fileSpec); + err = FSpDeleteCompat(&fileSpec); + if (err != noErr) { + FSpSetFLockCompat(&fileSpec); + } + } + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + return TCL_ERROR; + } + return TCL_OK; +} + +/* + *--------------------------------------------------------------------------- + * + * TclpObjCreateDirectory, DoCreateDirectory -- + * + * Creates the specified directory. All parent directories of the + * specified directory must already exist. The directory is + * automatically created with permissions so that user can access + * the new directory and create new files or subdirectories in it. + * + * Results: + * If the directory was successfully created, returns TCL_OK. + * Otherwise the return value is TCL_ERROR and errno is set to + * indicate the error. Some possible values for errno are: + * + * EACCES: a parent directory can't be read and/or written. + * EEXIST: path already exists. + * ENOENT: a parent directory doesn't exist. + * + * Side effects: + * A directory is created with the current umask, except that + * permission for u+rwx will always be added. + * + *--------------------------------------------------------------------------- + */ + +int +TclpObjCreateDirectory(pathPtr) + Tcl_Obj *pathPtr; +{ + return DoCreateDirectory(Tcl_FSGetNativePath(pathPtr)); +} + +static int +DoCreateDirectory( + CONST char *path) /* Pathname of directory to create (native). */ +{ + OSErr err; + FSSpec dirSpec; + long outDirID; + + err = FSpLocationFromPath(strlen(path), path, &dirSpec); + if (err == noErr) { + err = dupFNErr; /* EEXIST. */ + } else if (err == fnfErr) { + err = FSpDirCreateCompat(&dirSpec, smSystemScript, &outDirID); + } + + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + return TCL_ERROR; + } + return TCL_OK; +} + +/* + *--------------------------------------------------------------------------- + * + * TclpObjCopyDirectory, DoCopyDirectory -- + * + * Recursively copies a directory. The target directory dst must + * not already exist. Note that this function does not merge two + * directory hierarchies, even if the target directory is an an + * empty directory. + * + * Results: + * If the directory was successfully copied, returns TCL_OK. + * Otherwise the return value is TCL_ERROR, errno is set to indicate + * the error, and the pathname of the file that caused the error + * is stored in errorPtr. See TclpCreateDirectory and TclpCopyFile + * for a description of possible values for errno. + * + * Side effects: + * An exact copy of the directory hierarchy src will be created + * with the name dst. If an error occurs, the error will + * be returned immediately, and remaining files will not be + * processed. + * + *--------------------------------------------------------------------------- + */ + +int +TclpObjCopyDirectory(srcPathPtr, destPathPtr, errorPtr) + Tcl_Obj *srcPathPtr; + Tcl_Obj *destPathPtr; + Tcl_Obj **errorPtr; +{ + Tcl_DString ds; + int ret; + ret = DoCopyDirectory(Tcl_FSGetNativePath(srcPathPtr), + Tcl_FSGetNativePath(destPathPtr), &ds); + if (ret != TCL_OK) { + *errorPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1); + Tcl_DStringFree(&ds); + Tcl_IncrRefCount(*errorPtr); + } + return ret; +} + +static int +DoCopyDirectory( + CONST char *src, /* Pathname of directory to be copied + * (Native). */ + CONST char *dst, /* Pathname of target directory (Native). */ + Tcl_DString *errorPtr) /* If non-NULL, uninitialized or free + * DString filled with UTF-8 name of file + * causing error. */ +{ + OSErr err, saveErr; + long srcID, tmpDirID; + FSSpec srcFileSpec, dstFileSpec, dstDirSpec, tmpDirSpec, tmpFileSpec; + Boolean srcIsDirectory, srcLocked; + Boolean dstIsDirectory, dstExists; + Str31 tmpName; + + err = FSpLocationFromPath(strlen(src), src, &srcFileSpec); + if (err == noErr) { + err = FSpGetDirectoryID(&srcFileSpec, &srcID, &srcIsDirectory); + } + if (err == noErr) { + if (srcIsDirectory == false) { + err = afpObjectTypeErr; /* ENOTDIR. */ + } + } + if (err == noErr) { + err = GetFileSpecs(dst, &dstFileSpec, &dstDirSpec, &dstExists, + &dstIsDirectory); + } + if (dstExists) { + if (dstIsDirectory == false) { + err = afpObjectTypeErr; /* ENOTDIR. */ + } else { + err = dupFNErr; /* EEXIST. */ + } + } + if (err != noErr) { + goto done; + } + if ((srcFileSpec.vRefNum == dstFileSpec.vRefNum) && + (srcFileSpec.parID == dstFileSpec.parID) && + (Pstrequal(srcFileSpec.name, dstFileSpec.name) != 0)) { + /* + * Copying on top of self. No-op. + */ + + goto done; + } + + /* + * This algorthm will work making a copy of the source directory in + * the current directory with a new name, in a new directory with the + * same name, and in a new directory with a new name: + * + * 1. Make dstDir/tmpDir. + * 2. Copy srcDir/src to dstDir/tmpDir/src + * 3. Rename dstDir/tmpDir/src to dstDir/tmpDir/dst (if necessary). + * 4. CatMove dstDir/tmpDir/dst to dstDir/dst. + * 5. Remove dstDir/tmpDir. + */ + + err = FSpGetFLockCompat(&srcFileSpec, &srcLocked); + if (srcLocked) { + FSpRstFLockCompat(&srcFileSpec); + } + if (err == noErr) { + err = GenerateUniqueName(dstFileSpec.vRefNum, &startSeed, dstFileSpec.parID, + dstFileSpec.parID, tmpName); + } + if (err == noErr) { + FSMakeFSSpecCompat(dstFileSpec.vRefNum, dstFileSpec.parID, + tmpName, &tmpDirSpec); + err = FSpDirCreateCompat(&tmpDirSpec, smSystemScript, &tmpDirID); + } + if (err == noErr) { + err = FSpDirectoryCopy(&srcFileSpec, &tmpDirSpec, NULL, NULL, 0, true, + CopyErrHandler); + } + + /* + * Even if the Copy failed, Rename/Move whatever did get copied to the + * appropriate final destination, if possible. + */ + + saveErr = err; + err = noErr; + if (Pstrequal(srcFileSpec.name, dstFileSpec.name) == 0) { + err = FSMakeFSSpecCompat(tmpDirSpec.vRefNum, tmpDirID, + srcFileSpec.name, &tmpFileSpec); + if (err == noErr) { + err = FSpRenameCompat(&tmpFileSpec, dstFileSpec.name); + } + } + if (err == noErr) { + err = FSMakeFSSpecCompat(tmpDirSpec.vRefNum, tmpDirID, + dstFileSpec.name, &tmpFileSpec); + } + if (err == noErr) { + err = FSpCatMoveCompat(&tmpFileSpec, &dstDirSpec); + } + if (err == noErr) { + if (srcLocked) { + FSpSetFLockCompat(&dstFileSpec); + } + } + + FSpDeleteCompat(&tmpDirSpec); + + if (saveErr != noErr) { + err = saveErr; + } + + done: + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + if (errorPtr != NULL) { + Tcl_ExternalToUtfDString(NULL, dst, -1, errorPtr); + } + return TCL_ERROR; + } + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * CopyErrHandler -- + * + * This procedure is called from the MoreFiles procedure + * FSpDirectoryCopy whenever an error occurs. + * + * Results: + * False if the condition should not be considered an error, true + * otherwise. + * + * Side effects: + * Since FSpDirectoryCopy() is called only after removing any + * existing target directories, there shouldn't be any errors. + * + *---------------------------------------------------------------------- + */ + +static pascal Boolean +CopyErrHandler( + OSErr error, /* Error that occured */ + short failedOperation, /* operation that caused the error */ + short srcVRefNum, /* volume ref number of source */ + long srcDirID, /* directory id of source */ + ConstStr255Param srcName, /* name of source */ + short dstVRefNum, /* volume ref number of dst */ + long dstDirID, /* directory id of dst */ + ConstStr255Param dstName) /* name of dst directory */ +{ + return true; +} + +/* + *--------------------------------------------------------------------------- + * + * TclpObjRemoveDirectory, DoRemoveDirectory -- + * + * Removes directory (and its contents, if the recursive flag is set). + * + * Results: + * If the directory was successfully removed, returns TCL_OK. + * Otherwise the return value is TCL_ERROR, errno is set to indicate + * the error, and the pathname of the file that caused the error + * is stored in errorPtr. Some possible values for errno are: + * + * EACCES: path directory can't be read and/or written. + * EEXIST: path is a non-empty directory. + * EINVAL: path is a root directory. + * ENOENT: path doesn't exist or is "". + * ENOTDIR: path is not a directory. + * + * Side effects: + * Directory removed. If an error occurs, the error will be returned + * immediately, and remaining files will not be deleted. + * + *--------------------------------------------------------------------------- + */ + +int +TclpObjRemoveDirectory(pathPtr, recursive, errorPtr) + Tcl_Obj *pathPtr; + int recursive; + Tcl_Obj **errorPtr; +{ + Tcl_DString ds; + int ret; + ret = DoRemoveDirectory(Tcl_FSGetNativePath(pathPtr),recursive, &ds); + if (ret != TCL_OK) { + *errorPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1); + Tcl_DStringFree(&ds); + Tcl_IncrRefCount(*errorPtr); + } + return ret; +} + +static int +DoRemoveDirectory( + CONST char *path, /* Pathname of directory to be removed + * (native). */ + int recursive, /* If non-zero, removes directories that + * are nonempty. Otherwise, will only remove + * empty directories. */ + Tcl_DString *errorPtr) /* If non-NULL, uninitialized or free + * DString filled with UTF-8 name of file + * causing error. */ +{ + OSErr err; + FSSpec fileSpec; + long dirID; + int locked; + Boolean isDirectory; + CInfoPBRec pb; + Str255 fileName; + + + locked = 0; + err = FSpLocationFromPath(strlen(path), path, &fileSpec); + if (err != noErr) { + goto done; + } + + /* + * Since FSpDeleteCompat will delete a file, make sure this isn't + * a file first. + */ + + isDirectory = 1; + FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); + if (isDirectory == 0) { + errno = ENOTDIR; + return TCL_ERROR; + } + + err = FSpDeleteCompat(&fileSpec); + if (err == fLckdErr) { + locked = 1; + FSpRstFLockCompat(&fileSpec); + err = FSpDeleteCompat(&fileSpec); + } + if (err == noErr) { + return TCL_OK; + } + if (err != fBsyErr) { + goto done; + } + + if (recursive == 0) { + /* + * fBsyErr means one of three things: file busy, directory not empty, + * or working directory control block open. Determine if directory + * is empty. If directory is not empty, return EEXIST. + */ + + pb.hFileInfo.ioVRefNum = fileSpec.vRefNum; + pb.hFileInfo.ioDirID = dirID; + pb.hFileInfo.ioNamePtr = (StringPtr) fileName; + pb.hFileInfo.ioFDirIndex = 1; + if (PBGetCatInfoSync(&pb) == noErr) { + err = dupFNErr; /* EEXIST */ + goto done; + } + } + + /* + * DeleteDirectory removes a directory and all its contents, including + * any locked files. There is no interface to get the name of the + * file that caused the error, if an error occurs deleting this tree, + * unless we rewrite DeleteDirectory ourselves. + */ + + err = DeleteDirectory(fileSpec.vRefNum, dirID, NULL); + + done: + if (err != noErr) { + if (errorPtr != NULL) { + Tcl_UtfToExternalDString(NULL, path, -1, errorPtr); + } + if (locked) { + FSpSetFLockCompat(&fileSpec); + } + errno = TclMacOSErrorToPosixError(err); + return TCL_ERROR; + } + return TCL_OK; +} + +/* + *--------------------------------------------------------------------------- + * + * GetFileSpecs -- + * + * Gets FSSpecs for the specified path and its parent directory. + * + * Results: + * The return value is noErr if there was no error getting FSSpecs, + * otherwise it is an error describing the problem. Fills buffers + * with information, as above. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + +static OSErr +GetFileSpecs( + CONST char *path, /* The path to query. */ + FSSpec *pathSpecPtr, /* Filled with information about path. */ + FSSpec *dirSpecPtr, /* Filled with information about path's + * parent directory. */ + Boolean *pathExistsPtr, /* Set to true if path actually exists, + * false if it doesn't or there was an + * error reading the specified path. */ + Boolean *pathIsDirectoryPtr)/* Set to true if path is itself a directory, + * otherwise false. */ +{ + CONST char *dirName; + OSErr err; + int argc; + CONST char **argv; + long d; + Tcl_DString buffer; + + *pathExistsPtr = false; + *pathIsDirectoryPtr = false; + + Tcl_DStringInit(&buffer); + Tcl_SplitPath(path, &argc, &argv); + if (argc == 1) { + dirName = ":"; + } else { + dirName = Tcl_JoinPath(argc - 1, argv, &buffer); + } + err = FSpLocationFromPath(strlen(dirName), dirName, dirSpecPtr); + Tcl_DStringFree(&buffer); + ckfree((char *) argv); + + if (err == noErr) { + err = FSpLocationFromPath(strlen(path), path, pathSpecPtr); + if (err == noErr) { + *pathExistsPtr = true; + err = FSpGetDirectoryID(pathSpecPtr, &d, pathIsDirectoryPtr); + } else if (err == fnfErr) { + err = noErr; + } + } + return err; +} + +/* + *------------------------------------------------------------------------- + * + * FSpGetFLockCompat -- + * + * Determines if there exists a software lock on the specified + * file. The software lock could prevent the file from being + * renamed or moved. + * + * Results: + * Standard macintosh error code. + * + * Side effects: + * None. + * + * + *------------------------------------------------------------------------- + */ + +OSErr +FSpGetFLockCompat( + const FSSpec *specPtr, /* File to query. */ + Boolean *lockedPtr) /* Set to true if file is locked, false + * if it isn't or there was an error reading + * specified file. */ +{ + CInfoPBRec pb; + OSErr err; + + pb.hFileInfo.ioVRefNum = specPtr->vRefNum; + pb.hFileInfo.ioDirID = specPtr->parID; + pb.hFileInfo.ioNamePtr = (StringPtr) specPtr->name; + pb.hFileInfo.ioFDirIndex = 0; + + err = PBGetCatInfoSync(&pb); + if ((err == noErr) && (pb.hFileInfo.ioFlAttrib & 0x01)) { + *lockedPtr = true; + } else { + *lockedPtr = false; + } + return err; +} + +/* + *---------------------------------------------------------------------- + * + * Pstrequal -- + * + * Pascal string compare. + * + * Results: + * Returns 1 if strings equal, 0 otherwise. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +Pstrequal ( + ConstStr255Param stringA, /* Pascal string A */ + ConstStr255Param stringB) /* Pascal string B */ +{ + int i, len; + + len = *stringA; + for (i = 0; i <= len; i++) { + if (*stringA++ != *stringB++) { + return 0; + } + } + return 1; +} + +/* + *---------------------------------------------------------------------- + * + * GetFileFinderAttributes -- + * + * Returns a Tcl_Obj containing the value of a file attribute + * which is part of the FInfo record. Which attribute is controlled + * by objIndex. + * + * Results: + * Returns a standard TCL error. If the return value is TCL_OK, + * the new creator or file type object is put into attributePtrPtr. + * The object will have ref count 0. If there is an error, + * attributePtrPtr is not touched. + * + * Side effects: + * A new object is allocated if the file is valid. + * + *---------------------------------------------------------------------- + */ + +static int +GetFileFinderAttributes( + Tcl_Interp *interp, /* The interp to report errors with. */ + int objIndex, /* The index of the attribute option. */ + Tcl_Obj *fileName, /* The name of the file (UTF-8). */ + Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */ +{ + OSErr err; + FSSpec fileSpec; + FInfo finfo; + CInfoPBRec pb; + CONST char *native; + + native=Tcl_FSGetNativePath(fileName); + err = FSpLLocationFromPath(strlen(native), + native, &fileSpec); + + if (err == noErr) { + if (objIndex != MAC_RSRCLENGTH_ATTRIBUTE) { + err = FSpGetFInfo(&fileSpec, &finfo); + } else { + pb.hFileInfo.ioCompletion = NULL; + pb.hFileInfo.ioNamePtr = fileSpec.name; + pb.hFileInfo.ioVRefNum = fileSpec.vRefNum; + pb.hFileInfo.ioFDirIndex = 0; + pb.hFileInfo.ioDirID = fileSpec.parID; + err = PBGetCatInfo(&pb, 0); + } + } + + if (err == noErr) { + switch (objIndex) { + case MAC_CREATOR_ATTRIBUTE: + *attributePtrPtr = Tcl_NewOSTypeObj(finfo.fdCreator); + break; + case MAC_HIDDEN_ATTRIBUTE: + *attributePtrPtr = Tcl_NewBooleanObj(finfo.fdFlags + & kIsInvisible); + break; + case MAC_TYPE_ATTRIBUTE: + *attributePtrPtr = Tcl_NewOSTypeObj(finfo.fdType); + break; + case MAC_RSRCLENGTH_ATTRIBUTE: + *attributePtrPtr = Tcl_NewLongObj(pb.hFileInfo.ioFlRLgLen); + break; + } + } else if (err == fnfErr) { + long dirID; + Boolean isDirectory = 0; + + err = FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); + if ((err == noErr) && isDirectory) { + if (objIndex == MAC_HIDDEN_ATTRIBUTE) { + *attributePtrPtr = Tcl_NewBooleanObj(0); + } else { + /* Directories only support attribute "-hidden" */ + errno = EISDIR; + Tcl_AppendResult(interp, "invalid attribute: ", + Tcl_PosixError(interp), (char *) NULL); + return TCL_ERROR; + } + } + } + + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "could not read \"", Tcl_GetString(fileName), "\": ", + Tcl_PosixError(interp), (char *) NULL); + return TCL_ERROR; + } + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * GetFileReadOnly -- + * + * Returns a Tcl_Obj containing a Boolean value indicating whether + * or not the file is read-only. The object will have ref count 0. + * This procedure just checks the Finder attributes; it does not + * check AppleShare sharing attributes. + * + * Results: + * Returns a standard TCL error. If the return value is TCL_OK, + * the new creator type object is put into readOnlyPtrPtr. + * If there is an error, readOnlyPtrPtr is not touched. + * + * Side effects: + * A new object is allocated if the file is valid. + * + *---------------------------------------------------------------------- + */ + +static int +GetFileReadOnly( + Tcl_Interp *interp, /* The interp to report errors with. */ + int objIndex, /* The index of the attribute. */ + Tcl_Obj *fileName, /* The name of the file (UTF-8). */ + Tcl_Obj **readOnlyPtrPtr) /* A pointer to return the object with. */ +{ + OSErr err; + FSSpec fileSpec; + CInfoPBRec paramBlock; + CONST char *native; + + native=Tcl_FSGetNativePath(fileName); + err = FSpLLocationFromPath(strlen(native), + native, &fileSpec); + + if (err == noErr) { + if (err == noErr) { + paramBlock.hFileInfo.ioCompletion = NULL; + paramBlock.hFileInfo.ioNamePtr = fileSpec.name; + paramBlock.hFileInfo.ioVRefNum = fileSpec.vRefNum; + paramBlock.hFileInfo.ioFDirIndex = 0; + paramBlock.hFileInfo.ioDirID = fileSpec.parID; + err = PBGetCatInfo(¶mBlock, 0); + if (err == noErr) { + + /* + * For some unknown reason, the Mac does not give + * symbols for the bits in the ioFlAttrib field. + * 1 -> locked. + */ + + *readOnlyPtrPtr = Tcl_NewBooleanObj( + paramBlock.hFileInfo.ioFlAttrib & 1); + } + } + } + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "could not read \"", Tcl_GetString(fileName), "\": ", + Tcl_PosixError(interp), (char *) NULL); + return TCL_ERROR; + } + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * SetFileFinderAttributes -- + * + * Sets the file to the creator or file type given by attributePtr. + * objIndex determines whether the creator or file type is set. + * + * Results: + * Returns a standard TCL error. + * + * Side effects: + * The file's attribute is set. + * + *---------------------------------------------------------------------- + */ + +static int +SetFileFinderAttributes( + Tcl_Interp *interp, /* The interp to report errors with. */ + int objIndex, /* The index of the attribute. */ + Tcl_Obj *fileName, /* The name of the file (UTF-8). */ + Tcl_Obj *attributePtr) /* The command line object. */ +{ + OSErr err; + FSSpec fileSpec; + FInfo finfo; + CInfoPBRec pb; + CONST char *native; + + native=Tcl_FSGetNativePath(fileName); + err = FSpLLocationFromPath(strlen(native), + native, &fileSpec); + + if (err == noErr) { + if (objIndex != MAC_RSRCLENGTH_ATTRIBUTE) { + err = FSpGetFInfo(&fileSpec, &finfo); + } else { + pb.hFileInfo.ioCompletion = NULL; + pb.hFileInfo.ioNamePtr = fileSpec.name; + pb.hFileInfo.ioVRefNum = fileSpec.vRefNum; + pb.hFileInfo.ioFDirIndex = 0; + pb.hFileInfo.ioDirID = fileSpec.parID; + err = PBGetCatInfo(&pb, 0); + } + } + + if (err == noErr) { + switch (objIndex) { + case MAC_CREATOR_ATTRIBUTE: + if (Tcl_GetOSTypeFromObj(interp, attributePtr, + &finfo.fdCreator) != TCL_OK) { + return TCL_ERROR; + } + break; + case MAC_HIDDEN_ATTRIBUTE: { + int hidden; + + if (Tcl_GetBooleanFromObj(interp, attributePtr, &hidden) + != TCL_OK) { + return TCL_ERROR; + } + if (hidden) { + finfo.fdFlags |= kIsInvisible; + } else { + finfo.fdFlags &= ~kIsInvisible; + } + break; + } + case MAC_TYPE_ATTRIBUTE: + if (Tcl_GetOSTypeFromObj(interp, attributePtr, + &finfo.fdType) != TCL_OK) { + return TCL_ERROR; + } + break; + case MAC_RSRCLENGTH_ATTRIBUTE: + { + long newRsrcForkSize; + + if (Tcl_GetLongFromObj(interp, attributePtr, + &newRsrcForkSize) != TCL_OK) { + return TCL_ERROR; + } + if(newRsrcForkSize != pb.hFileInfo.ioFlRLgLen) { + short rf; + /* + * Only setting rsrclength to 0 to strip + * a file's resource fork is supported. + */ + if(newRsrcForkSize != 0) { + Tcl_AppendResult(interp, + "setting nonzero rsrclength not supported", + (char *) NULL); + return TCL_ERROR; + } + + if ((rf = FSpOpenResFile(&fileSpec, fsWrPerm)) >= 0) { + err = SetEOF(rf, 0); + CloseResFile(rf); + } + + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + Tcl_AppendResult(interp, + "could not truncate resource fork of \"", + Tcl_GetString(fileName), "\": ", + Tcl_PosixError(interp), (char *) NULL); + return TCL_ERROR; + } + } + break; + } + } + if (objIndex != MAC_RSRCLENGTH_ATTRIBUTE) { + err = FSpSetFInfo(&fileSpec, &finfo); + } + } else if (err == fnfErr) { + long dirID; + Boolean isDirectory = 0; + + err = FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); + if ((err == noErr) && isDirectory) { + Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); + Tcl_AppendStringsToObj(resultPtr, "cannot set ", + tclpFileAttrStrings[objIndex], ": \"", + Tcl_GetString(fileName), "\" is a directory", (char *) NULL); + return TCL_ERROR; + } + } + + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "could not read \"", Tcl_GetString(fileName), "\": ", + Tcl_PosixError(interp), (char *) NULL); + return TCL_ERROR; + } + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * SetFileReadOnly -- + * + * Sets the file to be read-only according to the Boolean value + * given by hiddenPtr. + * + * Results: + * Returns a standard TCL error. + * + * Side effects: + * The file's attribute is set. + * + *---------------------------------------------------------------------- + */ + +static int +SetFileReadOnly( + Tcl_Interp *interp, /* The interp to report errors with. */ + int objIndex, /* The index of the attribute. */ + Tcl_Obj *fileName, /* The name of the file (UTF-8). */ + Tcl_Obj *readOnlyPtr) /* The command line object. */ +{ + OSErr err; + FSSpec fileSpec; + HParamBlockRec paramBlock; + int hidden; + CONST char *native; + + native=Tcl_FSGetNativePath(fileName); + err = FSpLLocationFromPath(strlen(native), + native, &fileSpec); + + if (err == noErr) { + if (Tcl_GetBooleanFromObj(interp, readOnlyPtr, &hidden) != TCL_OK) { + return TCL_ERROR; + } + + paramBlock.fileParam.ioCompletion = NULL; + paramBlock.fileParam.ioNamePtr = fileSpec.name; + paramBlock.fileParam.ioVRefNum = fileSpec.vRefNum; + paramBlock.fileParam.ioDirID = fileSpec.parID; + if (hidden) { + err = PBHSetFLock(¶mBlock, 0); + } else { + err = PBHRstFLock(¶mBlock, 0); + } + } + + if (err == fnfErr) { + long dirID; + Boolean isDirectory = 0; + err = FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); + if ((err == noErr) && isDirectory) { + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "cannot set a directory to read-only when File Sharing is turned off", + (char *) NULL); + return TCL_ERROR; + } else { + err = fnfErr; + } + } + + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "could not read \"", Tcl_GetString(fileName), "\": ", + Tcl_PosixError(interp), (char *) NULL); + return TCL_ERROR; + } + return TCL_OK; +} + +/* + *--------------------------------------------------------------------------- + * + * TclpObjListVolumes -- + * + * Lists the currently mounted volumes + * + * Results: + * The list of volumes. + * + * Side effects: + * None + * + *--------------------------------------------------------------------------- + */ +Tcl_Obj* +TclpObjListVolumes(void) +{ + HParamBlockRec pb; + Str255 name; + OSErr theError = noErr; + Tcl_Obj *resultPtr, *elemPtr; + short volIndex = 1; + Tcl_DString dstr; + + resultPtr = Tcl_NewObj(); + + /* + * We use two facts: + * 1) The Mac volumes are enumerated by the ioVolIndex parameter of + * the HParamBlockRec. They run through the integers contiguously, + * starting at 1. + * 2) PBHGetVInfoSync returns an error when you ask for a volume index + * that does not exist. + * + */ + + while ( 1 ) { + pb.volumeParam.ioNamePtr = (StringPtr) &name; + pb.volumeParam.ioVolIndex = volIndex; + + theError = PBHGetVInfoSync(&pb); + + if ( theError != noErr ) { + break; + } + + Tcl_ExternalToUtfDString(NULL, (CONST char *)&name[1], name[0], &dstr); + elemPtr = Tcl_NewStringObj(Tcl_DStringValue(&dstr), + Tcl_DStringLength(&dstr)); + Tcl_AppendToObj(elemPtr, ":", 1); + Tcl_ListObjAppendElement(NULL, resultPtr, elemPtr); + + Tcl_DStringFree(&dstr); + + volIndex++; + } + + Tcl_IncrRefCount(resultPtr); + return resultPtr; +} + +/* + *--------------------------------------------------------------------------- + * + * TclpObjNormalizePath -- + * + * This function scans through a path specification and replaces + * it, in place, with a normalized version. On MacOS, this means + * resolving all aliases present in the path and replacing the head of + * pathPtr with the absolute case-sensitive path to the last file or + * directory that could be validated in the path. + * + * Results: + * The new 'nextCheckpoint' value, giving as far as we could + * understand in the path. + * + * Side effects: + * The pathPtr string, which must contain a valid path, is + * possibly modified in place. + * + *--------------------------------------------------------------------------- + */ + +int +TclpObjNormalizePath(interp, pathPtr, nextCheckpoint) + Tcl_Interp *interp; + Tcl_Obj *pathPtr; + int nextCheckpoint; +{ + #define MAXMACFILENAMELEN 31 /* assumed to be < sizeof(StrFileName) */ + + StrFileName fileName; + StringPtr fileNamePtr; + int fileNameLen,newPathLen; + Handle newPathHandle; + OSErr err; + short vRefNum; + long dirID; + Boolean isDirectory; + Boolean wasAlias=FALSE; + FSSpec fileSpec, lastFileSpec; + + Tcl_DString nativeds; + + char cur; + int firstCheckpoint=nextCheckpoint, lastCheckpoint; + int origPathLen; + char *path = Tcl_GetStringFromObj(pathPtr,&origPathLen); + + { + int currDirValid=0; + /* + * check if substring to first ':' after initial + * nextCheckpoint is a valid relative or absolute + * path to a directory, if not we return without + * normalizing anything + */ + + while (1) { + cur = path[nextCheckpoint]; + if (cur == ':' || cur == 0) { + if (cur == ':') { + /* jump over separator */ + nextCheckpoint++; cur = path[nextCheckpoint]; + } + Tcl_UtfToExternalDString(NULL,path,nextCheckpoint,&nativeds); + err = FSpLLocationFromPath(Tcl_DStringLength(&nativeds), + Tcl_DStringValue(&nativeds), + &fileSpec); + Tcl_DStringFree(&nativeds); + if (err == noErr) { + lastFileSpec=fileSpec; + err = ResolveAliasFile(&fileSpec, true, &isDirectory, + &wasAlias); + if (err == noErr) { + err = FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); + currDirValid = ((err == noErr) && isDirectory); + vRefNum = fileSpec.vRefNum; + } + } + break; + } + nextCheckpoint++; + } + + if(!currDirValid) { + /* can't determine root dir, bail out */ + return firstCheckpoint; + } + } + + /* + * Now vRefNum and dirID point to a valid + * directory, so walk the rest of the path + * ( code adapted from FSpLocationFromPath() ) + */ + + lastCheckpoint=nextCheckpoint; + while (1) { + cur = path[nextCheckpoint]; + if (cur == ':' || cur == 0) { + fileNameLen=nextCheckpoint-lastCheckpoint; + fileNamePtr=fileName; + if(fileNameLen==0) { + if (cur == ':') { + /* + * special case for empty dirname i.e. encountered + * a '::' path component: get parent dir of currDir + */ + fileName[0]=2; + strcpy((char *) fileName + 1, "::"); + lastCheckpoint--; + } else { + /* + * empty filename, i.e. want FSSpec for currDir + */ + fileNamePtr=NULL; + } + } else { + Tcl_UtfToExternalDString(NULL,&path[lastCheckpoint], + fileNameLen,&nativeds); + fileNameLen=Tcl_DStringLength(&nativeds); + if(fileNameLen > MAXMACFILENAMELEN) { + err = bdNamErr; + } else { + fileName[0]=fileNameLen; + strncpy((char *) fileName + 1, Tcl_DStringValue(&nativeds), + fileNameLen); + } + Tcl_DStringFree(&nativeds); + } + if(err == noErr) + err=FSMakeFSSpecCompat(vRefNum, dirID, fileNamePtr, &fileSpec); + if(err != noErr) { + if(err != fnfErr) { + /* + * this can occur if trying to get parent of a root + * volume via '::' or when using an illegal + * filename; revert to last checkpoint and stop + * processing path further + */ + err=FSMakeFSSpecCompat(vRefNum, dirID, NULL, &fileSpec); + if(err != noErr) { + /* should never happen, bail out */ + return firstCheckpoint; + } + nextCheckpoint=lastCheckpoint; + cur = path[lastCheckpoint]; + } + break; /* arrived at nonexistent file or dir */ + } else { + /* fileSpec could point to an alias, resolve it */ + lastFileSpec=fileSpec; + err = ResolveAliasFile(&fileSpec, true, &isDirectory, + &wasAlias); + if (err != noErr || !isDirectory) { + break; /* fileSpec doesn't point to a dir */ + } + } + if (cur == 0) break; /* arrived at end of path */ + + /* fileSpec points to possibly nonexisting subdirectory; validate */ + err = FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); + if (err != noErr || !isDirectory) { + break; /* fileSpec doesn't point to existing dir */ + } + vRefNum = fileSpec.vRefNum; + + /* found a new valid subdir in path, continue processing path */ + lastCheckpoint=nextCheckpoint+1; + } + wasAlias=FALSE; + nextCheckpoint++; + } + + if (wasAlias) + fileSpec=lastFileSpec; + + /* + * fileSpec now points to a possibly nonexisting file or dir + * inside a valid dir; get full path name to it + */ + + err=FSpPathFromLocation(&fileSpec, &newPathLen, &newPathHandle); + if(err != noErr) { + return firstCheckpoint; /* should not see any errors here, bail out */ + } + + HLock(newPathHandle); + Tcl_ExternalToUtfDString(NULL,*newPathHandle,newPathLen,&nativeds); + if (cur != 0) { + /* not at end, append remaining path */ + if ( newPathLen==0 || (*(*newPathHandle+(newPathLen-1))!=':' && path[nextCheckpoint] !=':')) { + Tcl_DStringAppend(&nativeds, ":" , 1); + } + Tcl_DStringAppend(&nativeds, &path[nextCheckpoint], + strlen(&path[nextCheckpoint])); + } + DisposeHandle(newPathHandle); + + fileNameLen=Tcl_DStringLength(&nativeds); + Tcl_SetStringObj(pathPtr,Tcl_DStringValue(&nativeds),fileNameLen); + Tcl_DStringFree(&nativeds); + + return nextCheckpoint+(fileNameLen-origPathLen); +} + diff --git a/mac/tclMacFile.c b/mac/tclMacFile.c new file mode 100644 index 0000000..de5f422 --- /dev/null +++ b/mac/tclMacFile.c @@ -0,0 +1,1402 @@ +/* + * tclMacFile.c -- + * + * This file implements the channel drivers for Macintosh + * files. It also comtains Macintosh version of other Tcl + * functions that deal with the file system. + * + * Copyright (c) 1995-1998 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacFile.c,v 1.30 2004/01/29 10:28:22 vincentdarley Exp $ + */ + +/* + * Note: This code eventually needs to support async I/O. In doing this + * we will need to keep track of all current async I/O. If exit to shell + * is called - we shouldn't exit until all asyc I/O completes. + */ + +#include "tclInt.h" +#include "tclPort.h" +#include "tclMacInt.h" +#include <Aliases.h> +#include <Resources.h> +#include <Files.h> +#include <Errors.h> +#include <Processes.h> +#include <Strings.h> +#include <Types.h> +#include <MoreFiles.h> +#include <MoreFilesExtras.h> +#include <FSpCompat.h> + +static int NativeMatchType(Tcl_Obj *tempName, Tcl_GlobTypeData *types, + HFileInfo fileInfo, OSType okType, OSType okCreator); +static OSErr FspLocationFromFsPath _ANSI_ARGS_((Tcl_Obj *pathPtr, + FSSpec* specPtr)); +static OSErr FspLLocationFromFsPath _ANSI_ARGS_((Tcl_Obj *pathPtr, + FSSpec* specPtr)); + +static OSErr CreateAliasFile _ANSI_ARGS_((FSSpec *theAliasFile, FSSpec *targetFile)); + +static OSErr +FspLocationFromFsPath(pathPtr, specPtr) + Tcl_Obj *pathPtr; + FSSpec* specPtr; +{ + CONST char *native = Tcl_FSGetNativePath(pathPtr); + return FSpLocationFromPath(strlen(native), native, specPtr); +} + +static OSErr +FspLLocationFromFsPath(pathPtr, specPtr) + Tcl_Obj *pathPtr; + FSSpec* specPtr; +{ + CONST char *native = Tcl_FSGetNativePath(pathPtr); + return FSpLLocationFromPath(strlen(native), native, specPtr); +} + + +/* + *---------------------------------------------------------------------- + * + * TclpFindExecutable -- + * + * This procedure computes the absolute path name of the current + * application, given its argv[0] value. However, this + * implementation doesn't need the argv[0] value. NULL + * may be passed in its place. + * + * Results: + * None. + * + * Side effects: + * The variable tclExecutableName gets filled in with the file + * name for the application, if we figured it out. If we couldn't + * figure it out, Tcl_FindExecutable is set to NULL. + * + *---------------------------------------------------------------------- + */ + +char * +TclpFindExecutable( + CONST char *argv0) /* The value of the application's argv[0]. */ +{ + ProcessSerialNumber psn; + ProcessInfoRec info; + Str63 appName; + FSSpec fileSpec; + int pathLength; + Handle pathName = NULL; + OSErr err; + Tcl_DString ds; + + TclInitSubsystems(argv0); + + GetCurrentProcess(&psn); + info.processInfoLength = sizeof(ProcessInfoRec); + info.processName = appName; + info.processAppSpec = &fileSpec; + GetProcessInformation(&psn, &info); + + if (tclExecutableName != NULL) { + ckfree(tclExecutableName); + tclExecutableName = NULL; + } + + err = FSpPathFromLocation(&fileSpec, &pathLength, &pathName); + HLock(pathName); + Tcl_ExternalToUtfDString(NULL, *pathName, pathLength, &ds); + HUnlock(pathName); + DisposeHandle(pathName); + + tclExecutableName = (char *) ckalloc((unsigned) + (Tcl_DStringLength(&ds) + 1)); + strcpy(tclExecutableName, Tcl_DStringValue(&ds)); + Tcl_DStringFree(&ds); + return tclExecutableName; +} + +/* + *---------------------------------------------------------------------- + * + * TclpMatchInDirectory -- + * + * This routine is used by the globbing code to search a + * directory for all files which match a given pattern. + * + * Results: + * + * The return value is a standard Tcl result indicating whether an + * error occurred in globbing. Errors are left in interp, good + * results are lappended to resultPtr (which must be a valid object) + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- */ + +int +TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types) + Tcl_Interp *interp; /* Interpreter to receive errors. */ + Tcl_Obj *resultPtr; /* List object to lappend results. */ + Tcl_Obj *pathPtr; /* Contains path to directory to search. */ + CONST char *pattern; /* Pattern to match against. NULL or empty + * means pathPtr is actually a single file + * to check. */ + Tcl_GlobTypeData *types; /* Object containing list of acceptable types. + * May be NULL. In particular the directory + * flag is very important. */ +{ + OSType okType = 0; + OSType okCreator = 0; + Tcl_Obj *fileNamePtr; + + if (types != NULL && types->type == TCL_GLOB_TYPE_MOUNT) { + /* The native filesystem never adds mounts */ + return TCL_OK; + } + + fileNamePtr = Tcl_FSGetTranslatedPath(interp, pathPtr); + if (fileNamePtr == NULL) { + return TCL_ERROR; + } + + if (types != NULL) { + if (types->macType != NULL) { + Tcl_GetOSTypeFromObj(NULL, types->macType, &okType); + } + if (types->macCreator != NULL) { + Tcl_GetOSTypeFromObj(NULL, types->macCreator, &okCreator); + } + } + + if (pattern == NULL || (*pattern == '\0')) { + /* Match a single file directly */ + Tcl_StatBuf buf; + CInfoPBRec paramBlock; + FSSpec fileSpec; + + if (TclpObjLstat(fileNamePtr, &buf) != 0) { + /* File doesn't exist */ + Tcl_DecrRefCount(fileNamePtr); + return TCL_OK; + } + + if (FspLLocationFromFsPath(fileNamePtr, &fileSpec) == noErr) { + paramBlock.hFileInfo.ioCompletion = NULL; + paramBlock.hFileInfo.ioNamePtr = fileSpec.name; + paramBlock.hFileInfo.ioVRefNum = fileSpec.vRefNum; + paramBlock.hFileInfo.ioFDirIndex = 0; + paramBlock.hFileInfo.ioDirID = fileSpec.parID; + + PBGetCatInfo(¶mBlock, 0); + } + + if (NativeMatchType(fileNamePtr, types, paramBlock.hFileInfo, + okType, okCreator)) { + int fnameLen; + char *fname = Tcl_GetStringFromObj(pathPtr,&fnameLen); + if ((fnameLen > 1) && (strchr(fname+1, ':') == NULL)) { + Tcl_ListObjAppendElement(interp, resultPtr, + Tcl_NewStringObj(fname+1, fnameLen-1)); + } else { + Tcl_ListObjAppendElement(interp, resultPtr, pathPtr); + } + } + Tcl_DecrRefCount(fileNamePtr); + return TCL_OK; + } else { + char *fname; + int fnameLen, result = TCL_OK; + int baseLength; + CInfoPBRec pb; + OSErr err; + FSSpec dirSpec; + Boolean isDirectory; + long dirID; + short itemIndex; + Str255 fileName; + Tcl_DString fileString; + Tcl_DString dsOrig; + + Tcl_DStringInit(&dsOrig); + Tcl_DStringAppend(&dsOrig, Tcl_GetString(fileNamePtr), -1); + baseLength = Tcl_DStringLength(&dsOrig); + + /* + * Make sure that the directory part of the name really is a + * directory. + */ + + Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&dsOrig), + Tcl_DStringLength(&dsOrig), &fileString); + + err = FSpLocationFromPath(Tcl_DStringLength(&fileString), + Tcl_DStringValue(&fileString), &dirSpec); + Tcl_DStringFree(&fileString); + if (err == noErr) { + err = FSpGetDirectoryID(&dirSpec, &dirID, &isDirectory); + } + + if ((err != noErr) || !isDirectory) { + /* + * Check if we had a relative path (unix style relative path + * compatibility for glob) + */ + Tcl_DStringFree(&dsOrig); + Tcl_DStringAppend(&dsOrig, ":", 1); + Tcl_DStringAppend(&dsOrig, Tcl_GetString(fileNamePtr), -1); + baseLength = Tcl_DStringLength(&dsOrig); + + Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&dsOrig), + Tcl_DStringLength(&dsOrig), &fileString); + + err = FSpLocationFromPath(Tcl_DStringLength(&fileString), + Tcl_DStringValue(&fileString), &dirSpec); + Tcl_DStringFree(&fileString); + if (err == noErr) { + err = FSpGetDirectoryID(&dirSpec, &dirID, &isDirectory); + } + + if ((err != noErr) || !isDirectory) { + Tcl_DStringFree(&dsOrig); + Tcl_DecrRefCount(fileNamePtr); + return TCL_OK; + } + } + + /* Make sure we have a trailing directory delimiter */ + if (Tcl_DStringValue(&dsOrig)[baseLength-1] != ':') { + Tcl_DStringAppend(&dsOrig, ":", 1); + baseLength++; + } + + /* + * Now open the directory for reading and iterate over the contents. + */ + + pb.hFileInfo.ioVRefNum = dirSpec.vRefNum; + pb.hFileInfo.ioDirID = dirID; + pb.hFileInfo.ioNamePtr = (StringPtr) fileName; + pb.hFileInfo.ioFDirIndex = itemIndex = 1; + + while (1) { + pb.hFileInfo.ioFDirIndex = itemIndex; + pb.hFileInfo.ioDirID = dirID; + err = PBGetCatInfoSync(&pb); + if (err != noErr) { + break; + } + + /* + * Now check to see if the file matches. + */ + + Tcl_ExternalToUtfDString(NULL, (char *) fileName + 1, fileName[0], + &fileString); + if (Tcl_StringMatch(Tcl_DStringValue(&fileString), pattern)) { + Tcl_Obj *tempName; + Tcl_DStringSetLength(&dsOrig, baseLength); + Tcl_DStringAppend(&dsOrig, Tcl_DStringValue(&fileString), -1); + fname = Tcl_DStringValue(&dsOrig); + fnameLen = Tcl_DStringLength(&dsOrig); + + /* + * We use this tempName in calls to check the file's + * type below. We may also use it for the result. + */ + tempName = Tcl_NewStringObj(fname, fnameLen); + Tcl_IncrRefCount(tempName); + + /* Is the type acceptable? */ + if (NativeMatchType(tempName, types, pb.hFileInfo, + okType, okCreator)) { + if ((fnameLen > 1) && (strchr(fname+1, ':') == NULL)) { + Tcl_ListObjAppendElement(interp, resultPtr, + Tcl_NewStringObj(fname+1, fnameLen-1)); + } else { + Tcl_ListObjAppendElement(interp, resultPtr, tempName); + } + } + /* + * This will free the object, unless it was inserted in + * the result list above. + */ + Tcl_DecrRefCount(tempName); + } + Tcl_DStringFree(&fileString); + itemIndex++; + } + + Tcl_DStringFree(&dsOrig); + Tcl_DecrRefCount(fileNamePtr); + return result; + } +} + +static int +NativeMatchType( + Tcl_Obj *tempName, /* Path to check */ + Tcl_GlobTypeData *types, /* Type description to match against */ + HFileInfo fileInfo, /* MacOS file info */ + OSType okType, /* Acceptable MacOS type, or zero */ + OSType okCreator) /* Acceptable MacOS creator, or zero */ +{ + if (types == NULL) { + /* If invisible, don't return the file */ + if (fileInfo.ioFlFndrInfo.fdFlags & kIsInvisible) { + return 0; + } + } else { + Tcl_StatBuf buf; + + if (fileInfo.ioFlFndrInfo.fdFlags & kIsInvisible) { + /* If invisible */ + if ((types->perm == 0) || + !(types->perm & TCL_GLOB_PERM_HIDDEN)) { + return 0; + } + } else { + /* Visible */ + if (types->perm & TCL_GLOB_PERM_HIDDEN) { + return 0; + } + } + if (types->perm != 0) { + if ( + ((types->perm & TCL_GLOB_PERM_RONLY) && + !(fileInfo.ioFlAttrib & 1)) || + ((types->perm & TCL_GLOB_PERM_R) && + (TclpObjAccess(tempName, R_OK) != 0)) || + ((types->perm & TCL_GLOB_PERM_W) && + (TclpObjAccess(tempName, W_OK) != 0)) || + ((types->perm & TCL_GLOB_PERM_X) && + (TclpObjAccess(tempName, X_OK) != 0)) + ) { + return 0; + } + } + if (types->type != 0) { + if (TclpObjStat(tempName, &buf) != 0) { + /* Posix error occurred */ + return 0; + } + /* + * In order bcdpfls as in 'find -t' + */ + if ( + ((types->type & TCL_GLOB_TYPE_BLOCK) && + S_ISBLK(buf.st_mode)) || + ((types->type & TCL_GLOB_TYPE_CHAR) && + S_ISCHR(buf.st_mode)) || + ((types->type & TCL_GLOB_TYPE_DIR) && + S_ISDIR(buf.st_mode)) || + ((types->type & TCL_GLOB_TYPE_PIPE) && + S_ISFIFO(buf.st_mode)) || + ((types->type & TCL_GLOB_TYPE_FILE) && + S_ISREG(buf.st_mode)) +#ifdef S_ISSOCK + || ((types->type & TCL_GLOB_TYPE_SOCK) && + S_ISSOCK(buf.st_mode)) +#endif + ) { + /* Do nothing -- this file is ok */ + } else { + int typeOk = 0; +#ifdef S_ISLNK + if (types->type & TCL_GLOB_TYPE_LINK) { + if (TclpObjLstat(tempName, &buf) == 0) { + if (S_ISLNK(buf.st_mode)) { + typeOk = 1; + } + } + } +#endif + if (typeOk == 0) { + return 0; + } + } + } + if (((okType != 0) && (okType != + fileInfo.ioFlFndrInfo.fdType)) || + ((okCreator != 0) && (okCreator != + fileInfo.ioFlFndrInfo.fdCreator))) { + return 0; + } + } + return 1; +} + + +/* + *---------------------------------------------------------------------- + * + * TclpObjAccess -- + * + * This function replaces the library version of access(). + * + * Results: + * See access documentation. + * + * Side effects: + * See access documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclpObjAccess(pathPtr, mode) + Tcl_Obj *pathPtr; + int mode; +{ + HFileInfo fpb; + HVolumeParam vpb; + OSErr err; + FSSpec fileSpec; + Boolean isDirectory; + long dirID; + int full_mode = 0; + + err = FspLLocationFromFsPath(pathPtr, &fileSpec); + + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + return -1; + } + + /* + * Fill the fpb & vpb struct up with info about file or directory. + */ + FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); + vpb.ioVRefNum = fpb.ioVRefNum = fileSpec.vRefNum; + vpb.ioNamePtr = fpb.ioNamePtr = fileSpec.name; + if (isDirectory) { + fpb.ioDirID = fileSpec.parID; + } else { + fpb.ioDirID = dirID; + } + + fpb.ioFDirIndex = 0; + err = PBGetCatInfoSync((CInfoPBPtr)&fpb); + if (err == noErr) { + vpb.ioVolIndex = 0; + err = PBHGetVInfoSync((HParmBlkPtr)&vpb); + if (err == noErr) { + /* + * Use the Volume Info & File Info to determine + * access information. If we have got this far + * we know the directory is searchable or the file + * exists. (We have F_OK) + */ + + /* + * Check to see if the volume is hardware or + * software locked. If so we arn't W_OK. + */ + if (mode & W_OK) { + if ((vpb.ioVAtrb & 0x0080) || (vpb.ioVAtrb & 0x8000)) { + errno = EROFS; + return -1; + } + if (fpb.ioFlAttrib & 0x01) { + errno = EACCES; + return -1; + } + } + + /* + * Directories are always searchable and executable. But only + * files of type 'APPL' are executable. + */ + if (!(fpb.ioFlAttrib & 0x10) && (mode & X_OK) + && (fpb.ioFlFndrInfo.fdType != 'APPL')) { + return -1; + } + } + } + + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + return -1; + } + + return 0; +} + +/* + *---------------------------------------------------------------------- + * + * TclpObjChdir -- + * + * This function replaces the library version of chdir(). + * + * Results: + * See chdir() documentation. + * + * Side effects: + * See chdir() documentation. Also the cache maintained used by + * Tcl_FSGetCwd() is deallocated and set to NULL. + * + *---------------------------------------------------------------------- + */ + +int +TclpObjChdir(pathPtr) + Tcl_Obj *pathPtr; +{ + FSSpec spec; + OSErr err; + Boolean isFolder; + long dirID; + + err = FspLocationFromFsPath(pathPtr, &spec); + + if (err != noErr) { + errno = ENOENT; + return -1; + } + + err = FSpGetDirectoryID(&spec, &dirID, &isFolder); + if (err != noErr) { + errno = ENOENT; + return -1; + } + + if (isFolder != true) { + errno = ENOTDIR; + return -1; + } + + err = FSpSetDefaultDir(&spec); + if (err != noErr) { + switch (err) { + case afpAccessDenied: + errno = EACCES; + break; + default: + errno = ENOENT; + } + return -1; + } + + return 0; +} + +/* + *--------------------------------------------------------------------------- + * + * TclpGetNativeCwd -- + * + * This function replaces the library version of getcwd(). + * + * Results: + * The input and output are filesystem paths in native form. The + * result is either the given clientData, if the working directory + * hasn't changed, or a new clientData (owned by our caller), + * giving the new native path, or NULL if the current directory + * could not be determined. If NULL is returned, the caller can + * examine the standard posix error codes to determine the cause of + * the problem. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +ClientData +TclpGetNativeCwd(clientData) + ClientData clientData; +{ + FSSpec theSpec; + int length; + Handle pathHandle = NULL; + OSErr err; + + err = FSpGetDefaultDir(&theSpec); + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + return NULL; + } + err = FSpPathFromLocation(&theSpec, &length, &pathHandle); + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + return NULL; + } + + if ((clientData != NULL) + && strcmp((CONST char*)(*pathHandle), (CONST char*)clientData) == 0) { + /* No change to pwd */ + DisposeHandle(pathHandle); + return clientData; + } else { + char *newCd; + + HLock(pathHandle); + newCd = (char *) ckalloc((unsigned) + (strlen((CONST char*)(*pathHandle)) + 1)); + strcpy(newCd, (CONST char*)(*pathHandle)); + HUnlock(pathHandle); + DisposeHandle(pathHandle); + return (ClientData) newCd; + } +} + +/* + *---------------------------------------------------------------------- + * + * TclpGetCwd -- + * + * This function replaces the library version of getcwd(). + * (Obsolete function, only retained for old extensions which + * may call it directly). + * + * Results: + * The result is a pointer to a string specifying the current + * directory, or NULL if the current directory could not be + * determined. If NULL is returned, an error message is left in the + * interp's result. Storage for the result string is allocated in + * bufferPtr; the caller must call Tcl_DStringFree() when the result + * is no longer needed. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +CONST char * +TclpGetCwd( + Tcl_Interp *interp, /* If non-NULL, used for error reporting. */ + Tcl_DString *bufferPtr) /* Uninitialized or free DString filled + * with name of current directory. */ +{ + FSSpec theSpec; + int length; + Handle pathHandle = NULL; + + if (FSpGetDefaultDir(&theSpec) != noErr) { + if (interp != NULL) { + Tcl_SetResult(interp, "error getting working directory name", + TCL_STATIC); + } + return NULL; + } + if (FSpPathFromLocation(&theSpec, &length, &pathHandle) != noErr) { + if (interp != NULL) { + Tcl_SetResult(interp, "error getting working directory name", + TCL_STATIC); + } + return NULL; + } + HLock(pathHandle); + Tcl_ExternalToUtfDString(NULL, *pathHandle, length, bufferPtr); + HUnlock(pathHandle); + DisposeHandle(pathHandle); + + return Tcl_DStringValue(bufferPtr); +} + +/* + *---------------------------------------------------------------------- + * + * TclpReadlink -- + * + * This function replaces the library version of readlink(). + * + * Results: + * The result is a pointer to a string specifying the contents + * of the symbolic link given by 'path', or NULL if the symbolic + * link could not be read. Storage for the result string is + * allocated in bufferPtr; the caller must call Tcl_DStringFree() + * when the result is no longer needed. + * + * Side effects: + * See readlink() documentation. + * + *--------------------------------------------------------------------------- + */ + +char * +TclpReadlink( + CONST char *path, /* Path of file to readlink (UTF-8). */ + Tcl_DString *linkPtr) /* Uninitialized or free DString filled + * with contents of link (UTF-8). */ +{ + HFileInfo fpb; + OSErr err; + FSSpec fileSpec; + Boolean isDirectory; + Boolean wasAlias; + long dirID; + char fileName[257]; + char *end; + Handle theString = NULL; + int pathSize; + Tcl_DString ds; + + Tcl_UtfToExternalDString(NULL, path, -1, &ds); + + /* + * Remove ending colons if they exist. + */ + + while ((Tcl_DStringLength(&ds) != 0) + && (Tcl_DStringValue(&ds)[Tcl_DStringLength(&ds) - 1] == ':')) { + Tcl_DStringSetLength(&ds, Tcl_DStringLength(&ds) - 1); + } + + end = strrchr(Tcl_DStringValue(&ds), ':'); + if (end == NULL ) { + strcpy(fileName + 1, Tcl_DStringValue(&ds)); + } else { + strcpy(fileName + 1, end + 1); + Tcl_DStringSetLength(&ds, end + 1 - Tcl_DStringValue(&ds)); + } + fileName[0] = (char) strlen(fileName + 1); + + /* + * Create the file spec for the directory of the file + * we want to look at. + */ + + if (end != NULL) { + err = FSpLocationFromPath(Tcl_DStringLength(&ds), + Tcl_DStringValue(&ds), &fileSpec); + if (err != noErr) { + Tcl_DStringFree(&ds); + errno = EINVAL; + return NULL; + } + } else { + FSMakeFSSpecCompat(0, 0, NULL, &fileSpec); + } + Tcl_DStringFree(&ds); + + /* + * Fill the fpb struct up with info about file or directory. + */ + + FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); + fpb.ioVRefNum = fileSpec.vRefNum; + fpb.ioDirID = dirID; + fpb.ioNamePtr = (StringPtr) fileName; + + fpb.ioFDirIndex = 0; + err = PBGetCatInfoSync((CInfoPBPtr)&fpb); + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + return NULL; + } else { + if (fpb.ioFlAttrib & 0x10) { + errno = EINVAL; + return NULL; + } else { + if (fpb.ioFlFndrInfo.fdFlags & 0x8000) { + /* + * The file is a link! + */ + } else { + errno = EINVAL; + return NULL; + } + } + } + + /* + * If we are here it's really a link - now find out + * where it points to. + */ + err = FSMakeFSSpecCompat(fileSpec.vRefNum, dirID, (StringPtr) fileName, + &fileSpec); + if (err == noErr) { + err = ResolveAliasFile(&fileSpec, true, &isDirectory, &wasAlias); + } + if ((err == fnfErr) || wasAlias) { + err = FSpPathFromLocation(&fileSpec, &pathSize, &theString); + if (err != noErr) { + DisposeHandle(theString); + errno = ENAMETOOLONG; + return NULL; + } + } else { + errno = EINVAL; + return NULL; + } + + Tcl_ExternalToUtfDString(NULL, *theString, pathSize, linkPtr); + DisposeHandle(theString); + + return Tcl_DStringValue(linkPtr); +} + +static int +TclpObjStatAlias _ANSI_ARGS_((Tcl_Obj *pathPtr, Tcl_StatBuf *bufPtr, + Boolean resolveLink)); + + +/* + *---------------------------------------------------------------------- + * + * TclpObjLstat -- + * + * This function replaces the library version of lstat(). + * + * Results: + * See lstat() documentation. + * + * Side effects: + * See lstat() documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclpObjLstat(pathPtr, buf) + Tcl_Obj *pathPtr; + Tcl_StatBuf *buf; +{ + return TclpObjStatAlias(pathPtr, buf, FALSE); +} + +/* + *---------------------------------------------------------------------- + * + * TclpObjStat -- + * + * This function replaces the library version of stat(). + * + * Results: + * See stat() documentation. + * + * Side effects: + * See stat() documentation. + * + *---------------------------------------------------------------------- + */ + +int +TclpObjStat(pathPtr, bufPtr) + Tcl_Obj *pathPtr; + Tcl_StatBuf *bufPtr; +{ + return TclpObjStatAlias(pathPtr, bufPtr, TRUE); +} + + +static int +TclpObjStatAlias (Tcl_Obj *pathPtr, Tcl_StatBuf *bufPtr, Boolean resolveLink) +{ + HFileInfo fpb; + HVolumeParam vpb; + OSErr err; + FSSpec fileSpec; + Boolean isDirectory; + long dirID; + + if (resolveLink) + err = FspLocationFromFsPath(pathPtr, &fileSpec); + else + err = FspLLocationFromFsPath(pathPtr, &fileSpec); + + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + return -1; + } + + /* + * Fill the fpb & vpb struct up with info about file or directory. + */ + + FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory); + vpb.ioVRefNum = fpb.ioVRefNum = fileSpec.vRefNum; + vpb.ioNamePtr = fpb.ioNamePtr = fileSpec.name; + if (isDirectory) { + fpb.ioDirID = fileSpec.parID; + } else { + fpb.ioDirID = dirID; + } + + fpb.ioFDirIndex = 0; + err = PBGetCatInfoSync((CInfoPBPtr)&fpb); + if (err == noErr) { + vpb.ioVolIndex = 0; + err = PBHGetVInfoSync((HParmBlkPtr)&vpb); + if (err == noErr && bufPtr != NULL) { + /* + * Files are always readable by everyone. + */ + + bufPtr->st_mode = S_IRUSR | S_IRGRP | S_IROTH; + + /* + * Use the Volume Info & File Info to fill out stat buf. + */ + if (fpb.ioFlAttrib & 0x10) { + bufPtr->st_mode |= S_IFDIR; + bufPtr->st_nlink = 2; + } else { + bufPtr->st_nlink = 1; + if (fpb.ioFlFndrInfo.fdFlags & 0x8000) { + bufPtr->st_mode |= S_IFLNK; + } else { + bufPtr->st_mode |= S_IFREG; + } + } + if ((fpb.ioFlAttrib & 0x10) || (fpb.ioFlFndrInfo.fdType == 'APPL')) { + /* + * Directories and applications are executable by everyone. + */ + + bufPtr->st_mode |= S_IXUSR | S_IXGRP | S_IXOTH; + } + if ((fpb.ioFlAttrib & 0x01) == 0){ + /* + * If not locked, then everyone has write acces. + */ + + bufPtr->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; + } + bufPtr->st_ino = fpb.ioDirID; + bufPtr->st_dev = fpb.ioVRefNum; + bufPtr->st_uid = -1; + bufPtr->st_gid = -1; + bufPtr->st_rdev = 0; + bufPtr->st_size = fpb.ioFlLgLen; + bufPtr->st_blksize = vpb.ioVAlBlkSiz; + bufPtr->st_blocks = (bufPtr->st_size + bufPtr->st_blksize - 1) + / bufPtr->st_blksize; + + /* + * The times returned by the Mac file system are in the + * local time zone. We convert them to GMT so that the + * epoch starts from GMT. This is also consistent with + * what is returned from "clock seconds". + */ + + bufPtr->st_atime = bufPtr->st_mtime = fpb.ioFlMdDat + - TclpGetGMTOffset() + tcl_mac_epoch_offset; + bufPtr->st_ctime = fpb.ioFlCrDat - TclpGetGMTOffset() + + tcl_mac_epoch_offset; + } + } + + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + } + + return (err == noErr ? 0 : -1); +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_WaitPid -- + * + * Fakes a call to wait pid. + * + * Results: + * Always returns -1. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_Pid +Tcl_WaitPid( + Tcl_Pid pid, + int *statPtr, + int options) +{ + return (Tcl_Pid) -1; +} + +/* + *---------------------------------------------------------------------- + * + * TclMacFOpenHack -- + * + * This function replaces fopen. It supports paths with alises. + * Note, remember to undefine the fopen macro! + * + * Results: + * See fopen documentation. + * + * Side effects: + * See fopen documentation. + * + *---------------------------------------------------------------------- + */ + +#undef fopen +FILE * +TclMacFOpenHack( + CONST char *path, + CONST char *mode) +{ + OSErr err; + FSSpec fileSpec; + Handle pathString = NULL; + int size; + FILE * f; + + err = FSpLocationFromPath(strlen(path), path, &fileSpec); + if ((err != noErr) && (err != fnfErr)) { + return NULL; + } + err = FSpPathFromLocation(&fileSpec, &size, &pathString); + if ((err != noErr) && (err != fnfErr)) { + return NULL; + } + + HLock(pathString); + f = fopen(*pathString, mode); + HUnlock(pathString); + DisposeHandle(pathString); + return f; +} + +/* + *--------------------------------------------------------------------------- + * + * TclpGetUserHome -- + * + * This function takes the specified user name and finds their + * home directory. + * + * Results: + * The result is a pointer to a string specifying the user's home + * directory, or NULL if the user's home directory could not be + * determined. Storage for the result string is allocated in + * bufferPtr; the caller must call Tcl_DStringFree() when the result + * is no longer needed. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +char * +TclpGetUserHome(name, bufferPtr) + CONST char *name; /* User name for desired home directory. */ + Tcl_DString *bufferPtr; /* Uninitialized or free DString filled + * with name of user's home directory. */ +{ + return NULL; +} + +/* + *---------------------------------------------------------------------- + * + * TclMacOSErrorToPosixError -- + * + * Given a Macintosh OSErr return the appropiate POSIX error. + * + * Results: + * A Posix error. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TclMacOSErrorToPosixError( + int error) /* A Macintosh error. */ +{ + switch (error) { + case noErr: + return 0; + case bdNamErr: + return ENAMETOOLONG; + case afpObjectTypeErr: + return ENOTDIR; + case fnfErr: + case dirNFErr: + return ENOENT; + case dupFNErr: + return EEXIST; + case dirFulErr: + case dskFulErr: + return ENOSPC; + case fBsyErr: + return EBUSY; + case tmfoErr: + return ENFILE; + case fLckdErr: + case permErr: + case afpAccessDenied: + return EACCES; + case wPrErr: + case vLckdErr: + return EROFS; + case badMovErr: + return EINVAL; + case diffVolErr: + return EXDEV; + default: + return EINVAL; + } +} + +int +TclMacChmod( + CONST char *path, + int mode) +{ + HParamBlockRec hpb; + OSErr err; + Str255 pathName; + strcpy((char *) pathName + 1, path); + pathName[0] = strlen(path); + hpb.fileParam.ioNamePtr = pathName; + hpb.fileParam.ioVRefNum = 0; + hpb.fileParam.ioDirID = 0; + + if (mode & 0200) { + err = PBHRstFLockSync(&hpb); + } else { + err = PBHSetFLockSync(&hpb); + } + + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + return -1; + } + + return 0; +} + + +/* + *---------------------------------------------------------------------- + * + * TclpTempFileName -- + * + * This function returns a unique filename. + * + * Results: + * Returns a valid Tcl_Obj* with refCount 0, or NULL on failure. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_Obj* +TclpTempFileName() +{ + char fileName[L_tmpnam]; + + if (tmpnam(fileName) == NULL) { /* INTL: Native. */ + return NULL; + } + + return TclpNativeToNormalized((ClientData) fileName); +} + +#ifdef S_IFLNK + +Tcl_Obj* +TclpObjLink(pathPtr, toPtr, linkAction) + Tcl_Obj *pathPtr; + Tcl_Obj *toPtr; + int linkAction; +{ + Tcl_Obj* link = NULL; + + if (toPtr != NULL) { + if (TclpObjAccess(pathPtr, F_OK) != -1) { + /* src exists */ + errno = EEXIST; + return NULL; + } + if (TclpObjAccess(toPtr, F_OK) == -1) { + /* target doesn't exist */ + errno = ENOENT; + return NULL; + } + + if (linkAction & TCL_CREATE_SYMBOLIC_LINK) { + /* Needs to create a new link */ + FSSpec spec; + FSSpec linkSpec; + OSErr err; + CONST char *path; + + err = FspLocationFromFsPath(toPtr, &spec); + if (err != noErr) { + errno = ENOENT; + return NULL; + } + + path = Tcl_FSGetNativePath(pathPtr); + err = FSpLocationFromPath(strlen(path), path, &linkSpec); + if (err == noErr) { + err = dupFNErr; /* EEXIST. */ + } else { + err = CreateAliasFile(&linkSpec, &spec); + } + if (err != noErr) { + errno = TclMacOSErrorToPosixError(err); + return NULL; + } + return toPtr; + } else { + errno = ENODEV; + return NULL; + } + } else { + Tcl_DString ds; + Tcl_Obj *transPtr = Tcl_FSGetTranslatedPath(NULL, pathPtr); + if (transPtr == NULL) { + return NULL; + } + if (TclpReadlink(Tcl_GetString(transPtr), &ds) != NULL) { + link = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1); + Tcl_IncrRefCount(link); + Tcl_DStringFree(&ds); + } + Tcl_DecrRefCount(transPtr); + } + return link; +} + +#endif + + +/* + *--------------------------------------------------------------------------- + * + * TclpFilesystemPathType -- + * + * This function is part of the native filesystem support, and + * returns the path type of the given path. Right now it simply + * returns NULL. In the future it could return specific path + * types, like 'HFS', 'HFS+', 'nfs', 'samba', 'FAT32', etc. + * + * Results: + * NULL at present. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ +Tcl_Obj* +TclpFilesystemPathType(pathPtr) + Tcl_Obj* pathPtr; +{ + /* All native paths are of the same type */ + return NULL; +} + +/* + *--------------------------------------------------------------------------- + * + * TclpUtime -- + * + * Set the modification date for a file. + * + * Results: + * 0 on success, -1 on error. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ +int +TclpUtime(pathPtr, tval) + Tcl_Obj *pathPtr; /* File to modify */ + struct utimbuf *tval; /* New modification date structure */ +{ + long gmt_offset=TclpGetGMTOffset(); + struct utimbuf local_tval; + local_tval.actime=tval->actime+gmt_offset; + local_tval.modtime=tval->modtime+gmt_offset; + return utime(Tcl_FSGetNativePath(Tcl_FSGetNormalizedPath(NULL,pathPtr)), + &local_tval); +} + +/* + *--------------------------------------------------------------------------- + * + * CreateAliasFile -- + * + * Creates an alias file located at aliasDest referring to the targetFile. + * + * Results: + * 0 on success, OS error code on error. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ +static OSErr +CreateAliasFile(FSSpec *theAliasFile, FSSpec *targetFile) +{ + CInfoPBRec cat; + FInfo fndrInfo; + AliasHandle theAlias; + short saveRef, rsrc = -1; + OSErr err; + + saveRef = CurResFile(); + /* set up the Finder information record for the alias file */ + cat.dirInfo.ioNamePtr = targetFile->name; + cat.dirInfo.ioVRefNum = targetFile->vRefNum; + cat.dirInfo.ioFDirIndex = 0; + cat.dirInfo.ioDrDirID = targetFile->parID; + err = PBGetCatInfoSync(&cat); + if (err != noErr) goto bail; + if ((cat.dirInfo.ioFlAttrib & 16) == 0) { + /* file alias */ + switch (cat.hFileInfo.ioFlFndrInfo.fdType) { + case 'APPL': fndrInfo.fdType = kApplicationAliasType; break; + case 'APPC': fndrInfo.fdType = kApplicationCPAliasType; break; + case 'APPD': fndrInfo.fdType = kApplicationDAAliasType; break; + default: fndrInfo.fdType = cat.hFileInfo.ioFlFndrInfo.fdType; break; + } + fndrInfo.fdCreator = cat.hFileInfo.ioFlFndrInfo.fdCreator; + } else { + /* folder alias */ + fndrInfo.fdType = kContainerFolderAliasType; + fndrInfo.fdCreator = 'MACS'; + } + fndrInfo.fdFlags = kIsAlias; + fndrInfo.fdLocation.v = 0; + fndrInfo.fdLocation.h = 0; + fndrInfo.fdFldr = 0; + /* create new file and set the file information */ + FSpCreateResFile( theAliasFile, fndrInfo.fdCreator, fndrInfo.fdType, smSystemScript); + if ((err = ResError()) != noErr) goto bail; + err = FSpSetFInfo( theAliasFile, &fndrInfo); + if (err != noErr) goto bail; + /* save the alias resource */ + rsrc = FSpOpenResFile(theAliasFile, fsRdWrPerm); + if (rsrc == -1) { err = ResError(); goto bail; } + UseResFile(rsrc); + err = NewAlias(theAliasFile, targetFile, &theAlias); + if (err != noErr) goto bail; + AddResource((Handle) theAlias, rAliasType, 0, theAliasFile->name); + if ((err = ResError()) != noErr) goto bail; + CloseResFile(rsrc); + rsrc = -1; + /* done */ + bail: + if (rsrc != -1) CloseResFile(rsrc); + UseResFile(saveRef); + return err; +} diff --git a/mac/tclMacInit.c b/mac/tclMacInit.c new file mode 100644 index 0000000..f132577 --- /dev/null +++ b/mac/tclMacInit.c @@ -0,0 +1,802 @@ +/* + * tclMacInit.c -- + * + * Contains the Mac-specific interpreter initialization functions. + * + * Copyright (c) 1995-1998 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacInit.c,v 1.9 2002/02/08 02:52:54 dgp Exp $ + */ + +#include <AppleEvents.h> +#include <AEDataModel.h> +#include <AEObjects.h> +#include <AEPackObject.h> +#include <AERegistry.h> +#include <Files.h> +#include <Folders.h> +#include <Gestalt.h> +#include <TextUtils.h> +#include <Resources.h> +#include <Strings.h> +#include "tclInt.h" +#include "tclMacInt.h" +#include "tclPort.h" +#include "tclInitScript.h" + +/* + * The following string is the startup script executed in new + * interpreters. It looks on the library path and in the resource fork for + * a script "init.tcl" that is compatible with this version of Tcl. The + * init.tcl script does all of the real work of initialization. + */ + +static char initCmd[] = "if {[info proc tclInit]==\"\"} {\n\ +proc tclInit {} {\n\ +global tcl_pkgPath env\n\ +proc sourcePath {file} {\n\ + foreach i $::auto_path {\n\ + set init [file join $i $file.tcl]\n\ + if {[catch {uplevel #0 [list source $init]}] == 0} {\n\ + return\n\ + }\n\ + }\n\ + if {[catch {uplevel #0 [list source -rsrc $file]}] == 0} {\n\ + return\n\ + }\n\ + rename sourcePath {}\n\ + set msg \"Can't find $file resource or a usable $file.tcl file\"\n\ + append msg \" in the following directories:\"\n\ + append msg \" $::auto_path\"\n\ + append msg \" perhaps you need to install Tcl or set your\"\n\ + append msg \" TCL_LIBRARY environment variable?\"\n\ + error $msg\n\ +}\n\ +if {[info exists env(EXT_FOLDER)]} {\n\ + lappend tcl_pkgPath [file join $env(EXT_FOLDER) {Tool Command Language}]\n\ +}\n\ +if {[info exists tcl_pkgPath] == 0} {\n\ + set tcl_pkgPath {no extension folder}\n\ +}\n\ +sourcePath init\n\ +sourcePath auto\n\ +sourcePath package\n\ +sourcePath history\n\ +sourcePath word\n\ +sourcePath parray\n\ +rename sourcePath {}\n\ +} }\n\ +tclInit"; + +/* + * The following structures are used to map the script/language codes of a + * font to the name that should be passed to Tcl_GetEncoding() to obtain + * the encoding for that font. The set of numeric constants is fixed and + * defined by Apple. + */ + +typedef struct Map { + int numKey; + char *strKey; +} Map; + +static Map scriptMap[] = { + {smRoman, "macRoman"}, + {smJapanese, "macJapan"}, + {smTradChinese, "macChinese"}, + {smKorean, "macKorean"}, + {smArabic, "macArabic"}, + {smHebrew, "macHebrew"}, + {smGreek, "macGreek"}, + {smCyrillic, "macCyrillic"}, + {smRSymbol, "macRSymbol"}, + {smDevanagari, "macDevanagari"}, + {smGurmukhi, "macGurmukhi"}, + {smGujarati, "macGujarati"}, + {smOriya, "macOriya"}, + {smBengali, "macBengali"}, + {smTamil, "macTamil"}, + {smTelugu, "macTelugu"}, + {smKannada, "macKannada"}, + {smMalayalam, "macMalayalam"}, + {smSinhalese, "macSinhalese"}, + {smBurmese, "macBurmese"}, + {smKhmer, "macKhmer"}, + {smThai, "macThailand"}, + {smLaotian, "macLaos"}, + {smGeorgian, "macGeorgia"}, + {smArmenian, "macArmenia"}, + {smSimpChinese, "macSimpChinese"}, + {smTibetan, "macTIbet"}, + {smMongolian, "macMongolia"}, + {smGeez, "macEthiopia"}, + {smEastEurRoman, "macCentEuro"}, + {smVietnamese, "macVietnam"}, + {smExtArabic, "macSindhi"}, + {NULL, NULL} +}; + +static Map romanMap[] = { + {langCroatian, "macCroatian"}, + {langSlovenian, "macCroatian"}, + {langIcelandic, "macIceland"}, + {langRomanian, "macRomania"}, + {langTurkish, "macTurkish"}, + {langGreek, "macGreek"}, + {NULL, NULL} +}; + +static Map cyrillicMap[] = { + {langUkrainian, "macUkraine"}, + {langBulgarian, "macBulgaria"}, + {NULL, NULL} +}; + +static int GetFinderFont(int *finderID); + +/* Used to store the encoding used for binary files */ +static Tcl_Encoding binaryEncoding = NULL; +/* Has the basic library path encoding issue been fixed */ +static int libraryPathEncodingFixed = 0; + + +/* + *---------------------------------------------------------------------- + * + * GetFinderFont -- + * + * Gets the "views" font of the Macintosh Finder + * + * Results: + * Standard Tcl result, and sets finderID to the font family + * id for the current finder font. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +static int +GetFinderFont(int *finderID) +{ + OSErr err = noErr; + OSType finderPrefs, viewFont = 'vfnt'; + DescType returnType; + Size returnSize; + long result, sys8Mask = 0x0800; + static AppleEvent outgoingAevt = {typeNull, NULL}; + AppleEvent returnAevt; + AEAddressDesc fndrAddress; + AEDesc nullContainer = {typeNull, NULL}, + tempDesc = {typeNull, NULL}, + tempDesc2 = {typeNull, NULL}, + finalDesc = {typeNull, NULL}; + const OSType finderSignature = 'MACS'; + + + if (outgoingAevt.descriptorType == typeNull) { + if ((Gestalt(gestaltSystemVersion, &result) != noErr) + || (result >= sys8Mask)) { + finderPrefs = 'pfrp'; + } else { + finderPrefs = 'pvwp'; + } + + AECreateDesc(typeApplSignature, &finderSignature, + sizeof(finderSignature), &fndrAddress); + + err = AECreateAppleEvent(kAECoreSuite, kAEGetData, &fndrAddress, + kAutoGenerateReturnID, kAnyTransactionID, &outgoingAevt); + + AEDisposeDesc(&fndrAddress); + + /* + * The structure is: + * the property view font ('vfnt') + * of the property view preferences ('pvwp') + * of the Null Container (i.e. the Finder itself). + */ + + AECreateDesc(typeType, &finderPrefs, sizeof(finderPrefs), &tempDesc); + err = CreateObjSpecifier(typeType, &nullContainer, formPropertyID, + &tempDesc, true, &tempDesc2); + AECreateDesc(typeType, &viewFont, sizeof(viewFont), &tempDesc); + err = CreateObjSpecifier(typeType, &tempDesc2, formPropertyID, + &tempDesc, true, &finalDesc); + + AEPutKeyDesc(&outgoingAevt, keyDirectObject, &finalDesc); + AEDisposeDesc(&finalDesc); + } + + err = AESend(&outgoingAevt, &returnAevt, kAEWaitReply, kAEHighPriority, + kAEDefaultTimeout, NULL, NULL); + if (err == noErr) { + err = AEGetKeyPtr(&returnAevt, keyDirectObject, typeInteger, + &returnType, (void *) finderID, sizeof(int), &returnSize); + if (err == noErr) { + return TCL_OK; + } + } + return TCL_ERROR; +} + +/* + *--------------------------------------------------------------------------- + * + * TclMacGetFontEncoding -- + * + * Determine the encoding of the specified font. The encoding + * can be used to convert bytes from UTF-8 into the encoding of + * that font. + * + * Results: + * The return value is a string that specifies the font's encoding + * and that can be passed to Tcl_GetEncoding() to construct the + * encoding. If the font's encoding could not be identified, NULL + * is returned. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + +char * +TclMacGetFontEncoding( + int fontId) +{ + int script, lang; + char *name; + Map *mapPtr; + + script = FontToScript(fontId); + lang = GetScriptVariable(script, smScriptLang); + name = NULL; + if (script == smRoman) { + for (mapPtr = romanMap; mapPtr->strKey != NULL; mapPtr++) { + if (mapPtr->numKey == lang) { + name = mapPtr->strKey; + break; + } + } + } else if (script == smCyrillic) { + for (mapPtr = cyrillicMap; mapPtr->strKey != NULL; mapPtr++) { + if (mapPtr->numKey == lang) { + name = mapPtr->strKey; + break; + } + } + } + if (name == NULL) { + for (mapPtr = scriptMap; mapPtr->strKey != NULL; mapPtr++) { + if (mapPtr->numKey == script) { + name = mapPtr->strKey; + break; + } + } + } + return name; +} + +/* + *--------------------------------------------------------------------------- + * + * TclpInitPlatform -- + * + * Initialize all the platform-dependant things like signals and + * floating-point error handling. + * + * Called at process initialization time. + * + * Results: + * None. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + +void +TclpInitPlatform() +{ + tclPlatform = TCL_PLATFORM_MAC; +} + +/* + *--------------------------------------------------------------------------- + * + * TclpInitLibraryPath -- + * + * Initialize the library path at startup. We have a minor + * metacircular problem that we don't know the encoding of the + * operating system but we may need to talk to operating system + * to find the library directories so that we know how to talk to + * the operating system. + * + * We do not know the encoding of the operating system. + * We do know that the encoding is some multibyte encoding. + * In that multibyte encoding, the characters 0..127 are equivalent + * to ascii. + * + * So although we don't know the encoding, it's safe: + * to look for the last colon character in a path in the encoding. + * to append an ascii string to a path. + * to pass those strings back to the operating system. + * + * But any strings that we remembered before we knew the encoding of + * the operating system must be translated to UTF-8 once we know the + * encoding so that the rest of Tcl can use those strings. + * + * This call sets the library path to strings in the unknown native + * encoding. TclpSetInitialEncodings() will translate the library + * path from the native encoding to UTF-8 as soon as it determines + * what the native encoding actually is. + * + * Called at process initialization time. + * + * Results: + * None. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + +void +TclpInitLibraryPath(argv0) + CONST char *argv0; /* Name of executable from argv[0] to main(). + * Not used because we can determine the name + * by querying the module handle. */ +{ + Tcl_Obj *objPtr, *pathPtr; + CONST char *str; + Tcl_DString ds; + + TclMacCreateEnv(); + + pathPtr = Tcl_NewObj(); + + /* + * Look for the library relative to default encoding dir. + */ + + str = Tcl_GetDefaultEncodingDir(); + if ((str != NULL) && (str[0] != '\0')) { + objPtr = Tcl_NewStringObj(str, -1); + Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); + } + + str = TclGetEnv("TCL_LIBRARY", &ds); + if ((str != NULL) && (str[0] != '\0')) { + /* + * If TCL_LIBRARY is set, search there. + */ + + objPtr = Tcl_NewStringObj(str, Tcl_DStringLength(&ds)); + Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); + Tcl_DStringFree(&ds); + } + + objPtr = TclGetLibraryPath(); + if (objPtr != NULL) { + Tcl_ListObjAppendList(NULL, pathPtr, objPtr); + } + + /* + * lappend path [file join $env(EXT_FOLDER) \ + * "Tool Command Language" "tcl[info version]" + */ + + str = TclGetEnv("EXT_FOLDER", &ds); + if ((str != NULL) && (str[0] != '\0')) { + Tcl_DString libPath, path; + CONST char *argv[3]; + + argv[0] = str; + argv[1] = "Tool Command Language"; + Tcl_DStringInit(&libPath); + Tcl_DStringAppend(&libPath, "tcl", -1); + argv[2] = Tcl_DStringAppend(&libPath, TCL_VERSION, -1); + Tcl_DStringInit(&path); + str = Tcl_JoinPath(3, argv, &path); + objPtr = Tcl_NewStringObj(str, Tcl_DStringLength(&path)); + Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); + Tcl_DStringFree(&ds); + Tcl_DStringFree(&libPath); + Tcl_DStringFree(&path); + } + TclSetLibraryPath(pathPtr); +} + +/* + *--------------------------------------------------------------------------- + * + * TclpSetInitialEncodings -- + * + * Based on the locale, determine the encoding of the operating + * system and the default encoding for newly opened files. + * + * Called at process initialization time, and part way through + * startup, we verify that the initial encodings were correctly + * setup. Depending on Tcl's environment, there may not have been + * enough information first time through (above). + * + * Results: + * None. + * + * Side effects: + * The Tcl library path is converted from native encoding to UTF-8, + * on the first call, and the encodings may be changed on first or + * second call. + * + *--------------------------------------------------------------------------- + */ + +void +TclpSetInitialEncodings() +{ + CONST char *encoding; + Tcl_Obj *pathPtr; + int fontId, err; + + fontId = 0; + GetFinderFont(&fontId); + encoding = TclMacGetFontEncoding(fontId); + if (encoding == NULL) { + encoding = "macRoman"; + } + + err = Tcl_SetSystemEncoding(NULL, encoding); + + if (err == TCL_OK && libraryPathEncodingFixed == 0) { + + /* + * Until the system encoding was actually set, the library path was + * actually in the native multi-byte encoding, and not really UTF-8 + * as advertised. We cheated as follows: + * + * 1. It was safe to allow the Tcl_SetSystemEncoding() call to + * append the ASCII chars that make up the encoding's filename to + * the names (in the native encoding) of directories in the library + * path, since all Unix multi-byte encodings have ASCII in the + * beginning. + * + * 2. To open the encoding file, the native bytes in the file name + * were passed to the OS, without translating from UTF-8 to native, + * because the name was already in the native encoding. + * + * Now that the system encoding was actually successfully set, + * translate all the names in the library path to UTF-8. That way, + * next time we search the library path, we'll translate the names + * from UTF-8 to the system encoding which will be the native + * encoding. + */ + + pathPtr = TclGetLibraryPath(); + if (pathPtr != NULL) { + int i, objc; + Tcl_Obj **objv; + + objc = 0; + Tcl_ListObjGetElements(NULL, pathPtr, &objc, &objv); + for (i = 0; i < objc; i++) { + int length; + char *string; + Tcl_DString ds; + + string = Tcl_GetStringFromObj(objv[i], &length); + Tcl_ExternalToUtfDString(NULL, string, length, &ds); + Tcl_SetStringObj(objv[i], Tcl_DStringValue(&ds), + Tcl_DStringLength(&ds)); + Tcl_DStringFree(&ds); + } + Tcl_InvalidateStringRep(pathPtr); + } + libraryPathEncodingFixed = 1; + } + + /* This is only ever called from the startup thread */ + if (binaryEncoding == NULL) { + /* + * Keep the iso8859-1 encoding preloaded. The IO package uses + * it for gets on a binary channel. + */ + binaryEncoding = Tcl_GetEncoding(NULL, "iso8859-1"); + } +} + +/* + *--------------------------------------------------------------------------- + * + * TclpSetVariables -- + * + * Performs platform-specific interpreter initialization related to + * the tcl_library and tcl_platform variables, and other platform- + * specific things. + * + * Results: + * None. + * + * Side effects: + * Sets "tcl_library" and "tcl_platform" Tcl variables. + * + *---------------------------------------------------------------------- + */ + +void +TclpSetVariables(interp) + Tcl_Interp *interp; +{ + long int gestaltResult; + int minor, major, objc; + Tcl_Obj **objv; + char versStr[2 * TCL_INTEGER_SPACE]; + CONST char *str; + Tcl_Obj *pathPtr; + Tcl_DString ds; + + str = "no library"; + pathPtr = TclGetLibraryPath(); + if (pathPtr != NULL) { + objc = 0; + Tcl_ListObjGetElements(NULL, pathPtr, &objc, &objv); + if (objc > 0) { + str = Tcl_GetStringFromObj(objv[0], NULL); + } + } + Tcl_SetVar(interp, "tcl_library", str, TCL_GLOBAL_ONLY); + + if (pathPtr != NULL) { + Tcl_SetVar2Ex(interp, "tcl_pkgPath", NULL, pathPtr, TCL_GLOBAL_ONLY); + } + + Tcl_SetVar2(interp, "tcl_platform", "platform", "macintosh", + TCL_GLOBAL_ONLY); + Tcl_SetVar2(interp, "tcl_platform", "os", "MacOS", TCL_GLOBAL_ONLY); + Gestalt(gestaltSystemVersion, &gestaltResult); + major = (gestaltResult & 0x0000FF00) >> 8; + minor = (gestaltResult & 0x000000F0) >> 4; + sprintf(versStr, "%d.%d", major, minor); + Tcl_SetVar2(interp, "tcl_platform", "osVersion", versStr, TCL_GLOBAL_ONLY); +#if GENERATINGPOWERPC + Tcl_SetVar2(interp, "tcl_platform", "machine", "ppc", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "tcl_platform", "machine", "68k", TCL_GLOBAL_ONLY); +#endif + + /* + * Copy USER or LOGIN environment variable into tcl_platform(user) + * These are set by SystemVariables in tclMacEnv.c + */ + + Tcl_DStringInit(&ds); + str = TclGetEnv("USER", &ds); + if (str == NULL) { + str = TclGetEnv("LOGIN", &ds); + if (str == NULL) { + str = ""; + } + } + Tcl_SetVar2(interp, "tcl_platform", "user", str, TCL_GLOBAL_ONLY); + Tcl_DStringFree(&ds); +} + +/* + *---------------------------------------------------------------------- + * + * TclpCheckStackSpace -- + * + * On a 68K Mac, we can detect if we are about to blow the stack. + * Called before an evaluation can happen when nesting depth is + * checked. + * + * Results: + * 1 if there is enough stack space to continue; 0 if not. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TclpCheckStackSpace() +{ + return StackSpace() > TCL_MAC_STACK_THRESHOLD; +} + +/* + *---------------------------------------------------------------------- + * + * TclpFindVariable -- + * + * Locate the entry in environ for a given name. On Unix and Macthis + * routine is case sensitive, on Windows this matches mixed case. + * + * Results: + * The return value is the index in environ of an entry with the + * name "name", or -1 if there is no such entry. The integer at + * *lengthPtr is filled in with the length of name (if a matching + * entry is found) or the length of the environ array (if no matching + * entry is found). + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TclpFindVariable(name, lengthPtr) + CONST char *name; /* Name of desired environment variable + * (native). */ + int *lengthPtr; /* Used to return length of name (for + * successful searches) or number of non-NULL + * entries in environ (for unsuccessful + * searches). */ +{ + int i, result = -1; + register CONST char *env, *p1, *p2; + Tcl_DString envString; + + Tcl_DStringInit(&envString); + for (i = 0, env = environ[i]; env != NULL; i++, env = environ[i]) { + p1 = Tcl_ExternalToUtfDString(NULL, env, -1, &envString); + p2 = name; + + for (; *p2 == *p1; p1++, p2++) { + /* NULL loop body. */ + } + if ((*p1 == '=') && (*p2 == '\0')) { + *lengthPtr = p2 - name; + result = i; + goto done; + } + + Tcl_DStringFree(&envString); + } + + *lengthPtr = i; + + done: + Tcl_DStringFree(&envString); + return result; +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_Init -- + * + * This procedure is typically invoked by Tcl_AppInit procedures + * to perform additional initialization for a Tcl interpreter, + * such as sourcing the "init.tcl" script. + * + * Results: + * Returns a standard Tcl completion code and sets the interp's result + * if there is an error. + * + * Side effects: + * Depends on what's in the init.tcl script. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_Init( + Tcl_Interp *interp) /* Interpreter to initialize. */ +{ + Tcl_Obj *pathPtr; + + if (tclPreInitScript != NULL) { + if (Tcl_Eval(interp, tclPreInitScript) == TCL_ERROR) { + return (TCL_ERROR); + }; + } + + /* + * For Macintosh applications the Init function may be contained in + * the application resources. If it exists we use it - otherwise we + * look in the tcl_library directory. Ditto for the history command. + */ + + pathPtr = TclGetLibraryPath(); + if (pathPtr == NULL) { + pathPtr = Tcl_NewObj(); + } + Tcl_SetVar2Ex(interp, "auto_path", NULL, pathPtr, TCL_GLOBAL_ONLY); + return Tcl_Eval(interp, initCmd); +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_SourceRCFile -- + * + * This procedure is typically invoked by Tcl_Main or Tk_Main + * procedure to source an application specific rc file into the + * interpreter at startup time. This will either source a file + * in the "tcl_rcFileName" variable or a TEXT resource in the + * "tcl_rcRsrcName" variable. + * + * Results: + * None. + * + * Side effects: + * Depends on what's in the rc script. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_SourceRCFile( + Tcl_Interp *interp) /* Interpreter to source rc file into. */ +{ + Tcl_DString temp; + CONST char *fileName; + Tcl_Channel errChannel; + Handle h; + + fileName = Tcl_GetVar(interp, "tcl_rcFileName", TCL_GLOBAL_ONLY); + + if (fileName != NULL) { + Tcl_Channel c; + CONST char *fullName; + + Tcl_DStringInit(&temp); + fullName = Tcl_TranslateFileName(interp, fileName, &temp); + if (fullName == NULL) { + /* + * Couldn't translate the file name (e.g. it referred to a + * bogus user or there was no HOME environment variable). + * Just do nothing. + */ + } else { + + /* + * Test for the existence of the rc file before trying to read it. + */ + + c = Tcl_OpenFileChannel(NULL, fullName, "r", 0); + if (c != (Tcl_Channel) NULL) { + Tcl_Close(NULL, c); + if (Tcl_EvalFile(interp, fullName) != TCL_OK) { + errChannel = Tcl_GetStdChannel(TCL_STDERR); + if (errChannel) { + Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); + Tcl_WriteChars(errChannel, "\n", 1); + } + } + } + } + Tcl_DStringFree(&temp); + } + + fileName = Tcl_GetVar(interp, "tcl_rcRsrcName", TCL_GLOBAL_ONLY); + + if (fileName != NULL) { + Str255 rezName; + Tcl_DString ds; + Tcl_UtfToExternalDString(NULL, fileName, -1, &ds); + strcpy((char *) rezName + 1, Tcl_DStringValue(&ds)); + rezName[0] = (unsigned) Tcl_DStringLength(&ds); + h = GetNamedResource('TEXT', rezName); + Tcl_DStringFree(&ds); + if (h != NULL) { + if (Tcl_MacEvalResource(interp, fileName, 0, NULL) != TCL_OK) { + errChannel = Tcl_GetStdChannel(TCL_STDERR); + if (errChannel) { + Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp)); + Tcl_WriteChars(errChannel, "\n", 1); + } + } + Tcl_ResetResult(interp); + ReleaseResource(h); + } + } +} diff --git a/mac/tclMacInt.h b/mac/tclMacInt.h new file mode 100644 index 0000000..ab7bc7f --- /dev/null +++ b/mac/tclMacInt.h @@ -0,0 +1,77 @@ +/* + * tclMacInt.h -- + * + * Declarations of Macintosh specific shared variables and procedures. + * + * Copyright (c) 1996-1998 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacInt.h,v 1.7 2001/11/23 01:27:36 das Exp $ + */ + +#ifndef _TCLMACINT +#define _TCLMACINT + +#ifndef _TCLINT +#include "tclInt.h" +#endif +#ifndef _TCLPORT +#include "tclPort.h" +#endif + +#include <Events.h> +#include <Files.h> + +/* + * Defines to control stack behavior. + * + * The Tcl8.2 regexp code is highly recursive for patterns with many + * subexpressions. So we have to increase the stack space to accomodate. + * 512 K is good enough for ordinary work, but you need 768 to pass the Tcl + * regexp testsuite. + * + * For the PPC, you need to set the stack space in the Project file. + * + */ + +#ifdef TCL_TEST +# define TCL_MAC_68K_STACK_GROWTH (768*1024) +#else +# define TCL_MAC_68K_STACK_GROWTH (512*1024) +#endif + +#define TCL_MAC_STACK_THRESHOLD 16384 + +#ifdef BUILD_tcl +# undef TCL_STORAGE_CLASS +# define TCL_STORAGE_CLASS DLLEXPORT +#endif + +/* + * This flag is passed to TclMacRegisterResourceFork + * by a file (usually a library) whose resource fork + * should not be closed by the resource command. + */ + +#define TCL_RESOURCE_DONT_CLOSE 2 + +/* + * Typedefs used by Macintosh parts of Tcl. + */ + +/* + * Prototypes of Mac only internal functions. + */ + +EXTERN char * TclMacGetFontEncoding _ANSI_ARGS_((int fontId)); +EXTERN int TclMacHaveThreads _ANSI_ARGS_((void)); +EXTERN long TclpGetGMTOffset _ANSI_ARGS_((void)); + +# undef TCL_STORAGE_CLASS +# define TCL_STORAGE_CLASS DLLIMPORT + +#include "tclIntPlatDecls.h" + +#endif /* _TCLMACINT */ diff --git a/mac/tclMacInterupt.c b/mac/tclMacInterupt.c new file mode 100644 index 0000000..7f37d2f --- /dev/null +++ b/mac/tclMacInterupt.c @@ -0,0 +1,289 @@ +/* + * tclMacInterupt.c -- + * + * This file contains routines that deal with the Macintosh's low level + * time manager. This code provides a better resolution timer than what + * can be provided by WaitNextEvent. + * + * Copyright (c) 1996 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacInterupt.c,v 1.2 1998/09/14 18:40:05 stanton Exp $ + */ + +#include "tclInt.h" +#include "tclMacInt.h" +#include <LowMem.h> +#include <Processes.h> +#include <Timer.h> + +/* + * Data structure for timer tasks. + */ +typedef struct TMInfo { + TMTask tmTask; + ProcessSerialNumber psn; + Point lastPoint; + Point newPoint; + long currentA5; + long ourA5; + int installed; +} TMInfo; + +/* + * Globals used within this file. + */ + +static TimerUPP sleepTimerProc = NULL; +static int interuptsInited = false; +static ProcessSerialNumber applicationPSN; +#define MAX_TIMER_ARRAY_SIZE 16 +static TMInfo timerInfoArray[MAX_TIMER_ARRAY_SIZE]; +static int topTimerElement = 0; + +/* + * Prototypes for procedures that are referenced only in this file: + */ + +#if !GENERATINGCFM +static TMInfo * GetTMInfo(void) ONEWORDINLINE(0x2E89); /* MOVE.L A1,(SP) */ +#endif +static void SleepTimerProc _ANSI_ARGS_((void)); +static pascal void CleanUpExitProc _ANSI_ARGS_((void)); +static void InitInteruptSystem _ANSI_ARGS_((void)); + +/* + *---------------------------------------------------------------------- + * + * InitInteruptSystem -- + * + * Does various initialization for the functions used in this + * file. Sets up Universial Pricedure Pointers, installs a trap + * patch for ExitToShell, etc. + * + * Results: + * None. + * + * Side effects: + * Various initialization. + * + *---------------------------------------------------------------------- + */ + +void +InitInteruptSystem() +{ + int i; + + sleepTimerProc = NewTimerProc(SleepTimerProc); + GetCurrentProcess(&applicationPSN); + for (i = 0; i < MAX_TIMER_ARRAY_SIZE; i++) { + timerInfoArray[i].installed = false; + } + + /* + * Install the ExitToShell patch. We use this patch instead + * of the Tcl exit mechanism because we need to ensure that + * these routines are cleaned up even if we crash or are forced + * to quit. There are some circumstances when the Tcl exit + * handlers may not fire. + */ + + TclMacInstallExitToShellPatch(CleanUpExitProc); + interuptsInited = true; +} + +/* + *---------------------------------------------------------------------- + * + * TclMacStartTimer -- + * + * Install a Time Manager task to wake our process up in the + * future. The process should get a NULL event after ms + * milliseconds. + * + * Results: + * None. + * + * Side effects: + * Schedules our process to wake up. + * + *---------------------------------------------------------------------- + */ + +void * +TclMacStartTimer( + long ms) /* Milliseconds. */ +{ + TMInfo *timerInfoPtr; + + if (!interuptsInited) { + InitInteruptSystem(); + } + + /* + * Obtain a pointer for the timer. We only allocate up + * to MAX_TIMER_ARRAY_SIZE timers. If we are past that + * max we return NULL. + */ + if (topTimerElement < MAX_TIMER_ARRAY_SIZE) { + timerInfoPtr = &timerInfoArray[topTimerElement]; + topTimerElement++; + } else { + return NULL; + } + + /* + * Install timer to wake process in ms milliseconds. + */ + timerInfoPtr->tmTask.tmAddr = sleepTimerProc; + timerInfoPtr->tmTask.tmWakeUp = 0; + timerInfoPtr->tmTask.tmReserved = 0; + timerInfoPtr->psn = applicationPSN; + timerInfoPtr->installed = true; + + InsTime((QElemPtr) timerInfoPtr); + PrimeTime((QElemPtr) timerInfoPtr, (long) ms); + + return (void *) timerInfoPtr; +} + +/* + *---------------------------------------------------------------------- + * + * TclMacRemoveTimer -- + * + * Remove the timer event from the Time Manager. + * + * Results: + * None. + * + * Side effects: + * A scheduled timer would be removed. + * + *---------------------------------------------------------------------- + */ + +void +TclMacRemoveTimer( + void * timerToken) /* Token got from start timer. */ +{ + TMInfo *timerInfoPtr = (TMInfo *) timerToken; + + if (timerInfoPtr == NULL) { + return; + } + + RmvTime((QElemPtr) timerInfoPtr); + timerInfoPtr->installed = false; + topTimerElement--; +} + +/* + *---------------------------------------------------------------------- + * + * TclMacTimerExpired -- + * + * Check to see if the installed timer has expired. + * + * Results: + * True if timer has expired, false otherwise. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TclMacTimerExpired( + void * timerToken) /* Our token again. */ +{ + TMInfo *timerInfoPtr = (TMInfo *) timerToken; + + if ((timerInfoPtr == NULL) || + !(timerInfoPtr->tmTask.qType & kTMTaskActive)) { + return true; + } else { + return false; + } +} + +/* + *---------------------------------------------------------------------- + * + * SleepTimerProc -- + * + * Time proc is called by the is a callback routine placed in the + * system by Tcl_Sleep. The routine is called at interupt time + * and threrfor can not move or allocate memory. This call will + * schedule our process to wake up the next time the process gets + * around to consider running it. + * + * Results: + * None. + * + * Side effects: + * Schedules our process to wake up. + * + *---------------------------------------------------------------------- + */ + +static void +SleepTimerProc() +{ + /* + * In CFM code we can access our code directly. In 68k code that + * isn't based on CFM we must do a glorious hack. The function + * GetTMInfo is an inline assembler call that moves the pointer + * at A1 to the top of the stack. The Time Manager keeps the TMTask + * info record there before calling this call back. In order for + * this to work the infoPtr argument must be the *last* item on the + * stack. If we "piggyback" our data to the TMTask info record we + * can get access to the information we need. While this is really + * ugly - it's the way Apple recomends it be done - go figure... + */ + +#if GENERATINGCFM + WakeUpProcess(&applicationPSN); +#else + TMInfo * infoPtr; + + infoPtr = GetTMInfo(); + WakeUpProcess(&infoPtr->psn); +#endif +} + +/* + *---------------------------------------------------------------------- + * + * CleanUpExitProc -- + * + * This procedure is invoked as an exit handler when ExitToShell + * is called. It removes the system level timer handler if it + * is installed. This must be called or the Mac OS will more than + * likely crash. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static pascal void +CleanUpExitProc() +{ + int i; + + for (i = 0; i < MAX_TIMER_ARRAY_SIZE; i++) { + if (timerInfoArray[i].installed) { + RmvTime((QElemPtr) &timerInfoArray[i]); + timerInfoArray[i].installed = false; + } + } +} diff --git a/mac/tclMacLibrary.c b/mac/tclMacLibrary.c new file mode 100644 index 0000000..59d4612 --- /dev/null +++ b/mac/tclMacLibrary.c @@ -0,0 +1,248 @@ +/* + * tclMacLibrary.c -- + * + * This file should be included in Tcl extensions that want to + * automatically open their resource forks when the code is linked. + * These routines should not be exported but should be compiled + * locally by each fragment. Many thanks to Jay Lieske + * <lieske@princeton.edu> who provide an initial version of this + * file. + * + * Copyright (c) 1996 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacLibrary.c,v 1.5 2001/11/23 01:27:39 das Exp $ + */ + +/* + * Here is another place that we are using the old routine names... + */ + +#include <CodeFragments.h> +#include <Errors.h> +#include <Resources.h> +#include <Strings.h> +#include "tclMacInt.h" + +#if defined(TCL_REGISTER_LIBRARY) && defined(USE_TCL_STUBS) +#error "Can't use TCL_REGISTER_LIBRARY and USE_TCL_STUBS at the same time!" +/* + * Can't register a library with Tcl when using stubs in the current + * implementation, since Tcl_InitStubs hasn't been called yet + * when OpenLibraryResource is executing. + */ +#endif + +/* + * These function are not currently defined in any header file. The + * only place they should be used is in the Initialization and + * Termination entry points for a code fragment. The prototypes + * are included here to avoid compile errors. + */ + +OSErr TclMacInitializeFragment _ANSI_ARGS_(( + struct CFragInitBlock* initBlkPtr)); +void TclMacTerminateFragment _ANSI_ARGS_((void)); + +/* + * Static functions in this file. + */ + +static OSErr OpenLibraryResource _ANSI_ARGS_(( + struct CFragInitBlock* initBlkPtr)); +static void CloseLibraryResource _ANSI_ARGS_((void)); + +/* + * The refnum of the opened resource fork. + */ +static short ourResFile = kResFileNotOpened; + +/* + * This is the resource token for the our resource file. + * It stores the name we registered with the resource facility. + * We only need to use this if we are actually registering ourselves. + */ + +#ifdef TCL_REGISTER_LIBRARY +static Tcl_Obj *ourResToken; +#endif + +/* + *---------------------------------------------------------------------- + * + * TclMacInitializeFragment -- + * + * Called by MacOS CFM when the shared library is loaded. All this + * function really does is give Tcl a chance to open and register + * the resource fork of the library. + * + * Results: + * MacOS error code if loading should be canceled. + * + * Side effects: + * Opens the resource fork of the shared library file. + * + *---------------------------------------------------------------------- + */ + +OSErr +TclMacInitializeFragment( + struct CFragInitBlock* initBlkPtr) /* Pointer to our library. */ +{ + OSErr err = noErr; + +#ifdef __MWERKS__ + { + extern OSErr __initialize( CFragInitBlock* initBlkPtr); + err = __initialize((CFragInitBlock *) initBlkPtr); + } +#endif + if (err == noErr) + err = OpenLibraryResource( initBlkPtr); + return err; +} + +/* + *---------------------------------------------------------------------- + * + * TclMacTerminateFragment -- + * + * Called by MacOS CFM when the shared library is unloaded. + * + * Results: + * None. + * + * Side effects: + * The resource fork of the code fragment is closed. + * + *---------------------------------------------------------------------- + */ + +void +TclMacTerminateFragment() +{ + CloseLibraryResource(); + +#ifdef __MWERKS__ + { + extern void __terminate(void); + __terminate(); + } +#endif +} + +/* + *---------------------------------------------------------------------- + * + * OpenLibraryResource -- + * + * This routine can be called by a MacOS fragment's initialiation + * function to open the resource fork of the file. + * Call it with the same data passed to the initialization function. + * If the fragment loading should fail if the resource fork can't + * be opened, then the initialization function can pass on this + * return value. + * + * If you #define TCL_REGISTER_RESOURCE before compiling this resource, + * then your library will register its open resource fork with the + * resource command. + * + * Results: + * It returns noErr on success and a MacOS error code on failure. + * + * Side effects: + * The resource fork of the code fragment is opened read-only and + * is installed at the head of the resource chain. + * + *---------------------------------------------------------------------- + */ + +static OSErr +OpenLibraryResource( + struct CFragInitBlock* initBlkPtr) +{ + /* + * The 3.0 version of the Universal headers changed CFragInitBlock + * to an opaque pointer type. CFragSystem7InitBlock is now the + * real pointer. + */ + +#if !defined(UNIVERSAL_INTERFACES_VERSION) || (UNIVERSAL_INTERFACES_VERSION < 0x0300) + struct CFragInitBlock *realInitBlkPtr = initBlkPtr; +#else + CFragSystem7InitBlock *realInitBlkPtr = (CFragSystem7InitBlock *) initBlkPtr; +#endif + FSSpec* fileSpec = NULL; + OSErr err = noErr; + + + if (realInitBlkPtr->fragLocator.where == kDataForkCFragLocator) { + fileSpec = realInitBlkPtr->fragLocator.u.onDisk.fileSpec; + } else if (realInitBlkPtr->fragLocator.where == kResourceCFragLocator) { + fileSpec = realInitBlkPtr->fragLocator.u.inSegs.fileSpec; + } else { + err = resFNotFound; + } + + /* + * Open the resource fork for this library in read-only mode. + * This will make it the current res file, ahead of the + * application's own resources. + */ + + if (fileSpec != NULL) { + ourResFile = FSpOpenResFile(fileSpec, fsRdPerm); + if (ourResFile == kResFileNotOpened) { + err = ResError(); + } else { +#ifdef TCL_REGISTER_LIBRARY + ourResToken = Tcl_NewObj(); + Tcl_IncrRefCount(ourResToken); + p2cstr(realInitBlkPtr->libName); + Tcl_SetStringObj(ourResToken, (char *) realInitBlkPtr->libName, -1); + c2pstr((char *) realInitBlkPtr->libName); + TclMacRegisterResourceFork(ourResFile, ourResToken, + TCL_RESOURCE_DONT_CLOSE); +#endif + SetResFileAttrs(ourResFile, mapReadOnly); + } + } + + return err; +} + +/* + *---------------------------------------------------------------------- + * + * CloseLibraryResource -- + * + * This routine should be called by a MacOS fragment's termination + * function to close the resource fork of the file + * that was opened with OpenLibraryResource. + * + * Results: + * None. + * + * Side effects: + * The resource fork of the code fragment is closed. + * + *---------------------------------------------------------------------- + */ + +static void +CloseLibraryResource() +{ + if (ourResFile != kResFileNotOpened) { +#ifdef TCL_REGISTER_LIBRARY + int length; + TclMacUnRegisterResourceFork( + Tcl_GetStringFromObj(ourResToken, &length), + NULL); + Tcl_DecrRefCount(ourResToken); +#endif + CloseResFile(ourResFile); + ourResFile = kResFileNotOpened; + } +} diff --git a/mac/tclMacLibrary.r b/mac/tclMacLibrary.r new file mode 100644 index 0000000..5fd1cbe --- /dev/null +++ b/mac/tclMacLibrary.r @@ -0,0 +1,209 @@ +/* + * tclMacLibrary.r -- + * + * This file creates resources used by the Tcl shared library. + * Many thanks go to "Jay Lieske, Jr." <lieske@princeton.edu> who + * wrote the initial version of this file. + * + * Copyright (c) 1996-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacLibrary.r,v 1.7 2002/09/12 17:33:20 das Exp $ + */ + +#include <Types.r> +#include <SysTypes.r> + +/* + * The folowing include and defines help construct + * the version string for Tcl. + */ + +#define RC_INVOKED +#include "tcl.h" + +#if (TCL_RELEASE_LEVEL == 0) +# define RELEASE_LEVEL alpha +#elif (TCL_RELEASE_LEVEL == 1) +# define RELEASE_LEVEL beta +#elif (TCL_RELEASE_LEVEL == 2) +# define RELEASE_LEVEL final +#endif + +#if (TCL_RELEASE_LEVEL == 2) +# define MINOR_VERSION (TCL_MINOR_VERSION * 16) + TCL_RELEASE_SERIAL +# define RELEASE_CODE 0x00 +#else +# define MINOR_VERSION TCL_MINOR_VERSION * 16 +# define RELEASE_CODE TCL_RELEASE_SERIAL +#endif + +resource 'vers' (1) { + TCL_MAJOR_VERSION, MINOR_VERSION, + RELEASE_LEVEL, RELEASE_CODE, verUS, + TCL_PATCH_LEVEL, + TCL_PATCH_LEVEL ", by Ray Johnson & Jim Ingham" "\n" "© 2001 Tcl Core Team" +}; + +resource 'vers' (2) { + TCL_MAJOR_VERSION, MINOR_VERSION, + RELEASE_LEVEL, RELEASE_CODE, verUS, + TCL_PATCH_LEVEL, + "Tcl Library " TCL_PATCH_LEVEL " © 1993-2001" +}; + +/* + * Currently the creator for all Tcl/Tk libraries and extensions + * should be 'TclL'. This will allow those extension and libraries + * to use the common icon for Tcl extensions. However, this signature + * still needs to be approved by the signature police at Apple and may + * change. + */ +#define TCL_CREATOR 'TclL' +#define TCL_LIBRARY_RESOURCES 2000 + +/* + * The 'BNDL' resource is the primary link between a file's + * creator/type and its icon. This resource acts for all Tcl shared + * libraries; other libraries will not need one and ought to use + * custom icons rather than new file types for a different appearance. + */ + +resource 'BNDL' (TCL_LIBRARY_RESOURCES, "Tcl bundle", purgeable) +{ + TCL_CREATOR, + 0, + { /* array TypeArray: 2 elements */ + /* [1] */ + 'FREF', + { /* array IDArray: 1 elements */ + /* [1] */ + 0, TCL_LIBRARY_RESOURCES + }, + /* [2] */ + 'ICN#', + { /* array IDArray: 1 elements */ + /* [1] */ + 0, TCL_LIBRARY_RESOURCES + } + } +}; + +resource 'FREF' (TCL_LIBRARY_RESOURCES, purgeable) +{ + 'shlb', 0, "" +}; + +type TCL_CREATOR as 'STR '; +resource TCL_CREATOR (0, purgeable) { + "Tcl Library " TCL_PATCH_LEVEL " © 1993-2001" +}; + +/* + * The 'kind' resource works with a 'BNDL' in Macintosh Easy Open + * to affect the text the Finder displays in the "kind" column and + * file info dialog. This information will be applied to all files + * with the listed creator and type. + */ + +resource 'kind' (TCL_LIBRARY_RESOURCES, "Tcl kind", purgeable) { + TCL_CREATOR, + 0, /* region = USA */ + { + 'shlb', "Tcl Library" + } +}; + + +/* + * The -16397 string will be displayed by Finder when a user + * tries to open the shared library. The string should + * give the user a little detail about the library's capabilities + * and enough information to install the library in the correct location. + * A similar string should be placed in all shared libraries. + */ +resource 'STR ' (-16397, purgeable) { + "Tcl Library\n\n" + "This is the core library needed to run Tool Command Language programs. " + "To work properly, it should be placed in the ŒTool Command Language¹ folder " + "within the Extensions folder." +}; + +/* + * The following are icons for the shared library. + */ + +data 'icl4' (2000, "Tcl Shared Library", purgeable) { + $"0FFF FFFF FFFF FFFF FFFF FFFF FFFF 0000" + $"F000 0000 0000 0000 0000 0000 000C F000" + $"F0CC CFFF CCCC CCC6 66CC CCCC CCCC F000" + $"F0CC CFFF FFFF FF66 F6CC CCCC CCCC F000" + $"F0CC CFFF 2000 0D66 6CCC CCCC CCCC F000" + $"F0CC CFFF 0202 056F 6E5C CCCC CCCC F000" + $"F0CC CFFF 2020 C666 F66F CCCC CCCC F000" + $"F0CC CFFF 0200 B66F 666B FCCC CCCC F000" + $"F0FC CFFF B020 55F6 6F52 BFCC CCCC F000" + $"FF0F 0CCC FB02 5665 66D0 2FCC CCCC F0F0" + $"F00F 0CCC CFB0 BF55 F6CF FFCC CCCC FFCF" + $"000F 0CCC CCFB 06C9 66CC CCCC CCCC F0CF" + $"000F 0CCC CCCF 56C6 6CCC CCCC CCCC CCCF" + $"000F 0CCC CCCC 6FC6 FCCC CCCC CCCC CCCF" + $"000F 0CCC CCCC 65C5 65CC CCCC CCCC CCCF" + $"000F 0CCC CCCC 55D6 57CC CCCC CCCC CCCF" + $"000F 0CCC CCCC 65CF 6CCC CCCC CCCC CCCF" + $"000F 0CCC CCCC 5AC6 6CFF CCCC CCCC CCCF" + $"000F 0CCC CCCC 65C5 6CF0 FCCC CCCC CCCF" + $"000F 0CCC CCCC CECF CCF0 0FCC CCCC CCCF" + $"000F 0CCC CCCC C5C6 CCCF 20FC CCCC FCCF" + $"F00F 0CCC CCCF FFD5 CCCC F20F CCCC FFCF" + $"FF0F 0CCC CCCF 20CF CCCC F020 FCCC F0F0" + $"F0F0 CCCC CCCF B2C2 FFFF 0002 0FFC F000" + $"F00C CCCC CCCC FBC0 2000 0020 2FFC F000" + $"F0CC CCCC CCCC CFCB 0202 0202 0FFC F000" + $"F0CC CCCC CCCC CCCF B020 2020 2FFC F000" + $"F0CC CCCC CCCC CCDC FBBB BBBB BFFC F000" + $"F0CC CCCC CCCC CCCC CFFF FFFF FFFC F000" + $"F0CC CCCC CCCC CCCC CCCC CCCC CFFC F000" + $"FCCC CCCC CCCC CCCC CCCC CCCC CCCC F000" + $"0FFF FFFF FFFF FFFF FFFF FFFF FFFF 0000" +}; + +data 'ICN#' (2000, "Tcl Shared Library", purgeable) { + $"7FFF FFF0 8000 0008 8701 C008 87FF C008" + $"8703 8008 8707 E008 8707 F008 870F F808" + $"A78F EC08 D0CF C40A 906F DC0D 1035 C009" + $"101D 8001 100D 8001 100D C001 100D C001" + $"100D 8001 100D B001 100D A801 1005 2401" + $"1005 1209 901D 090D D011 088A A018 F068" + $"800C 0068 8005 0068 8001 8068 8000 FFE8" + $"8000 7FE8 8000 0068 8000 0008 7FFF FFF0" + $"7FFF FFF0 FFFF FFF8 FFFF FFF8 FFFF FFF8" + $"FFFF FFF8 FFFF FFF8 FFFF FFF8 FFFF FFF8" + $"FFFF FFF8 DFFF FFFA 9FFF FFFF 1FFF FFFF" + $"1FFF FFFF 1FFF FFFF 1FFF FFFF 1FFF FFFF" + $"1FFF FFFF 1FFF FFFF 1FFF FFFF 1FFF FFFF" + $"1FFF FFFF 9FFF FFFF DFFF FFFA FFFF FFF8" + $"FFFF FFF8 FFFF FFF8 FFFF FFF8 FFFF FFF8" + $"FFFF FFF8 FFFF FFF8 FFFF FFF8 7FFF FFF0" +}; + +data 'ics#' (2000, "Tcl Shared Library", purgeable) { + $"FFFE B582 BB82 B3C2 BFA2 43C3 4381 4381" + $"4381 4763 4392 856E 838E 81AE 811E FFFE" + $"FFFE FFFE FFFE FFFE FFFE FFFF 7FFF 7FFF" + $"7FFF 7FFF 7FFF FFFE FFFE FFFE FFFE FFFE" +}; + +data 'ics4' (2000, "Tcl Shared Library", purgeable) { + $"FFFF FFFF FFFF FFF0 FCFF DED5 6CCC CCF0" + $"FCFF C0D6 ECCC CCF0 FCFF 2056 65DC CCF0" + $"FDFE D256 6DAC CCFF FFCC DDDE 5DDC CCEF" + $"0FCC CD67 5CCC CCCF 0FCC CC5D 6CCC CCCF" + $"0FCC CC5D 5CCC CCCF 0FCC CCD5 5CCC CCCF" + $"FFCC CFFD CCFF CCFF FCCC CF2D DF20 FCFC" + $"FCCC CCFD D202 FEF0 FCCC CC0D 2020 FEF0" + $"FCCC CCCD FBBB FEF0 FFFF FFFF FFFF FFE0" +}; + diff --git a/mac/tclMacLoad.c b/mac/tclMacLoad.c new file mode 100644 index 0000000..379b450 --- /dev/null +++ b/mac/tclMacLoad.c @@ -0,0 +1,380 @@ +/* + * tclMacLoad.c -- + * + * This procedure provides a version of the TclLoadFile for use + * on the Macintosh. This procedure will only work with systems + * that use the Code Fragment Manager. + * + * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacLoad.c,v 1.16 2002/10/09 11:54:26 das Exp $ + */ + +#include <CodeFragments.h> +#include <Errors.h> +#include <Resources.h> +#include <Strings.h> +#include <FSpCompat.h> + +/* + * Seems that the 3.0.1 Universal headers leave this define out. So we + * define it here... + */ + +#ifndef fragNoErr + #define fragNoErr noErr +#endif + +#include "tclPort.h" +#include "tclInt.h" +#include "tclMacInt.h" + +#if GENERATINGPOWERPC + #define OUR_ARCH_TYPE kPowerPCCFragArch +#else + #define OUR_ARCH_TYPE kMotorola68KCFragArch +#endif + +/* + * The following data structure defines the structure of a code fragment + * resource. We can cast the resource to be of this type to access + * any fields we need to see. + */ +struct CfrgHeader { + long res1; + long res2; + long version; + long res3; + long res4; + long filler1; + long filler2; + long itemCount; + char arrayStart; /* Array of externalItems begins here. */ +}; +typedef struct CfrgHeader CfrgHeader, *CfrgHeaderPtr, **CfrgHeaderPtrHand; + +/* + * The below structure defines a cfrag item within the cfrag resource. + */ +struct CfrgItem { + OSType archType; + long updateLevel; + long currVersion; + long oldDefVersion; + long appStackSize; + short appSubFolder; + char usage; + char location; + long codeOffset; + long codeLength; + long res1; + long res2; + short itemSize; + Str255 name; /* This is actually variable sized. */ +}; +typedef struct CfrgItem CfrgItem; + +/* + * On MacOS, old shared libraries which contain many code fragments + * cannot, it seems, be loaded in one go. We need to look provide + * the name of a code fragment while we load. Since with the + * separation of the 'load' and 'findsymbol' be do not necessarily + * know a symbol name at load time, we have to store some further + * information in a structure like this so we can ensure we load + * properly in 'findsymbol' if the first attempts didn't work. + */ +typedef struct TclMacLoadInfo { + int loaded; + CFragConnectionID connID; + FSSpec fileSpec; +} TclMacLoadInfo; + +static int TryToLoad(Tcl_Interp *interp, TclMacLoadInfo *loadInfo, Tcl_Obj *pathPtr, + CONST char *sym /* native */); + + +/* + *---------------------------------------------------------------------- + * + * TclpDlopen -- + * + * This procedure is called to carry out dynamic loading of binary + * code for the Macintosh. This implementation is based on the + * Code Fragment Manager & will not work on other systems. + * + * Results: + * The result is TCL_ERROR, and an error message is left in + * the interp's result. + * + * Side effects: + * New binary code is loaded. + * + *---------------------------------------------------------------------- + */ + +int +TclpDlopen(interp, pathPtr, loadHandle, unloadProcPtr) + Tcl_Interp *interp; /* Used for error reporting. */ + Tcl_Obj *pathPtr; /* Name of the file containing the desired + * code (UTF-8). */ + Tcl_LoadHandle *loadHandle; /* Filled with token for dynamically loaded + * file which will be passed back to + * (*unloadProcPtr)() to unload the file. */ + Tcl_FSUnloadFileProc **unloadProcPtr; + /* Filled with address of Tcl_FSUnloadFileProc + * function which should be used for + * this file. */ +{ + OSErr err; + FSSpec fileSpec; + CONST char *native; + TclMacLoadInfo *loadInfo; + + native = Tcl_FSGetNativePath(pathPtr); + err = FSpLocationFromPath(strlen(native), native, &fileSpec); + + if (err != noErr) { + Tcl_SetResult(interp, "could not locate shared library", TCL_STATIC); + return TCL_ERROR; + } + + loadInfo = (TclMacLoadInfo *) ckalloc(sizeof(TclMacLoadInfo)); + loadInfo->loaded = 0; + loadInfo->fileSpec = fileSpec; + loadInfo->connID = NULL; + + if (TryToLoad(interp, loadInfo, pathPtr, NULL) != TCL_OK) { + ckfree((char*) loadInfo); + return TCL_ERROR; + } + + *loadHandle = (Tcl_LoadHandle)loadInfo; + *unloadProcPtr = &TclpUnloadFile; + return TCL_OK; +} + +/* + * See the comments about 'struct TclMacLoadInfo' above. This + * function ensures the appropriate library or symbol is + * loaded. + */ +static int +TryToLoad(Tcl_Interp *interp, TclMacLoadInfo *loadInfo, Tcl_Obj *pathPtr, + CONST char *sym /* native */) +{ + OSErr err; + CFragConnectionID connID; + Ptr dummy; + short fragFileRef, saveFileRef; + Handle fragResource; + UInt32 offset = 0; + UInt32 length = kCFragGoesToEOF; + Str255 errName; + StringPtr fragName=NULL; + + if (loadInfo->loaded == 1) { + return TCL_OK; + } + + /* + * See if this fragment has a 'cfrg' resource. It will tell us where + * to look for the fragment in the file. If it doesn't exist we will + * assume we have a ppc frag using the whole data fork. If it does + * exist we find the frag that matches the one we are looking for and + * get the offset and size from the resource. + */ + + saveFileRef = CurResFile(); + SetResLoad(false); + fragFileRef = FSpOpenResFile(&loadInfo->fileSpec, fsRdPerm); + SetResLoad(true); + if (fragFileRef != -1) { + if (sym != NULL) { + UseResFile(fragFileRef); + fragResource = Get1Resource(kCFragResourceType, kCFragResourceID); + HLock(fragResource); + if (ResError() == noErr) { + CfrgItem* srcItem; + long itemCount, index; + Ptr itemStart; + + itemCount = (*(CfrgHeaderPtrHand)fragResource)->itemCount; + itemStart = &(*(CfrgHeaderPtrHand)fragResource)->arrayStart; + for (index = 0; index < itemCount; + index++, itemStart += srcItem->itemSize) { + srcItem = (CfrgItem*)itemStart; + if (srcItem->archType != OUR_ARCH_TYPE) continue; + if (!strncasecmp(sym, (char *) srcItem->name + 1, + strlen(sym))) { + offset = srcItem->codeOffset; + length = srcItem->codeLength; + fragName=srcItem->name; + } + } + } + } + /* + * Close the resource file. If the extension wants to reopen the + * resource fork it should use the tclMacLibrary.c file during it's + * construction. + */ + HUnlock(fragResource); + ReleaseResource(fragResource); + CloseResFile(fragFileRef); + UseResFile(saveFileRef); + if (sym == NULL) { + /* We just return */ + return TCL_OK; + } + } + + /* + * Now we can attempt to load the fragment using the offset & length + * obtained from the resource. We don't worry about the main entry point + * as we are going to search for specific entry points passed to us. + */ + + err = GetDiskFragment(&loadInfo->fileSpec, offset, length, fragName, + kLoadCFrag, &connID, &dummy, errName); + + if (err != fragNoErr) { + p2cstr(errName); + if(pathPtr) { + Tcl_AppendResult(interp, "couldn't load file \"", + Tcl_GetString(pathPtr), + "\": ", errName, (char *) NULL); + } else if(sym) { + Tcl_AppendResult(interp, "couldn't load library \"", + sym, + "\": ", errName, (char *) NULL); + } + return TCL_ERROR; + } + + loadInfo->connID = connID; + loadInfo->loaded = 1; + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclpFindSymbol -- + * + * Looks up a symbol, by name, through a handle associated with + * a previously loaded piece of code (shared library). + * + * Results: + * Returns a pointer to the function associated with 'symbol' if + * it is found. Otherwise returns NULL and may leave an error + * message in the interp's result. + * + *---------------------------------------------------------------------- + */ +Tcl_PackageInitProc* +TclpFindSymbol(interp, loadHandle, symbol) + Tcl_Interp *interp; + Tcl_LoadHandle loadHandle; + CONST char *symbol; +{ + Tcl_DString ds; + Tcl_PackageInitProc *proc=NULL; + TclMacLoadInfo *loadInfo = (TclMacLoadInfo *)loadHandle; + Str255 symbolName; + CFragSymbolClass symClass; + OSErr err; + + if (loadInfo->loaded == 0) { + int res; + /* + * First thing we must do is infer the package name from the + * sym variable. We do this by removing the '_Init'. + */ + Tcl_UtfToExternalDString(NULL, symbol, -1, &ds); + Tcl_DStringSetLength(&ds, Tcl_DStringLength(&ds) - 5); + res = TryToLoad(interp, loadInfo, NULL, Tcl_DStringValue(&ds)); + Tcl_DStringFree(&ds); + if (res != TCL_OK) { + return NULL; + } + } + + Tcl_UtfToExternalDString(NULL, symbol, -1, &ds); + strcpy((char *) symbolName + 1, Tcl_DStringValue(&ds)); + symbolName[0] = (unsigned) Tcl_DStringLength(&ds); + err = FindSymbol(loadInfo->connID, symbolName, (Ptr *) &proc, &symClass); + Tcl_DStringFree(&ds); + if (err != fragNoErr || symClass == kDataCFragSymbol) { + Tcl_SetResult(interp, + "could not find Initialization routine in library", + TCL_STATIC); + return NULL; + } + return proc; +} + +/* + *---------------------------------------------------------------------- + * + * TclpUnloadFile -- + * + * Unloads a dynamically loaded binary code file from memory. + * Code pointers in the formerly loaded file are no longer valid + * after calling this function. + * + * Results: + * None. + * + * Side effects: + * Does nothing. Can anything be done? + * + *---------------------------------------------------------------------- + */ + +void +TclpUnloadFile(loadHandle) + Tcl_LoadHandle loadHandle; /* loadHandle returned by a previous call + * to TclpDlopen(). The loadHandle is + * a token that represents the loaded + * file. */ +{ + TclMacLoadInfo *loadInfo = (TclMacLoadInfo *)loadHandle; + if (loadInfo->loaded) { + CloseConnection((CFragConnectionID*) &(loadInfo->connID)); + } + ckfree((char*)loadInfo); +} + +/* + *---------------------------------------------------------------------- + * + * TclGuessPackageName -- + * + * If the "load" command is invoked without providing a package + * name, this procedure is invoked to try to figure it out. + * + * Results: + * Always returns 0 to indicate that we couldn't figure out a + * package name; generic code will then try to guess the package + * from the file name. A return value of 1 would have meant that + * we figured out the package name and put it in bufPtr. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TclGuessPackageName( + CONST char *fileName, /* Name of file containing package (already + * translated to local form if needed). */ + Tcl_DString *bufPtr) /* Initialized empty dstring. Append + * package name to this if possible. */ +{ + return 0; +} diff --git a/mac/tclMacMath.h b/mac/tclMacMath.h new file mode 100644 index 0000000..6366dc3 --- /dev/null +++ b/mac/tclMacMath.h @@ -0,0 +1,145 @@ +/* + * tclMacMath.h -- + * + * This file is necessary because of Metrowerks CodeWarrior Pro 1 + * on the Macintosh. With 8-byte doubles turned on, the definitions of + * sin, cos, acos, etc., are screwed up. They are fine as long as + * they are used as function calls, but if the function pointers + * are passed around and used, they will crash hard on the 68K. + * + * Copyright (c) 1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacMath.h,v 1.3 2001/11/23 01:27:50 das Exp $ + */ + +#ifndef _TCLMACMATH +#define _TCLMACMATH + +#include <math.h> + +#if defined(__MWERKS__) && !defined(__POWERPC__) +#if __option(IEEEdoubles) + +# ifdef cos +# undef cos +# define cos cosd +# endif + +# ifdef sin +# undef sin +# define sin sind +# endif + +# ifdef tan +# undef tan +# define tan tand +# endif + +# ifdef acos +# undef acos +# define acos acosd +# endif + +# ifdef asin +# undef asin +# define asin asind +# endif + +# ifdef atan +# undef atan +# define atan atand +# endif + +# ifdef cosh +# undef cosh +# define cosh coshd +# endif + +# ifdef sinh +# undef sinh +# define sinh sinhd +# endif + +# ifdef tanh +# undef tanh +# define tanh tanhd +# endif + +# ifdef exp +# undef exp +# define exp expd +# endif + +# ifdef ldexp +# undef ldexp +# define ldexp ldexpd +# endif + +# ifdef log +# undef log +# define log logd +# endif + +# ifdef log10 +# undef log10 +# define log10 log10d +# endif + +# ifdef fabs +# undef fabs +# define fabs fabsd +# endif + +# ifdef sqrt +# undef sqrt +# define sqrt sqrtd +# endif + +# ifdef fmod +# undef fmod +# define fmod fmodd +# endif + +# ifdef atan2 +# undef atan2 +# define atan2 atan2d +# endif + +# ifdef frexp +# undef frexp +# define frexp frexpd +# endif + +# ifdef modf +# undef modf +# define modf modfd +# endif + +# ifdef pow +# undef pow +# define pow powd +# endif + +# ifdef ceil +# undef ceil +# define ceil ceild +# endif + +# ifdef floor +# undef floor +# define floor floord +# endif +#endif +#endif + +#if (defined(THINK_C)) +#pragma export on +double hypotd(double x, double y); +#define hypot hypotd +#pragma export reset +#endif + +#endif /* _TCLMACMATH */ diff --git a/mac/tclMacNotify.c b/mac/tclMacNotify.c new file mode 100644 index 0000000..f2704be --- /dev/null +++ b/mac/tclMacNotify.c @@ -0,0 +1,581 @@ +/* + * tclMacNotify.c -- + * + * This file contains Macintosh-specific procedures for the notifier, + * which is the lowest-level part of the Tcl event loop. This file + * works together with ../generic/tclNotify.c. + * + * The Mac notifier only polls for system and OS events, so it is process + * wide, rather than thread specific. However, this means that the convert + * event proc will have to arbitrate which events go to which threads. + * + * Copyright (c) 1995-1996 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacNotify.c,v 1.9 2003/03/21 03:23:24 dgp Exp $ + */ + +#include "tclInt.h" +#include "tclPort.h" +#include "tclMac.h" +#include "tclMacInt.h" +#include <signal.h> +#include <Events.h> +#include <LowMem.h> +#include <Processes.h> +#include <Timer.h> +#include <Threads.h> + + +/* + * This is necessary to work around a bug in Apple's Universal header files + * for the CFM68K libraries. + */ + +#ifdef __CFM68K__ +#undef GetEventQueue +extern pascal QHdrPtr GetEventQueue(void) + THREEWORDINLINE(0x2EBC, 0x0000, 0x014A); +#pragma import list GetEventQueue +#define GetEvQHdr() GetEventQueue() +#endif + +/* + * Need this for replacing Tcl_SetTimer and Tcl_WaitForEvent defined + * in THIS file with ones defined in the stub table. + */ + +extern TclStubs tclStubs; +extern Tcl_NotifierProcs tclOriginalNotifier; + +/* + * The follwing static indicates whether this module has been initialized. + */ + +static int initialized = 0; + +/* + * The following structure contains the state information for the + * notifier module. + */ + +static struct { + int timerActive; /* 1 if timer is running. */ + Tcl_Time timer; /* Time when next timer event is expected. */ + int flags; /* OR'ed set of flags defined below. */ + Point lastMousePosition; /* Last known mouse location. */ + RgnHandle utilityRgn; /* Region used as the mouse region for + * WaitNextEvent and the update region when + * checking for events. */ + Tcl_MacConvertEventPtr eventProcPtr; + /* This pointer holds the address of the + * function that will handle all incoming + * Macintosh events. */ +} notifier; + +/* + * The following defines are used in the flags field of the notifier struct. + */ + +#define NOTIFY_IDLE (1<<1) /* Tcl_ServiceIdle should be called. */ +#define NOTIFY_TIMER (1<<2) /* Tcl_ServiceTimer should be called. */ + +/* + * Prototypes for procedures that are referenced only in this file: + */ + +static int HandleMacEvents _ANSI_ARGS_((void)); +static void InitNotifier _ANSI_ARGS_((void)); +static void NotifierExitHandler _ANSI_ARGS_(( + ClientData clientData)); + +/* + *---------------------------------------------------------------------- + * + * Tcl_InitNotifier -- + * + * Initializes the platform specific notifier state. There is no thread + * specific platform notifier on the Mac, so this really doesn't do + * anything. However, we need to return the ThreadID, since the generic + * notifier hands this back to us in AlertThread. + * + * Results: + * Returns the threadID for this thread. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +ClientData +Tcl_InitNotifier() +{ + +#ifdef TCL_THREADS + ThreadID curThread; + if (TclMacHaveThreads()) { + GetCurrentThread(&curThread); + return (ClientData) curThread; + } else { + return NULL; + } +#else + return NULL; +#endif + +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_FinalizeNotifier -- + * + * This function is called to cleanup the notifier state before + * a thread is terminated. There is no platform thread specific + * notifier, so this does nothing. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_FinalizeNotifier(clientData) + ClientData clientData; /* Pointer to notifier data. */ +{ + /* Nothing to do on the Mac */ +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_AlertNotifier -- + * + * Wake up the specified notifier from any thread. This routine + * is called by the platform independent notifier code whenever + * the Tcl_ThreadAlert routine is called. This routine is + * guaranteed not to be called on a given notifier after + * Tcl_FinalizeNotifier is called for that notifier. + * + * Results: + * None. + * + * Side effects: + * Calls YieldToThread from this thread. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_AlertNotifier(clientData) + ClientData clientData; /* Pointer to thread data. */ +{ + +#ifdef TCL_THREADS + if (TclMacHaveThreads()) { + YieldToThread((ThreadID) clientData); + } +#endif + +} + +/* + *---------------------------------------------------------------------- + * + * InitNotifier -- + * + * Initializes the notifier structure. Note - this function is never + * used. + * + * Results: + * None. + * + * Side effects: + * Creates a new exit handler. + * + *---------------------------------------------------------------------- + */ + +static void +InitNotifier(void) +{ + initialized = 1; + memset(¬ifier, 0, sizeof(notifier)); + Tcl_CreateExitHandler(NotifierExitHandler, NULL); +} + +/* + *---------------------------------------------------------------------- + * + * NotifierExitHandler -- + * + * This function is called to cleanup the notifier state before + * Tcl is unloaded. This function is never used, since InitNotifier + * isn't either. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static void +NotifierExitHandler( + ClientData clientData) /* Not used. */ +{ + initialized = 0; +} + +/* + *---------------------------------------------------------------------- + * + * HandleMacEvents -- + * + * This function checks for events from the Macintosh event queue. + * + * Results: + * Returns 1 if event found, 0 otherwise. + * + * Side effects: + * Pulls events off of the Mac event queue and then calls + * convertEventProc. + * + *---------------------------------------------------------------------- + */ + +static int +HandleMacEvents(void) +{ + EventRecord theEvent; + int eventFound = 0, needsUpdate = 0; + Point currentMouse; + WindowRef windowRef; + Rect mouseRect; + + /* + * Check for mouse moved events. These events aren't placed on the + * system event queue unless we call WaitNextEvent. + */ + + GetGlobalMouseTcl(¤tMouse); + if ((notifier.eventProcPtr != NULL) && + !EqualPt(currentMouse, notifier.lastMousePosition)) { + notifier.lastMousePosition = currentMouse; + theEvent.what = nullEvent; + if ((*notifier.eventProcPtr)(&theEvent) == true) { + eventFound = 1; + } + } + + /* + * Check for update events. Since update events aren't generated + * until we call GetNextEvent, we may need to force a call to + * GetNextEvent, even if the queue is empty. + */ + + for (windowRef = FrontWindow(); windowRef != NULL; + windowRef = GetNextWindow(windowRef)) { + GetWindowUpdateRgn(windowRef, notifier.utilityRgn); + if (!EmptyRgn(notifier.utilityRgn)) { + needsUpdate = 1; + break; + } + } + + /* + * Process events from the OS event queue. + */ + + while (needsUpdate || (GetEvQHdr()->qHead != NULL)) { + GetGlobalMouseTcl(¤tMouse); + SetRect(&mouseRect, currentMouse.h, currentMouse.v, + currentMouse.h + 1, currentMouse.v + 1); + RectRgn(notifier.utilityRgn, &mouseRect); + + WaitNextEvent(everyEvent, &theEvent, 5, notifier.utilityRgn); + needsUpdate = 0; + if ((notifier.eventProcPtr != NULL) + && ((*notifier.eventProcPtr)(&theEvent) == true)) { + eventFound = 1; + } + } + + return eventFound; +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_SetTimer -- + * + * This procedure sets the current notifier timer value. The + * notifier will ensure that Tcl_ServiceAll() is called after + * the specified interval, even if no events have occurred. + * + * Results: + * None. + * + * Side effects: + * Replaces any previous timer. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_SetTimer( + Tcl_Time *timePtr) /* New value for interval timer. */ +{ + /* + * Allow the notifier to be hooked. This may not make sense + * on the Mac, but mirrors the UNIX hook. + */ + + if (tclStubs.tcl_SetTimer != tclOriginalNotifier.setTimerProc) { + tclStubs.tcl_SetTimer(timePtr); + return; + } + + if (!timePtr) { + notifier.timerActive = 0; + } else { + /* + * Compute when the timer should fire. + */ + + Tcl_GetTime(¬ifier.timer); + notifier.timer.sec += timePtr->sec; + notifier.timer.usec += timePtr->usec; + if (notifier.timer.usec >= 1000000) { + notifier.timer.usec -= 1000000; + notifier.timer.sec += 1; + } + notifier.timerActive = 1; + } +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_ServiceModeHook -- + * + * This function is invoked whenever the service mode changes. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_ServiceModeHook(mode) + int mode; /* Either TCL_SERVICE_ALL, or + * TCL_SERVICE_NONE. */ +{ +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_WaitForEvent -- + * + * This function is called by Tcl_DoOneEvent to wait for new + * events on the message queue. If the block time is 0, then + * Tcl_WaitForEvent just polls the event queue without blocking. + * + * Results: + * Always returns 0. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_WaitForEvent( + Tcl_Time *timePtr) /* Maximum block time. */ +{ + int found; + EventRecord macEvent; + long sleepTime = 5; + long ms; + Point currentMouse; + void * timerToken; + Rect mouseRect; + + /* + * Allow the notifier to be hooked. This may not make + * sense on the Mac, but mirrors the UNIX hook. + */ + + if (tclStubs.tcl_WaitForEvent != tclOriginalNotifier.waitForEventProc) { + return tclStubs.tcl_WaitForEvent(timePtr); + } + + /* + * Compute the next timeout value. + */ + + if (!timePtr) { + ms = INT_MAX; + } else { + ms = (timePtr->sec * 1000) + (timePtr->usec / 1000); + } + timerToken = TclMacStartTimer((long) ms); + + /* + * Poll the Mac event sources. This loop repeats until something + * happens: a timeout, a socket event, mouse motion, or some other + * window event. Note that we don't call WaitNextEvent if another + * event is found to avoid context switches. This effectively gives + * events coming in via WaitNextEvent a slightly lower priority. + */ + + found = 0; + if (notifier.utilityRgn == NULL) { + notifier.utilityRgn = NewRgn(); + } + + while (!found) { + /* + * Check for generated and queued events. + */ + + if (HandleMacEvents()) { + found = 1; + } + + /* + * Check for time out. + */ + + if (!found && TclMacTimerExpired(timerToken)) { + found = 1; + } + + /* + * Check for window events. We may receive a NULL event for + * various reasons. 1) the timer has expired, 2) a mouse moved + * event is occuring or 3) the os is giving us time for idle + * events. Note that we aren't sharing the processor very + * well here. We really ought to do a better job of calling + * WaitNextEvent for time slicing purposes. + */ + + if (!found) { + /* + * Set up mouse region so we will wake if the mouse is moved. + * We do this by defining the smallest possible region around + * the current mouse position. + */ + + GetGlobalMouseTcl(¤tMouse); + SetRect(&mouseRect, currentMouse.h, currentMouse.v, + currentMouse.h + 1, currentMouse.v + 1); + RectRgn(notifier.utilityRgn, &mouseRect); + + WaitNextEvent(everyEvent, &macEvent, sleepTime, + notifier.utilityRgn); + + if (notifier.eventProcPtr != NULL) { + if ((*notifier.eventProcPtr)(&macEvent) == true) { + found = 1; + } + } + } + } + TclMacRemoveTimer(timerToken); + + /* + * Yield time to nay other thread at this point. If we find that the + * apps thrash too switching between threads, we can put a timer here, + * and only yield when the timer fires. + */ + + if (TclMacHaveThreads()) { + YieldToAnyThread(); + } + + return 0; +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_Sleep -- + * + * Delay execution for the specified number of milliseconds. This + * is not a very good call to make. It will block the system - + * you will not even be able to switch applications. + * + * Results: + * None. + * + * Side effects: + * Time passes. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_Sleep( + int ms) /* Number of milliseconds to sleep. */ +{ + EventRecord dummy; + void *timerToken; + + if (ms <= 0) { + return; + } + + timerToken = TclMacStartTimer((long) ms); + while (1) { + WaitNextEvent(0, &dummy, (ms / 16.66) + 1, NULL); + if (TclMacHaveThreads()) { + YieldToAnyThread(); + } + if (TclMacTimerExpired(timerToken)) { + break; + } + } + TclMacRemoveTimer(timerToken); +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_MacSetEventProc -- + * + * This function sets the event handling procedure for the + * application. This function will be passed all incoming Mac + * events. This function usually controls the console or some + * other entity like Tk. + * + * Results: + * None. + * + * Side effects: + * Changes the event handling function. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_MacSetEventProc( + Tcl_MacConvertEventPtr procPtr) +{ + notifier.eventProcPtr = procPtr; +} diff --git a/mac/tclMacOSA.c b/mac/tclMacOSA.c new file mode 100644 index 0000000..fdcd56e --- /dev/null +++ b/mac/tclMacOSA.c @@ -0,0 +1,2958 @@ +/* + * tclMacOSA.c -- + * + * This contains the initialization routines, and the implementation of + * the OSA and Component commands. These commands allow you to connect + * with the AppleScript or any other OSA component to compile and execute + * scripts. + * + * Copyright (c) 1996 Lucent Technologies and Jim Ingham + * Copyright (c) 1997 Sun Microsystems, Inc. + * + * See the file "License Terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacOSA.c,v 1.11 2003/12/24 04:18:21 davygrvy Exp $ + */ + +#define MAC_TCL + +#include <Aliases.h> +#include <string.h> +#include <AppleEvents.h> +#include <AppleScript.h> +#include <OSA.h> +#include <OSAGeneric.h> +#include <Script.h> + +#include <FullPath.h> +#include <components.h> + +#include <resources.h> +#include <FSpCompat.h> +/* + * The following two Includes are from the More Files package. + */ +#include <MoreFiles.h> +#include <FullPath.h> + +#include "tcl.h" +#include "tclInt.h" + +/* + * I need this only for the call to FspGetFullPath, + * I'm really not poking my nose where it does not belong! + */ +#include "tclMacInt.h" + +/* + * Data structures used by the OSA code. + */ +typedef struct tclOSAScript { + OSAID scriptID; + OSType languageID; + long modeFlags; +} tclOSAScript; + +typedef struct tclOSAContext { + OSAID contextID; +} tclOSAContext; + +typedef struct tclOSAComponent { + char *theName; + ComponentInstance theComponent; /* The OSA Component represented */ + long componentFlags; + OSType languageID; + char *languageName; + Tcl_HashTable contextTable; /* Hash Table linking the context names & ID's */ + Tcl_HashTable scriptTable; + Tcl_Interp *theInterp; + OSAActiveUPP defActiveProc; + long defRefCon; +} tclOSAComponent; + +/* + * Prototypes for static procedures. + */ + +static pascal OSErr TclOSAActiveProc _ANSI_ARGS_((long refCon)); +static int TclOSACompileCmd _ANSI_ARGS_((Tcl_Interp *interp, + tclOSAComponent *OSAComponent, int argc, + CONST char **argv)); +static int tclOSADecompileCmd _ANSI_ARGS_((Tcl_Interp * Interp, + tclOSAComponent *OSAComponent, int argc, + CONST char **argv)); +static int tclOSADeleteCmd _ANSI_ARGS_((Tcl_Interp *interp, + tclOSAComponent *OSAComponent, int argc, + CONST char **argv)); +static int tclOSAExecuteCmd _ANSI_ARGS_((Tcl_Interp *interp, + tclOSAComponent *OSAComponent, int argc, + CONST char **argv)); +static int tclOSAInfoCmd _ANSI_ARGS_((Tcl_Interp *interp, + tclOSAComponent *OSAComponent, int argc, + CONST char **argv)); +static int tclOSALoadCmd _ANSI_ARGS_((Tcl_Interp *interp, + tclOSAComponent *OSAComponent, int argc, + CONST char **argv)); +static int tclOSARunCmd _ANSI_ARGS_((Tcl_Interp *interp, + tclOSAComponent *OSAComponent, int argc, + CONST char **argv)); +static int tclOSAStoreCmd _ANSI_ARGS_((Tcl_Interp *interp, + tclOSAComponent *OSAComponent, int argc, + CONST char **argv)); +static void GetRawDataFromDescriptor _ANSI_ARGS_((AEDesc *theDesc, + Ptr destPtr, Size destMaxSize, Size *actSize)); +static OSErr GetCStringFromDescriptor _ANSI_ARGS_(( + AEDesc *sourceDesc, char *resultStr, + Size resultMaxSize,Size *resultSize)); +static int Tcl_OSAComponentCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int argc, CONST char **argv)); +static void getSortedHashKeys _ANSI_ARGS_((Tcl_HashTable *theTable, + CONST char *pattern, Tcl_DString *theResult)); +static int ASCIICompareProc _ANSI_ARGS_((const void *first, + const void *second)); +static int Tcl_OSACmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int argc, CONST char **argv)); +static void tclOSAClose _ANSI_ARGS_((ClientData clientData)); +/*static void tclOSACloseAll _ANSI_ARGS_((ClientData clientData));*/ +static tclOSAComponent *tclOSAMakeNewComponent _ANSI_ARGS_((Tcl_Interp *interp, + char *cmdName, char *languageName, + OSType scriptSubtype, long componentFlags)); +static int prepareScriptData _ANSI_ARGS_((int argc, CONST char **argv, + Tcl_DString *scrptData ,AEDesc *scrptDesc)); +static void tclOSAResultFromID _ANSI_ARGS_((Tcl_Interp *interp, + ComponentInstance theComponent, OSAID resultID)); +static void tclOSAASError _ANSI_ARGS_((Tcl_Interp * interp, + ComponentInstance theComponent, char *scriptSource)); +static int tclOSAGetContextID _ANSI_ARGS_((tclOSAComponent *theComponent, + CONST char *contextName, OSAID *theContext)); +static void tclOSAAddContext _ANSI_ARGS_((tclOSAComponent *theComponent, + char *contextName, const OSAID theContext)); +static int tclOSAMakeContext _ANSI_ARGS_((tclOSAComponent *theComponent, + CONST char *contextName, OSAID *theContext)); +static int tclOSADeleteContext _ANSI_ARGS_((tclOSAComponent *theComponent, + CONST char *contextName)); +static int tclOSALoad _ANSI_ARGS_((Tcl_Interp *interp, + tclOSAComponent *theComponent, CONST char *resourceName, + int resourceNumber, CONST char *fileName,OSAID *resultID)); +static int tclOSAStore _ANSI_ARGS_((Tcl_Interp *interp, + tclOSAComponent *theComponent, CONST char *resourceName, + int resourceNumber, CONST char *scriptName, CONST char *fileName)); +static int tclOSAAddScript _ANSI_ARGS_((tclOSAComponent *theComponent, + char *scriptName, long modeFlags, OSAID scriptID)); +static int tclOSAGetScriptID _ANSI_ARGS_((tclOSAComponent *theComponent, + CONST char *scriptName, OSAID *scriptID)); +static tclOSAScript * tclOSAGetScript _ANSI_ARGS_((tclOSAComponent *theComponent, + CONST char *scriptName)); +static int tclOSADeleteScript _ANSI_ARGS_((tclOSAComponent *theComponent, + CONST char *scriptName,char *errMsg)); + +/* + * "export" is a MetroWerks specific pragma. It flags the linker that + * any symbols that are defined when this pragma is on will be exported + * to shared libraries that link with this library. + */ + + +#pragma export on +int Tclapplescript_Init( Tcl_Interp *interp ); +#pragma export reset + +/* + *---------------------------------------------------------------------- + * + * Tclapplescript_Init -- + * + * Initializes the the OSA command which opens connections to + * OSA components, creates the AppleScript command, which opens an + * instance of the AppleScript component,and constructs the table of + * available languages. + * + * Results: + * A standard Tcl result. + * + * Side Effects: + * Opens one connection to the AppleScript component, if + * available. Also builds up a table of available OSA languages, + * and creates the OSA command. + * + *---------------------------------------------------------------------- + */ + +int +Tclapplescript_Init( + Tcl_Interp *interp) /* Tcl interpreter. */ +{ + char *errMsg = NULL; + OSErr myErr = noErr; + Boolean gotAppleScript = false; + Boolean GotOneOSALanguage = false; + ComponentDescription compDescr = { + kOSAComponentType, + (OSType) 0, + (OSType) 0, + (long) 0, + (long) 0 + }, *foundComp; + Component curComponent = (Component) 0; + ComponentInstance curOpenComponent; + Tcl_HashTable *ComponentTable; + Tcl_HashTable *LanguagesTable; + Tcl_HashEntry *hashEntry; + int newPtr; + AEDesc componentName = { typeNull, NULL }; + char nameStr[32]; + Size nameLen; + long appleScriptFlags; + + /* + * Perform the required stubs magic... + */ + + if (!Tcl_InitStubs(interp, "8.2", 0)) { + return TCL_ERROR; + } + + /* + * Here We Will Get The Available Osa Languages, Since They Can Only Be + * Registered At Startup... If You Dynamically Load Components, This + * Will Fail, But This Is Not A Common Thing To Do. + */ + + LanguagesTable = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); + + if (LanguagesTable == NULL) { + Tcl_Panic("Memory Error Allocating Languages Hash Table"); + } + + Tcl_SetAssocData(interp, "OSAScript_LangTable", NULL, LanguagesTable); + Tcl_InitHashTable(LanguagesTable, TCL_STRING_KEYS); + + + while ((curComponent = FindNextComponent(curComponent, &compDescr)) != 0) { + int nbytes = sizeof(ComponentDescription); + foundComp = (ComponentDescription *) + ckalloc(sizeof(ComponentDescription)); + myErr = GetComponentInfo(curComponent, foundComp, NULL, NULL, NULL); + if (foundComp->componentSubType == + kOSAGenericScriptingComponentSubtype) { + /* Skip the generic component */ + ckfree((char *) foundComp); + } else { + GotOneOSALanguage = true; + + /* + * This is gross: looks like I have to open the component just + * to get its name!!! GetComponentInfo is supposed to return + * the name, but AppleScript always returns an empty string. + */ + + curOpenComponent = OpenComponent(curComponent); + if (curOpenComponent == NULL) { + Tcl_AppendResult(interp,"Error opening component", + (char *) NULL); + return TCL_ERROR; + } + + myErr = OSAScriptingComponentName(curOpenComponent,&componentName); + if (myErr == noErr) { + myErr = GetCStringFromDescriptor(&componentName, + nameStr, 31, &nameLen); + AEDisposeDesc(&componentName); + } + CloseComponent(curOpenComponent); + + if (myErr == noErr) { + hashEntry = Tcl_CreateHashEntry(LanguagesTable, + nameStr, &newPtr); + Tcl_SetHashValue(hashEntry, (ClientData) foundComp); + } else { + Tcl_AppendResult(interp,"Error getting componentName.", + (char *) NULL); + return TCL_ERROR; + } + + /* + * Make sure AppleScript is loaded, otherwise we will + * not bother to make the AppleScript command. + */ + if (foundComp->componentSubType == kAppleScriptSubtype) { + appleScriptFlags = foundComp->componentFlags; + gotAppleScript = true; + } + } + } + + /* + * Create the OSA command. + */ + + if (!GotOneOSALanguage) { + Tcl_AppendResult(interp,"Could not find any OSA languages", + (char *) NULL); + return TCL_ERROR; + } + + /* + * Create the Component Assoc Data & put it in the interpreter. + */ + + ComponentTable = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); + + if (ComponentTable == NULL) { + Tcl_Panic("Memory Error Allocating Hash Table"); + } + + Tcl_SetAssocData(interp, "OSAScript_CompTable", NULL, ComponentTable); + + Tcl_InitHashTable(ComponentTable, TCL_STRING_KEYS); + + /* + * The OSA command is not currently supported. + Tcl_CreateCommand(interp, "OSA", Tcl_OSACmd, (ClientData) NULL, + (Tcl_CmdDeleteProc *) NULL); + */ + + /* + * Open up one AppleScript component, with a default context + * and tie it to the AppleScript command. + * If the user just wants single-threaded AppleScript execution + * this should be enough. + * + */ + + if (gotAppleScript) { + if (tclOSAMakeNewComponent(interp, "AppleScript", + "AppleScript English", kAppleScriptSubtype, + appleScriptFlags) == NULL ) { + return TCL_ERROR; + } + } + + return Tcl_PkgProvide(interp, "OSAConnect", "1.0"); +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_OSACmd -- + * + * This is the command that provides the interface to the OSA + * component manager. The subcommands are: close: close a component, + * info: get info on components open, and open: get a new connection + * with the Scripting Component + * + * Results: + * A standard Tcl result. + * + * Side effects: + * Depends on the subcommand, see the user documentation + * for more details. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_OSACmd( + ClientData clientData, + Tcl_Interp *interp, + int argc, + CONST char **argv) +{ + static unsigned short componentCmdIndex = 0; + char autoName[32]; + char c; + int length; + Tcl_HashTable *ComponentTable = NULL; + + + if (argc == 1) { + Tcl_AppendResult(interp, "Wrong # of arguments, should be \"", + argv[0], " option\"", (char *) NULL); + return TCL_ERROR; + } + + c = *argv[1]; + length = strlen(argv[1]); + + /* + * Query out the Component Table, since most of these commands use it... + */ + + ComponentTable = (Tcl_HashTable *) Tcl_GetAssocData(interp, + "OSAScript_CompTable", (Tcl_InterpDeleteProc **) NULL); + + if (ComponentTable == NULL) { + Tcl_AppendResult(interp, "Error, could not get the Component Table", + " from the Associated data.", (char *) NULL); + return TCL_ERROR; + } + + if (c == 'c' && strncmp(argv[1],"close",length) == 0) { + Tcl_HashEntry *hashEntry; + if (argc != 3) { + Tcl_AppendResult(interp, "Wrong # of arguments, should be \"", + argv[0], " ",argv[1], " componentName\"", + (char *) NULL); + return TCL_ERROR; + } + + if ((hashEntry = Tcl_FindHashEntry(ComponentTable,argv[2])) == NULL) { + Tcl_AppendResult(interp, "Component \"", argv[2], "\" not found", + (char *) NULL); + return TCL_ERROR; + } else { + Tcl_DeleteCommand(interp,argv[2]); + return TCL_OK; + } + } else if (c == 'o' && strncmp(argv[1],"open",length) == 0) { + /* + * Default language is AppleScript. + */ + OSType scriptSubtype = kAppleScriptSubtype; + char *languageName = "AppleScript English"; + char *errMsg = NULL; + ComponentDescription *theCD; + + argv += 2; + argc -= 2; + + while (argc > 0 ) { + if (*argv[0] == '-') { + c = *(argv[0] + 1); + if (c == 'l' && strcmp(argv[0] + 1, "language") == 0) { + if (argc == 1) { + Tcl_AppendResult(interp, + "Error - no language provided for the -language switch", + (char *) NULL); + return TCL_ERROR; + } else { + Tcl_HashEntry *hashEntry; + Tcl_HashSearch search; + Boolean gotIt = false; + Tcl_HashTable *LanguagesTable; + + /* + * Look up the language in the languages table + * Do a simple strstr match, so AppleScript + * will match "AppleScript English"... + */ + + LanguagesTable = Tcl_GetAssocData(interp, + "OSAScript_LangTable", + (Tcl_InterpDeleteProc **) NULL); + + for (hashEntry = + Tcl_FirstHashEntry(LanguagesTable, &search); + hashEntry != NULL; + hashEntry = Tcl_NextHashEntry(&search)) { + languageName = Tcl_GetHashKey(LanguagesTable, + hashEntry); + if (strstr(languageName,argv[1]) != NULL) { + theCD = (ComponentDescription *) + Tcl_GetHashValue(hashEntry); + gotIt = true; + break; + } + } + if (!gotIt) { + Tcl_AppendResult(interp, + "Error, could not find the language \"", + argv[1], + "\" in the list of known languages.", + (char *) NULL); + return TCL_ERROR; + } + } + } + argc -= 2; + argv += 2; + } else { + Tcl_AppendResult(interp, "Expected a flag, but got ", + argv[0], (char *) NULL); + return TCL_ERROR; + } + } + + sprintf(autoName, "OSAComponent%-d", componentCmdIndex++); + if (tclOSAMakeNewComponent(interp, autoName, languageName, + theCD->componentSubType, theCD->componentFlags) == NULL ) { + return TCL_ERROR; + } else { + Tcl_SetResult(interp,autoName,TCL_VOLATILE); + return TCL_OK; + } + + } else if (c == 'i' && strncmp(argv[1],"info",length) == 0) { + if (argc == 2) { + Tcl_AppendResult(interp, "Wrong # of arguments, should be \"", + argv[0], " ", argv[1], " what\"", + (char *) NULL); + return TCL_ERROR; + } + + c = *argv[2]; + length = strlen(argv[2]); + + if (c == 'c' && strncmp(argv[2], "components", length) == 0) { + Tcl_DString theResult; + + Tcl_DStringInit(&theResult); + + if (argc == 3) { + getSortedHashKeys(ComponentTable,(char *) NULL, &theResult); + } else if (argc == 4) { + getSortedHashKeys(ComponentTable, argv[3], &theResult); + } else { + Tcl_AppendResult(interp, "Error: wrong # of arguments", + ", should be \"", argv[0], " ", argv[1], " ", + argv[2], " ?pattern?\".", (char *) NULL); + return TCL_ERROR; + } + Tcl_DStringResult(interp, &theResult); + return TCL_OK; + } else if (c == 'l' && strncmp(argv[2],"languages",length) == 0) { + Tcl_DString theResult; + Tcl_HashTable *LanguagesTable; + + Tcl_DStringInit(&theResult); + LanguagesTable = Tcl_GetAssocData(interp, + "OSAScript_LangTable", (Tcl_InterpDeleteProc **) NULL); + + if (argc == 3) { + getSortedHashKeys(LanguagesTable, (char *) NULL, &theResult); + } else if (argc == 4) { + getSortedHashKeys(LanguagesTable, argv[3], &theResult); + } else { + Tcl_AppendResult(interp, "Error: wrong # of arguments", + ", should be \"", argv[0], " ", argv[1], " ", + argv[2], " ?pattern?\".", (char *) NULL); + return TCL_ERROR; + } + Tcl_DStringResult(interp,&theResult); + return TCL_OK; + } else { + Tcl_AppendResult(interp, "Unknown option: ", argv[2], + " for OSA info, should be one of", + " \"components\" or \"languages\"", + (char *) NULL); + return TCL_ERROR; + } + } else { + Tcl_AppendResult(interp, "Unknown option: ", argv[1], + ", should be one of \"open\", \"close\" or \"info\".", + (char *) NULL); + return TCL_ERROR; + } + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_OSAComponentCmd -- + * + * This is the command that provides the interface with an OSA + * component. The sub commands are: + * - compile ? -context context? scriptData + * compiles the script data, returns the ScriptID + * - decompile ? -context context? scriptData + * decompiles the script data, source code + * - execute ?-context context? scriptData + * compiles and runs script data + * - info what: get component info + * - load ?-flags values? fileName + * loads & compiles script data from fileName + * - run scriptId ?options? + * executes the compiled script + * + * Results: + * A standard Tcl result + * + * Side Effects: + * Depends on the subcommand, see the user documentation + * for more details. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_OSAComponentCmd( + ClientData clientData, + Tcl_Interp *interp, + int argc, + CONST char **argv) +{ + int length; + char c; + + tclOSAComponent *OSAComponent = (tclOSAComponent *) clientData; + + if (argc == 1) { + Tcl_AppendResult(interp, "wrong # args: should be \"", + argv[0], " option ?arg ...?\"", + (char *) NULL); + return TCL_ERROR; + } + + c = *argv[1]; + length = strlen(argv[1]); + if (c == 'c' && strncmp(argv[1], "compile", length) == 0) { + return TclOSACompileCmd(interp, OSAComponent, argc, argv); + } else if (c == 'l' && strncmp(argv[1], "load", length) == 0) { + return tclOSALoadCmd(interp, OSAComponent, argc, argv); + } else if (c == 'e' && strncmp(argv[1], "execute", length) == 0) { + return tclOSAExecuteCmd(interp, OSAComponent, argc, argv); + } else if (c == 'i' && strncmp(argv[1], "info", length) == 0) { + return tclOSAInfoCmd(interp, OSAComponent, argc, argv); + } else if (c == 'd' && strncmp(argv[1], "decompile", length) == 0) { + return tclOSADecompileCmd(interp, OSAComponent, argc, argv); + } else if (c == 'd' && strncmp(argv[1], "delete", length) == 0) { + return tclOSADeleteCmd(interp, OSAComponent, argc, argv); + } else if (c == 'r' && strncmp(argv[1], "run", length) == 0) { + return tclOSARunCmd(interp, OSAComponent, argc, argv); + } else if (c == 's' && strncmp(argv[1], "store", length) == 0) { + return tclOSAStoreCmd(interp, OSAComponent, argc, argv); + } else { + Tcl_AppendResult(interp,"bad option \"", argv[1], + "\": should be compile, decompile, delete, ", + "execute, info, load, run or store", + (char *) NULL); + return TCL_ERROR; + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclOSACompileCmd -- + * + * This is the compile subcommand for the component command. + * + * Results: + * A standard Tcl result + * + * Side Effects: + * Compiles the script data either into a script or a script + * context. Adds the script to the component's script or context + * table. Sets interp's result to the name of the new script or + * context. + * + *---------------------------------------------------------------------- + */ + +static int +TclOSACompileCmd( + Tcl_Interp *interp, + tclOSAComponent *OSAComponent, + int argc, + CONST char **argv) +{ + int tclError = TCL_OK; + int augment = 1; + int makeContext = 0; + char c; + char autoName[16]; + char buffer[32]; + char *resultName; + Boolean makeNewContext = false; + Tcl_DString scrptData; + AEDesc scrptDesc = { typeNull, NULL }; + long modeFlags = kOSAModeCanInteract; + OSAID resultID = kOSANullScript; + OSAID contextID = kOSANullScript; + OSAID parentID = kOSANullScript; + OSAError osaErr = noErr; + + if (!(OSAComponent->componentFlags && kOSASupportsCompiling)) { + Tcl_AppendResult(interp, + "OSA component does not support compiling", + (char *) NULL); + return TCL_ERROR; + } + + /* + * This signals that we should make up a name, which is the + * default behavior: + */ + + autoName[0] = '\0'; + resultName = NULL; + + if (argc == 2) { + numArgs: + Tcl_AppendResult(interp, + "wrong # args: should be \"", argv[0], " ", argv[1], + " ?options? code\"",(char *) NULL); + return TCL_ERROR; + } + + argv += 2; + argc -= 2; + + /* + * Do the argument parsing. + */ + + while (argc > 0) { + + if (*argv[0] == '-') { + c = *(argv[0] + 1); + + /* + * "--" is the only switch that has no value, stops processing + */ + + if (c == '-' && *(argv[0] + 2) == '\0') { + argv += 1; + argc--; + break; + } + + /* + * So we can check here a switch with no value. + */ + + if (argc == 1) { + Tcl_AppendResult(interp, + "no value given for switch: ", + argv[0], (char *) NULL); + return TCL_ERROR; + } + + if (c == 'c' && strcmp(argv[0] + 1, "context") == 0) { + if (Tcl_GetBoolean(interp, argv[1], &makeContext) != TCL_OK) { + return TCL_ERROR; + } + } else if (c == 'a' && strcmp(argv[0] + 1, "augment") == 0) { + /* + * Augment the current context which implies making a context. + */ + + if (Tcl_GetBoolean(interp, argv[1], &augment) != TCL_OK) { + return TCL_ERROR; + } + makeContext = 1; + } else if (c == 'n' && strcmp(argv[0] + 1, "name") == 0) { + strncpy(autoName, argv[1], 15); + autoName[15] = '\0'; + resultName = autoName; + } else if (c == 'p' && strcmp(argv[0] + 1,"parent") == 0) { + /* + * Since this implies we are compiling into a context, + * set makeContext here + */ + if (tclOSAGetContextID(OSAComponent, + argv[1], &parentID) != TCL_OK) { + Tcl_AppendResult(interp, "context not found \"", + argv[1], "\"", (char *) NULL); + return TCL_ERROR; + } + makeContext = 1; + } else { + Tcl_AppendResult(interp, "bad option \"", argv[0], + "\": should be -augment, -context, -name or -parent", + (char *) NULL); + return TCL_ERROR; + } + argv += 2; + argc -= 2; + + } else { + break; + } + } + + /* + * Make sure we have some data left... + */ + if (argc == 0) { + goto numArgs; + } + + /* + * Now if we are making a context, see if it is a new one... + * There are three options here: + * 1) There was no name provided, so we autoName it + * 2) There was a name, then check and see if it already exists + * a) If yes, then makeNewContext is false + * b) Otherwise we are making a new context + */ + + if (makeContext) { + modeFlags |= kOSAModeCompileIntoContext; + if (resultName == NULL) { + /* + * Auto name the new context. + */ + resultName = autoName; + resultID = kOSANullScript; + makeNewContext = true; + } else if (tclOSAGetContextID(OSAComponent, + resultName, &resultID) == TCL_OK) { + } else { + makeNewContext = true; + } + + /* + * Deal with the augment now... + */ + if (augment && !makeNewContext) { + modeFlags |= kOSAModeAugmentContext; + } + } else if (resultName == NULL) { + resultName = autoName; /* Auto name the script */ + } + + /* + * Ok, now we have the options, so we can compile the script data. + */ + + if (prepareScriptData(argc, argv, &scrptData, &scrptDesc) == TCL_ERROR) { + Tcl_DStringResult(interp, &scrptData); + AEDisposeDesc(&scrptDesc); + return TCL_ERROR; + } + + /* + * If we want to use a parent context, we have to make the context + * by hand. Note, parentID is only specified when you make a new context. + */ + + if (parentID != kOSANullScript && makeNewContext) { + AEDesc contextDesc = { typeNull, NULL }; + + osaErr = OSAMakeContext(OSAComponent->theComponent, + &contextDesc, parentID, &resultID); + modeFlags |= kOSAModeAugmentContext; + } + + osaErr = OSACompile(OSAComponent->theComponent, &scrptDesc, + modeFlags, &resultID); + if (osaErr == noErr) { + + if (makeContext) { + /* + * For the compiled context to be active, you need to run + * the code that is in the context. + */ + OSAID activateID; + + osaErr = OSAExecute(OSAComponent->theComponent, resultID, + resultID, kOSAModeCanInteract, &activateID); + OSADispose(OSAComponent->theComponent, activateID); + + if (osaErr == noErr) { + if (makeNewContext) { + /* + * If we have compiled into a context, + * this is added to the context table + */ + + tclOSAAddContext(OSAComponent, resultName, resultID); + } + + Tcl_SetResult(interp, resultName, TCL_VOLATILE); + tclError = TCL_OK; + } + } else { + /* + * For a script, we return the script name. + */ + tclOSAAddScript(OSAComponent, resultName, modeFlags, resultID); + Tcl_SetResult(interp, resultName, TCL_VOLATILE); + tclError = TCL_OK; + } + } + + /* + * This catches the error either from the original compile, + * or from the execute in case makeContext == true + */ + + if (osaErr == errOSAScriptError) { + OSADispose(OSAComponent->theComponent, resultID); + tclOSAASError(interp, OSAComponent->theComponent, + Tcl_DStringValue(&scrptData)); + tclError = TCL_ERROR; + } else if (osaErr != noErr) { + sprintf(buffer, "Error #%-6ld compiling script", osaErr); + Tcl_AppendResult(interp, buffer, (char *) NULL); + tclError = TCL_ERROR; + } + + Tcl_DStringFree(&scrptData); + AEDisposeDesc(&scrptDesc); + + return tclError; +} + +/* + *---------------------------------------------------------------------- + * + * tclOSADecompileCmd -- + * + * This implements the Decompile subcommand of the component command + * + * Results: + * A standard Tcl result. + * + * Side Effects: + * Decompiles the script, and sets interp's result to the + * decompiled script data. + * + *---------------------------------------------------------------------- + */ + +static int +tclOSADecompileCmd( + Tcl_Interp * interp, + tclOSAComponent *OSAComponent, + int argc, + CONST char **argv) +{ + AEDesc resultingSourceData = { typeChar, NULL }; + OSAID scriptID; + Boolean isContext; + long result; + OSErr sysErr = noErr; + + if (argc == 2) { + Tcl_AppendResult(interp, "Wrong # of arguments, should be \"", + argv[0], " ",argv[1], " scriptName \"", (char *) NULL ); + return TCL_ERROR; + } + + if (!(OSAComponent->componentFlags && kOSASupportsGetSource)) { + Tcl_AppendResult(interp, + "Error, this component does not support get source", + (char *) NULL); + return TCL_ERROR; + } + + if (tclOSAGetScriptID(OSAComponent, argv[2], &scriptID) == TCL_OK) { + isContext = false; + } else if (tclOSAGetContextID(OSAComponent, argv[2], &scriptID) + == TCL_OK ) { + isContext = true; + } else { + Tcl_AppendResult(interp, "Could not find script \"", + argv[2], "\"", (char *) NULL); + return TCL_ERROR; + } + + OSAGetScriptInfo(OSAComponent->theComponent, scriptID, + kOSACanGetSource, &result); + + sysErr = OSAGetSource(OSAComponent->theComponent, + scriptID, typeChar, &resultingSourceData); + + if (sysErr == noErr) { + Tcl_DString theResult; + Tcl_DStringInit(&theResult); + + Tcl_DStringAppend(&theResult, *resultingSourceData.dataHandle, + GetHandleSize(resultingSourceData.dataHandle)); + Tcl_DStringResult(interp, &theResult); + AEDisposeDesc(&resultingSourceData); + return TCL_OK; + } else { + Tcl_AppendResult(interp, "Error getting source data", (char *) NULL); + AEDisposeDesc(&resultingSourceData); + return TCL_ERROR; + } +} + +/* + *---------------------------------------------------------------------- + * + * tclOSADeleteCmd -- + * + * This implements the Delete subcommand of the Component command. + * + * Results: + * A standard Tcl result. + * + * Side Effects: + * Deletes a script from the script list of the given component. + * Removes all references to the script, and frees the memory + * associated with it. + * + *---------------------------------------------------------------------- + */ + +static int +tclOSADeleteCmd( + Tcl_Interp *interp, + tclOSAComponent *OSAComponent, + int argc, + CONST char **argv) +{ + char c,*errMsg = NULL; + int length; + + if (argc < 4) { + Tcl_AppendResult(interp, "Wrong # of arguments, should be \"", + argv[0], " ", argv[1], " what scriptName", (char *) NULL); + return TCL_ERROR; + } + + c = *argv[2]; + length = strlen(argv[2]); + if (c == 'c' && strncmp(argv[2], "context", length) == 0) { + if (strcmp(argv[3], "global") == 0) { + Tcl_AppendResult(interp, "You cannot delete the global context", + (char *) NULL); + return TCL_ERROR; + } else if (tclOSADeleteContext(OSAComponent, argv[3]) != TCL_OK) { + Tcl_AppendResult(interp, "Error deleting script \"", argv[2], + "\": ", errMsg, (char *) NULL); + ckfree(errMsg); + return TCL_ERROR; + } + } else if (c == 's' && strncmp(argv[2], "script", length) == 0) { + if (tclOSADeleteScript(OSAComponent, argv[3], errMsg) != TCL_OK) { + Tcl_AppendResult(interp, "Error deleting script \"", argv[3], + "\": ", errMsg, (char *) NULL); + ckfree(errMsg); + return TCL_ERROR; + } + } else { + Tcl_AppendResult(interp,"Unknown value ", argv[2], + " should be one of ", + "\"context\" or \"script\".", + (char *) NULL ); + return TCL_ERROR; + } + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * tclOSAExecuteCmd -- + * + * This implements the execute subcommand of the component command. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * Executes the given script data, and sets interp's result to + * the OSA component's return value. + * + *---------------------------------------------------------------------- + */ + +static int +tclOSAExecuteCmd( + Tcl_Interp *interp, + tclOSAComponent *OSAComponent, + int argc, + CONST char **argv) +{ + int tclError = TCL_OK, resID = 128; + char c,buffer[32], + *contextName = NULL,*scriptName = NULL, *resName = NULL; + Boolean makeNewContext = false,makeContext = false; + AEDesc scrptDesc = { typeNull, NULL }; + long modeFlags = kOSAModeCanInteract; + OSAID resultID = kOSANullScript, + contextID = kOSANullScript, + parentID = kOSANullScript; + Tcl_DString scrptData; + OSAError osaErr = noErr; + OSErr sysErr = noErr; + + if (argc == 2) { + Tcl_AppendResult(interp, + "Error, no script data for \"", argv[0], + " run\"", (char *) NULL); + return TCL_ERROR; + } + + argv += 2; + argc -= 2; + + /* + * Set the context to the global context by default. + * Then parse the argument list for switches + */ + tclOSAGetContextID(OSAComponent, "global", &contextID); + + while (argc > 0) { + + if (*argv[0] == '-') { + c = *(argv[0] + 1); + + /* + * "--" is the only switch that has no value. + */ + + if (c == '-' && *(argv[0] + 2) == '\0') { + argv += 1; + argc--; + break; + } + + /* + * So we can check here for a switch with no value. + */ + + if (argc == 1) { + Tcl_AppendResult(interp, + "Error, no value given for switch ", + argv[0], (char *) NULL); + return TCL_ERROR; + } + + if (c == 'c' && strcmp(argv[0] + 1, "context") == 0) { + if (tclOSAGetContextID(OSAComponent, + argv[1], &contextID) == TCL_OK) { + } else { + Tcl_AppendResult(interp, "Script context \"", + argv[1], "\" not found", (char *) NULL); + return TCL_ERROR; + } + } else { + Tcl_AppendResult(interp, "Error, invalid switch ", argv[0], + " should be \"-context\"", (char *) NULL); + return TCL_ERROR; + } + + argv += 2; + argc -= 2; + } else { + break; + } + } + + if (argc == 0) { + Tcl_AppendResult(interp, "Error, no script data", (char *) NULL); + return TCL_ERROR; + } + + if (prepareScriptData(argc, argv, &scrptData, &scrptDesc) == TCL_ERROR) { + Tcl_DStringResult(interp, &scrptData); + AEDisposeDesc(&scrptDesc); + return TCL_ERROR; + } + /* + * Now try to compile and run, but check to make sure the + * component supports the one shot deal + */ + if (OSAComponent->componentFlags && kOSASupportsConvenience) { + osaErr = OSACompileExecute(OSAComponent->theComponent, + &scrptDesc, contextID, modeFlags, &resultID); + } else { + /* + * If not, we have to do this ourselves + */ + if (OSAComponent->componentFlags && kOSASupportsCompiling) { + OSAID compiledID = kOSANullScript; + osaErr = OSACompile(OSAComponent->theComponent, &scrptDesc, + modeFlags, &compiledID); + if (osaErr == noErr) { + osaErr = OSAExecute(OSAComponent->theComponent, compiledID, + contextID, modeFlags, &resultID); + } + OSADispose(OSAComponent->theComponent, compiledID); + } else { + /* + * The scripting component had better be able to load text data... + */ + OSAID loadedID = kOSANullScript; + + scrptDesc.descriptorType = OSAComponent->languageID; + osaErr = OSALoad(OSAComponent->theComponent, &scrptDesc, + modeFlags, &loadedID); + if (osaErr == noErr) { + OSAExecute(OSAComponent->theComponent, loadedID, + contextID, modeFlags, &resultID); + } + OSADispose(OSAComponent->theComponent, loadedID); + } + } + if (osaErr == errOSAScriptError) { + tclOSAASError(interp, OSAComponent->theComponent, + Tcl_DStringValue(&scrptData)); + tclError = TCL_ERROR; + } else if (osaErr != noErr) { + sprintf(buffer, "Error #%-6ld compiling script", osaErr); + Tcl_AppendResult(interp, buffer, (char *) NULL); + tclError = TCL_ERROR; + } else { + tclOSAResultFromID(interp, OSAComponent->theComponent, resultID); + osaErr = OSADispose(OSAComponent->theComponent, resultID); + tclError = TCL_OK; + } + + Tcl_DStringFree(&scrptData); + AEDisposeDesc(&scrptDesc); + + return tclError; +} + +/* + *---------------------------------------------------------------------- + * + * tclOSAInfoCmd -- + * + * This implements the Info subcommand of the component command + * + * Results: + * A standard Tcl result. + * + * Side effects: + * Info on scripts and contexts. See the user documentation for details. + * + *---------------------------------------------------------------------- + */ +static int +tclOSAInfoCmd( + Tcl_Interp *interp, + tclOSAComponent *OSAComponent, + int argc, + CONST char **argv) +{ + char c; + int length; + Tcl_DString theResult; + + if (argc == 2) { + Tcl_AppendResult(interp, "Wrong # of arguments, should be \"", + argv[0], " ", argv[1], " what \"", (char *) NULL ); + return TCL_ERROR; + } + + c = *argv[2]; + length = strlen(argv[2]); + if (c == 's' && strncmp(argv[2], "scripts", length) == 0) { + Tcl_DStringInit(&theResult); + if (argc == 3) { + getSortedHashKeys(&OSAComponent->scriptTable, (char *) NULL, + &theResult); + } else if (argc == 4) { + getSortedHashKeys(&OSAComponent->scriptTable, argv[3], &theResult); + } else { + Tcl_AppendResult(interp, "Error: wrong # of arguments,", + " should be \"", argv[0], " ", argv[1], " ", + argv[2], " ?pattern?", (char *) NULL); + return TCL_ERROR; + } + Tcl_DStringResult(interp, &theResult); + return TCL_OK; + } else if (c == 'c' && strncmp(argv[2], "contexts", length) == 0) { + Tcl_DStringInit(&theResult); + if (argc == 3) { + getSortedHashKeys(&OSAComponent->contextTable, (char *) NULL, + &theResult); + } else if (argc == 4) { + getSortedHashKeys(&OSAComponent->contextTable, + argv[3], &theResult); + } else { + Tcl_AppendResult(interp, "Error: wrong # of arguments for ,", + " should be \"", argv[0], " ", argv[1], " ", + argv[2], " ?pattern?", (char *) NULL); + return TCL_ERROR; + } + Tcl_DStringResult(interp, &theResult); + return TCL_OK; + } else if (c == 'l' && strncmp(argv[2], "language", length) == 0) { + Tcl_SetResult(interp, OSAComponent->languageName, TCL_STATIC); + return TCL_OK; + } else { + Tcl_AppendResult(interp, "Unknown argument \"", argv[2], + "\" for \"", argv[0], " info \", should be one of ", + "\"scripts\" \"language\", or \"contexts\"", + (char *) NULL); + return TCL_ERROR; + } +} + +/* + *---------------------------------------------------------------------- + * + * tclOSALoadCmd -- + * + * This is the load subcommand for the Component Command + * + * + * Results: + * A standard Tcl result. + * + * Side effects: + * Loads script data from the given file, creates a new context + * for it, and sets interp's result to the name of the new context. + * + *---------------------------------------------------------------------- + */ + +static int +tclOSALoadCmd( + Tcl_Interp *interp, + tclOSAComponent *OSAComponent, + int argc, + CONST char **argv) +{ + int tclError = TCL_OK, resID = 128; + char c, autoName[24], + *contextName = NULL, *scriptName = NULL; + CONST char *resName = NULL; + Boolean makeNewContext = false, makeContext = false; + AEDesc scrptDesc = { typeNull, NULL }; + long modeFlags = kOSAModeCanInteract; + OSAID resultID = kOSANullScript, + contextID = kOSANullScript, + parentID = kOSANullScript; + OSAError osaErr = noErr; + OSErr sysErr = noErr; + long scptInfo; + + autoName[0] = '\0'; + scriptName = autoName; + contextName = autoName; + + if (argc == 2) { + Tcl_AppendResult(interp, + "Error, no data for \"", argv[0], " ", argv[1], + "\"", (char *) NULL); + return TCL_ERROR; + } + + argv += 2; + argc -= 2; + + /* + * Do the argument parsing. + */ + + while (argc > 0) { + + if (*argv[0] == '-') { + c = *(argv[0] + 1); + + /* + * "--" is the only switch that has no value. + */ + + if (c == '-' && *(argv[0] + 2) == '\0') { + argv += 1; + argc--; + break; + } + + /* + * So we can check here a switch with no value. + */ + + if (argc == 1) { + Tcl_AppendResult(interp, "Error, no value given for switch ", + argv[0], (char *) NULL); + return TCL_ERROR; + } + + if (c == 'r' && strcmp(argv[0] + 1, "rsrcname") == 0) { + resName = argv[1]; + } else if (c == 'r' && strcmp(argv[0] + 1, "rsrcid") == 0) { + if (Tcl_GetInt(interp, argv[1], &resID) != TCL_OK) { + Tcl_AppendResult(interp, + "Error getting resource ID", (char *) NULL); + return TCL_ERROR; + } + } else { + Tcl_AppendResult(interp, "Error, invalid switch ", argv[0], + " should be \"--\", \"-rsrcname\" or \"-rsrcid\"", + (char *) NULL); + return TCL_ERROR; + } + + argv += 2; + argc -= 2; + } else { + break; + } + } + /* + * Ok, now we have the options, so we can load the resource, + */ + if (argc == 0) { + Tcl_AppendResult(interp, "Error, no filename given", (char *) NULL); + return TCL_ERROR; + } + + if (tclOSALoad(interp, OSAComponent, resName, resID, + argv[0], &resultID) != TCL_OK) { + Tcl_AppendResult(interp, "Error in load command", (char *) NULL); + return TCL_ERROR; + } + + /* + * Now find out whether we have a script, or a script context. + */ + + OSAGetScriptInfo(OSAComponent->theComponent, resultID, + kOSAScriptIsTypeScriptContext, &scptInfo); + + if (scptInfo) { + autoName[0] = '\0'; + tclOSAAddContext(OSAComponent, autoName, resultID); + + Tcl_SetResult(interp, autoName, TCL_VOLATILE); + } else { + /* + * For a script, we return the script name + */ + autoName[0] = '\0'; + tclOSAAddScript(OSAComponent, autoName, kOSAModeCanInteract, resultID); + Tcl_SetResult(interp, autoName, TCL_VOLATILE); + } + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * tclOSARunCmd -- + * + * This implements the run subcommand of the component command + * + * Results: + * A standard Tcl result. + * + * Side effects: + * Runs the given compiled script, and returns the OSA + * component's result. + * + *---------------------------------------------------------------------- + */ + +static int +tclOSARunCmd( + Tcl_Interp *interp, + tclOSAComponent *OSAComponent, + int argc, + CONST char **argv) +{ + int tclError = TCL_OK, + resID = 128; + char c, *contextName = NULL, + *scriptName = NULL, + *resName = NULL; + AEDesc scrptDesc = { typeNull, NULL }; + long modeFlags = kOSAModeCanInteract; + OSAID resultID = kOSANullScript, + contextID = kOSANullScript, + parentID = kOSANullScript; + OSAError osaErr = noErr; + OSErr sysErr = noErr; + CONST char *componentName = argv[0]; + OSAID scriptID; + + if (argc == 2) { + Tcl_AppendResult(interp, "Wrong # of arguments, should be \"", + argv[0], " ", argv[1], " scriptName", (char *) NULL); + return TCL_ERROR; + } + + /* + * Set the context to the global context for this component, + * as a default + */ + if (tclOSAGetContextID(OSAComponent, "global", &contextID) != TCL_OK) { + Tcl_AppendResult(interp, + "Could not find the global context for component ", + OSAComponent->theName, (char *) NULL ); + return TCL_ERROR; + } + + /* + * Now parse the argument list for switches + */ + argv += 2; + argc -= 2; + + while (argc > 0) { + if (*argv[0] == '-') { + c = *(argv[0] + 1); + /* + * "--" is the only switch that has no value + */ + if (c == '-' && *(argv[0] + 2) == '\0') { + argv += 1; + argc--; + break; + } + + /* + * So we can check here for a switch with no value. + */ + if (argc == 1) { + Tcl_AppendResult(interp, "Error, no value given for switch ", + argv[0], (char *) NULL); + return TCL_ERROR; + } + + if (c == 'c' && strcmp(argv[0] + 1, "context") == 0) { + if (argc == 1) { + Tcl_AppendResult(interp, + "Error - no context provided for the -context switch", + (char *) NULL); + return TCL_ERROR; + } else if (tclOSAGetContextID(OSAComponent, + argv[1], &contextID) == TCL_OK) { + } else { + Tcl_AppendResult(interp, "Script context \"", argv[1], + "\" not found", (char *) NULL); + return TCL_ERROR; + } + } else { + Tcl_AppendResult(interp, "Error, invalid switch ", argv[0], + " for ", componentName, + " should be \"-context\"", (char *) NULL); + return TCL_ERROR; + } + argv += 2; + argc -= 2; + } else { + break; + } + } + + if (tclOSAGetScriptID(OSAComponent, argv[0], &scriptID) != TCL_OK) { + if (tclOSAGetContextID(OSAComponent, argv[0], &scriptID) != TCL_OK) { + Tcl_AppendResult(interp, "Could not find script \"", + argv[2], "\"", (char *) NULL); + return TCL_ERROR; + } + } + + sysErr = OSAExecute(OSAComponent->theComponent, + scriptID, contextID, modeFlags, &resultID); + + if (sysErr == errOSAScriptError) { + tclOSAASError(interp, OSAComponent->theComponent, (char *) NULL); + tclError = TCL_ERROR; + } else if (sysErr != noErr) { + char buffer[32]; + sprintf(buffer, "Error #%6.6d encountered in run", sysErr); + Tcl_SetResult(interp, buffer, TCL_VOLATILE); + tclError = TCL_ERROR; + } else { + tclOSAResultFromID(interp, OSAComponent->theComponent, resultID ); + } + OSADispose(OSAComponent->theComponent, resultID); + + return tclError; +} + +/* + *---------------------------------------------------------------------- + * + * tclOSAStoreCmd -- + * + * This implements the store subcommand of the component command + * + * Results: + * A standard Tcl result. + * + * Side effects: + * Runs the given compiled script, and returns the OSA + * component's result. + * + *---------------------------------------------------------------------- + */ + +static int +tclOSAStoreCmd( + Tcl_Interp *interp, + tclOSAComponent *OSAComponent, + int argc, + CONST char **argv) +{ + int tclError = TCL_OK, resID = 128; + char c, *contextName = NULL, *scriptName = NULL; + CONST char *resName = NULL; + Boolean makeNewContext = false, makeContext = false; + AEDesc scrptDesc = { typeNull, NULL }; + long modeFlags = kOSAModeCanInteract; + OSAID resultID = kOSANullScript, + contextID = kOSANullScript, + parentID = kOSANullScript; + OSAError osaErr = noErr; + OSErr sysErr = noErr; + + if (argc == 2) { + Tcl_AppendResult(interp, "Error, no data for \"", argv[0], + " ",argv[1], "\"", (char *) NULL); + return TCL_ERROR; + } + + argv += 2; + argc -= 2; + + /* + * Do the argument parsing + */ + + while (argc > 0) { + if (*argv[0] == '-') { + c = *(argv[0] + 1); + + /* + * "--" is the only switch that has no value + */ + if (c == '-' && *(argv[0] + 2) == '\0') { + argv += 1; + argc--; + break; + } + + /* + * So we can check here a switch with no value. + */ + if (argc == 1) { + Tcl_AppendResult(interp, + "Error, no value given for switch ", + argv[0], (char *) NULL); + return TCL_ERROR; + } + + if (c == 'r' && strcmp(argv[0] + 1, "rsrcname") == 0) { + resName = argv[1]; + } else if (c == 'r' && strcmp(argv[0] + 1, "rsrcid") == 0) { + if (Tcl_GetInt(interp, argv[1], &resID) != TCL_OK) { + Tcl_AppendResult(interp, + "Error getting resource ID", (char *) NULL); + return TCL_ERROR; + } + } else { + Tcl_AppendResult(interp, "Error, invalid switch ", argv[0], + " should be \"--\", \"-rsrcname\" or \"-rsrcid\"", + (char *) NULL); + return TCL_ERROR; + } + + argv += 2; + argc -= 2; + } else { + break; + } + } + /* + * Ok, now we have the options, so we can load the resource, + */ + if (argc != 2) { + Tcl_AppendResult(interp, "Error, wrong # of arguments, should be ", + argv[0], " ", argv[1], "?option flag? scriptName fileName", + (char *) NULL); + return TCL_ERROR; + } + + if (tclOSAStore(interp, OSAComponent, resName, resID, + argv[0], argv[1]) != TCL_OK) { + Tcl_AppendResult(interp, "Error in load command", (char *) NULL); + return TCL_ERROR; + } else { + Tcl_ResetResult(interp); + tclError = TCL_OK; + } + + return tclError; +} + +/* + *---------------------------------------------------------------------- + * + * tclOSAMakeNewComponent -- + * + * Makes a command cmdName to represent a new connection to the + * OSA component with componentSubType scriptSubtype. + * + * Results: + * Returns the tclOSAComponent structure for the connection. + * + * Side Effects: + * Adds a new element to the component table. If there is an + * error, then the result of the Tcl interpreter interp is set + * to an appropriate error message. + * + *---------------------------------------------------------------------- + */ + +tclOSAComponent * +tclOSAMakeNewComponent( + Tcl_Interp *interp, + char *cmdName, + char *languageName, + OSType scriptSubtype, + long componentFlags) +{ + char buffer[32]; + AEDesc resultingName = {typeNull, NULL}; + AEDesc nullDesc = {typeNull, NULL }; + OSAID globalContext; + char global[] = "global"; + int nbytes; + ComponentDescription requestedComponent = { + kOSAComponentType, + (OSType) 0, + (OSType) 0, + (long int) 0, + (long int) 0 + }; + Tcl_HashTable *ComponentTable; + Component foundComponent = NULL; + OSAActiveUPP myActiveProcUPP; + + tclOSAComponent *newComponent; + Tcl_HashEntry *hashEntry; + int newPtr; + + requestedComponent.componentSubType = scriptSubtype; + nbytes = sizeof(tclOSAComponent); + newComponent = (tclOSAComponent *) ckalloc(sizeof(tclOSAComponent)); + if (newComponent == NULL) { + goto CleanUp; + } + + foundComponent = FindNextComponent(0, &requestedComponent); + if (foundComponent == 0) { + Tcl_AppendResult(interp, + "Could not find component of requested type", (char *) NULL); + goto CleanUp; + } + + newComponent->theComponent = OpenComponent(foundComponent); + + if (newComponent->theComponent == NULL) { + Tcl_AppendResult(interp, + "Could not open component of the requested type", + (char *) NULL); + goto CleanUp; + } + + newComponent->languageName = (char *) ckalloc(strlen(languageName) + 1); + strcpy(newComponent->languageName,languageName); + + newComponent->componentFlags = componentFlags; + + newComponent->theInterp = interp; + + Tcl_InitHashTable(&newComponent->contextTable, TCL_STRING_KEYS); + Tcl_InitHashTable(&newComponent->scriptTable, TCL_STRING_KEYS); + + if (tclOSAMakeContext(newComponent, global, &globalContext) != TCL_OK) { + sprintf(buffer, "%-6.6ld", globalContext); + Tcl_AppendResult(interp, "Error ", buffer, " making ", global, + " context.", (char *) NULL); + goto CleanUp; + } + + newComponent->languageID = scriptSubtype; + + newComponent->theName = (char *) ckalloc(strlen(cmdName) + 1 ); + strcpy(newComponent->theName, cmdName); + + Tcl_CreateCommand(interp, newComponent->theName, Tcl_OSAComponentCmd, + (ClientData) newComponent, tclOSAClose); + + /* + * Register the new component with the component table + */ + + ComponentTable = (Tcl_HashTable *) Tcl_GetAssocData(interp, + "OSAScript_CompTable", (Tcl_InterpDeleteProc **) NULL); + + if (ComponentTable == NULL) { + Tcl_AppendResult(interp, "Error, could not get the Component Table", + " from the Associated data.", (char *) NULL); + return (tclOSAComponent *) NULL; + } + + hashEntry = Tcl_CreateHashEntry(ComponentTable, + newComponent->theName, &newPtr); + Tcl_SetHashValue(hashEntry, (ClientData) newComponent); + + /* + * Set the active proc to call Tcl_DoOneEvent() while idle + */ + if (OSAGetActiveProc(newComponent->theComponent, + &newComponent->defActiveProc, &newComponent->defRefCon) != noErr ) { + /* TODO -- clean up here... */ + } + + myActiveProcUPP = NewOSAActiveUPP(TclOSAActiveProc); + OSASetActiveProc(newComponent->theComponent, + myActiveProcUPP, (long) newComponent); + return newComponent; + + CleanUp: + + ckfree((char *) newComponent); + return (tclOSAComponent *) NULL; +} + +/* + *---------------------------------------------------------------------- + * + * tclOSAClose -- + * + * This procedure closes the connection to an OSA component, and + * deletes all the script and context data associated with it. + * It is the command deletion callback for the component's command. + * + * Results: + * None + * + * Side effects: + * Closes the connection, and releases all the script data. + * + *---------------------------------------------------------------------- + */ + +void +tclOSAClose( + ClientData clientData) +{ + tclOSAComponent *theComponent = (tclOSAComponent *) clientData; + Tcl_HashEntry *hashEntry; + Tcl_HashSearch search; + tclOSAScript *theScript; + Tcl_HashTable *ComponentTable; + + /* + * Delete the context and script tables + * the memory for the language name, and + * the hash entry. + */ + + for (hashEntry = Tcl_FirstHashEntry(&theComponent->scriptTable, &search); + hashEntry != NULL; + hashEntry = Tcl_NextHashEntry(&search)) { + + theScript = (tclOSAScript *) Tcl_GetHashValue(hashEntry); + OSADispose(theComponent->theComponent, theScript->scriptID); + ckfree((char *) theScript); + Tcl_DeleteHashEntry(hashEntry); + } + + for (hashEntry = Tcl_FirstHashEntry(&theComponent->contextTable, &search); + hashEntry != NULL; + hashEntry = Tcl_NextHashEntry(&search)) { + + Tcl_DeleteHashEntry(hashEntry); + } + + ckfree(theComponent->languageName); + ckfree(theComponent->theName); + + /* + * Finally close the component + */ + + CloseComponent(theComponent->theComponent); + + ComponentTable = (Tcl_HashTable *) + Tcl_GetAssocData(theComponent->theInterp, + "OSAScript_CompTable", (Tcl_InterpDeleteProc **) NULL); + + if (ComponentTable == NULL) { + Tcl_Panic("Error, could not get the Component Table from the Associated data."); + } + + hashEntry = Tcl_FindHashEntry(ComponentTable, theComponent->theName); + if (hashEntry != NULL) { + Tcl_DeleteHashEntry(hashEntry); + } + + ckfree((char *) theComponent); +} + +/* + *---------------------------------------------------------------------- + * + * tclOSAGetContextID -- + * + * This returns the context ID, given the component name. + * + * Results: + * A context ID + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ + +static int +tclOSAGetContextID( + tclOSAComponent *theComponent, + CONST char *contextName, + OSAID *theContext) +{ + Tcl_HashEntry *hashEntry; + tclOSAContext *contextStruct; + + if ((hashEntry = Tcl_FindHashEntry(&theComponent->contextTable, + contextName)) == NULL ) { + return TCL_ERROR; + } else { + contextStruct = (tclOSAContext *) Tcl_GetHashValue(hashEntry); + *theContext = contextStruct->contextID; + } + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * tclOSAAddContext -- + * + * This adds the context ID, with the name contextName. If the + * name is passed in as a NULL string, space is malloc'ed for the + * string and a new name is made up, if the string is empty, you + * must have allocated enough space ( 24 characters is fine) for + * the name, which is made up and passed out. + * + * Results: + * Nothing + * + * Side effects: + * Adds the script context to the component's context table. + * + *---------------------------------------------------------------------- + */ + +static void +tclOSAAddContext( + tclOSAComponent *theComponent, + char *contextName, + const OSAID theContext) +{ + static unsigned short contextIndex = 0; + tclOSAContext *contextStruct; + Tcl_HashEntry *hashEntry; + int newPtr; + + if (contextName == NULL) { + contextName = ckalloc(16 + TCL_INTEGER_SPACE); + sprintf(contextName, "OSAContext%d", contextIndex++); + } else if (*contextName == '\0') { + sprintf(contextName, "OSAContext%d", contextIndex++); + } + + hashEntry = Tcl_CreateHashEntry(&theComponent->contextTable, + contextName, &newPtr); + + contextStruct = (tclOSAContext *) ckalloc(sizeof(tclOSAContext)); + contextStruct->contextID = theContext; + Tcl_SetHashValue(hashEntry,(ClientData) contextStruct); +} + +/* + *---------------------------------------------------------------------- + * + * tclOSADeleteContext -- + * + * This deletes the context struct, with the name contextName. + * + * Results: + * A normal Tcl result + * + * Side effects: + * Removes the script context to the component's context table, + * and deletes the data associated with it. + * + *---------------------------------------------------------------------- + */ + +static int +tclOSADeleteContext( + tclOSAComponent *theComponent, + CONST char *contextName) +{ + Tcl_HashEntry *hashEntry; + tclOSAContext *contextStruct; + + hashEntry = Tcl_FindHashEntry(&theComponent->contextTable, contextName); + if (hashEntry == NULL) { + return TCL_ERROR; + } + /* + * Dispose of the script context data + */ + contextStruct = (tclOSAContext *) Tcl_GetHashValue(hashEntry); + OSADispose(theComponent->theComponent,contextStruct->contextID); + /* + * Then the hash entry + */ + ckfree((char *) contextStruct); + Tcl_DeleteHashEntry(hashEntry); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * tclOSAMakeContext -- + * + * This makes the context with name contextName, and returns the ID. + * + * Results: + * A standard Tcl result + * + * Side effects: + * Makes a new context, adds it to the context table, and returns + * the new contextID in the variable theContext. + * + *---------------------------------------------------------------------- + */ + +static int +tclOSAMakeContext( + tclOSAComponent *theComponent, + CONST char *contextName, + OSAID *theContext) +{ + AEDesc contextNameDesc = {typeNull, NULL}; + OSAError osaErr = noErr; + + AECreateDesc(typeChar, contextName, strlen(contextName), &contextNameDesc); + osaErr = OSAMakeContext(theComponent->theComponent, &contextNameDesc, + kOSANullScript, theContext); + + AEDisposeDesc(&contextNameDesc); + + if (osaErr == noErr) { + char name[24]; + strncpy(name, contextName, 23); + name[23] = '\0'; + tclOSAAddContext(theComponent, name, *theContext); + } else { + *theContext = (OSAID) osaErr; + return TCL_ERROR; + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * tclOSAStore -- + * + * This stores a script resource from the file named in fileName. + * + * Most of this routine is caged from the Tcl Source, from the + * Tcl_MacSourceCmd routine. This is good, since it ensures this + * follows the same convention for looking up files as Tcl. + * + * Returns + * A standard Tcl result. + * + * Side Effects: + * The given script data is stored in the file fileName. + * + *---------------------------------------------------------------------- + */ + +int +tclOSAStore( + Tcl_Interp *interp, + tclOSAComponent *theComponent, + CONST char *resourceName, + int resourceNumber, + CONST char *scriptName, + CONST char *fileName) +{ + Handle resHandle; + Str255 rezName; + int result = TCL_OK; + short saveRef, fileRef = -1; + char idStr[16 + TCL_INTEGER_SPACE]; + FSSpec fileSpec; + Tcl_DString ds, buffer; + CONST char *nativeName; + OSErr myErr = noErr; + OSAID scriptID; + Size scriptSize; + AEDesc scriptData; + + /* + * First extract the script data + */ + + if (tclOSAGetScriptID(theComponent, scriptName, &scriptID) != TCL_OK ) { + if (tclOSAGetContextID(theComponent, scriptName, &scriptID) + != TCL_OK) { + Tcl_AppendResult(interp, "Error getting script ", + scriptName, (char *) NULL); + return TCL_ERROR; + } + } + + myErr = OSAStore(theComponent->theComponent, scriptID, + typeOSAGenericStorage, kOSAModeNull, &scriptData); + if (myErr != noErr) { + sprintf(idStr, "%d", myErr); + Tcl_AppendResult(interp, "Error #", idStr, + " storing script ", scriptName, (char *) NULL); + return TCL_ERROR; + } + + /* + * Now try to open the output file + */ + + saveRef = CurResFile(); + + if (fileName != NULL) { + OSErr err; + + if (Tcl_TranslateFileName(interp, fileName, &buffer) == NULL) { + return TCL_ERROR; + } + nativeName = Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&buffer), + Tcl_DStringLength(&buffer), &ds); + err = FSpLocationFromPath(strlen(nativeName), nativeName, &fileSpec); + + Tcl_DStringFree(&ds); + Tcl_DStringFree(&buffer); + if ((err != noErr) && (err != fnfErr)) { + Tcl_AppendResult(interp, + "Error getting a location for the file: \"", + fileName, "\".", NULL); + return TCL_ERROR; + } + + FSpCreateResFileCompatTcl(&fileSpec, + 'WiSH', 'osas', smSystemScript); + myErr = ResError(); + + if ((myErr != noErr) && (myErr != dupFNErr)) { + sprintf(idStr, "%d", myErr); + Tcl_AppendResult(interp, "Error #", idStr, + " creating new resource file ", fileName, (char *) NULL); + result = TCL_ERROR; + goto rezEvalCleanUp; + } + + fileRef = FSpOpenResFileCompatTcl(&fileSpec, fsRdWrPerm); + if (fileRef == -1) { + Tcl_AppendResult(interp, "Error reading the file: \"", + fileName, "\".", NULL); + result = TCL_ERROR; + goto rezEvalCleanUp; + } + UseResFile(fileRef); + } else { + /* + * The default behavior will search through all open resource files. + * This may not be the behavior you desire. If you want the behavior + * of this call to *only* search the application resource fork, you + * must call UseResFile at this point to set it to the application + * file. This means you must have already obtained the application's + * fileRef when the application started up. + */ + } + + /* + * Load the resource by name + */ + if (resourceName != NULL) { + strcpy((char *) rezName + 1, resourceName); + rezName[0] = strlen(resourceName); + resHandle = Get1NamedResource('scpt', rezName); + myErr = ResError(); + if (resHandle == NULL) { + /* + * These signify either the resource or the resource + * type were not found + */ + if (myErr == resNotFound || myErr == noErr) { + short uniqueID; + while ((uniqueID = Unique1ID('scpt') ) < 128) {} + AddResource(scriptData.dataHandle, 'scpt', uniqueID, rezName); + WriteResource(resHandle); + result = TCL_OK; + goto rezEvalCleanUp; + } else { + /* + * This means there was some other error, for now + * I just bag out. + */ + sprintf(idStr, "%d", myErr); + Tcl_AppendResult(interp, "Error #", idStr, + " opening scpt resource named ", resourceName, + " in file ", fileName, (char *) NULL); + result = TCL_ERROR; + goto rezEvalCleanUp; + } + } + /* + * Or ID + */ + } else { + resHandle = Get1Resource('scpt', resourceNumber); + rezName[0] = 0; + rezName[1] = '\0'; + myErr = ResError(); + if (resHandle == NULL) { + /* + * These signify either the resource or the resource + * type were not found + */ + if (myErr == resNotFound || myErr == noErr) { + AddResource(scriptData.dataHandle, 'scpt', + resourceNumber, rezName); + WriteResource(resHandle); + result = TCL_OK; + goto rezEvalCleanUp; + } else { + /* + * This means there was some other error, for now + * I just bag out */ + sprintf(idStr, "%d", myErr); + Tcl_AppendResult(interp, "Error #", idStr, + " opening scpt resource named ", resourceName, + " in file ", fileName,(char *) NULL); + result = TCL_ERROR; + goto rezEvalCleanUp; + } + } + } + + /* + * We get to here if the resource exists + * we just copy into it... + */ + + scriptSize = GetHandleSize(scriptData.dataHandle); + SetHandleSize(resHandle, scriptSize); + HLock(scriptData.dataHandle); + HLock(resHandle); + BlockMove(*scriptData.dataHandle, *resHandle,scriptSize); + HUnlock(scriptData.dataHandle); + HUnlock(resHandle); + ChangedResource(resHandle); + WriteResource(resHandle); + result = TCL_OK; + goto rezEvalCleanUp; + + rezEvalError: + sprintf(idStr, "ID=%d", resourceNumber); + Tcl_AppendResult(interp, "The resource \"", + (resourceName != NULL ? resourceName : idStr), + "\" could not be loaded from ", + (fileName != NULL ? fileName : "application"), + ".", NULL); + + rezEvalCleanUp: + if (fileRef != -1) { + CloseResFile(fileRef); + } + + UseResFile(saveRef); + + return result; +} + +/*---------------------------------------------------------------------- + * + * tclOSALoad -- + * + * This loads a script resource from the file named in fileName. + * Most of this routine is caged from the Tcl Source, from the + * Tcl_MacSourceCmd routine. This is good, since it ensures this + * follows the same convention for looking up files as Tcl. + * + * Returns + * A standard Tcl result. + * + * Side Effects: + * A new script element is created from the data in the file. + * The script ID is passed out in the variable resultID. + * + *---------------------------------------------------------------------- + */ + +int +tclOSALoad( + Tcl_Interp *interp, + tclOSAComponent *theComponent, + CONST char *resourceName, + int resourceNumber, + CONST char *fileName, + OSAID *resultID) +{ + Handle sourceData; + Str255 rezName; + int result = TCL_OK; + short saveRef, fileRef = -1; + char idStr[16 + TCL_INTEGER_SPACE]; + FSSpec fileSpec; + Tcl_DString ds, buffer; + CONST char *nativeName; + + saveRef = CurResFile(); + + if (fileName != NULL) { + OSErr err; + + if (Tcl_TranslateFileName(interp, fileName, &buffer) == NULL) { + return TCL_ERROR; + } + nativeName = Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&buffer), + Tcl_DStringLength(&buffer), &ds); + err = FSpLocationFromPath(strlen(nativeName), nativeName, &fileSpec); + Tcl_DStringFree(&ds); + Tcl_DStringFree(&buffer); + if (err != noErr) { + Tcl_AppendResult(interp, "Error finding the file: \"", + fileName, "\".", NULL); + return TCL_ERROR; + } + + fileRef = FSpOpenResFileCompatTcl(&fileSpec, fsRdPerm); + if (fileRef == -1) { + Tcl_AppendResult(interp, "Error reading the file: \"", + fileName, "\".", NULL); + return TCL_ERROR; + } + UseResFile(fileRef); + } else { + /* + * The default behavior will search through all open resource files. + * This may not be the behavior you desire. If you want the behavior + * of this call to *only* search the application resource fork, you + * must call UseResFile at this point to set it to the application + * file. This means you must have already obtained the application's + * fileRef when the application started up. + */ + } + + /* + * Load the resource by name or ID + */ + if (resourceName != NULL) { + strcpy((char *) rezName + 1, resourceName); + rezName[0] = strlen(resourceName); + sourceData = GetNamedResource('scpt', rezName); + } else { + sourceData = GetResource('scpt', (short) resourceNumber); + } + + if (sourceData == NULL) { + result = TCL_ERROR; + } else { + AEDesc scriptDesc; + OSAError osaErr; + + scriptDesc.descriptorType = typeOSAGenericStorage; + scriptDesc.dataHandle = sourceData; + + osaErr = OSALoad(theComponent->theComponent, &scriptDesc, + kOSAModeNull, resultID); + + ReleaseResource(sourceData); + + if (osaErr != noErr) { + result = TCL_ERROR; + goto rezEvalError; + } + + goto rezEvalCleanUp; + } + + rezEvalError: + sprintf(idStr, "ID=%d", resourceNumber); + Tcl_AppendResult(interp, "The resource \"", + (resourceName != NULL ? resourceName : idStr), + "\" could not be loaded from ", + (fileName != NULL ? fileName : "application"), + ".", NULL); + + rezEvalCleanUp: + if (fileRef != -1) { + CloseResFile(fileRef); + } + + UseResFile(saveRef); + + return result; +} + +/* + *---------------------------------------------------------------------- + * + * tclOSAGetScriptID -- + * + * This returns the context ID, gibven the component name. + * + * Results: + * A standard Tcl result + * + * Side effects: + * Passes out the script ID in the variable scriptID. + * + *---------------------------------------------------------------------- + */ + +static int +tclOSAGetScriptID( + tclOSAComponent *theComponent, + CONST char *scriptName, + OSAID *scriptID) +{ + tclOSAScript *theScript; + + theScript = tclOSAGetScript(theComponent, scriptName); + if (theScript == NULL) { + return TCL_ERROR; + } + + *scriptID = theScript->scriptID; + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * tclOSAAddScript -- + * + * This adds a script to theComponent's script table, with the + * given name & ID. + * + * Results: + * A standard Tcl result + * + * Side effects: + * Adds an element to the component's script table. + * + *---------------------------------------------------------------------- + */ + +static int +tclOSAAddScript( + tclOSAComponent *theComponent, + char *scriptName, + long modeFlags, + OSAID scriptID) +{ + Tcl_HashEntry *hashEntry; + int newPtr; + static int scriptIndex = 0; + tclOSAScript *theScript; + + if (*scriptName == '\0') { + sprintf(scriptName, "OSAScript%d", scriptIndex++); + } + + hashEntry = Tcl_CreateHashEntry(&theComponent->scriptTable, + scriptName, &newPtr); + if (newPtr == 0) { + theScript = (tclOSAScript *) Tcl_GetHashValue(hashEntry); + OSADispose(theComponent->theComponent, theScript->scriptID); + } else { + theScript = (tclOSAScript *) ckalloc(sizeof(tclOSAScript)); + if (theScript == NULL) { + return TCL_ERROR; + } + } + + theScript->scriptID = scriptID; + theScript->languageID = theComponent->languageID; + theScript->modeFlags = modeFlags; + + Tcl_SetHashValue(hashEntry,(ClientData) theScript); + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * tclOSAGetScriptID -- + * + * This returns the script structure, given the component and script name. + * + * Results: + * A pointer to the script structure. + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ + +static tclOSAScript * +tclOSAGetScript( + tclOSAComponent *theComponent, + CONST char *scriptName) +{ + Tcl_HashEntry *hashEntry; + + hashEntry = Tcl_FindHashEntry(&theComponent->scriptTable, scriptName); + if (hashEntry == NULL) { + return NULL; + } + + return (tclOSAScript *) Tcl_GetHashValue(hashEntry); +} + +/* + *---------------------------------------------------------------------- + * + * tclOSADeleteScript -- + * + * This deletes the script given by scriptName. + * + * Results: + * A standard Tcl result + * + * Side effects: + * Deletes the script from the script table, and frees up the + * resources associated with it. If there is an error, then + * space for the error message is malloc'ed, and passed out in + * the variable errMsg. + * + *---------------------------------------------------------------------- + */ + +static int +tclOSADeleteScript( + tclOSAComponent *theComponent, + CONST char *scriptName, + char *errMsg) +{ + Tcl_HashEntry *hashEntry; + tclOSAScript *scriptPtr; + + hashEntry = Tcl_FindHashEntry(&theComponent->scriptTable, scriptName); + if (hashEntry == NULL) { + errMsg = ckalloc(17); + strcpy(errMsg,"Script not found"); + return TCL_ERROR; + } + + scriptPtr = (tclOSAScript *) Tcl_GetHashValue(hashEntry); + OSADispose(theComponent->theComponent, scriptPtr->scriptID); + ckfree((char *) scriptPtr); + Tcl_DeleteHashEntry(hashEntry); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclOSAActiveProc -- + * + * This is passed to each component. It is run periodically + * during script compilation and script execution. It in turn + * calls Tcl_DoOneEvent to process the event queue. We also call + * the default Active proc which will let the user cancel the script + * by hitting Command-. + * + * Results: + * A standard MacOS system error + * + * Side effects: + * Any Tcl code may run while calling Tcl_DoOneEvent. + * + *---------------------------------------------------------------------- + */ + +static pascal OSErr +TclOSAActiveProc( + long refCon) +{ + tclOSAComponent *theComponent = (tclOSAComponent *) refCon; + + Tcl_DoOneEvent(TCL_DONT_WAIT); + InvokeOSAActiveUPP(theComponent->defRefCon, theComponent->defActiveProc); + + return noErr; +} + +/* + *---------------------------------------------------------------------- + * + * ASCIICompareProc -- + * + * Trivial ascii compare for use with qsort. + * + * Results: + * strcmp of the two input strings + * + * Side effects: + * None + * + *---------------------------------------------------------------------- + */ +static int +ASCIICompareProc(const void *first,const void *second) +{ + int order; + + char *firstString = *((char **) first); + char *secondString = *((char **) second); + + order = strcmp(firstString, secondString); + + return order; +} + +#define REALLOC_INCR 30 +/* + *---------------------------------------------------------------------- + * + * getSortedHashKeys -- + * + * returns an alphabetically sorted list of the keys of the hash + * theTable which match the string "pattern" in the DString + * theResult. pattern == NULL matches all. + * + * Results: + * None + * + * Side effects: + * ReInitializes the DString theResult, then copies the names of + * the matching keys into the string as list elements. + * + *---------------------------------------------------------------------- + */ + +static void +getSortedHashKeys( + Tcl_HashTable *theTable, + CONST char *pattern, + Tcl_DString *theResult) +{ + Tcl_HashSearch search; + Tcl_HashEntry *hPtr; + Boolean compare = true; + char *keyPtr; + static char **resultArgv = NULL; + static int totSize = 0; + int totElem = 0, i; + + if (pattern == NULL || *pattern == '\0' || + (*pattern == '*' && *(pattern + 1) == '\0')) { + compare = false; + } + + for (hPtr = Tcl_FirstHashEntry(theTable,&search), totElem = 0; + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + + keyPtr = (char *) Tcl_GetHashKey(theTable, hPtr); + if (!compare || Tcl_StringMatch(keyPtr, pattern)) { + totElem++; + if (totElem >= totSize) { + totSize += REALLOC_INCR; + resultArgv = (char **) ckrealloc((char *) resultArgv, + totSize * sizeof(char *)); + } + resultArgv[totElem - 1] = keyPtr; + } + } + + Tcl_DStringInit(theResult); + if (totElem == 1) { + Tcl_DStringAppendElement(theResult, resultArgv[0]); + } else if (totElem > 1) { + qsort((VOID *) resultArgv, (size_t) totElem, sizeof (char *), + ASCIICompareProc); + + for (i = 0; i < totElem; i++) { + Tcl_DStringAppendElement(theResult, resultArgv[i]); + } + } +} + +/* + *---------------------------------------------------------------------- + * + * prepareScriptData -- + * + * Massages the input data in the argv array, concating the + * elements, with a " " between each, and replacing \n with \r, + * and \\n with " ". Puts the result in the the DString scrptData, + * and copies the result to the AEdesc scrptDesc. + * + * Results: + * Standard Tcl result + * + * Side effects: + * Creates a new Handle (with AECreateDesc) for the script data. + * Stores the script in scrptData, or the error message if there + * is an error creating the descriptor. + * + *---------------------------------------------------------------------- + */ + +static int +prepareScriptData( + int argc, + CONST char **argv, + Tcl_DString *scrptData, + AEDesc *scrptDesc) +{ + char * ptr; + int i; + char buffer[7]; + OSErr sysErr = noErr; + Tcl_DString encodedText; + + Tcl_DStringInit(scrptData); + + for (i = 0; i < argc; i++) { + Tcl_DStringAppend(scrptData, argv[i], -1); + Tcl_DStringAppend(scrptData, " ", 1); + } + + /* + * First replace the \n's with \r's in the script argument + * Also replace "\\n" with " ". + */ + + for (ptr = scrptData->string; *ptr != '\0'; ptr++) { + if (*ptr == '\n') { + *ptr = '\r'; + } else if (*ptr == '\\') { + if (*(ptr + 1) == '\n') { + *ptr = ' '; + *(ptr + 1) = ' '; + } + } + } + + Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(scrptData), + Tcl_DStringLength(scrptData), &encodedText); + sysErr = AECreateDesc(typeChar, Tcl_DStringValue(&encodedText), + Tcl_DStringLength(&encodedText), scrptDesc); + Tcl_DStringFree(&encodedText); + + if (sysErr != noErr) { + sprintf(buffer, "%6d", sysErr); + Tcl_DStringFree(scrptData); + Tcl_DStringAppend(scrptData, "Error #", 7); + Tcl_DStringAppend(scrptData, buffer, -1); + Tcl_DStringAppend(scrptData, " creating Script Data Descriptor.", 33); + return TCL_ERROR; + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * tclOSAResultFromID -- + * + * Gets a human readable version of the result from the script ID + * and returns it in the result of the interpreter interp + * + * Results: + * None + * + * Side effects: + * Sets the result of interp to the human readable version of resultID. + * + * + *---------------------------------------------------------------------- + */ + +void +tclOSAResultFromID( + Tcl_Interp *interp, + ComponentInstance theComponent, + OSAID resultID ) +{ + OSErr myErr = noErr; + AEDesc resultDesc; + Tcl_DString resultStr; + + Tcl_DStringInit(&resultStr); + + myErr = OSADisplay(theComponent, resultID, typeChar, + kOSAModeNull, &resultDesc); + Tcl_DStringAppend(&resultStr, (char *) *resultDesc.dataHandle, + GetHandleSize(resultDesc.dataHandle)); + Tcl_DStringResult(interp,&resultStr); +} + +/* + *---------------------------------------------------------------------- + * + * tclOSAASError -- + * + * Gets the error message from the AppleScript component, and adds + * it to interp's result. If the script data is known, will point + * out the offending bit of code. This MUST BE A NULL TERMINATED + * C-STRING, not a typeChar. + * + * Results: + * None + * + * Side effects: + * Sets the result of interp to error, plus the relevant portion + * of the script. + * + *---------------------------------------------------------------------- + */ + +void +tclOSAASError( + Tcl_Interp * interp, + ComponentInstance theComponent, + char *scriptData ) +{ + OSErr myErr = noErr; + AEDesc errResult,errLimits; + Tcl_DString errStr; + DescType returnType; + Size returnSize; + short srcStart,srcEnd; + char buffer[16]; + + Tcl_DStringInit(&errStr); + Tcl_DStringAppend(&errStr, "An AppleScript error was encountered.\n", -1); + + OSAScriptError(theComponent, kOSAErrorNumber, + typeShortInteger, &errResult); + + sprintf(buffer, "Error #%-6.6d\n", (short int) **errResult.dataHandle); + + AEDisposeDesc(&errResult); + + Tcl_DStringAppend(&errStr,buffer, 15); + + OSAScriptError(theComponent, kOSAErrorMessage, typeChar, &errResult); + Tcl_DStringAppend(&errStr, (char *) *errResult.dataHandle, + GetHandleSize(errResult.dataHandle)); + AEDisposeDesc(&errResult); + + if (scriptData != NULL) { + int lowerB, upperB; + + myErr = OSAScriptError(theComponent, kOSAErrorRange, + typeOSAErrorRange, &errResult); + + myErr = AECoerceDesc(&errResult, typeAERecord, &errLimits); + myErr = AEGetKeyPtr(&errLimits, keyOSASourceStart, + typeShortInteger, &returnType, &srcStart, + sizeof(short int), &returnSize); + myErr = AEGetKeyPtr(&errLimits, keyOSASourceEnd, typeShortInteger, + &returnType, &srcEnd, sizeof(short int), &returnSize); + AEDisposeDesc(&errResult); + AEDisposeDesc(&errLimits); + + Tcl_DStringAppend(&errStr, "\nThe offending bit of code was:\n\t", -1); + /* + * Get the full line on which the error occured: + */ + for (lowerB = srcStart; lowerB > 0; lowerB--) { + if (*(scriptData + lowerB ) == '\r') { + lowerB++; + break; + } + } + + for (upperB = srcEnd; *(scriptData + upperB) != '\0'; upperB++) { + if (*(scriptData + upperB) == '\r') { + break; + } + } + + Tcl_DStringAppend(&errStr, scriptData+lowerB, srcStart - lowerB); + Tcl_DStringAppend(&errStr, "_", 1); + Tcl_DStringAppend(&errStr, scriptData+srcStart, upperB - srcStart); + } + + Tcl_DStringResult(interp,&errStr); +} + +/* + *---------------------------------------------------------------------- + * + * GetRawDataFromDescriptor -- + * + * Get the data from a descriptor. + * + * Results: + * None + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static void +GetRawDataFromDescriptor( + AEDesc *theDesc, + Ptr destPtr, + Size destMaxSize, + Size *actSize) + { + Size copySize; + + if (theDesc->dataHandle) { + HLock((Handle)theDesc->dataHandle); + *actSize = GetHandleSize((Handle)theDesc->dataHandle); + copySize = *actSize < destMaxSize ? *actSize : destMaxSize; + BlockMove(*theDesc->dataHandle, destPtr, copySize); + HUnlock((Handle)theDesc->dataHandle); + } else { + *actSize = 0; + } + + } + +/* + *---------------------------------------------------------------------- + * + * GetRawDataFromDescriptor -- + * + * Get the data from a descriptor. Assume it's a C string. + * + * Results: + * None + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static OSErr +GetCStringFromDescriptor( + AEDesc *sourceDesc, + char *resultStr, + Size resultMaxSize, + Size *resultSize) +{ + OSErr err; + AEDesc resultDesc; + + resultDesc.dataHandle = nil; + + err = AECoerceDesc(sourceDesc, typeChar, &resultDesc); + + if (!err) { + GetRawDataFromDescriptor(&resultDesc, (Ptr) resultStr, + resultMaxSize - 1, resultSize); + resultStr[*resultSize] = 0; + } else { + err = errAECoercionFail; + } + + if (resultDesc.dataHandle) { + AEDisposeDesc(&resultDesc); + } + + return err; +} diff --git a/mac/tclMacOSA.r b/mac/tclMacOSA.r new file mode 100644 index 0000000..c994e60 --- /dev/null +++ b/mac/tclMacOSA.r @@ -0,0 +1,78 @@ +/* + * tkMacOSA.r -- + * + * This file creates resources used by the AppleScript package. + * + * Copyright (c) 1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacOSA.r,v 1.5 2001/12/27 22:46:24 das Exp $ + */ + +#include <Types.r> +#include <SysTypes.r> + +/* + * The folowing include and defines help construct + * the version string for Tcl. + */ + +#define SCRIPT_MAJOR_VERSION 1 /* Major number */ +#define SCRIPT_MINOR_VERSION 1 /* Minor number */ +#define SCRIPT_RELEASE_SERIAL 0 /* Really minor number! */ +#define RELEASE_LEVEL final /* alpha, beta, or final */ +#define SCRIPT_VERSION "1.1" +#define SCRIPT_PATCH_LEVEL "1.1.0" +#define FINAL 1 /* Change to 1 if final version. */ + +#if FINAL +# define MINOR_VERSION (SCRIPT_MINOR_VERSION * 16) + SCRIPT_RELEASE_SERIAL +# define RELEASE_CODE 0x00 +#else +# define MINOR_VERSION SCRIPT_MINOR_VERSION * 16 +# define RELEASE_CODE SCRIPT_RELEASE_SERIAL +#endif + +#define RELEASE_CODE 0x00 + +resource 'vers' (1) { + SCRIPT_MAJOR_VERSION, MINOR_VERSION, + RELEASE_LEVEL, RELEASE_CODE, verUS, + SCRIPT_PATCH_LEVEL, + SCRIPT_PATCH_LEVEL ", by Jim Ingham © Cygnus Solutions" "\n" "© 2001 Tcl Core Team" +}; + +resource 'vers' (2) { + SCRIPT_MAJOR_VERSION, MINOR_VERSION, + RELEASE_LEVEL, RELEASE_CODE, verUS, + SCRIPT_PATCH_LEVEL, + "Tclapplescript " SCRIPT_PATCH_LEVEL " © 1996-2001" +}; + +/* + * The -16397 string will be displayed by Finder when a user + * tries to open the shared library. The string should + * give the user a little detail about the library's capabilities + * and enough information to install the library in the correct location. + * A similar string should be placed in all shared libraries. + */ +resource 'STR ' (-16397, purgeable) { + "TclAppleScript Library\n\n" + "This library provides the ability to run AppleScript " + " commands from Tcl/Tk programs. To work properly, it " + "should be placed in the ŒTool Command Language¹ folder " + "within the Extensions folder." +}; + + +/* + * We now load the Tk library into the resource fork of the library. + */ + +data 'TEXT' (4000,"pkgIndex",purgeable, preload) { + "# Tcl package index file, version 1.0\n" + "package ifneeded Tclapplescript 1.1 [list tclPkgSetup $dir Tclapplescript 1.1 {{Tclapplescript" + ".shlb load AppleScript}}]\n" +}; diff --git a/mac/tclMacPanic.c b/mac/tclMacPanic.c new file mode 100644 index 0000000..d916cab --- /dev/null +++ b/mac/tclMacPanic.c @@ -0,0 +1,172 @@ +/* + * tclMacPanic.c -- + * + * Source code for the "Tcl_Panic" library procedure used in "Simple + * Shell"; other Mac applications will probably call Tcl_SetPanicProc + * to set a more robust application-specific panic procedure. + * + * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center + * Copyright (c) 1995-1996 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacPanic.c,v 1.6 2001/11/23 01:28:08 das Exp $ + */ + + +#include <Events.h> +#include <Controls.h> +#include <ControlDefinitions.h> +#include <Windows.h> +#include <TextEdit.h> +#include <Fonts.h> +#include <Dialogs.h> +#include <Icons.h> +#include <Sound.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +#include "tclInt.h" +#include "tclMacInt.h" + +/* + * constants for panic dialog + */ +#define PANICHEIGHT 150 /* Height of dialog */ +#define PANICWIDTH 350 /* Width of dialog */ +#define PANIC_BUTTON_RECT {125, 260, 145, 335} /* Rect for button. */ +#define PANIC_ICON_RECT {10, 20, 42, 52} /* Rect for icon. */ +#define PANIC_TEXT_RECT {10, 65, 140, 330} /* Rect for text. */ +#define ENTERCODE (0x03) +#define RETURNCODE (0x0D) + + +/* + *---------------------------------------------------------------------- + * + * TclpPanic -- + * + * Displays panic info, then aborts + * + * Results: + * None. + * + * Side effects: + * The process dies, entering the debugger if possible. + * + *---------------------------------------------------------------------- + */ + + /* VARARGS ARGSUSED */ +void +TclpPanic TCL_VARARGS_DEF(CONST char *, format) +{ + va_list varg; + char msg[256]; + WindowRef macWinPtr, foundWinPtr; + Rect macRect; + Rect buttonRect = PANIC_BUTTON_RECT; + Rect iconRect = PANIC_ICON_RECT; + Rect textRect = PANIC_TEXT_RECT; + ControlHandle okButtonHandle; + EventRecord event; + Handle stopIconHandle; + int part; + Boolean done = false; + + va_start(varg, format); + vsprintf(msg, format, varg); + va_end(varg); + + /* + * Put up an alert without using the Resource Manager (there may + * be no resources to load). Use the Window and Control Managers instead. + * We want the window centered on the main monitor. The following + * should be tested with multiple monitors. Look and see if there is a way + * not using qd.screenBits. + */ + + macRect.top = (qd.screenBits.bounds.top + qd.screenBits.bounds.bottom) + / 2 - (PANICHEIGHT / 2); + macRect.bottom = (qd.screenBits.bounds.top + qd.screenBits.bounds.bottom) + / 2 + (PANICHEIGHT / 2); + macRect.left = (qd.screenBits.bounds.left + qd.screenBits.bounds.right) + / 2 - (PANICWIDTH / 2); + macRect.right = (qd.screenBits.bounds.left + qd.screenBits.bounds.right) + / 2 + (PANICWIDTH / 2); + + macWinPtr = NewWindow(NULL, &macRect, "\p", true, dBoxProc, (WindowRef) -1, + false, 0); + if (macWinPtr == NULL) { + goto exitNow; + } + + okButtonHandle = NewControl(macWinPtr, &buttonRect, "\pOK", true, + 0, 0, 1, pushButProc, 0); + if (okButtonHandle == NULL) { + CloseWindow(macWinPtr); + goto exitNow; + } + + SelectWindow(macWinPtr); + SetCursor(&qd.arrow); + stopIconHandle = GetIcon(kStopIcon); + + while (!done) { + if (WaitNextEvent(mDownMask | keyDownMask | updateMask, + &event, 0, NULL)) { + switch(event.what) { + case mouseDown: + part = FindWindow(event.where, &foundWinPtr); + + if ((foundWinPtr != macWinPtr) || (part != inContent)) { + SysBeep(1); + } else { + SetPortWindowPort(macWinPtr); + GlobalToLocal(&event.where); + part = FindControl(event.where, macWinPtr, + &okButtonHandle); + + if ((kControlButtonPart == part) && + (TrackControl(okButtonHandle, + event.where, NULL))) { + done = true; + } + } + break; + case keyDown: + switch (event.message & charCodeMask) { + case ENTERCODE: + case RETURNCODE: + HiliteControl(okButtonHandle, 1); + HiliteControl(okButtonHandle, 0); + done = true; + } + break; + case updateEvt: + SetPortWindowPort(macWinPtr); + TextFont(systemFont); + + BeginUpdate(macWinPtr); + if (stopIconHandle != NULL) { + PlotIcon(&iconRect, stopIconHandle); + } + TETextBox(msg, strlen(msg), &textRect, teFlushDefault); + DrawControls(macWinPtr); + EndUpdate(macWinPtr); + } + } + } + + CloseWindow(macWinPtr); + + exitNow: +#ifdef TCL_DEBUG + Debugger(); +#else + abort(); +#endif +} + diff --git a/mac/tclMacPkgConfig.c b/mac/tclMacPkgConfig.c new file mode 100644 index 0000000..6b28d3e --- /dev/null +++ b/mac/tclMacPkgConfig.c @@ -0,0 +1,107 @@ +/* + * tclMacPkgConfig.c -- + * + * This file contains the Mac configuration information to + * embed into the tcl binary library. + * + * Copyright (c) 2002 Daniel Steffen <das@users.sourceforge.net> + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacPkgConfig.c,v 1.2 2003/06/09 22:49:29 andreas_kupries Exp $ + */ + +#include "tclInt.h" + +#ifdef __MWERKS__ + +/* define DEBUG/OPTIMIZED macros depending on the value of + * Metrowerks specific precompiler functions. + * (traceback is for PPC, macsbug for 68k) */ +# if __option(traceback) || __option(macsbug) +# define TCL_CFG_DEBUG +# else +# define TCL_CFG_OPTIMIZED +# endif + +/* define PROFILED macros depending depending on the value of + * Metrowerks specific precompiler functions. */ +# if __option(profile) +# define TCL_CFG_PROFILED +# endif + +#else + +# ifdef TCL_DEBUG +# define TCL_CFG_DEBUG +# else +# define TCL_CFG_OPTIMIZED +# endif + +#endif + +/* the CFG_*DIR values need to be built up dynamically at runtime + * because the name of the Macintosh Extension directory on a user's + * system is not known at build time */ +#define CFG_RUNTIME_PREFIX "${::env(EXT_FOLDER)}Tool Command Language" +#define CFG_RUNTIME_LIBDIR CFG_RUNTIME_PREFIX +#define CFG_RUNTIME_BINDIR CFG_RUNTIME_PREFIX +#define CFG_RUNTIME_SCRDIR CFG_RUNTIME_PREFIX":tcl"TCL_VERSION +#define CFG_RUNTIME_INCDIR CFG_RUNTIME_PREFIX +#define CFG_RUNTIME_DOCDIR CFG_RUNTIME_PREFIX +#define CFG_INSTALL_LIBDIR CFG_RUNTIME_LIBDIR +#define CFG_INSTALL_BINDIR CFG_RUNTIME_BINDIR +#define CFG_INSTALL_SCRDIR CFG_RUNTIME_SCRDIR +#define CFG_INSTALL_INCDIR CFG_RUNTIME_INCDIR +#define CFG_INSTALL_DOCDIR CFG_RUNTIME_DOCDIR + +/* use system encoding */ +#define TCL_CFGVAL_ENCODING NULL + +/* We want to include tclPkgConfig.c to get the remaining CFG_* macros + * and the cfg array declaration, but need our own definition of + * TclInitEmbeddedConfigurationInformation, so we rename this routine + * for the duration of the inclusion and declare it static */ +static void TclUnusedInitEmbeddedConfigurationInformation + _ANSI_ARGS_((Tcl_Interp *interp)); +#define TclInitEmbeddedConfigurationInformation \ + TclUnusedInitEmbeddedConfigurationInformation +#include "tclPkgConfig.c" +#undef TclInitEmbeddedConfigurationInformation + + +void +TclInitEmbeddedConfigurationInformation (interp) + Tcl_Interp* interp; /* Interpreter the configuration + * command is registered in. */ +{ + Tcl_Config *cfgp; + Tcl_Obj *valObj, *substObj; + char *subst; + int len; + + valObj = Tcl_NewObj(); + + /* Call Tcl_SubstObj on all values in the cfg array and replace + * the existing value by the result if any substitution has + * occurred. This is needed because on the Mac the CFG_*DIR + * macros contain variables that are not known until runtime */ + for (cfgp = cfg; + (cfgp->key != (CONST char*) NULL) && (cfgp->key [0] != '\0') ; + cfgp++) + { + Tcl_SetStringObj(valObj, cfgp->value, -1); + substObj = Tcl_SubstObj(interp, valObj, TCL_SUBST_VARIABLES); + if( substObj ) { + subst = Tcl_GetStringFromObj(substObj, &len); + if ( strcmp(cfgp->value, subst) ) + cfgp->value = strcpy(ckalloc((unsigned)len+1), subst); + Tcl_DecrRefCount(substObj); + } + } + + Tcl_DecrRefCount(valObj); + + Tcl_RegisterConfig (interp, "tcl", cfg, TCL_CFGVAL_ENCODING); +} diff --git a/mac/tclMacPort.h b/mac/tclMacPort.h new file mode 100644 index 0000000..482f6e8 --- /dev/null +++ b/mac/tclMacPort.h @@ -0,0 +1,279 @@ +/* + * tclMacPort.h -- + * + * This header file handles porting issues that occur because of + * differences between the Mac and Unix. It should be the only + * file that contains #ifdefs to handle different flavors of OS. + * + * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacPort.h,v 1.17 2003/03/03 20:22:44 das Exp $ + */ + + +#ifndef _MACPORT +#define _MACPORT + +#ifndef _TCLINT +# include "tclInt.h" +#endif + +/* + *--------------------------------------------------------------------------- + * The following sets of #includes and #ifdefs are required to get Tcl to + * compile on the macintosh. + *--------------------------------------------------------------------------- + */ + +#include "tclErrno.h" + +#ifndef EOVERFLOW +# ifdef EFBIG +# define EOVERFLOW EFBIG /* The object couldn't fit in the datatype */ +# else /* !EFBIG */ +# define EOVERFLOW EINVAL /* Better than nothing! */ +# endif /* EFBIG */ +#endif /* !EOVERFLOW */ + +#include <float.h> + +#ifdef THINK_C + /* + * The Symantic C code has not been tested + * and probably will not work. + */ +# include <pascal.h> +# include <posix.h> +# include <string.h> +# include <fcntl.h> +# include <pwd.h> +# include <sys/param.h> +# include <sys/types.h> +# include <sys/stat.h> +# include <unistd.h> +#elif defined(__MWERKS__) +# include <time.h> +# include <unistd.h> +# include <utime.h> +# include <fcntl.h> +# include <stat.h> + +#if __MSL__ < 0x6000 +# define isatty(arg) 1 + +/* + * Defines used by access function. This function is provided + * by Mac Tcl as the function TclpAccess. + */ + +# define F_OK 0 /* test for existence of file */ +# define X_OK 0x01 /* test for execute or search permission */ +# define W_OK 0x02 /* test for write permission */ +# define R_OK 0x04 /* test for read permission */ +#endif + +#endif /* __MWERKS__ */ + +#if defined(S_IFBLK) && !defined(S_ISLNK) +#define S_ISLNK(m) (((m)&(S_IFMT)) == (S_IFLNK)) +#endif + +/* + * Many signals are not supported on the Mac and are thus not defined in + * <signal.h>. They are defined here so that Tcl will compile with less + * modification. + */ + +#ifndef SIGQUIT +#define SIGQUIT 300 +#endif + +#ifndef SIGPIPE +#define SIGPIPE 13 +#endif + +#ifndef SIGHUP +#define SIGHUP 100 +#endif + +/* + * waitpid doesn't work on a Mac - the following makes + * Tcl compile without errors. These would normally + * be defined in sys/wait.h on UNIX systems. + */ + +#define WAIT_STATUS_TYPE int +#define WNOHANG 1 +#define WIFSTOPPED(stat) (1) +#define WIFSIGNALED(stat) (1) +#define WIFEXITED(stat) (1) +#define WIFSTOPSIG(stat) (1) +#define WIFTERMSIG(stat) (1) +#define WIFEXITSTATUS(stat) (1) +#define WEXITSTATUS(stat) (1) +#define WTERMSIG(status) (1) +#define WSTOPSIG(status) (1) + +#ifdef BUILD_tcl +# undef TCL_STORAGE_CLASS +# define TCL_STORAGE_CLASS DLLEXPORT +#endif + +/* + * Make sure that MAXPATHLEN is defined. + */ + +#ifndef MAXPATHLEN +# ifdef PATH_MAX +# define MAXPATHLEN PATH_MAX +# else +# define MAXPATHLEN 2048 +# endif +#endif + +/* + * Define "NBBY" (number of bits per byte) if it's not already defined. + */ + +#ifndef NBBY +# define NBBY 8 +#endif + +/* + * These functions always return dummy values on Mac. + */ +#ifndef geteuid +# define geteuid() 1 +#endif +#ifndef getpid +# define getpid() -1 +#endif + +/* + * Variables provided by the C library. + */ + +extern char **environ; + +/* + *--------------------------------------------------------------------------- + * The following macros and declarations represent the interface between + * generic and mac-specific parts of Tcl. Some of the macros may override + * functions declared in tclInt.h. + *--------------------------------------------------------------------------- + */ + +/* + * The default platform eol translation on Mac is TCL_TRANSLATE_CR: + */ + +#define TCL_PLATFORM_TRANSLATION TCL_TRANSLATE_CR + +/* + * Declare dynamic loading extension macro. + */ + +#define TCL_SHLIB_EXT ".shlb" + +/* + * The following define is defined as a workaround on the mac. It claims that + * struct tm has the timezone string in it, which is not true. However, + * the code that works around this fact does not compile on the Mac, since + * it relies on the fact that time.h has a "timezone" variable, which the + * Metrowerks time.h does not have... + * + * The Mac timezone stuff is implemented via the TclpGetTZName() routine in + * tclMacTime.c + * + */ + +#define HAVE_TM_ZONE + + +/* + * If we're using the Metrowerks MSL, we need to convert time_t values from + * the mac epoch to the msl epoch (== unix epoch) by adding the offset from + * <time.mac.h> to mac time_t values, as MSL is using its epoch for file + * access routines such as stat or utime + */ + +#ifdef __MSL__ +#include <time.mac.h> +#ifdef _mac_msl_epoch_offset_ +#define tcl_mac_epoch_offset _mac_msl_epoch_offset_ +#define TCL_MAC_USE_MSL_EPOCH /* flag for TclDate.c */ +#else +#define tcl_mac_epoch_offset 0L +#endif +#else +#define tcl_mac_epoch_offset 0L +#endif + +/* + * The following macros have trivial definitions, allowing generic code to + * address platform-specific issues. + */ + +#define TclpGetPid(pid) ((unsigned long) (pid)) +#define TclSetSystemEnv(a,b) +#define tzset() + +char *TclpFindExecutable(const char *argv0); +int TclpFindVariable(CONST char *name, int *lengthPtr); + +#define fopen(path, mode) TclMacFOpenHack(path, mode) +#define readlink(fileName, buffer, size) TclMacReadlink(fileName, buffer, size) +#ifdef TCL_TEST +#define chmod(path, mode) TclMacChmod(path, mode) +#endif + +/* + * Prototypes needed for compatability + */ + +/* EXTERN int strncasecmp _ANSI_ARGS_((CONST char *s1, + CONST char *s2, size_t n)); */ + +/* + * These definitions force putenv & company to use the version + * supplied with Tcl. + */ +#ifndef putenv +# define unsetenv TclUnsetEnv +# define putenv Tcl_PutEnv +# define setenv TclSetEnv +void TclSetEnv(CONST char *name, CONST char *value); +/* int Tcl_PutEnv(CONST char *string); */ +void TclUnsetEnv(CONST char *name); +#endif + +/* + * Platform specific mutex definition used by memory allocators. + * These are all no-ops on the Macintosh, since the threads are + * all cooperative. + */ + +#ifdef TCL_THREADS +typedef int TclpMutex; +#define TclpMutexInit(a) +#define TclpMutexLock(a) +#define TclpMutexUnlock(a) +#else +typedef int TclpMutex; +#define TclpMutexInit(a) +#define TclpMutexLock(a) +#define TclpMutexUnlock(a) +#endif /* TCL_THREADS */ + +typedef pascal void (*ExitToShellProcPtr)(void); + +#include "tclMac.h" // contains #include "tclPlatDecls.h" +#include "tclIntPlatDecls.h" + +# undef TCL_STORAGE_CLASS +# define TCL_STORAGE_CLASS DLLIMPORT + +#endif /* _MACPORT */ diff --git a/mac/tclMacProjects.sea.hqx b/mac/tclMacProjects.sea.hqx new file mode 100644 index 0000000..178f9d6 --- /dev/null +++ b/mac/tclMacProjects.sea.hqx @@ -0,0 +1,3759 @@ +(This file must be converted with BinHex 4.0) +:%R4ME%eKBe"bEfTPBh4c,R0PB3""8&"-BA9cG#!!!!%Z[J!"NlA,LP0dG@CQ5A3 +J+'-T-6Nj0bda16Ni)%&XB@4ND@iJ8hPcG'9YFb`J5@jM,L`JD(4dF$S[,hH3!bj +KE'&NC'PZFhPc,Q0[E5p6G(9QCNPd,`d+'J!&%!!",Vi!N!0b!!%!N!0bca`0TD9 +5CA0PFRCPC+@P!+@3"!%!!$i!4,GD)G+jbMBk!*!0$Jc@!*!$e!!Q*!F!!5hU!!* +dBfa0B@03FQpUC@0dF`!!#f3#@3&G![-$"J(!rj!%!Klrq2r`bd!!!)!!N!3",JZ +PN!3"!!!i!%5fm8lcY[&2-`#3!h)!!5fN!*!$FJ!)#A-!!!%`!#BL)3!",(3!!Ld +q)%*eD@aN!!!A8J"&!#)"8`*#!F$rN!3$([rirr$,4!!!J!#3"k@3"!%!!$B!4,3 +GFA1i)pb!!*!$e!!",)d!N!28!!CX5!!!!BS!*L!l!!%V!`!),6iJG'0X!!#-6J" +p!"!"f3(d!F$rN!3#([rirr$,3!!!J!#3"k@3"!%!!%!!J,B'`L+hF!IL!!!"-!! +!)5`!!!%`!"#N(J!#@aS!!"mq!*!%$`"#6d&I9'0X8fKPE'ac,Xq!!!"!XNe08(* +$9dP&!3$rN!3!N!U!F!#3"N,"e'PFK"b(4aK@[R1qJ(P@i%H83GqET6BT*14UHT, +eK$hlfi9(H0B6dI!$U#L1N8h0Cq2k3TGqDC@Vm@q&Q`J@9lZrhZCT8r+TZ$)k8++ +`8fpXhmSZf!"JIDUP)VGk*fJIQeXaYV@6!j!!8jZi&[XVa+YZ4J!'$$#05VZ6LBN +H%K++"cX0PA2T`+8mhb"PQqPfA-PJN!#P,fj)deA`mk95kQPPLSmUV*&SQfY6VS9 ++[h9UI2`FS"#!A#9'H'3E"PX[YZR"kNXXmL6'lU[,'Pb9M!+dP0,06aAeV!lIhTT ++G0K+l0RbT6mX(&T'mabLP"a2NrJ*qG`+IS*'mKCHZY*5NQ+PEIE"&E1`,F*H0VJ +(ZB(BYiLJmIJDpU*#meb#JPqY!1q)-RE&EB&8#2YD$k'@eV119U'f6HR%q%B&KVZ ++Xh#p99K4kd'DkQ!6-jIVe6qH@U)JNYGb0TBUGXF4b*T@S*!!ec@'8C3cS8cSXP% +V'NDMlL!B@G'%1(5*4l)pKZ3S&lCArdL%*&6H6pVcd'"j-$L*Hh#RlGaLJe@#YQ) +iq'Q)J5JdA*+e0ljlXI)3KVmY8i2FB6MBrPq(M#[qjC+%3DL9E$2)K90Qr20HB53 +cjUQjK2'"jSCpme@6YT*@0(Q,+P1hEZ3b1@ZjcDB60jph83pRb5X%Sk@fQJV@Z2i +K&)$`9$+8Y"TDdef4l30NZU@ZUAY&C)Urhd"%ff&(P`-JEBT-fbqDP%@VHGNFFR' +L*Blb4R0GQV9BjQ'pYTf2UZ#%fM063U0PQGdLrl1Qrc108I,)#!pCjX([LC!!fCp +[8+4QR@Z0(P3SjDmGN`b(RMDR-f*dX(96bf0V&U*)+C+9'ljS'&c#rp-*)B2AmeZ +E&1!39hic*VHTLp[bY5XjZ%-PCE)V8*Qi#EMB#LNYBJr'&XhKrVrNQK!c$+k&KUA +keiV"cKUC[kL1pAAhL2d0&AUQNV'imp#25d1K4Sm@imRTD[RB2XfiFJ(`@'CrKEY +$4eKCJ!A%kmj`#L)*jR6)*15r8&&S@+FX-jPF-kl(SrhD'G2)bYIrj*0SlJMZGYK +ZpFd$j*T#`0beN!"mhRqZh6,T2q"hI@f3!+"(,SCA0%pSU2c@#EYS@0Thh9Bml"5 +l4k5$eA-RqfHqU!plEV"[pGQ"H98*rBLXEe)NjDJ"+d3TlbN3,Z0Pdh!V-HEib4C +#TKZ05*KJhEaM,(`,V$&0N!$!YJlr22fi"VE'[-LeTF9E51c91,G4mBSH(U4+fE3 +j#QJNH[YPVMm"G-c5A&kFfE(CPDHVfB"-`1N19a#`-h4-3F!)Br'[Gm6K*ak8LEi +@!K8bjB1*iQ!2KJNIj*YLZ!hRP"dZemV-c"#fj&h+%-)FTU&Z-RLl4ZF0,[IXX9I +RJ,qPYL0kS5`JfSqUJ@Ad[1HKYiLGh*Lc[a)8%RL)!pV5Th0S08qjr"S8apHRq54 +dX#`ZX",N3!AEi1"FR1TrrI%q8+2Fq+`,aQQD#k$!L(4k#*XVb1ErG!QpY5$6SY@ +d83ePf"GfB)@q[Bmrk(Pd8NqdT`-b*)'P",BcRi3!im(I)d0PSJa82iTKGHm,krb +ir*Z3!*iJZUXH5X3Mhrpam#lXmY$FmH"9fASdSAM+hE(QdmPZYeXcVX&JU$V!00p +H0HbI"0[5lJ&eBKYfX!+a3B)!3I-B&fr[f-fS6T@ilrP8fp)KlJli*KPTbM5*SjI +Bp8S$)LP$JPX+`J*+Qh+B2XhI`9XcbAREbp!!r29CCbK)$kXqqq"#C@[-T'$e!HE +C"qSB!dMC(Z9bK-5rpmIi+))YXqL'b'[8Y&&-MEXDQh`+)HD[!'kULh!Sl6Me1TB +NBfTI*Bpra%@iK*pp*l1KE)fQkV6GD!pl424(R-`3XLpNb6"[Ci,bE%R`&(#I$,( +G'`pGrblMK,CiJ[-9RemS9(b9315)XpdRhPck45XmEklB*YQHQ#qYG5V`aB#lN@K +4UjhrPULm'LSG"*dq@1kS03fSJ6lF56dU4Gd92DAAl0GECdq#A(T3pB&UC"!N3m4 +VdH(1Fh5E!P1GP9FcXe$Ed1p`R06QMhNl6hlm61`JV8NQ[(V!($6bbfV#b"EaS)6 +5VDV!VPfCC45lFGc-YJ9)E[$"4G6,GkJ,HJ8KlR8%j*T,T(ZD8cZecZ-60@dS8aR +h'M08'Kpdi-#120URl([H(#1qE`!$6b0U"Fj[J2F*pG1B`(KGaf3QF$*d9j!!"X@ +fPGM&4,5K9GI$bM`Q-+d2Nmlp)J$#GcU&JX8Ea5cp&$K3F&#)+96Tf'C193lK2A! +c'R&&Acq5J,94KS3AAUB#2Nh#M#61jH[H+#@Sb))2-5rB-SbMSbemZf(eC6aLV-* +%F6PSG(cNU*GZkQReYb2-5GCfUVce[iY0X4"T)aJcP52fAmaB94K&[P9P09Y6dZN +e00S-GlL3!#aX"6P@,RZ!p1LSC6B!NFT0E)5ei!(#Dl1qAK[U'J8HpbPRd$RdhAJ +cR*HR0LQV`$,)iQ,aC`$a46RhUZ9RiCbE*0&&(QGpC655UUcb1$Z!D!XGZPYR+q, +E2[l4*l@3!(VfJHR4hl-5KBbX$LDLc$MK0GdpN!$+@ridD@EajBq&6rq)Q@DK&%j +K,I!Jhd1A,i4Vb$D9YHUhPmAJZfq"3)(kQjZQI*-HfNc*S-RkZH5A4QACbEAl+Uk +h&[m[8))UAFeBJVc64BaQdk00%N"lrDUd!D(A'3,!N!"4NIlfkaD0RDT82GD"9kL +"6*GB8kpd3N4`SdQk&RcE$,'VU$mFD-d)3"RG5ThL&P'iZd!lD9C$9G12@U[l6*V +A6RK#j'DC`M2Kc3a9T&bJGKqKm#i$+Q@#kj!!F'dq90UYjPC"6Kcj!jqk@VBqZIh +N"K2QNNCH5V3EcY69@HZB(Sh$$-Lir3RUPGf,`Xmk81a"bF!'c8-r+eS*C%34@mZ +PZP"Z)'9c$)-59'ePaa[V*mBk1FX84f-bBVCG&S-dB(d%YJaS5L)#AN#IH#q21Hh +kc$RE`,(Pf*`3"J)Zf$CT+5e-+ERZ%KGFZCihV+P2qI5k*PhJ98SAecDc(Ub)I[5 +#Vr8LpT!!i%bEZNVmC!EDPjq!U8R2!A-qDhN`rLV"iEF#l'D$`AqdYY2[a0AR"Ne +b5m1qE(U!qM&)SHapc$lTCQPT$X%$qMhTJ8EBFQA$e1)TT9!N0P"m'8-p0a5h8`@ +ccr6KA@l2-e-3``!iBic*0*3(Z!m[H#3#qj6EMe2QX1A4D6-53j1HkBPV-q-24@a +"b)$*eTG*UKN8+4,KkN)5U"%cY"diF2HI#[jrTJ*[*NZ"PAZ"B@94MHDmZ'(-[(8 +$+l@`68[pqhRjF)U$m[dadi(G$CRL-X$UX#D3!2F6M'6rB-#20A#X991hMS+-*S+ +B%5F%YIfaYG9D`U(FN!!GYk8km`)rX%HVE-SMIXZGZfk92Zb9JFKY5Cd`Up[1dBH +rKlXHf#MZ6*[GbhEX[G30`G1rPK3`)A"`0d-[,"Q&9PBjm8q"TH'J'UGG`H"U3b( +IC%RXa&Ti4UF4QF`hM0LL4V42VGK5NM*TPZ%Q6GcD&eeR84UN6@8'cTBeDmp9SUj +RP9I%A#3Y1KN)b6MFKENMFHcPl)FDNj(F8jm`qTV3LLK`j#f%U!!99jIPYU13!%a ++8#daH881[H'l6kcZ91#6a01ljIA,(Hrr+qFB1cLHPTB*1riNa)kaBGb!9)TQ[IQ +$DVUhS*(+lKAdek,Mr8QT#IaA%#qq!S%qCrEhQidQFZPE#V1p(ZC6`4LY!c*dUE1 +QmM9JNTh2bpTG$k0-m3``UBCH9rB#0$GRBqFAa1bHaP#qUiV&PXI#l(i+3L+2Ve1 +)BQlLR0KQ"J#r4l*fAEF1U`$CL@dikV!1QN6QiQ&FNI(VeVSkQFd)drG'98E%@dY +pT3bIr2K38'dLG#-P552[pakjcH0dKEMfCl'imC'fU`jAQQqKbbRj[l0aNXmr$[A +18i28&9NmC(hKSc0jBP1MB&U`f,Bq04!jeXPELr,XV*RXLNbNbrJcVE[FP4RF`f( +,4PHXpUe!%dNpCDRQ+Nql$P5V3f5CF8%HMbE"h#K1'qljV#bSYJMH8%-YR1)Jr)6 +mkdPmb8r2PH[8A&9J0)!`#hm@IUN',)dmV)2G&cL%!VfA,+Ra,q8,Q0de6Kr1Ne5 +l9fe*GA5e+(@ZLG*"K-h2bq`4C-+E+m#e#1G!,%p13RIPJ5C5eYHKf+JTYJ&rjNV +CY*X$Ak+8QFNGk`U&VCa39K[p4i,[@&Aer#iQ%AHUc2e+-*U2,FK%[rfrd+I3hC3 +[lDBU)3[`F!CICC!!*Jbmae9JllV!$88%jQ$8!R&TZM4`iI#H#!+db`Fe11'T"UI +C(IVDJ-4+C3Z"6*lp&VKKD6DrHb[QrcDD8(0!q`dL++Ir(8dhh*CXpYFSelRi!4` +LU6P`MFA@mX0CRS4F4G'SaV9Q%&B$+!+eCSmk5ef'Yl,9AV19X$NcY(%$[G"Y4Rr +k@rrM1R,P(H3rFpq"h@D)--rE-+K`J-hBk-j(cd&ekU"A#B4#L9lh0*AAdEdPS*0 +B[BhD1QFTD+V5hbB2SVN*!S`HQKG5YN[-JUf+#e[Z$HdeBDahibjlZ3Nm1e)r6-F +dXVfLm%me*2G`3AZ&!h9ZYpV,V$H*'QY2%k(BRRpXa$J'H1c@[b-ra6pLJ%fjVa3 +19)QNHTr'6"0cEUpFVP)fc8P(K")CTXSLccLmLkRV)4f-Z(c2q-E6F'JMbpEr+Y[ +,!kLIePjSP2[%-SScFpYf!h-$ZCJ2PBeE"Q$Q3IjYa(ld2Tj%R@i+3p*-H@R-edJ +(5&AqSr#kdilSISdh'I8+0I"a*NHZ#1d3[M8p(&*+J',UP*,8Z&1!Q%kJqJaXHkR +0+NZKC`ACSC5F2&*NUjQPCq8jGUKSlG"9f5$p&Zq[NrMbX&$!Hf$jQQM5UY%5!h0 +H#blD1$Z8h%[AMe#L)YYH'q5m%*cZMEL'`VF`N!!Hj6"a%QBV&l#D#LK'*9NKeB3 +NT3hQ4R%c#N@4Q!18R#1X6&'%406jVQRR6[@BU))-+V$8-"VFT&U3!!3%ZZdQSMr +TmR3*V`%CKPQk&8%'E&h-Tb46R&*"b(DBr#m0a*VE%Gp9FE-YIYF(aE)[601l,XK +)XhKLl-'A`"'UAN6hkZB@@&S0kH$1C$E@FXNKGB,aL)6S!b1hVG8#kG3604AdCUJ +e#R+U"*%3SPjZ1RCM%Qa4[KP,Mci8bb(J5P2c33r0,GQJI`(NfMPl%S-iQK(N+h3 +h&PRG*B02A!!iKI,m!B&!2Umibm(HJdT)V998H*)&#jl-F6f'(b@T(FpC&f1q[e# +eDH`[PPpilM+CV$NR$1IG+XpX0VG9m*6)K`3LlVV,"kG%*m8ij4K%cK1!1*LaR@C +f0,8KLN%TVNQ!p2MdMbQ',J8Kq#i1'Z5lGbA@I"Fq+KY!hHUp&C-)-U['9%"8EK6 +VGe3dP-VkZi,qG'U3!2f5&&!)Tm)b[)S#C6Gp`Feh&)&0hY@$"m8IdqdU8Mh&X1P +$kdP6K,cGrlf6"8PebC9YaTRjiV[5KL+6L5X(!Q!hpK+!P0()%VV,IdiFH'mV&9k +XLcJib'#9FjCpUk#LF)U+6"8$AA@BS*6qf1dCIhK"rV`m(5aIRZ-U'HELMi4BG*q +!#Xr8j'Cb1Y(CSTY'DQDQ9@FH%0efcDYHZ,$bq4X8JjfSFA)-E!Xp',FkZ1NhK32 +MSY"(b@pGJRTDR+HV0*CJ!d4CVi@m[A$m#5"$L4,N,#dGa9i@U,)a"VTp,p#)k)L +k8%-U8(+BV*')2LreL*b1)%iCXB3rbGI#-GA")Q!IBMPDSj!!dA$R3rp0&Le"`-J +("XCfT8i'C6[5V+B3'QlG&pQKBB[[!h!S`1C)LYkXl#2QT"[r%Arb)qRcC6*`5r! +kS#PLI`-)aa1L+$*BEa)RqTAGpe-jQ2eZ9MMm#MfLdN2YId[Q$l+-9IbqUZ31#EC +(l`MAp5`V(29c-pPVGN0fapQ!`PkFGT6QADT"JiaeVQ&R3,3(c2aidmXDCD,6f,N +d(AAk0qCjaS#(8$FeM(%ES4$YdKa(!TL5Th,qZr6AHkCRjXPl+j(ZbR*P$N`HQ5T +J88#$FGUdXR`B,G8l+bBXlTK()[[c4M'D5X''Rjh)f*E56FlH&ia[!j38"CZL33m +CN@"+)hLRCXjDLDlT2!VkQ"N@+a!ES9N"qSAQ@'G6!b2*aA5SSGHcbiL`ZmXRFCK +!$D0dj@&#NeY4qI2r6F)#N!!B#-,JfBXq5f$G+2mk6XBR2XYS,kfQQP$SQP1"8eS +9FpeB2BFSY54FK1-9YqH3!2!PY*K[Xr$HkPR8+qJkCdK%G3a6@$F)EB%4Z!5I@1R +%'MDUbEe3VhE6I*`0VK9+SPb+V@`2KbL,q)'mhlZNJ%`5RVK2Q#3!!rN4Ck-)ej[ +Z%jQ0FepC8qm@RTRNFcH@VMSAbI0r[Xk6pk3D8-i2e4&,Ia2lR*j$clBb(M1RdQA +CC4K[-$J(AV5TaQP"4Ar,4F&UB$f4#kim6#!K8HpNA[$'`4b0iG,Q!PT'+I(LKK* +D2!cHl0%KT'6$(TbHE9(jZ*p%qF3(+RCp[Qrm'BA(ml9(F%LXBHZ(DNXchNAVpQQ +XE@H*3(1Jb%l5l5cTFEXV+J#aI&#,LQiml2hjX3HffH&AV3MJ9rkG@2Y-aJ01UTa +rqVFiHrZ6Gp0U[lX(442LXh9%[paqqY%dkJ3iPH"VEF@kK#adN!#@cDSh3'LMZ8A +'(,6"4$(H[#l$NYk+3q$YKN9$9NR1ejJ6G8j9%5Pq,PSA2TSPr`*H&PjAHL1J"Z( +K2QAR4Sff%eb8"$iETR,+TL+lF@cVNKP6Q!ZJr9'h[hTaSq!+SQIaB+bD"+6V'L, +!V-aZ$!Hmfh(eJ9`Ua5'E,#)bGi32!eadACE!CBBY#4&+FGahJj&'%P(pe%8'(9b +M%M6a*8H4+Sk("H3lpP6DFV8mN6jk&JV"0M@rkhMaJNm)e%N6jC!!8CSp'0C*p5d +XZmUIU5SQIi-A8-q'0Ab!CTrKa`Z3!$I#G!+fSTVXT*)Ui6[RHif%9r+-ZCRm($A +'DEF0f-ZVC6iDZJ93,09XU+TEDV3ZfbpYI@[PB2BKHdia+e3!GG*`bB*-+VJfpNY +m[,N3i#deR(p,A[L(C$Jd'Ic+EDh18Zq"jIKLGNildLSNFUidB-P)e3FV64Tjc#) +U&H25QYI!-i*'`fb((aTHPT80dM3U3h$C+HJUK&rSphAmA5KD6UI'TFq!k4cbk`a +YfIN!,a3hK@MmZ'NX)8cR8qCk-q#BG)eR4Z6mM&%XBR$2!kU8L@U[fAF*9SF"R+R +R40M1mCfXI(kd4QA(ld$j66c5LVAU0KNPV(0m9[q$i!j35faRT,mqN!!RR,c)[48 +j$%0!H@IbK&BVH8TqS'*BB%Y6hI6lc*R%Y19R-!#J(`kG*dp94ELNbr*$T5VSEhh +9HbqX+'Rl+5BCiRk%2j)"6Jq&XkQ&96$da3YV#bRGrJ2clF8jFHjHrL")Bh$IPPI +T6bd90&'[2c![3NLFZDRplq+*T[r1[(DRL1,eiEG"ESa19AeRIT!!p8-Z!ie[NDB +HpCYhjqM-Uck&f4rd-&Si*N"4!3Dii-9d0H-M'C*lMMQJ)KkB`PGqUN*V-CN3lB! +NLP5PfQJ+[cdH,eZ)ADh@$Hr@VYI0N!"69[q+(,VX%JpdhQJ-@UHbjIPG*b2Xjk0 +DH&I5YfZpaf!Q(-6S2'[IES5@X8#EBZ!8F@(YaF@0Q(A,+ah"!ZHDr-*2p$XfXkR +QS%rT4)Ic*X%&(Z$1rmI[V1d`&e$@AK3LP'HDP03!4G0@TBEMTqbHeb'U#9*9mGH +pBr6EZ$@FQIpC,MkLRNpB2elHKh$KPl`5pFM&kCdKIEVY))0GGX,X5-Ll1,-dfr" +,q,JQA#i((VQbFlqq+H@2BKF-Kip8bl[%KcK%684+-d()EJAc(&%Gk*IK4UbNh3* +h[#9NPm4AbH-%*Z9d+`TFpRA$j!8HX%EIri`,PRcXYTp*+Cq)ElSfc2&IRUa+edq +@MSLU@+l#j`H-(YrbM8,`"Z8@MCVh%AG!e19"*D1-1Pcj'#+"3,0(`q%C@,20QK` +YhU*prPL21,Jj4E0D`CQbeYMAb-*C)U3SjP4`30cSrY1U`l@IATb+m3Q4,@hFMIZ +!USPPf9Z$,fKj*eAeb0h1$`KFm5iRJ)4,HN`Y"BfT+TKal6p31P(4Al)TiC[da&H +!T"L@f,NmiYG[AT[fQJ'P4a2mPh(6%X"C9$"eA,)8CYZdE+GPdJHlj(4Ehj-"Al& +kF&rN,U@pR@bFD[DDJA6BX9D$Iee[NCcN`Ma#XLrSMGTP$+,KR1H9"QV85TF8M*V +#Y+HN(Q*'1,e08TDFJN90mf3TmBf#LJJQ$ST)T#[AGNUa$%0,j(mZb,c%2Fa#-pj +Fp1EkaaK"U5S!N@+-#CS&MHUFT'X(limlR3KU,&c1KP@mQ*C*RMZrY-6%4-jpceM +*E3eVHRXfA`"0PTA5C"GjABqEj*9D"Mqfj$Pf5AQ8VTd+VaZK0C,AjfYPqhB16,L +H%M#lY(,pKC%6'l(l+aZ8e-TVZiUP)6c"+P2-'f`#KefmfdY45EJd4aUp+rGHqk% +#(d*6+8ic15PkSX4Kj8d(m--e#Z2d!TN9l)M4P8ZK%%E$*kTFBMaepNi-PY"cEbE +5@QH8*UcJ[jfM$E3AGS%q1*MV9l$FeKD@QMB48L8p@CQ())i9p[rNUebCEm!Yhb3 +lZ9ESm3G[$*Q6K6chFR'L9`5mHjHR[-e8%YGUce[ar@pYGqc1NYYCil-hj`$+9Bl +jH4RXZ#9M@YlH1f1@%m)9E,0IZ0+DP3!3%rbUi`kdC5!-6"eGCQZf,(&d+'eM5EM +`flh*-1"Ml!YFLf3KkGcicL(554Vmc[c86XffSf!9L&X#-%$"qpeih8$*8Hb#9`I +3b`6PlA!2*(DUEMqUcQmr+%9GXc*4RYA[SNi[6m*l-5Pfbk@a9`38drlYK45ceYB +NqUPS,X@+NI-Dj&mDHD)YjCqZJSre+q!#@RL5cX`K3ahmI!@G-XaLZ,,qLj,'jDc +!2Qp+HD%k2d8"bID[6l[LL'E`U0",qB1SPVY*DNYDkJrc(3qqBDc@bG21`hAKMd@ +Lp-E$3d0Z4lBhkX-0P"V")([8mcCJbL9QaVLrM4[9h#k"pd&VF4rUMLmA*$+jbVp +K,JA&-UHj-TeKQd[RKZ041)@eq[,Ma38&Y(AhAQqY[af[@11MF1`H6V@aZ@e$+I% +h"KC3`d5#*)R%#Yk)@#Rjl#mNfbIZBMfVHZeV14cp'q-8,$fe$U`fqf+`PeX3[Fr +P&G*G!fHUl5H2K!(U25DMX$Ed)+0kjCRKRi,&*1AfXlIjE(r)BbV)jE9C*'NMFbF +Q3+lTbi%dPFK@44EMkA3i+!G'0G0L0+k(Fmm,-GD%LCI*CiS("Bjr!Mer6SUH+EP +mepA'BPKR5#M2XH(A%'!+cj6Z$3"lmE[c8kBd"0hNkZSLNB)m4ECLAGV"EVM$X$@ +j)0R3F@Z$8jQ,C0N8(a3kbq2,@HPcPrAB#LbR'mZ8Q5X-e%2)XU`+bpYM@q0Ee)p +3!8HfJ*fM45#D0kcCQ+M@r5`MShZ4YphA$d'aMBP`S*E$hRlA%MTQmTq2YaValdd +l$6JP0b6*"CpQEad+!4%C6FG6RK+0A8i[459Bi*!!Bmr''aqp''GBbG@&4U,5`F1 +,pfREV48KqC1'6UBT"Dd-U'%N@6c,&P2[284AHS$&**TSV4"V"9I#-`8D$8j`Ij, +"f4mSID(lY5@l#2HdPkDhbL1Nam%EL#E6@PMaXZCU2hdclm%H+)eJFKB!61[Q+QL +"2(qb%LV&6jD4'89L38@LCYq+YC!!R[)-88l$ZS'&[Z"!(hBSQ"M2BU@+6F,BmK( +bZK#4#@D`QC!!&Akm&IhVV)5($)l(-%,J5ANJB!S"DkSVLYkk40jmkST-#2lpTbJ +2hfFe')M1E3YPrEM9kETI3ZaVK&,)"DQ14FX4)6D)%X(89Ze[5ZFVZ-1NXAID$*L +c,!A@I[CGMhE8+PTkJZC,BmQ`R"6bbKJB!RDYV[qNKFCEe[ZDm$-6)0NMQcT*cIe +iX[*NSe[904PicU9mbp%ZrIRSkY*`j+Z!S0LFI5DEMj!!Ta9M+-6VLpc4Pb5*[BV +1l[9lp&IF@1qr-*C3QI!PkXF(+*)"K'l&qQbp`4#4Jp`24@ELXH$,pU,fI*XBfdd +KhBCDTiL!(iKU#C4UT4MLb*,10U2r)S!)(E2X12G%&2X8,iX3VF"!99epAB`Yl&I +Tk'%TPeDX-Li,B%4hIphIlcfafKaflmFVLpS2J`8[JcaZ3lTMqXE5c28*jU4$H[B +"iG!BBQ-K*k%'mif-#jLRqf3,pp#8`EJY@Km)h*KMiV#5QK9J$Gkec%aY"h[Qd@E +ED!CRMP6KkbTd1I#ZBLr9fZL6dC!!")#[5(!AU2f+ZFc')DPZ245mArZQdUT5a"q +q-XBM-Yk(bhedR(ViCmX'`%I1V)Ge0[BEPTc@-b3eZDd9SMVF3TSU+T&R+4!B4"e +9%SY-1)`@jkHFY(e#5li!K&@aQ5$e-URJ9a)!e'"2(3[(RD59G)Lcil+A4X`Jj1) +!1K(T-VNlcH-'r#cB"N1[9FE4Mj9SlN1fF+cA'mb$MT9DaU,YR,qJd3+kHep2F1R +&%3jE9,Lp3XrEH9F(ID2IXph3YUR"fD2ipbdC#43XDcr!Z&'VhFc'TcN-`8&4e&S +B5I5KZ92PK!h@JQ'lbMNcC84riDQ6G-paKX0Mek-1PUjm`+@3"!%!!%3!%,JMfUZ +i)pUV!!!"LJ!!1aJ!!!%`!"3h*J!$lbd!!"Nr!*!%$`"#6d&I9'0X8fKPE'ac,Xq +!,RKYE!!"0cC849K83eG*43%!rj!%!*!+J!#3#3%k!*!$0`#3"!m!3X(9#he9rJK +eEik-8V@kZdUV2E5CM[,Q!QPqceI`p4Mi%Ir,pA,iSf5%CNQ6JE&I4Gf(b46X!%, +"e3qeE'il$r6I&A"ADfRMa1#5dEk6cNSf[XQ!TmiKlIrJQhrjCrdk19B[NbM#Yb+ +G@RAa!kLGZ(1MD9kqS9ApeVSdPap3d`N1Br2+I"Q*J@!+rL"ETEVKLPZ&Yp38NEN +D*9c)B*3B#cBVKMePJqq+N54CZF6kC8ebd)VTreliJRK9)+flaCX@,8MC[(98m+D +Bc1NQ-BS8$+DZjFk2`-1AHq9iKPS-c(i)#8mpp!$DeeM!ZU3RYlKqEf*m,E#q3jj +%C1GS)Z'G+ZA!Em)8MHeh",ZcUVb5T!"q@Y963YbCK%RNrDZ@KZ)@C2($kP*bifB +YUiYiqFrb+FE'@4A!ekR862BZ-&RM&93LAqX,M4m5Vf44"c-Eh1LaQi0[@lA%XaQ +LS,#(*RrYhRjS@09-1'4CBTe4aQe98m"I5MQ6,MXa93&DKE[qbNmV!NI,"[h!(hV +'4(R3[KDKJT4Uq-(eeZ+YLcdfF1"TVibCijf+VAddTYiDF`0FF`4-5K9&88eB$"R +8&B&3NIkPPd9QZSCD(G3)18pAV,`)XDmr0+5B5)+kBVe,26(eAK[#@(I`YLAPl&S +5H6*Fj6VF+$-3aCr%%Y*EMYC,#iKCpem535(irl4I&jqYaM*f0YcR%)!b&S)f"de +#8`3TH#qUY(["SQlKIqV0NR'fIbJFQlNIE@!H(-UkfT[P@lGic0X$lPRkLY`VAkk +b@1am!KK8YrhM5(b5$c84(kjdb8')k9$R"j)#)IDN[i(HTURph-I*JZV-@T,+,Tm +U&0d+(3kp-6jZAJ853LEXAE4Z5D@A&1X@rM#SZUCqe[9RKEQ)8Ul(R6m5MT3P6L5 +)h3'f$ef!--fq@+TNbVH)dITkR3P#@)Y"ePPHBl8br$624dXMb[l59L3fk4Qie[f +1VEbYK8F5L`M6mcScBqmED4"C6%'rpaZ4l0IJp1pAJc'4K'2KCicl2Y1bQLlGFBc +A9@rm+RPV9QZpMG[GTY)YPm&K[M+[X,2%JG,-QBheqIjlEc2#b5pBA'QN32kXT1m +3,5&a0Uh,@*!!K3#F!+qT+!@5Aj(r`Ic1EZ@YrJ98FUk'(q+a,hr'IHJEm5(6BVF +XE-Tm@lX0SiJpa+aadrc36+K9*cKi1p3F1KBq"EH%Le-#XTVaQlBD"L+(U),2h9- +h31$Y%4elh[HiJAY3@@-aHeB+!e1Ua-9K'ZXPc03)3bH`j!`h*8c1iX5q!bJl3D8 +0DRdj-F)hGDIMCQjP,SVhU&XT,E[Qd8(BQ%JJEJ23M5-5HBD*+X[QG'Q2M*5rZIS +bT[e)!QBqT!,Mc1G'lIJm40hD!-5AAl'15EHX9-qZm'd58i23'iTDN!"XAKAV(rM +ikQJ'jS!U9fa0JJ-cRT[PjY#r-Q8I+$m8-`L!3RpDekGN#RA)h-(fAM%bMGr$L*2 +)rQk4jkMX#Z%@!,9+8JfGq5K+heHYZ5S6eZGce!)TU4m5Yq01Yh,ek(2&TL8cipK +Va1-X)"P*2V-Sp%h`hBmkS)@V-ZFljqJ#S2$J3$Yec@G`Tc4TA8k6X(&M3PeAPjM +NRGUC%*hHeqkpP4rc5S2K%p5kDCIVki,@#YhL+1DMG&!5Q*XiKq%0"b@1[&V2d!M +NTC!!MrTh6qR$`8N%C4EP[HY)k(p@8m`aN!#[c9m1hp,-m+e(`Sl,+VBX$$FEklI +qhQ9bV!)P`i83j%S[&R[PrU*HlSaP92SUU6Per$,e5),i[$3j@!J)YRpeZBIa5@1 +-eYE3l@jPT5@SFfdrce-S0qFJ4P8dl8Q,(U$PkH8"C%H"b!6JHH4GbN''1$M%1bc +@d[Y5Y6pCqFFDjLfYYH[VI%Si4@BLXl'$-DS`qcXA*RFkCNSJji"93Fa5K(Z6,3) +j0DCSa3YI+$PAbR60j*qQ*jF([YIEH!3Z*i&"H88L&4M-J08k,c3YC[BK(E)MT31 +8KU%DFp#R0)mXp9S5[&MJ8ZSVb@8#*Da%AHQP$PP&RdhipKp3!`h"JhilM2RIb#Z +#+@9j#1fMlqd9D5lcHc,$8iMhNmKVARZ5qAeY)Q"dCD9ECRjj,@DNqD4IFNLl,P8 +dD2i8*NB$ajP!M4kLEGq@r4"f98YPe&++bAYd(&e'$46*($L835HQ5l`4BYiDAaZ +p!r+)Gk98+P6lbX`4ZP!%mZ%Rq984*&-4IM,SF"QLCdkKed[-a@PZkKK9BZQLC0h +&K4CTl!I!pX4q'(9Mm@T,diA60Ki*%iL24pq@LS*U6(#HkN,PJ`35q!NIl5Yb`2D +M`*!!X2(RB#`eJDI'`Fa6cPaSi62IZ@B+F#L[ADmM"3JPiRe'cej"X19P@'TPhBH +%*e5d+5[&P2LA"Z%"d(@@+MrXM#)D92qP@D*(faN5R-G&BB0MHeUGLphC+NBS2JV +FMDU0&p!pdNYNj-+X$%lD@486G411QS'mbDhmm)Tcp'#ZeiQCD'Zb*2eZHbAahG) +-EM`D43Z,[VmppYkTX4HVI`p3a,J@1Mkkj3[laNe,h6l,,@$cY2QSNp93cC3,+f5 +bMBlbib@Bj5eHJ5GS+Shqh#M9@&1#kCl-M"6rkmd6J'1"([[2$9ZaUYj5j2b!6F* +AT*KNI6-@i9QB(LfD8k1!K4*"DUCpm+MReY&SV(fAk)m4S+X[q3SVr6!&9&Ul-mF +VPC%,e("H&Hqf3BJG@qJ'Vi2r59k+aVLUT@)CAp5FG&c"AlLM)JJqc&FmL-B%#"$ +%*4MbKe[kVmI,"3@de`f4fTh2ABUMBlN#8q,6D#aG9AX*hi&G'riZ&b8NkAk'#1P +lZ"p%PH2&*S`DQ&&)&YehPQC6"D)M4(J)*9!9r93Rqb$P9'`MY+EhE1(b(Ah,@Sf +C(Lid3R!@364@LJSLFI,aS32DZii!U&CpDb)Hr!%6())3*[&2j@(R[,P'-P)L0pf +b@HkAF0!FJRX32`[E&Nq`*e$LH9@$A'%F3D@YGIKVAB2HB,4NTRVN@A%4'ZM2D0- +@ZEp5@TNkKT2H*!0CbUU2clZp5X"DZNpL$(Xkaa5@Z+&(1Yff-rG2ip&MMIX14r& +m6VpPc*ZE0J)GA'L*V9`NM0q6%!QG$p[A)MbFiNQ-M@e[6FVq[5!QME2IVHjL,A4 +r'VcQUk4hp4Vcq4e906aPpelE3lEm5A$(+6D9'lkRFfm6"VPjUrD3!!eVNUH"4H` +hmV(,4dp22ShQp&LV9pmI'qD@`4-r[A+3!"a4894-hH31RJ'cmmSkSIc[fk10-kM +3*GQHc2E)L*CaGj%f'$+*0%l`M[+83GBL%22c'h'6C&'))845S*ZaEqV-AdjG`H` +Dp2f@Ue*IJ0A)'qrZSGUTTMe-klYBYeZeMj3Mfm,)$dA0f&905YJY4db-a-JfZXP +1[+EN6Dmka"f0$4!Xmj5$[HG"fL!2@D*AI&,dVm@"Gd#)fXV"B49qq+GDG+0XD!P +C@bVq9NK30Nra*JR1G`*25B*kJSZk`"iMm14V0G"Y$P%%jbNBdd[AF1fCD+a5I%' +TE#SUD9pqmQMIRIXL%"MZdI#$dMRC`8I)'5lBF+ieF[P!qXkRcE$N(Pj!2(&0Q+T +RTiT[m)[CcdC`dJ'503Yq%6pjcTVp-&#i'FKdBbJilqfQ'XqSS8G"@-#Qh*hpB2q +!Q,M364iaEB5)mG1f@e'L`@5bc4+Qd2V`BVM&a&)HJp1m)804d-hbdlF22Jm5ZM9 +H"JbFLl5F#j2TJA8hRTGRXfe-qVBcHBYdYeSIUGIbL6bA(1lSm"!@'Rp!8`%mF%K +XMA29RLa"Lk!HNX%I+mK`CAbP9Q5fUD$#*@JH`E@TB,rdMZ'IfPAii,F+kD%BcMA +cri@*[Nl*cI66@&@*f@*%K4X@8!jeRjLbjjqX05@cif`BKXS1+l`RG`QdR38ji6$ +Dm@5XUl[j)01GJFZBVKK`B1MlhHB8pFl4ZfdY5j5NQ*P5VEZrCF(pq2fVF"pTJm, +B,2N2$RGAiK&(DCT*IQD2UcpApd*!VEeIkRe1)P4iMbKMr!Z-h1I[hPeBqYm'G6X +ffP-"HccL,0Lf4DT+6m*(8f3a@3HH,$ZMDL8fPU+JU@lVmAmZMSB&0rlm,*JFd`H +#&5ilC,CK*E(12e%kjRSN0-)pV)rB&9qQl[a@BBDj(YAaf)JD2cFKrA!LNID`mbP +@mlj%I8[C)@%IVf(B3[(H2#![ShDC)R"Vm%M9erEm[A0[!*YHXA0C@BM*1khZaZ# +rqYJ-C'%(@lrC)qiJh`BYU%1K!c%JVb0i2QRq0qCh"A@Q)"LeXQAQ4"m41Ac[Gl" +Ic&Phm*R!acV%A0%+6)`pFqSqm5E*lF%(EKCM!ldM5Sr)kM`VVp2q-'jeF'RjL,3 +Z"jD&RaAZ8Q%lfTIl4-&"2&Nk#VjhrXCV@lD,92F%LP)#EBJf-e43DDVqA4,SQLp +jJBZm*TpTUcQ@A9a5@Pa@2"5R!L6kaS'[GKYA65ERdmRPIej6d)cAl&C"%ZhmFcd +452Li1)EUC#,MRiVCp383#F3Ej@)%H'SchbpUq3HRR)cMD#+2a!b,mX+K[',Y30Y +AkcA%(JFA"hP6lQdmBbpR%J25$X40dKPPM3Ba1%0&[)P$G)"8"imm4D5bDG$&T&B +eCa)3@fTC-D"l+EqFKQZkFS"2icra6!b&a-DK,Jb,ZFN&)aFH!MZDfhhH)4A2FDK +$CT8)f+PZ`(iG@[1-pMG8"H4+-a5$AP5DikaSX@+1FHHp(cQpQqijKl6mr#N'VkT +J"@KFkUF4U,fS-QAL8fkc$$#facNA[[Y"YHA[L(#@XDV#qEm5U6b89!2'6rq0,jP +c3IiL@%PU,,'*5a2X'"AQdla%U@Qd4D`!hk**6$#MCCd,kUH[80T1,`Ze"`JVmA[ +GCB5pU`pX4KNC!G)DP2e"+1%HhiS&C&9"'3m59N5eZEb*`L3*ca1+aYFT2#ml(US +C*iPNqc8RKRC#P!a)UjJI&44KJhm,NLL*QC2MZe[8%,1V8pVUhhE*+pDEa#GA!qA +JC!`9mGC`cNBZ&!4'Mf65XECD!6jRP*k8mIVJ@!)j*&e-,-0*6pL4XCFEMmFS!4S +mQfZj!cfNj'kjY*6dA*!!L',Jmi-URMEM&S*lL[`HZVbfGJVMek,QY!hDRa0%Y4% +rH`ccSZT0Ylal-Z8K"fk@Xm)0H#!K-EDAq0k,Q)iDd2B%lj!!FKRM,5C[DY-hlkU +F[T!!5j)")eq!`XHb-J,8lp5+jI)iqLXi-jbpllG[f*V*+*T1"FHJIpQ!bf+*KSa +"*+$9NkD(kVN3fpQ!6[MZ0@QqA1#SiRqSj+ZK#(+245VJFSUp&cVli%DY16l`N30 +K0e"apf[Xkpq9a%#QcemN-A!h-H@mQr+adZqDQU(R*G(PFjCpr*($JIA#KB9F@RZ +![!G)P,[b1,JEKB9hj5'6,IUGNc4hPB8lqH6IpE+F6-GGaX"#6B-f81c2R@-S8er +`5%'CRf8YcaD%#mR'"YLj-6L%NMa*3!N,@@P*`MT"TKmcX8R,-0RDk"FECZ5M@*( +A1Q$&&jX)%!Ajf[ZH@05C9`5A6baIC'*$B1&0KCL2ihEprR-#*BbmZUMPN@*34YP +rRUBG#&Y',36IAXAlII'!'i`B5T*ACjlGj-P3qUjVG+KA@6K@j-JNM!&kV0XXP9h +%PV"C"d+6D*5X`PBSA%QQRdaS,F3ZS3PE[MV!X6@EqMpeFZ-BQmPBEQmZQ[b1@lU +`-,8"[Id-Q$mmQUA1-)06!4@V`9PZ,+a[p(82N!$lq+8NeaZbbQ6rV8JCRFcJ*K4 +5%2+ij'!+-1`a#UTBiEb(XE3+M9ra2)D*&%bfYUYJS&%Z3XKq2aMeh5R49M)!8(J +%mMDUN!!f-XiC+&r5EJZcc!fPrNAdVE2)Mcb9EdH(0P!miV-%&FUp#bTZ,hHcbb$ +l(Up"#*Pb'$l+dN0!%%LmP3$pfLq,b"G%+252EM,PTfK)U$ffR%amJq`aP)aVC%N +dQ,lm%%HMjZZQ1kc82V3bP6E%,$$X)69$R3c#b(i)PbibXCbGH0'!j%*D#E9qDU3 +qV`!aG4AkkPr['ah&`q6Zm8a&Hh46Rpjp9CZ+([d$EK1&M9P#83l@I[k+K`bN0KS +bH@kGD&92k45BZX31jFd(PCce9CH`4&B[R(5H[aEZPMieY(DN!!RN'`5[,XF41&2 +li[S&fG(`-3e%L(-&lKI-D@0K'+-+64I36Hc01%0&5Y`khQVdJaiN4KbZlDSET+A +'IT'2'2plQ)['Z&hq5I#1BRVRq2CNNIVpia+A2h%UU$ejXI8``Ec(lr%iE'')ClT +lr-r5B@9B+,L`Z%jL6[DG%%5e3I*"M+SGkL!PjS!#CSFUBD4+e6[I5+TX)CiF@HX +GcUFIb8&`6qhfp-iVR&'*'B!Cf4j&L6k$K!d"-0`6(jmRD,@dAV5Z$BN6dQHFlG` +XiA%biFfbGA3Q@'TE8fbThYF#G#@cZABN6i@HPBFfG%QA5NV$'j`(CBiYcTik&Rl +a-qXTm'`j5083%laY*NA-Y2UN'EfrIRfjZ[``YmG"GVCNapici`4d*5Y"RPeCNDd +MT-,edHGme#*b"D"B3jE,6dkUGMA"f2M2NGBbm)qi*TP"eB**)GlNHf(Mj1&J2-+ +CK!AK-CT9`&JP-CX9q8VQC825,1!9"H@+EBHXSXqaJ(f0$[(X@CffkkaHF&SPXkN +D@,FC1i,Qe564jfrNFB+`C4!2&T4p(k%)JHDBIh8$@D[S,"fKIXAG,VQ@$-hEQ0G ++jqj5l`3%0C)BD"Q26ieYEpUj5j(lqP#aHXS8Ci-CBS5qQ$mbh8BaDC&UijJaXUQ +@BqN$SA6L9PhX6&-f9$YCTh(NU[hIH(JLj(Z`['bc&#&Y3e8Y4Aj8b#6*9TCPlJX +bi6!Gdac3"15kZ!&6%SqdBEhTjJTq)B[`C['GqEP)P&+P0RL[&P9"&FH6Y3(5%XD +5I$%KXeB#[rl"EMZN0p[AGl3*DB3PdmZCd(Pd$KplPmL+LIjflj`!(C%rhEXQ(R@ +B4fK1X)5f[B0mej9-jhKZ9KLLUX(JQ,Bm6[$Pp3r#3PFU@-*S6Vp!Hb4jp*8b69- +&d$CT&)0&A21FZTKL4'Ld"rTDMcR%KA8V0V9#!mGf8GkPL(M"JV`[GFN6*@iU@&h +(PKSp`a3dXZYGF(Sh*[`lU6[2lYIk`[8EYp&h@6**9p'LZ5H'+j&,SN@EpVQG2Nh +-iYMriq1'&9-JeP#&%%jcI"q@#Uc"ZRBANj,l!$665af0"VIE5`08lV!3RD8"*iL +LDqF5`iM-Kdr%'e3*HZ26kL+NLXDHG26a(#LV9mkr`+b&qX2r*`,ippjljAE`q&a +#qd)*)+Bm!lfpB#d`hFpB!`b(C4G@!@f)Ih9QIG86CJ+*0ZJTLD+"@CHJFfkck!B +ZJlq#T+8*`1NmD+9e`-4ZdXlBMV8Fj"p0N!#9@1UN[XKVK,aI#DaGq2eMSDZV9Ma +K%$LBRP`51e%HfEq+UmjF0#1jJZaKl2Tp3@S'QEHIa0kmN!"P!5#AZ)#%VZGNSbU +G$TGeb)Q5[r4U0dJL-P-!jZ(bVF5i'!B)h5)2f'!fF@eV,F2"@'h31X,%2Z%4TTM +#!JTbL4l[jY3#hF-P`%GHelH$3p#YHG-3F-e6Yfh5mb&f$IGhRIGlK4LdAVfR4Nd +*5MiRZfB#Z0rCJ6McJpQS`*Kr,mlMC4qUEi0I3[JpN9S`GAC$PLceq5JCj[bZ5N6 +m"ek#4ilr5U#0,c(#LcL5SFN3I#H*pN6-HRrXH-pa,6,446Dap1AE-'%A(F8+YIM +62$Y%kiZ@`5*f!2Zf$[YBQ)8qj0RIE4*%kH`0Jp(HSf$T`TZRP$[(M)e95"U!+h2 +R69flG,%Y!J054UL#MCEpF0ZSR[lG%3+aSdELDXhDXSp36`DiRLL5djAXkb)ZpBl +BBA+I&MUKaTIk1NGP3B8YqqS"D@(#$i,emBNNBakq[UUHDl2JDZmpq&!hCGp9--# +VZ"TEM[C,b+CQhhZdUCrM5(#'')-b4"6"K3AT-Pk$E$kkd#92IG9FPr1Rj1!E0mf +XYi)j5,9fH8`LpiMJPK+jeT!!QU[Q!cCEZA-KjBb(G+C[U"3fLD!G2-&&Ql)Z[hL +d2+Y%`ciGN6NYK%j*M'+%Z)"Aji25Bd%4$KqUF*8&K$Fce!a)Z)GS*+RdNi(iQ)i +PcV+X8-iS!%UU!rlCi1r3MR-Mk!+cRM$QJk1UI(GIb(kiKHM-fS1h,Pj$`TVfmUR +$a1-PdhA24TkXl,8Z(P1NpH+V+i6ij6m[mIh8qZ(-U*lrlV-9)%4Kq@BfE,Y8aPU +#NBKiMi!P$JX0d63+mfUKLj!!q1*E$V)(lcRDXFCikZbE"M0jbfMQZDCMPA6@bfj +%KE#cE34@%[YAAV*b1C'IB86#4+FK"+kGrU!q,ba"SHIXe))X-S4I5idbV3ZMmT! +!rFhR'3'D2rqAPkI36@f8bY9r)6-5#f-`0lm6l-@A8e#N5kQSf(+4)NmT#Fp)C8S +IM,38Jr#JpA!m'`Q5TLb+dIlHcZercL2N(c4TT*DIhPTfKULSQ(QaCYFFUK!VMdf +6fBD"-4%0r)A'82fA94d!C#9FIPr'C0--R'45LdB#UcliP-kVr`lkRVdlK4i84D! +B+I26"#Ek)@-dXDEd(%#M`jRU0H)3hCk53!NX([eLSaeeHRJZEf%GAJKe0Yl#NjD +p#100'rCb$rX&@Q4cU+B&KQ,2ZST[PjID@mIM[9N`raEQ-RMPfFfJ`Hp!8e`@3+@ +3"!%!!%%!J,5KU6Uh66Z#!!!K,!!!@-F!!!%`!"%p$3!"iq3!!"e+!*!%$`"8Bfa +KF("XCA0MFQP`G#l2J!!!3,*069"b3eG*43%!rj!%!*!+J(!!N!C#`G6%@f`GLi0 +)4DkN[b4RC2,[p#G'&Ba5`H5melD4TILkXNc(dUD4AADeYh`"ae8f(MfSk)LA3PP +1c[3#,a2j``qGXElqPTKk3KGX'TDk!hVB4Ff`[h*lLUD'L`+BN6c+ph@'P!&+HQC +-r)R0'I*m-,@$l!'[Q8GFUd@%2X2,T"Lj"'+11`*Pc2PXHmZMq,k0rdC$J%*!aGk +V-6Z`A**1B`f)kF9I0hGA"S9eM5UU&Q0DH&Nce%$r6!CET+h4Ij+E*AKY)T4rN!! +eeR69mlA95SVK,X6LPP3-CEEURhK&'T1aXj4@*5k&L*3eldG'S6jC&9E10a(FPQQ +mKqIrX93df1k#Zb4FkJU8eN&Jm[+fM`+19c'+,b8P2)XA80L+X%#62HeHbH!&`TT +k,1mMj*HCmA!qY+j18l4Sj8`$D"&6-N,Pq*YIlAa3$HJp'#hFE["N-$K#*FR2%2q +5[N9Vi3+dQ&$A)-KC%B'e[PPB$k6*+f+Qb6bH%bAYARAL+02j[aX%p8j%jDD@[FU ++(0q"3dhB0PqX'Fhq,4qVi*G1RrlF1&NGh3H[CM$D8!!I0VHGIf#5E)MjG#k1R,d +#@hZ!1erY&#"A9lb[6r2ZR&'[lHrT25rGd`e@GdhCrqpN[jiDMdMSValBrm`'"*! +!LZSPm5meDEVi*LSbYb(b#K(ZMSjadYT)j4Ue,hHQK(XLGM%i6JV)#`2$Ik#q,0+ +E5-%YL2[&X4Cbqm,r5b6JAL`P)MYH+USBi-`1G*B!c8mQmq@PGI)D0*2-aqP"hLi +FXPr)e!ZZVA%ka)V+FDTJBL#(4K!+pa+5pSC)9K$#TeJVpNrF-H@+*B[ffalK+R3 +dB1(B9QYQId@H"rAq&TE2V!2A1cDFdMJ`PHBjD0bk0EKHHU#CBr(j@aq[!8U%XBU +ZlSDp1X9E"2TTT'eAdJ61[5B*I,4@QKA%YY*qfaJab4Gk-,k6N@Vre+JLI*qh623 +4`RM&*d1pac@LC*B-YU6CNID4fFFpA&)fU'$[G&G)q1lLPjK`@5Vp9N`4PM#lCNS +Pd&Mb@SD6d%'YX'2[db,DT`MAr@805'5%bY9&)S-1elM)C@c#AS(FDlPQYJ#X$6H +2CK33[!+fC)UEhS)*&*p$&EXbjDp5mU3+m5Yiq@fNMBJ*I[M6*110iP)qUGj$hZI +88Q)JF`1&@A2'6p(5K46d3`Nb!M'0S%YTkKj4A3`TlTJfl+Eb6X!+)rdVX'41@Ub +NSHcZY)Bq@`hDPBjqUBR9@FRmBdUdJZP)h@rEaa3!KEaaQYX1LAEYSkdDj[IZ!+b +'b#VLf)qF1a[1k2KPC!dl4PZH4q+b)00d!HTkfL@Z2UMI5,9JBl%,ejmh$NDer$L +FhBi*KU!2EN*9JE%MTp5Ze`MMD'*M)ZC$T5%P4,8kX#Qj%Q[`QX#H8,2bHhA'Z') +N)CJkRc)LpFb"p,%i4RfiQ-+C6`-pCVU&P+bQH*)L5J`(EcMUTYrXi0ZaFh9lf#q +VA()+5MjeP*[$@TYJIm-!$CHIRRHi8jEc3m52b0H%&Q9b[aRQQd8B`[5mjJdIK9c +,p!P%dC*9!#aZ@[2`UaZV+R8##YiBMkGMh&bMqT8rl&#"+BV2GV48c``8G+Vq$A% +imGd1b&AV[-MJTdb0i*dmlCCGIp,X*Mb06c-4%GZeQPlGm99jZe%l)@[+e23iTBV +id+$454R"TT`UHbKAfN*HFLSmY8a26pQp$dXKQ2b"9"er"%(#Ri-!#VM`EjHBC+, +I(+U2M1XEFaE)$q"[,VBpp%b,,Tb1'CY8$Td,eMaia%'YFMB@J$Z1Ml`KrT!!!R* +0T!V*(U',df0@T-S"-!Z[ieD*k%N&9G'-SM6AXXBZqdZdNYIDi!Q)[)`TN`D#(G$ +llHDEG-`AffqpE%d$+%*jK`!ETm[P6mcEbQ8EZVJPK-eK2FNl1(rcf-8F[j[LVl1 +YT9j+CdBZ'*JDVSZ(d#JRelLN'-S3-qBe[ql[mdD'qIJYVLMBrhlH#QCEKB"SamP +VB8e84Uaji3"Sia4aAeHZKVkZQ9Bqb'k*9bi9(0$H5a[bG3q-G0U$h*&*j0S+eD* +fYDAqKXISJ%dNMbp*!9fL`cH$#YdCT!+b!pE+C%)kqbY$1,"iKhm0I1UhrMm["I9 +1RY5`*d!1h#eY)$VI@QX@4e3&p#D+FaHT[FUllBTS4LUkPKBlS""HFM#00)$ZAN) +XrK0j)G2Ad0L#23Mcj+TPEY,iBP$!aqMJj#m)['%RT*-+'e&qbdIQ!+%*L`Zp +%(lQIB(m$jj[2leU4bGMcIL8)kHH2b3U*!R,-1j5dGR%S@4C0)#F-1BL@I6!qUU0 +Jp3AmBBmYlF,JIcBS9pi8RdEF'%TkkFjKNc#faNlP4M`RBq5'APV@!SB3kh!TY,U +Hk0S)EmI*f5@*,Jm9-#Jh#G,&1Gq1F)'Tf#hP!2p$Y%Z"&-YPZI"AKJZTm*D3!"V +q0(-mK8PLKRKLkmD9rX,K%15EI1(G@-53!#QK9)+Jj4#'%U$V6c`L)!*1pKp*ZJf +S(+,Q$[`*BADjZ+!a*(fPZ-PN5r2H@IApm@'N"TRQ08UBHRSD-m2p'523!rf0SPM +C05DB`,N*-R84-L+K+R98-2DZr5'i%'')1l@PEAk+K(1J9SSSGAlE&i36L$k&6CQ +&-M"Eccq,1L#3!24I428,eE)'GTLcSPc3,YL+YZ@PSQC0lck3!+FbDRXQ,Ul)b&E +PFXb6!AmDF+V94'ImM&88ki,ipGa0@i6qSD,0)F")Pk&0fT50bU-PSQiaVBD%P2, +XcA4mI!%Q-r#BhNE+"9m`(iRpPPlU3`IFH8$1J#f6PLBCf-qHeYL+C@,TH@P@TPQ +Uh'"8ENi"eNjCP`Ph0#Ze$PVqc9pjYLj(Q6qZLU9ZIAVE1fE%TD`E2I3P4k$qI#C +m+ef62J6h0VADr$b*,A"X05%SCBF"68V)T4r9Mhd"aDjh0i4mXX"bT29d3kDaCHR +D#cp2HrqhbH&D16U%P[UF8M3@@'`8*qjHUV#GAmP`r$S8LF4q5`8i$a08PmI+ImL +&%N0GD$`%HB%qcILq9jd93H0dF*hB!i4iKR"%6p$eTk39hZ0@d8c+2ZIreDFNi!B +P+35eMle`YZV$K@PXFIm[`81CBk-c#AJ"KiMbdch8kmfP,HQr,P3lB@TT[pE0GZ, +!D,(afA),PkMKRM34PBN`lE,S-Nqh$ZQL!`@XBTiT[(i)MLBbqf4b!GZjVf68i0S +@!pLJAZdS,6$eS,5qX$f0$@f&aS8ahPXl-2**i*b&J1+h*YBYFB2Y9*8L#@q)9Ld +!ap+lkXXXmK!N"$ELVBj%)J-`&X#j#,S+!!e+Z#&pqQ*2!iAC`CTqi@b[2-SL4,I +-ca2`"c8B'X0S9hYmX)2Rbe"MN5NQclrR*8A-4E(YNfd'Zrf8aJ2!e,0,imlMHB) +8U"PEPkmNLSI!*pk4+b@lGMKKc'llU&6-i@BbCPeLLF9@(QfX*T8r#TG(4+G)ZCB +RU[)P6FTR849TMNdT0mcpXGFrYI&pR9(mh4qBbT+,eAFXTK'R$N`Fd*hSCRSH*D+ +YQN1X[T,QMf`@,"GS$*YT8@jX`&CZPaCdH`jI-@RAAdRVP289qmICQ#8#,XMhJQ6 +)[G1!j5V(',Z@JYhbqb9Te%qhSq+G5lNP8K8Vf+2qYmrN6Sp*MHF1RVXqY(0e6%5 +9b0`R$%I8ZTr6,IYm*U+(PGlH[bcG8U6f1*!!Zm*B)$NbrBK"5`m%l6eAN!"'bD- +@BB`B,lQ1EdS@T14,)8E,$TpJeaH,PTUcqYcpE6#fPbjRk@Cpmc&,Gr%*QHc($qF +38S@fAAJ"AeiSkpR5kq5Nfm"*KZ#*lkAifcDYS8Uh-lAFk3@,8J$p!hlS,6rE[%5 +Lql"AV#(l#LhI#!X(3Afe39Bqk4HaZmDZ'5GYR`V5Im(Y6jUhVaYBc-B8l`ME!8T +Mrcld&L,F0hjbND[XlMN1A+6REPb1%YY@fHq8kTq434f$#c&5jd4(L[4(R0SULX( +"Q$**jAB4ck1KVV68`hdPTHlah)B8rjG,R13#fdRdB(ce1EI`'r(#I3J'%-j0Yr@ +L)9rkmPb&Yl$i&6bk%dQSRJI5ASr$[GJ&GQbM(ieCZpf+4&84$,PN%#1e#%#mZJR +!dHFHSLJ!D5r[cb@1C@mQC-N#-jlIf8Aq`r0')&PPI980MNYQcm@I!28J$5EM-)1 +pbc@F`RkF&RmlB+#qFK5Kmdi9U86SA(Ef2H"c2YcI580bA2IHi$Ke-,F2A0Kc +)-Ie63bTlfrq"IiH"qCJ`U6Sk19%RTj(qedHXlDCP(9I[!(5-+2,2Cfb*#P3(Cc0 +hdJkEl#Z$1mSN1JkeiGMc3Qf#cbUAIdB"i)#K&mAaH[Ype#(B`p-G%-VrL%%MqcK +pT0I!AaMd1fNPpQC4M+-dZ2lAb)`9U5dZcD0G2phM%rLlbUJR@p23RUAAm(pkdJc +U@E+c,+@$jR353k8c+ZZfkhPQc)HHFHdrqXJ@h4#jP3k))pd-([YPBVc@P)H`,+a +SK4,*Mimj1G#)Af,F((bEKP[UriFD,iTrei*[eD$F"P2Z(`KqhiCCe1bhT48*@TU +XqQH*hZINRPa38YVjfkfMUDXj(@),9Ci8ShqSaU1hMF*5"-("DeSeCK2kqr96[US +ThB5i+@*%21%6fkK5TJ"FM5IRqdECL,Qk[$fAJ0CK1480q#*"qEp+aI$8SrU&FPB +01pjkbDiiFIeSZM6Yl4a3!*jec&(bhpcVM8EUr)'Hrl@rH*d[h#Cfb@2KbljiP@M +1bENG6PViS0HKi13((!DSE+!R3dl$8pMT6$56IbU+(#CrflmAJ1+I3[G!j'C6U)p +XlMRG[a2&S6FF5[-hJ[4MB&0!fBblLh'THH,)qI&ri%AkEl+NeCH'lrjjjpPF,mS +CNPfjE(!KV,aejI%hKDrZhECfdQJb%ZEZQA5aMl,[90S")Y4F"31AL!0E8I8)'ek +UM%*FUST`C-9-iTT'(6Si1Z$(-NEAk8@Req!PGa)5VcAiKZiJA6ehUCjlIFdb0`H +PEBeP25!E`eqL3CcRE$S$13C%4Sm6@M0JlpE(#YP!HDDa9La6T*cCaS(#JAeBDp1 +Pfc-RbCQKchqm8ecEYUIJ,'&lEM%`G-eQ*N@K8I@ciH3M`X9h)#i"[5iire8!Iq, +'lU!+i)fhaKr2V0*,i1Kl53lf6`'fZ!-N+SII$SM*X0US00#NB3N!64Cq+EP345i +Xq`-EFYM35Gl)qkEjekZQK!,IN!!Q&Cbe9'c'&`Sh8kb1kllV%mXD(ZQlBRRMG'& +$dqAdl!+4V`hBK,fZ(A0K&+BRAB9Z@q%Re+f`QmMG0KH9hd6[8%*`9SH93Y!DfQ8 +A+H4fVkVR[Xd8Zq1![fEHQE@pemQS'([GNNT%lTZF3hT!YdKHH9V*2Kb)[KP6ldM +APDqJ(Z*DTR0VRbP'e*pEj8Y$*ZD4Q%%2M*(Se#QVVib3!1KG`r"FlY9lTF(bM%P +Vpq'`Hj!!Br8Cbb*LdZ#B8ZR,NB8aXqj#I&JMQK(lID3ABY4Q10Cc'i&8LV@LUa4 +9[i(1[5SZq(QmSph5SBc1j'A@lC3%2UqC1*EE4,If+[#C%amlk2JM[me[PaC$6P` +9e,1rmN[B9'lji0332bZlce,'R&i%KVSCqfL)3pLA[*-F#5jT"`)3IR,dHM%V2YU +T`qf-ZjXee-M4Y)pR1pIS5AA-#U0l)fQF+f[DY840[)N9Cj-Mk5RBK8&T0[V`k!F +TRZDj#R+2*Y0(kD[,U$3MJ2G$-DVQpL-Ha"$G$"04HMCI"pCC(QefGQF0QE8$CDb +HAXY1H2&,GEU8bXl1mCYRMK[iUiV3jZfC$+!Uf@`4rm-%[kQ%`FD%NP@ki#,9!"e +bfKi2iZU&1#Q#&i260@Idp!GjIjcdkIF3"ZX)#+F9!!Zr(q1NfX[Lf(#PK+ja2@4 +&EI&mZU`'Kd281Ra'hX[KE,Sp4V#($0Hhh3ik"0dXX!q!lL-YC4r$Ha@NXZb!fHF +R9FVDV&-%UUr09lK[hjlV"k6VGmDDfMQpjSCCIRC1q2B@F`$AXK`VrE@kNP`VB(4 +XhLLT9B4qBS4Sa"-HFGiH26Z"TX,9[rIDJ)F-"`DmaCHD'jNb*(C1HkRT!QfDGCf +8)-fl+X58kV[[l)Z%"'XJTM(5R&+,%D'k4EP0CKCCYY1b`l8Eb`BjC4@"5%1"BiD +RdLV3hI88bJ1@%0PJK(5YqLFA(eYSq&UEk-$3qR-*6d6b%jcF!8XZN58NBE`PGi[ +9-[Tj(JZZ5NT$IK)AlV$5LkK4d4k&K1DYQdfcRU%'@6mh@AU5$&UZV9'Pkickq&` +U*eDB&"T4eU1jXq'Ce4q!N!"CB,P[DcrRB4Fq1,bCh4PiHhBLQq0+Vr)V5jaf!0R +rMqBp9#PDYKV`Jc*CGahpreNB2&A4B3V"%GYId`P2&jjl-T!!LhcipmJJHUU0l%! +K6e#p[jJ4k9EaeSSAkmKRKNBYQ'MCr2`Cj9)P2U'EmlM5'U6PY3UT5k*4i$jQk3Y +jMC)B%MN6'8FY-qXfi#qLkKIlS26F9L6P4@fU'0bAb'6Bhrb3!%%rH'&[*ij!b,F +!R&&p)1cFdd%TR*!!S'''c(&h59,DLaEdb(Kf@cLb(JXH)`5LMrCG'!"bZJ09-R* ++bBSqp01rGh`DN!$)T)lJb&N2ZX--K8D'aI5kmVej`+2a[#N$R0HBHpmB5Y"hr"Q +mBYqM(KKT`fHN5MQ2Rl[NDkBT@P'&"Z-cV"Gi4!Fr#"f@d`JGcLd4fRUk@YF$D@0 +9qm$&"EY-&NSdDJ!"5B5P`U2q5Q#eA')!3&+"*EKPM,2ID*%9A96al3QHRXpC*ZI ++&5N+#jNB$6!,*`[a6La0(E1`BQM'cF(ilQME%XmI*8F)',)L0kRcq&1X5r14KP, +a8##DecE&Njl40$R4M*YcE(Cd!,9PDH[LJqjhq)50)%E)(Ta*pBJpIpcA#5$X$dU +edqJFS(BSH'D2@)(jE*L68eEd2DM%kQMkh6q3!)FB[TkqelG*9mM-LNd+Njp'@6@ +9G'Bf6E690UfY&Rhl5$X6Gd6Kd`KP,Y3IK3Cf81'a5hU!NL(P0C0`E"@#16iV1Bc +C$b@IEf'A5ZT0kD(!2Pr0@ZRpThBU14[c4+Iq5I#,3+1@ZQ,YAQdd4*J(iZfFI!` +UT!NL[,Phh9Z-Zriq%UC1AI!da,1BlibB%#(4GM1V[L3YQ'fG)i*B$UDbBRU9c"T +mV+UZPBCHI6$&CLeXDTdJcFm$jCTHJ"!-a6GF`R2jYX!mej9QDL3A%#2FbmMi#99 +5(5H2Q!3h@1ZD8!4aICXfJlLU"@HXUMKbp-[A9#G"TVF@%U2$YAh9-#0i"19pCT6 +MRCb-ml8"e*keaR%%4i6GiYPI29c@pH1VL#NT0jlNa8ZRYrbq[bJ(U#(da@[RkJQ +(Ma,bIf"#-i*K@5b)VU4,QGQdhRRk41SG-UPbN96NDp"%kdmL5YpJaFGU"eBUVpZ +9Drdq5dqhiSeFCq1fG,46amR6D002-F2LPHM+!CpBjX%rRMFUXH`!#pUd*5"9&GB +EX9@F,D1[K#K*#X*,M$39b*Eq52k[Pk3QEU%KLjZjD4%ESA(@M1q#eK1qaP0FpPH +`2j)p10-Z%(k&5f(!mC3hIUA[e-SkbNTcfJjk2-TqPB1bUqqkI[6erFSQi$ADYG, +&CN4hm%H(T3fhVNMaY'DEf$bBi(Sr5kTacDkTIpDD,Vmq8NP2$2SjqNPj9V8cm9" +j4SkV)F$a8KY"'(%FP%8$F3GpppZ*UHicK2m4`jr1"HI[PC,d3NZ!mL"c'U"1b!" +eVSaY)YDj(@PSC$99f1Lj9Rqf+J@&8%D4cC08KIGfS'MeURYYpQrpXI(JK24,9pJ +432aeKL@a8MC182eYU)aX%1)E+3)9ULU6HqFDhT+3!2b9Rpa#h0"lHB4R&hCGD!5 +LaiqMEmc2-(VQ2@P#X"%daQ`15cQG#FM,U'EbPG!VpX90kHNe%6U#+!!F'F+RTj% +M9Zc*(R4&8C%9%Ra,-M4,6Kp*l[0VX6'CM0Z6USJ&rfqYR#pCGHY&bL4$RRGG`Vp +aL$AE'GG"S4lXK`2V*$5lm&Ib4V*jFN1HM[hfNcS"8`G"4H@TZV`QTp3hpecGrqa +dDZU[c28ADS6U9BNp03XZ$bfVU*kXV*!!i1Y8p!6Tfhfrb0jjHXJ5E2!AAQE9kCQ +N"VZKmC&YdjSTA0bM06e60M'0@L-b@&kec6T,K3JI(Xdj+Tm"eaCir#+bYAXVHI3 +h2R)'9Bfq-D95lcb@I"XQG!-KCq6(meN%$GP#,K2-L['Kfl8,XRQ)B23f(GA)Er, +PDpB-[)rPKbCRa-,XLmL6KQeN[2(8ZrVGFT3epD8dR%6bSNb8A#!FqA9$Ej-H4kT +K5aT,BTXS*1jThXB-pqZ*EFU3!'A`6@GY5SM0j$@RQ6K6p6aNi%0$G6J"GVMm6pD +pe)Rcd8j*)he-UPb"IM#6B3l%$+kcUrePhi%d!(9X#CRh5"G%Eqcbake0'l%&eFp +J34h(1[#BlQ+kB!I@JDDD8ZV8B6IVM"@UG,QGdijH$F1k2+9M`EI!&(`$L[3+#'D +I6crX*",#1*@FPfL-Ha-UU$IC[bY[GXIDUiJ2*4"bec[i+Q"IqF!@km0qqm3-9%` +KiTqkI1r`2-SP+Z0hM(A#dfNQ2b5@!`a9jN"CB#V$GpF'iBNJ$b+C!fTEkYjmicM +rYec+r4&Lf!m,k$[*34Uf-A+U%a[ikSUFX"-IRH6XpVV$"6!KG1l2@qLk)!*"R&J +IB%Hja1pTAfQ5Pbp51[Qam(UJ%jP(mYAe#D"[1D-'4K9LIq#mVfphA`EehQhEGIK +1eI$Qm4ce`0Fd$MLp-LBC@#8qSZVKi,Z8A!8Z'4P%rh5[kk0Nj#FBU$N!k2U%3A3 +rPfhC0kU!4c1Gq+ZkLb+-T(##&-VecNUl*Y[1fl#[MB-#qNMaZ1m,"*J*GII3Z2N +TVQl!KQ9QqJhP$KfSX%pRNbMa+e1,UE$(ck@[ZJ8$edP@R!AF#S@4PPF0'&'(GjD +5`pA+cU#KY$c*hDS@dr94!e+3!%AND-0+I(5M`4UXq+05I&TAcS`d&U8B6G1LEEV +Lm&dkPd+V-)8)$eM8[hpd(Q$,5r![+PRd6AhA3bUClF-XX8QBleEQ$9-'!9,85F& +%9(M[BdJI%2"Tb24A$D,*,6DlXjqUQ`C-&A9B1'2hUJZf"K2(5i%6I!Qq+#G%V!9 +GII"-MJbcb1l5@F5A4HlQTQB)B*bk2$J`+Dm&S`bd,hM+3XFdf!d0'A1a@eq*,XM +K,SEeI%m[-cT*)1QZPIV089RcTl@,(3ehcDK*D81+4bICrVlXVrkklL&&h5'K$'j +fPq!KqU*4([+0lQDSCmTaS)[k-r9iharrb5)3PALLGQHUI%fa%2VP0#3*j+r2hiZ +PRcLa%-#V`"KlGJK4lN3AB)G!jG``3%(-#015IH+('kKR1hi+AV&[`&"X#0EU0Iq +FF!4BpU0@kl9UZG-hrd(CY&2iU`[l@50Z5pCUA!#r[HFKYjp'%Lh[i0S)jH#*pTY +NTM-0N!"ei&+M,&!F0RSY6P'q&+5BY2!kL(VJJM4feLS"3rSiG@QGceS'am-!L", +FHeda9p*8V#SeNF!`#Y0qYMJ*,hZa-Y`+k"kjQe(,RT90@kp,`m[EA9HD*+16Mep +J2A9`6%3eASH2LEIKMckf6RlR-kN3r[I0PYqaFK$R8l)dR!"S3N#Kp!Z6(KZK[Pd +HA+a3kKfPGH(j21FPZ4MXPp("NPaMD@qc%p9@3GkZ-3pjPp+ilSNN%&PL@TFh&90 +T!!LFTUfJZeiVfV#q42TkX2r+TQhIl[-P9!8T+l"a3,1fh-aTAmi6Xabd,&jIEYf +T%ZQ+C-$)INQ'JGJ&SHMJG8p1,jY52DDqEX-2KER!8B96+V"%Jd+*[YkKkJqDFQ' +S'q[&ejGJJHlZcaiLIS-X9Kr++R9XX`VMX[qc61f1SJ!@R%qpG%HDSZ9HPcUC6G# +&'(Gp%cC3FqJ-2Y*$@baMifc#4G'%p2Eq#%a[i)&#f`YG%ebGML"32##J3GhXXPP +c,EXKUpL1'R"p!Br`-SGaQ[KaBAF!K4#PN!3"!!"&!"#i)pUKZ#2DS3!!1aJ!!'r +F!!!"-!!9liJ!!U4E!!!@V!#3"!m!9'0XBA"`E'9cBh*TF(3Zci!ZH'eX!!"c`94 +&@&4$9dP&!3$rN!3!N!U!!*!(3X(8iXXZp(-krTf8IY"Piq#rik,"FeHi09PXX+H +qVbNSXImj5m86%'83J!02008HiH%4L*(c)IEi3[$9Kb@DaNZ9#L-cE+j"D*)*rmG +r(q0I)pYVB36,65&C4R80PLm1C2mB3lkV%ia3d$05+DF9T9(2i%Pp,R',&KYJ5,8 +pj#*e3YhJ#L0Mf&4Gp4Q%0'T!3ILQ#B-T-jY5j`%ZRqjkrfZ1lfpfq)`E8jjB-8p +ISm4Ip*,XqE2XPr#qY-K8-r#P[N'(59M%(GA+I*(6##2)`q5bS5'#JAp@46CK9(I +[J4*chDR4c-YSr*[Y3J3i$8me-aQrJN4@'NZA+hXiDl3flG[-G[8UNf&h,Gr29Nf +*K`L3!1l%$bUl9K+i(`bpEC[Mc`LKjCmB,L'X1ipjTEqf,FM!f$$p6C4,@h+EMJb +i$U$6@S'459-K3`pQi0bmDcVRLSfIJJNp-aDhkif2D1!4@Kqm!)h*lqP4eQZ98EU +"*QmTNdd++&fjfqPL'3p'*DG&GZ"CKf!T%V$`ki1X#eSjLD&&'D`F3PMM'rJ'@@' +hF5Z05'cp%DmQ4a+l*-&T964*"V)AeUpmCpR2h1%mSMF(q+-'Ti6G#E5R4q%"a1i +D*-E0Kbeqc&YI!p[e,ZcFpEm'9D+(Iq#bHE5T,AD2@Xf#%arVJ@EGdqDc5""D%EN +c(ep%!9*"`h@iM,Xl*I5MPpEe%Z*phC%ffD%B4%k4l'BBAf16e1jp!qCLJ+9i6b3 +6qj(%hGb3!+SI*rHid3rN8#ClH%eLG%ST1Xh(&`Ii$pi%ZTSN2S""dEL2,3)Z9JU +9UA51mhqh,DYD$X+#`[qZqXC"Rd$ejC@MU`eaG1M'1IJ9@!@,rN9MPA'-PA8$Y8# +ILi$`@eSpYb1LN4"D-b'IJd'5@'#hEA&MhaZ4'SSLLISbddS##T[rd+Jk5L0T$A% +"m$UC#S1fCHaED)hNjNf$bCA,04m83Dl+!!TfDN*CY0LDdmQZAf'ArmUG98lIBhC +JEJ9&HpR"2LN-dLSe01V"E3I*&pl-3m2eh1Sb)Dd'[lH0HC6QI(@d1d25#"8U+#F +#(#&2b'L**[Tqr9JcJ1a-$NL1$I96Ae+'Cpp8'PPmAk1C&LId&i[[c,$H%$MYZK) +`,k3U-+'U5KHCY)`"8'fQIL&'jIljFj4jK'hiEI#8q9-Kd4p#`"*TUcZiBUeG'Cd +NB&c[VBQmb3i!1la(*QINT5i15"bR2PmV0$(`V`0#RIY[KB&'pp#8[Aqpi%$&8dR +D*bpI#c9b0#Y+!Xll+k6'`EXZM2ac"H+j2drQiC!!%QeT1N!*`Ci6C#krmAPl)6p +4LND96"hB8%["-3Rhl[-,0lA6[QRh((GX0BqXCCYm9GcT4J&kV*-Dp201bp(fP5E +p6kpAMfJ-HBVI"![-U6qbp%j!IA`UM++9Ml#HEJRZeAC6`SDI#KlFf`4Vm5$F&UL +P&H1K`LHqaZHh6@m(GA$ID,)KNfD-QA0*jNj5$K8Bmd3L9rpd%"9A(('RQ[kq%6b +1dLiEc1cqK#i2XfTrI5)JU"+!S$$HM'rr#1A2j*)N%jh&D@M0rL@cQ#"3hBr#SI- +6J$Tb3N0"`NE#'JQKY2F'r!)aGYq-pL-4MGfA0J$L`c03iRf4"1T'd!c9%er2XIi +qIq"e30JjT#J$FNpb820IS9-4BdN3AR@Je6GVeFh@9T0+pll%L-DXVI%#X)NVS2R +`ZqJ$6+*EAVNXK#bb4cCk+8aD3d''l2@(FYR8IR&fV%3V8JMG[%b'!*01'CJ(F+l +m)U5MQZ,(@T)Y4NhmqPL`qfS0EHl@32U5NreY-X8MYIANPeG0AU%hf!eMD"Lh,S6 +6&6$#,!`NAJlG`rGVL5+DZIX3G&1*JrX3bTq5'iB4MGjGFe#fD'UP2(D4J'lS+@R +3DRcPqN,$SRch"Da[Hb6!GXM+*"bQa@0`dl#GFhLZ!%la1,TF'Dh[&TC-mTAm+D" +R"18K+KYe@kB[Y$hBp$#41T1mlJFb83q'BH&H@Tc3KhBN(D2T&K*aD&RBhe)q0c5 +k1FqPSp)EF4Tk%Df4IZ)BG!fMCQ954TRK19d2U@&,mkGd'rdqdP&ZYlD#(9rAeYX +`Z&0FM&`f!24EG6SdJSiD`0,%eqcV9r6!LJYMpqDqP6MT$S'UGaMU[&43JC3f1Q' +LidP%2VjJb64$'@2&"(N3Vfj!1Qe$*VS@jdFharZpFE*!!IcM6aecDZ+@lE@!iLN +K,a6fZH*m[,lH'r`91Rk2aBr(0X1VYGXe,9mN&,1U2Gb,C2Sk"L11F*'@`"@!jh+ +M9kJ8%a1eJK"$8rR%lCC9F5mPC4!4S!+VTh-d8J2$G,ifVAC9HqECdXm$*r0%GBc +IFA!AJ3)ej1%Ri4"MQic0kl2CmDYDA4i(6)Qdp3hEmB)M+i3R,3d(Ghd%Pb+FS%2 +qjbDFB5N!aYrKY#f&HSGBAYJhY@hJR8mHTr!RjNdA$C5&eXla1B[rEUk`)Nb&Xqj +)55Eh5UN1!"dQrN3B)D5)H"ZqZKr1[-Y@Dr+6*F!4BJ&3@9Cc$-*9jlT&8+-A&a# +KCd'&2hN1Nl@VpZei(a+SF3CA3%L(H8q3!2Dd2eQ@(k$5GA#C@[[ER9(#@C9(*%c +1k0&(fSKdSHk%CE1ZCA1J*BR2'AIadGCkF@5rikr(SY9RT8TIP0XiU8)3ZPk*UU3 +BTP9hh1#+J[RRG`QjJpZT*NYMSYLr1T,PmQC3dIe5[p&X9QbGKm+b6["0YafcQ)! +(4q@cK28qNcQ9H&[F*Gb@Aecf`YV'2ri#qC-cB!A4+X20U1D5EekA[De!%Bf-MDj +0HrU,dFPk`1,C#eUX[LeE1GrL0fMhYRF4$#YH1FQA1E'JiQj3Mh8F$j(9)Na[mhb +4QiP%MC@L6`r"lDlVR*3a*H$%c2pC'P,@fjUK'62LN!")-VlCR+TjM2`"9RYc3Ie +[jUDX3r5@b-&lHD[CjK6*dD4iP5Q%fr'L[`-%6"[&I)+f49&4`ALCj4B)*"KFK!1 +Vj4rLJ"!ESPadE0YI3,eERRVe*M%TfP,#i6r)-!lEpeMk9,0fq!'8)EJ$1!D+X*p +qAdHkQE0cJM@UiC`R%kI,QMr+QM''45)$Krph*,(*3Ia8P'IT@"T!HHK3GJqEd4" +N(+lTKJCcpXJHh`"a&J,QTE(C8jQ4Yf#V$&"Z0I"2!fl8rZ13!#c1ehJqV-U)3d% +-BSS9hPS!M9Q5LcUE$N8"l66hK3U'RGKm&l&TDm*&1!P4PQlYbDGN$1BqZaG"a8r +53MTS[0c1TK3X)aX#DR6SM!-Z2,a&iGCQJ'@$V9#C`dfZk4G()[aadj!!-KHem-B +GIPI(2FSZHQb9e#5AC,Dl1$9re8`k+(&"r@VFl0&f54V$F%c6E6"(BZ!hC6k'PQi +4H$Vq@MSH*AXT(b)(e$*MN!"-XpT9D,G25SQ$EGiA[)Q@f`3@"m6jPfhe+lUKEh2 +Y)h`@4fX1AGG'""&h@ec3hPU)bVd%C#&D86D6%[YlF0&E@YL*mbFGQN"6BRK!kl# +hpRUBleqM8H3qVh+hjXhDEm@9h!1IZaN2I4`#FZca*TAKqYCDiBIq@kJGd'd1XP& +!-jd'FG%p69L@Xd"F"%jUYkQ#%l(9arp$2H#3!#i!1Re*28BDFk"c25"dJE[TU`F +BjMYRk-D'(Ca'q0#NeIX5GUQY#V&XDpc!4PdZe,G&l55m6krmC3'M(0eLG`c-$Ze +ZTVA+8SYS+$BBSDI[S4SV`k[0A8A"CGkT-CGGd61Ke8"jr8PTTaEM6K$iRh0e[&b +,@f5[1h)2GAd1%"DqjAY&!bRp+T9R*P#+c6(DR"&)cdQrhZFVXciH4XZcfU&@NCX +6AcR0P+ciJHcXjHm0dj-C6bC'`@RbcEca&5*CFpc#,C3-Ra$lP&#kl1XZ(k`9Gf8 +dRGl0!5&kKqbb4K5YDp2CAq('HX0[Y3RK9H8U%rf"V0M&'V#SYlm5&(MI1N`*!cU +"`*QBrr-#-Q3'556pfD`2'cXcKhHYdLS@+0&keRBQe35"SRF-Lma8[h1j3Z+ipqa +P%Y8LfXZYF`18ABfV&iBJNQbZ1'iidA1(RI2G666a,YZAlSULp%Ta%9QrLFHEMC4 +r9QRp)UrH&K5l(Yd1A52XQ-S&GB#aBe"d[i"[kSbIaS*c$QciLr-K-FKQ`Ukb6Mm +Rca!c2M##l6$epilpM3dA`la2IR,!jX-jI#E2$X$Nk&BG+m)YXB$TdV2"PfeBfCM +EqKEP*U*(MaQ(aUJ&lMDDh+Z&pZJKTbc*)&'6,L5Q`9VaRc-G)Y"Be!T!MB5#!T- +T1bIAqL4!GI4V!3&V*6blm!23(S#emQAqC`4pMQrmQmTHf!`HS9dc9NfPiQ6[bqr +@bS[)GK#H['m*XImbD[IJYK"r-cCCVVMal5$Ae()BVMbr-CVX-BC4FpHP)lJD"ED +@apUBLqT9KA`Y6Nlq,mh@AE@'FdB-0bNDR5ek$rjJH0ajj64MLH%PG")VYPFVf,J +6rVaYfVYLi&f`)'IjK2HcK+,9HEfFQ,I*ZM8Y4'c9QiSI-eqZr'TY`9m'A+I(ZEe +T30+hjpa9l!Z[*`M'Em#I,dQEYCKZrM4pdhlY2YTXDcbBJRqebDk@RP'`J(FkGc& +Zq1JY[b-3[-RV6,4T,PqVV*+QejcB1hMLri(+L$pM4#h"QfIaj%+XFK$AB69a(TC +*Ef``*#EkVlck%85ck`bdGd9r'FDBfFi'"fKmdTeUaIH%A8+(qCaBAAFkV%2PNl# +B+*)+I!KX"Am'1M(3lTS'CmEPI@bj@S"#CicPA`K4lJ&)NJ*X3c2(DV02*0#"e&Y +!l9pTj2@I(4Fr6hk-F&01-aRq(qYrrj!!6bESB'035kQRdGR)idH,$`m-9&-qRj- +mli$QcAU18AfJiSrB[`D@[6pPpX[6)k`NMmmKU,k"#G@F6me!"KIY0aDdBd'EJ"0 +)dpb#M4YPGLhNXQKImTdABHacR$jU2HUVmAG,XI2rhmDG#$d!!c3fUCI3Jc8)p)k +!P`AK$45Hq$"SchXaBpf'b0H(F!YFKJS9j#(@ZfA"keKF3CdZP(lTfLTA-djYSU9 +[[-pB6YaXq,9Y8+qL"N(qpMmlM%EfeLV*Ip-I1paKGXkK$5*'X6k-*fp+bpp#,&% +TG)llUX8XX01qq9k@P(FEb@[-"S1Y+K1'%!fh6P0pV(`q&CiEllV3`R0lN8*Z,Ac +$p%BE408dhJT4`iB@a50-P"m08#FVkV`[q@#[l1p@bmfl'L&C!rrH10&)*arB`AR +f2Gd!mE*&!KDXEF)hXX@bPejHcFSLQm%UJ1D9+,&c!RUDiDFk6NlUF%NYEF&6pl- +Q!#+,E#6L)h@-j'MpAl#UK(G'l0k8h+A@hSF95mZI9GerZ6NPApph,[IlmSXIR%6 +"ScBe5Ief(VmJmFj&hIV9r1ML"+3-+1fDF$b2brIN3QBU0Q(L$KUBeE8XcNm'+a6 +A%rM5[i%jcr80UK`hX@Vj[,"0*1)4KVrE,#4M*qPEZ2+#(iRP3d2V`C@8"m,Br+T +C'LH1j"0X-"DI&%B-XC3mk&qd9[dR'K2[0eea9J-Y"()Xh"0l(`jKH#DK@0Aah)U +iKCCaF,bZhp0!)MULqpV6pM4S+fHf)&rfJV(G0``"$&8%a1"NaRKZYd9MZihm2fL +)dp`CpE#UE"f26MX1JK`L[i"TS%UeEJ(Qma2(ikKLU34&T@YXQ%c8fL+,if,*"dL +4KIR"kd(N09IST6d-f-,DX[QLN!$05TM%'XPScN'+F'8q#CXXPPGc"jPE94VCR&C +P&NqQM1Y&I@8R#dR6cP$8fb5))mQk6lCb&qB,pcAU6eZ66rFX'm4UZHam[hM4HSh +SURSNNm3A92)+NlGQSchm5EdM!j!!4E*p[lU%,p8K&H4cE@rkrQ&#l`HmaVE,k[K +3YV!Vq6`(pfDJ2RYbJf9NSQl*!2XKd03K'B[b6#PYdlp!fTr[e(eqUdDLF5(&Ip2 +&'0)V##"rfa1,0F2ilYN30mr`@PFACp)K6k,d4pJq)YVBI0@DcRcJcZ(3+4S@J-L +')2Z5qKZIKD[VDAKG9eU0$`h6"jC,(KcZf(bpdBIBqBKTbY8eN!$Ar,6SFHT5"3U +TZ59d[(H2Z&#UIpIBfRIj0I#Z+3aiB1"K9(q-GNU+bpBMfk0b8Z"DQ"(V8abXNMR +5f@ppHP22Zq)JM'p#LBjjiC+VYG)l0l9&m,DED,la$4J-dQ8k-S'3!(04AfXG1-& +!NdJf@%BbpNZ88NQF[i"qfrh%e99SrQDIk!%KXiAF[rITj&9((f+K)PXN!6QMUkF +lGeUiYH999$pjCkm9$kGU&PDaK%Ur3kLAfeY[&#Bb*ld4RhhH"IIVIZA#$6X6YfI +jN!!&b9DTcU48-6(6N!!iD+`Z+VZK(CNNhk$Pk3H%+VEd(JZIj9*JX8a+0m6hld4 +eKBNUcJ""3CUcY&9%fPFC+2FT[*dRD[D[b8E-#h0P@m'9'`2a-@RD14(*T01N30* +pqjG&iI*fAYr!AYfZCr"RYKmIMY4+%J+0,DQMi8I3kNil'%L68[Mp[$Q($&-VbTY +q"SD8jrU+1r8#UUIjJdJT*mP%0I*8["AF98SA(E$RXXhR+kf5@0Je$4TI#klk-IM +*iS4'(BRG(@*cGdQ"4p"QE@%SHSB9b!3HPq"l60fE1SK8'G-0G82[I#h6mEpb!Z) +QcK`fVVR598F*VV'3!2ME,6I5-GfPJZSNB#iEP46Z'F%BlC[DHrbXZp"+kESk(3Z +IAC*3b3H6DmdK"HZSI[VH0XdeRm1UDB#+ZbhI%)mIcfiL(3!M,EP(1ITD2L(Kep@ +N)+H)"3P3d!66L$pBeLZ3!)i4BL6QbC,EKIITd$p,FlK-'bbe)%T#4CYfjr2X$*8 +&(RNCP#9*!$Nrp`6L@ZD-cS[,#d+-2$p@(5#YH'cMQaLQa1PMb*8aTIbhcHP"#,H +#d0QY*aK`AV[MM@-)B(YF5bR,Ra[pV&#dmlS[T3mS-8Hkf8,3kB#eUh(+e(#9EBZ +A6[iPr0I#ie'lla+i`(mVPI0R(q4VcibXjl[1H`[k'KMrkN[aB5T9Fhmp$jTQi,U +ALGaa0FmUHr9G&!qY`&rkQTJV*'hd4fK8Z0iFCp@keR!JKiHKJ%raGIB0DQ9'k@r +q$lq[1Yk'5cliEd'4GFqFJ6j@a'CQkRA(3I8#kEFQ3dGlVTjNZ[IeGNC,DS-L((b +)1r6![lTk8r80Up5)bV)R!8eREC(4AdU*`C+Z$IPd93+FP#MPJ8RD5,(P[BH)cR! +p&(CJANqR+GNGkT(SS#0Zd1(R'De4E#2[#1M*j#HV4NVD)P@,!F[PpAKIZ*&8YQ3 +cb48ZMbDM!,YmraJpLq0@&DaalYqa8RGSL1pf+Xj+)XrAYpiLN@@1PGpk+65Mf'K +eKRA[3JX#SXklC)[4ScJSeR6ca)T2fD)[kXjr`9r`0+Y"8Uqk6V3,A`LA%a!N4(3 +4C%pYM,dLb%H$`3[afBalFd#'[JKdC3XMN!$,(95KFcN9JY08heDX-Ti`'&6a4df +IQl!UGjhVCba)E!($03!'e$j4aJ8kZaS(L!Phf[jI#pN8)m!"0"QBYb`bEl0Y3[p +IT[l[V0@$)2c"2daCrF6epKEc8,%0dI@E-6De3NQ9h&QN)XlY0N54p+CZk%DVkpa +aE8TpN!!FB6q!XMLJ`ak!cQFl!%BHQA8P$!8pe56DEG,jGKCb(V`K"1'q+I-%lk3 +K8(Y0P*!!`5elB-m`@D-qqK9#mAVB`FQC#N*33d1[pjV!)ch@)1j4aDd%()LKaLZ +!j5*2+SY0hb8IT$$F,3Ef'X+BD"&)RmIDejh3T&bb%qFaMS#PN!3"!!!r!)#dSD1 +fZ#0piJ!!@-F!!,L#!!!"-!!21mF!"@Tj!!")3`#3"!m!9'0X6'PLFQ&bD@9c,Xq +!!!"!XNe08(*$9dP&!3$rN!3!N!U!F!#3"N,"e-&U[TX*XY+6YAlamJKQZS(1"N" +RGSJ$2JY`9L(8jLldKr!KEIrqiA('+SKEH-lJ$H6Qc3@D!XhKHQI4#BF(daA$k@% +2#p(X2K%3Q'$XQ$qZhfVM%3e2p,jHD'c30qqe,**l(R6PcR!EVjM&DSifaEX"KH& +LJEqqU90djX11RPmaIed$1D$AmHL("J"3%I*34XlaiDb2Xrj69NfEL5Rfq@8YDYd +MeFHl`eJh!*PF-UP9r#YL!4SXfU9Jpcr+E8MRQieA!+KA4*F!JJc9p!ehJpYm4*p +dR'[NMa2"l@+dYr%T,CGA$YM9icaH,*BKjjJ09'6)"M)l&6Q2,pLqPkDhFUZGA)L +3!-Kcbk5S19rY6Pd1j'J[5FYjrJ)'#(aB1GqI!aB8CAdNrf)0VIY(qIr#K#P[hDT +ki!eDcJb!bLe@Bfl*&FB1NB`GSa@`'JYTi%$RjkaC)8&VI[!+TiL#d(DL8V-@++r +FeP#C[FNhV4ji4X`R640d5b%Hd-ZXj48$`CA+R-UGV5P#$fDB9ZC+T0cUY8cJJ"% +f,"MX&ibNh--&Nd)FD3RJRS`#JVS,RP2prBi$HrYffUcUlZ@elRa!YQ0F#'BKLjU +F68q"X&eJ5E3P56rJ3-#i!&$1G[D3!-S#kF[2f+r((*K*%eiAPPX('bl#69TVVYq +lGKP-#j&&eq!9jRF`"ff5QhfBXRJaHL&CX1R3'G1B10LkIT3Z$h`8Kq*)U1-Y%FE +8aRq&-d3m-mZ69ScTTJ$f"6i@,qcHrU[(KA!5cKAQKk1mpXI%28&)hjM8!95Gm!( +#6m0TmM9T@cd8d@V[NfbL$%ed(,TL)YDd*2@qPr$ep(fqGj,906[`l+IbcJlqSCE +Jh3`ibU45QK!B2#BhF#[IT*ZRHrXVbVE!eK&+l@bMmqh"&ZdJE-kSAPH9mae,Tq1 +6T$IjL0*d0Q[p(Kc&"!r@dTISYipJG*!!ES+Hjh[i)0p'IB(@2XmcXN*9#9[iTS3 +d)1T5CkE$jqmpGD'iB*Df#)J%S$D&T"ra,S%e@bTBfq!UZ"I0N`Z"`EQl+adRLC6 +ZFSF)4fbN99H4+*!!14PH29'6*9iI0,,4#6cNj!#,Uj`l+2rVbLjKjIQYh`HkNde +*BkD`93jSrb5GG&iIR$V,"q@1*QNY$03d9P4K4M&aL+cFl#hhGR!ZZN1qbF8Q!Fp +F9db!%iHBKT!!LmYI#4ePU'8&M(R[%ZMa0kD*ClHheDMS9X!$$6(NjMZ'PYY-XH` +1&p[pN5i#PXeF9`KmZSb(S)6fPm"KD'FH&-ZM$RBG(B%KI@%(AM'Y8N`B&"LUI9q ++%ja5CR9(mqhT2erEk$0dlMJZbCNM$Z3P8RL9Pre`qK%kDrCXDk&HE'lh,D4!bHp +@%Iik)SCi!dF$el"!9-[lF5JfqQDpr3rKFLkJCNk91*p81Mjm'%#rGP9b2U3`8hN +,@)Yl'M)Cp0qSQp9N)XdB,NC&V2@k[hqHP0p$,(85I6XX-XV1qHTV[9XiJ9f-1!q +r&Y2ai9(-EV`9aH)JjN@Qk3-ISfJk"ZQ#KbCUM8Ed90+DTq2cN6m!fKRll"#6NDp +3B*2SfRN'3QA3A2%BMrMJHXVL-3`QX6cBLR34P(F[T[Pd@)36UYc!KG2k0PI+e(U +LPV2)ZqZr[e`6YHeFN4P!SmR35Pi4MK0f6*MTk8E%DrNR`FA#UPhKkL9bMNcJhp* +!9LX6h2l4Pq0Npl$G[MSj@(Mj@af4+e"%U896`,8rk9P[Y0*'Km,K5UL$+ci)P)Q +65XM2[f[!pel$mdIFjJ0@+pYplRqeKCbb8E0[dh6'Zh)j$69#*4G'Y`PD0p+V806 +f1F!11lC`Cf6k5T*rH[3*cDKjdVHXL8(GACq'0NT+CMHkB,"(86RjH%HRc-ebSSN +)l-l+fBT5NIP8J-10p@`fPbq9STmUq0)88fL0F0qbclkY@@VcTj!!"D*dAUL9H"9 +0`U)NdY'&Gib2*Vl2@KBKP%ji(3EdA6AHeXhF'V6LP3KL,ZFX&dJ8VeX&PZh-VbD +BL$HR)0,d)L-0I4F%6lNi8ph+fjS'm(rqk%ScG(#c-53N2)E2S1*!fl#Yl8C%UGd +mMH%0)(4k3Y"qSN%Ja+DX&FeCe&-6$IU1i#lY9,!D8U#Y!rr[+43EVZ6J28i4"qL +++di[8C%pR()6$k,lJ4')ke25(fSl#iH[pN[T)ee@cZ(fiKF'``TFkBXk4%6HPe) +,(iE8AQSK-q`Bm'34k*@685#Kh3!50BCG4Mace(#SX3(5AK2%r2RLZ1qaN9ZF5+Q +MFcUCSfPQ#,$,3(3ED-[T)1!X$4*ZlpIT4`Ei9''"`NaSSQJ+2PQ*V&H9kkrSE'" +hefPf@aXZKJb+-22"0KP1FZB-`hAcb)Z'iZSbP+%$qY4r9(l26pFZ&`kX[H4EYX) +e$ZFAX1"5)I13!0+6@LhYbFG$Xfr5mf&`IQIjQHA+0ld39-d2XK%h%`mBQ[DGHRD +-9!AZLTM+X(Z4"H63f2Z[BER3@FALXpchkUd'V8QI[@V#3BY!j5JfH1IPQPII!(G +#$d-VQZZ%dMRVmKQDr1U)&P8RePYQ2%''ca&U9P(SkH&EPPT8U+,2S#BfZCmp*mj +!PFVHR"GjC9lI&AhNBl*1jESS1%Yc[YeB-B%%Uf'qD0md38!'fX&PD%#aDMlEQ0* +mQp&4d%P*,H!XD`+&UJ(UXAQ!ec-6X2Z@F9MHZ)FGSi!UqiYla"ZIriPjN!"fqc) +DFGZkp%*aPmSjX4Pq6[XI6Y)9,CE-#-*`UD`"JK*)Mce642!i8[8Xp"1d+e0V(J( +0(2J@ZDfqELISmE0d,5@k0k@mFqEDd(c@Te(jke"eUBmRr`CrbAL09Z'6dih$D!, +Up8Ae6[+kcDpp06#QEDZ18pC%Ad38,FXVR1kUEZDiKVlA[16DVQP+1@qDB6T8UY& +BmpE9Pm1,Q-Y-VTBaD5[G2ipf,LT'GClL0B-V(r)m@#T0k%IQ0Fp4!m5)C5X-$A6 +&QQf-CCkM)R!kU$&48E1Ak,T%`hiTbfC4+R%H[&PYcZ1Mb4LDHAB3DefL[$K23eX +CG+J0*(CaBNDkT`2kEiXi"5620Uq63D`A'+m31@@B9UbPb++m0M2jfraD5"UAd+i +UN4+[!I%B6AVZDFqM#N-`4KP(VXPjc8NFFEihGPH+J8`-$*!!,h23*,8M*`a,298 +p`@iL2c)[XJbir*ACEX1k2F(Bde+1jUUf1[l4B5q+JD4mY)i+[86#2X"TrX!h[5L +Ka4diMf!!j3"F$2Cce5`r-6qZqK%eP'U8ilZbVQM'hYlNqX#HP`r(KQ#LF9iff'q +a$ZQ&CrTmeMUR"GG#`8NmjIkS2YXT&0!C9a'pPkQ@l%5Tdb4ULb4GM)(VKQ8RJ*' +"`*G2QF6Z)6kU0GGj5eJ+U5-D4MT#C9amqJ46K"UhqE*+YkpD8%L48i69HI91ZrC +j%&eYkjYqRQ[[)CmfkHSSEd,RXLSDA"X9Ekh-CkXf9#,+VG9)2(,ipb@@cDC&EKS +CK-M$Ki-Qq$[)kMZZSkGE6KJ6phlai,LLaC1X`SDA2!RPC!Bf`GF,2MahEkhLF** +1@V'Bdd6NA8e(A@95&-HlNrZ'il$L2kE`@RIXGiU*4`-PLeiK[lqSh4eI1Gi`rJ$ +2AJElR*V!&r5+aD54UQN0$X2Vq`NP%IIf8IjERD6!Yc9CdMH$6jbGpB9SYT-BJY@ +lcjLkA#Dhdq0(Tj@A2A9arr%DM%)TX'fUdlUAbhB@-Ceh2e63A2'8!Lmr[8L@UZM +8%edSpmZm$)S3kl1UbLKDHb(22`Y"50dP`Ua00j6$@hmGH'Nr-FR1jicN"VP8BPH +,a'jZ2C-L3N59Q"Jkf[k2-)TGV,N#)VNC9r%a80ri''p$V5!5NFBKb,UkG5@m&4a +jkkYXlP)QQCpG*eGpY166K$0[N!#2[r3+d&h!)NN-U``'!EbQT',dVeYcm'1"VTq +k@&b4j*heI9fEpZS*h@Jk,m+dFLZPFCHE1(K2+)+I4q(C+1+dAB8p$e4FN!#''** +)N@J8'FSjT!&M,I15&%4HV9`bFkCJdkI++KkLFAXk6Njd-TN`YiCUH63Qc,CTDm9 +)!`EaF5aV&Q2*%pSck$fALEbh0*AUG$b$mb#eX6DP6c6-hbk1,`FDE,GD@36qM4j +bG,c+!(I(1PARBCp[8G4(UeVeB!Y%5+fQDS0*b@SBHI2bJ[X*SlkKkqXFPfeV'AR +rD`[0M'H)(a$APST1Lk`Bk&p&Ta[1(ThSk-GpIMZTNXC)T0Y,V@p2M0QjbX41[48 +[rj4-m`5F-"`9NfTFjKRFQlljSrj6!fYPDH2+!lHM2QSFBlqFZEDm'ff-LeC&&kH +@6Apa5l*h-F'a$G$q*@`H8!@i#-`@iK4ADl%ECd*4J#EbX#)R+(`mHh(R4f6h8#@ +qTaMcdZ*5'UiFbVXf3FFEd$Ie&YZYTT*ZFV&C+e`G+"TBeiJ9eNPI(k1#TIJCYqR +X%l21GDp1p0)6a*dLHQ#21)H@TC01%%9-P@j2r"-+jAiT'1LUEG8FI4-&ab[X-D- +TS4c@@je!8Hq$%Q-LH24kd@M58#ZdIhMee`Df(Z(I8!`JIQ9Br-[+%SX[K1(12US +#62U@Yj1)$V@d-G)#i[Td[jdT4BK-,C5KB2BA#[Q8!ekF4TX95HI8L&X#pARRRc) +ZF8*BplB0Ercb2UcP`'YP29IkA@3l"DA3VrEJrM&B,fi+)L8"KT12JL'([Q`0FrS +6@+mZ'0FGi1NIhIhDm%UY-38b,,3HBQChpTJfCN,lk4h9LCKR%q1[)3j)3@9*3fJ +&+0VXGY!ZE#$4e+cQ5KEf%Kq"0BJXlB%[6DKmU2YaH-GDpq8$)Cf'$YB)36i1JcU +SPL1r"-T2)pE(85[eT#T%L&K49C5G(kZZlY"AS#2K5EM$K32m!Ff66jJ5rh5+Ui3 +fHC+P,#XGa*!!T50pX)'%4k[iK'M)8L`2K'JRf,9aqV2+SmcUX5QYUkBB@(NRB"8 +m-3LLC[a!R+qaQjHA2@br`Qk*a9a"kSjmjEmF"%0V6"PHe*C'K#f#1hRJAi#4q#M +QQ61Z9+!@)I#5Zpal"U*hQlGV)Ll-Z'aI3d5le!V9c6)BC8+mmaJG9GJqM1S[#ZL +8(1@![M[+aMeLZ`ANM08f8F1L3-6$%d&p(5QlRp*$,!-a$'!Ze!TP$")`&fjBj!U +UYZ8p3HiQGTb0Mi*F''E&#j(qkJC`T!3N)iS0*!B4!M4AY2[MraIAPlH(JUQDR5S +)``p1lq"24US#j3F#5)T8lUmAhdG6aT(E69[[@XaJAqRhdG[3Fq)H@N#C"dB,IkH +3!1hb5kf)dQZ4HARGSiAETbr`3(,$M&,Gj,fXE+L%+&XrQ'BjXk#9kED@EMTb(+a +%&,Hd1QM@5FcHTmZA[Yb8B&0F*QjS8hP)JHU!e$FDpi2&1%@,SJ'@*K9pGiY!AQ` +0kiUdX8(XC$,b%B&%[LIAMlQ4ZX&m4aA%`he8QJqqajhU*,UE`3ZZ44B5cKCK5YA +I2Nd'B$`X4FfZK0,4Pc#)&leXL1PcMJF2U+[!XRQTLhLqXP4e$JfB%Z[k"lqQTEm +-0H2f#Kfhkl(R393SC`$C6aBX`%lP'42"4!8&l*(#rh)UiKJK@mKL[R0T5SAFJi@ +*!S5dRh3jMCZiij-F0#,!PX5jfcT#l09dSZ(S9KD22-1fhMIX3J$SmQ[0m60"h!F +NDU96EPi,JR`JEdi!$CbT4Ea2cV-(ElZlKJfqSdCC"NK5H`q1"(5m+A42KmEG#-V +c!%"$*@iU-ei*S%Ak,0M%mXShKKR)NmIBHjYU),&92RZ*Z)C-k,)9#E#4-mS!l5Z +kQ[GQel3$FHN%ql0AX90r+[iEeIj5!R2Y8PeE2!a5m"9JqVI6P+k2NYJQpqfqLcT +-Z(4fmMqrr$Y0N!"m!I*5"'8bM1A'RTRNfE%#eIB#DG#1m8`me!HG'TY+p,3JF)r +1i&IUjZ(f8+$)RNSX"[S+QBNV(JlQYec(EYmHUc#950L$8KaX[!f(fY,9#S8bf4k +1V,#R+$h!EA2Df#-qbakIVU4q$-0UNdHf[L1JDY%R3Y#p"Fq6BQ"60L5UZZ9h8jL +IV))%cSKmHB0`5GFjTN*C-AZ,V0R9R4(aKamfccKqD3+qmdfpEB'he-@X%kAXer` +2+p)3Q'RVjI&E2l@"YeVmF2QDJQ[LN!"Qfk*b!Q[-NP'e*h$QA@MpGcM',6Bi@EQ +2Gq@Ql-'M$p3B4kmLlRBjLXY0HM)1aP1+Jr['YiIaDT&0Y"6b3,mF`2lcG0RI8G' +qQiI3rXhaTVK9(fPKGA)YP8iMGI@Ph-4GpPBelX$pB,-ramNRB-Fa`2FAhM#T5mG +lG$2JAQ8(2jJjCqQ3!2Se$(,dQK$PI)@8ALd-N85HLpjT43QkHR-8E#+&ibr8[*E +9Epka(+iD%!cK5)J1M`*C##)HRC0feS0'b-%!GD4X$c4+'HrjJe1c5S86LMpGS2P +e(dXPRK#&d+fQrj'[qi*pQ5$TU)m+ZlPjH"CFRQd,lq%45Xiq1iT(%kP6bLTfaYf +$I+UKB%G"J&94ipS'$(b[*'@*FaZ0jRFNZZ[%XF9jJkSQ(A+X4EfKD+iVafLB'i- +e%UT6X)!JdSQ$EB-F8'KZ"bNa5j-kG'GU)[-,-c(j,265-86k4UfJ$Ka3KDQ@1YT +)CGj"rq4mp86Y#*!!TK%%ai#ABVD,Fd6mJ`A9EFQSrVN#jkM)6T,6AjVHR*TLSd$ +GG!L,P3lC9T,M6K$DrC4D1)PcUFi2b4@JD&*L-H'EEII0mb"%N!$%SJ1Fq'NR6CD +Zm10R5h8TYRQf2#8Vcrb9'3h$*"1S3*%V$d023KqADc&ES`XTK0%B,iJX5QEh,Ad +fYR9faC(caZ%5U,[d5+G9DlIHPPE''VpX5'3[UPjmBAcEIX)A&3pZVZ1%bF'3!%@ +T"+ZK@*-606P44I)5VaieF-0q@rE*'rS-10`!(rE*,RFe3Q2AA@[YG&!"V6TD6PS +hX46(#HS)MPH6"3&L'II`!T&NTRd2f+f5`)-PiLh!#6Z#"C6r(G@'f+e!*VeCJd- +8ReaBV+L0jFEljDQq3RXJ'HA`CZif%9F,pG+LCIjKRpp[5+J%!da4Xr(4hNR+am9 +Mm*qh"KcMSqNEm(XYq&h-f8MSI6&N3ClS`*HZdXe0,lcfP9+E)QIeq#m2cRk"PUL +')'rD4kNRTM@jYq[[P#-G83Ack$p8(32-Al@ed0aL2$9FR*d1H-#K4P1kPBHX`04 +VEqDK(PZ,1(aYiXPR)@G+'ENhZN#15-Y*e2'KJ2EfdACKa9ENC!HiA'AVQ2k14LH ++M2bN8Re5F2(G-*9h!55CJMAcK8($f$##GGMM)1YS@D6-5c)k)q@4*#8&dS!G+q4 +%p)8P5$36i("K@#ClZPcq$YQlCfEfI`bTGR1-(RR*I`A($X!6RVkNA3T[dYRedK4 +9E49)VK%%-Y0Kk5q(JRM)0CQNEk%F%%K9ZDBq4E$XmF!5p'cF2DKf!"5LPiGYPXG +8K#64ZC3SIQ31,b'*m&rR6,Ph+Y[-Zb*+d*!!rmRj%#jMZ&HmGMd35,6A5CMq"jU +#`+e[*1PXf3KT6(3(piP'$'V*GKdr'iDU(+Mq!9E[I6YKde"hD`0hBRL`h+i`KT@ +Ea30b(NiLa&QbHmDbaM6aUS03'Y('ipd9$24FCYr0k#5+T[Z'MX[P2cB4F*kN5R` +T5VKmeL`$R#j%qYkXDc)@EU5#+&m"![drY,dT(qd&S[Q'@eK4jN9eCS5RLKMQhED +J,f35q96G8pp6Ld4Ee6VTf-E%+9QCrT@QQ-,XFC)ePH%)#N1UF+Nbb2'6c(Kd+L@ +X1ZE4,Me,1F95k*cGP%V*iU%bXK'Yh8DSRNjYQq'ljeqQj(UI*DRbH',GJh,*E!i +L@)FdFTY-Y!5bFc9F300&)9iHj)bba`E(TVEdCSP22VHp4%RR`0IiI0R9V@XI&e6 +i3d+1Y1&,8Y%SHXQdH[+52rX+0MdM,SIL`458U3Y4`YZSf2ca06ER%I2jXGD+8F6 +ChKa"f9Nr3)QSDT!!lXA-NMkh*"X-1jmeHm%%(VQKHr00l[U+SX1BjTDF'fB4dp- +'ZXEK"IqPPk4NfI3H,`PZ'Iahbm,91EVrM)p1jD6rJD5jBU-IYZSi*GqD@6Kr!fG +F("J3MSV%Vh6FJ0$-05&'!@"U5#,9NV[QRZG5+`&TS-Y*mjReAh#jXXNGB5r`["! +F1BLrl%,R1`JXA0Mp31K[C&I6EaiSHZ2A0a@DH+fHDDh3BG9LUN%kU+K5bL!iS)@ +CjSVP((Q2N!#iaENkkE$fU*SNr,VN*#kIJff6UMTERIc'!pkSQjMjGJk5ZBR&k%G +&SakX9TDkM!&eS&X,CPJ-e*3+*i-fq3IFj,k$Y*1mRAJ`pfkV34KSk9XffrkpQVZ +Y($5di%4E6VYbHiVG@@-&$'ZjYc@JDI6"Ip3haB(`aG*Ki+Jm)"0%d$UZCrNHlb` +JZ2p-rRpK1pe!cY%P0&pIRE5SZF1I3"+`5lRDJ$kPf$[1B%@f+NS@iMA6#Y8iVjI +D4Xl[fD*8@H&AY3(KDIm4rPJJGjMDp&fPd3YVVfAD1J`Vm&!0rlX$U5+9`3f8ESd +-`46Z(9,&3h!L3m9f,k%0T-k9AZXGF`NA&)6Y9i9De()N!A@Li[bQL,K)X@-)@6U +I&d#Gk,*Mk,q$EPr2F'9h3YKpDI#p$eYU)LrifTCNF`ECY9VU[f%r"fm)QmjCK3G +qGeJEdk[KVV`r8hXjm%%Q@S#U`RcN"Sf"+0jiGBRCr)"QCJ,hF*)GT$rJ`Y-%I*[ +ZN5AZ2)KMm(V)c6$!LY+Db[hP3UT0H8VUDFN!!ZhK#TTrp6B%%X`2*bi2,ie3SAh +F"J)JC"28CPb*DZD1bUm055qN2B2YC2AJPkfSe$0E`LY+ja`q@K*f`lPh3aZiII( +p34AS3T9!MYpY9NCjNV*H[6a-16NAd9@lS#5FQbL-#*mDFk8j8TX4eFC[#+cQXBA +c0L6hc1L!KD,hqJ0f`Bh8P#SbU1%(12@QI!KPijVcb5$0a)qLSBAMYcpkPGHKGep +Ch+h4+A[mL4'Zc#2%UK"A6rdNbD8ir3PiU"FYG)T-KNMRf6UVdYd5Xl31EjF[4*r +dX-4+ef6[AU6q&TV"`5dQZbpI`daaLT1ch8hV-XUfd2*9*bap3#CVGbehEEZ1*Vd +i6R$jVRjRGTbaUEH-ZXdI,1jmeGIUQT6E4(G4dCI#"3R"ZFKfbi8J``fefqBMBV, +!50ALD)i8@!X,@B,R+MMBNjHV`BXZi1USEfbQq"G(VSNQlNVhDcmGbjfbl5d6b!E +F1CVj"IX[+LRk+qq1)H`,'Sr&)M$&Epm,*UZPCdQ0Pc`Z@0qSYl8,R!h9GIJTk8K +,60,jRDcf2VmhGmGK54ZrNIYM2RdGiLV!Vc+J@RNQXQ3eC9e2XEdIk8DAL0hD2"5 +ZB34"TjBZC01FHl0dE#fm"0rqGZla'"ih`@c43AJdN!$VV13$BAd(Nj!!EX!aRi% +h,)*9GhkQG+IJLe$fVkKPdUl[4i%2a%q@6(!8-PE`lm2B%CAaj'8H2BS#em65NVr +4Kce#`iA)cJ++!2C6Ypc*N!!!DqK3)e!B2HAET1Sa`&i'DQ8pVRL!MGbD)86m*1+ +A2AKAm1i42Le6$0Kl8i8+BLX2AbLaihc&8(EZ6G4l9[6V0ikpYV`34+L())fD,K` +QTaa-`iFfD$NRE)93ZXMT9+%h!FeGI`dTNXbhF&UCJ,#k%iN[Ce-PBDj)AD@KAD1 +(P*B08i#!`FZSFhG!k-8U$`&@F[eXcq!rcJeH#2l[Y1dc,H%U,M&PbdSR-E*'P$k +l6qlb0pEe+3LM5Sck-%AiZAGC)!1Ma+d4#YKV@+JDIh9!Pf'a@CrdVr-5E"1#iX( +NT&[65!@L%3X)A)'A3l$2Ej)$LYZK5F*G0jb%LImF@#[Me1dLXY(a`4$H9&j31+H +pe&Kk0Ja$RAQh&!l"!8qU&aINNX0-+NHDhm&JZK%cHZ',CB5@BNDHT1,d(K("HBS +c$Tkr)FEC5`VNSdBj[fa1l-,!-Am`QYqGjA+1+keL'MGipVDGQS&G%A!5`$YlrET +CXi`FQSTTC%VJAZYG0LbC,biI'lr12#TbVd-[$"HTa$e@crk0"%hDMj!!YSM!3[Q +)U-BkLf6d88r"6b6dQ!(C&-$mMDD0mRqbQ-HM9+'I9%FFQB!+`5C5AZX)pLl&@(9 +&BL1A*QcdRaJ*QQh"Ujk@k0Kb9j!!'KD3!,"mcFA*bYj"dEFB"k-h20LE5f'&E$Y +DIfAfb&*LlF305V`iBmJ#JHU0lG984+%,kGH$kq%c2(9lXI%LE1`D!G`Rc(Ub+rH +jH[KYVTL4Aqq$U`JIEL2cXT8#-98TM0[4JfcABKZ@$"$V%[#EqU84$efe-+k0rLc +cP(H6),eGSkG-P+&dpIZq4Cq1LAm&YKUSLjN,Mlea[r"r45,K*+if4fAlZ'KhS,Q +"-hlAI1+VbCG+K[8-@a0qD5M5YG`3cL85`A@5[B"+T@'4HPM(lk3q64SVDDrM83d +G(Qb++#h!ZGUHR%R$53&Y(@TT4I1jr$KMd"$$q(Q3!0Z+l4'8*5*6+(AIreF[qM' +3!!9'&I8-$RL)k*&10b"&4AM-p`B6UHE5!b4QJZS%`AZ!S-6p3rNPD#-"9Qj43F& +AE"MV)'h`H!B3qi`644jl,6Fi5A)RBpAKQVVkRk[96SGdqb[f2UX1CKZ2Cri2[eS +%`jJGMJ0,RID+[MdShTR2#LEQCM0V*[$M"`kRr#S5K1,LG+93Xdr2MIRa$DCD'Kk +dBi#lV0KUHA!P(Q[&*#6AjGMSmpNFTN$b(F56Z"bR`+fF`rRGCCK(4"F&0aQpLHi +9X8U[r#AmID6C5bjA1@4pBEk@5Q#$F#CYN!#XY"!FQ`MNYHhU2eUUVKr[X-#aFQI +(8BS'5[hV$"PQ69QZ+$`9-+L1[T2X%[ahU(`4U8$9Z5)X*SGGJqBJ'[R+a0E"p&3 +fqBf0JiHXplJCMVI*R`AVp&V83hYeV1J*[AD!030q%9VbFU1B-%$UGBV0rUX4K"B +4SFShN!#5B+HEe-LdJ1I0P-bkG4P6AMH6i-k#aTTAIh(`&[jN'c+$@freN3U-Aji +ef'r)99PL$M1ZcpAPh98iHe*H2H55FPL06EX94kmb!rb%1pEVh#PYL+qR@`qj1BY +'F4A9X1)ZSF@Hijahc(*3aCDFT3"3V*S35&hk*(%G*qNSER%#a6L-l,!0,fEr!Kj +'6)(mF$,[Z*&#fR*S+T-@9AQF6%mF6+FG1k"[5"M&pr5SjP)%-q,MNrGFerN@,&L ++c'kCAIiP!PBBC"eQ-4`J`(J0YI[fN5Gqm'!*%BAJh*TIpJUZ@He9bhRBHG$'-IY +iI)lFY-aF`aEaYkh1RY1B`!Dj,G-Zq0f-ZQ(E534kN3"ViYJEfAq-9A-LVT!!+Yj +AZ[AimZ!6-JB!#0Zb&49C95mUb,*TAd,p2ICFmN9AHAD9K*-r*N'6"JqC"HNmQZP +FNr&Z+#i4Bl6[kSRXQXMhHB5%M0ce8ejVB[FS4SNkSmGN5JqMhIE+%BN23AlqFh0 ++#erXKJ1`jD5M-8EKM@C(hQpVH9-3d[&!eJ`rBJe5qr+kSmAU!,jQ8*LN&`P4A,L +8m*IFCNq(fNIdApe`U6Fh5R(*hLZS![a"q6iKiP)HFCih'Br`VP,@*r`@JFKd22H +ei#QE'1M%j%#`a)X8f3UVl*3+ee+UPU#qUI99k6Hr[a5[4iR`+[L@K)G2Pd9FK-* +qT4BFNbCSQ,T0Q6aS2ZG8VXU8jE'mq5CTUT69hVkj4#)N-XQYdZ'HpajP,pZahjm +k8Hl0'ekhSP,%arrKJmR6%LU%+PcfXHk'MfDI*Ea4S*!!89$[BS+I,8b(#ZE+"83 +JUEUhpRV`*)5`[b!pYFZ[a"-h-"*KNcU,'&p4RP6iHm3(Ua8$M&1kqdXAJr"XmmP +LfV'IRCD,d,@1PPK5T532#M-6[hXKfj-2!F43NUJ,,Np,,maMEL4(*h6NAD-Q3I! +mhGrSFpYpfq6J3m+efE@`[LR1)ZK$"pUmVDMYRckMQ!`SPTlC+F`p!jF'[UbV2jL +`55dPJfP6m'BVj"XlE8hqb)PB3!5`BQqAp-8*E2prMFDD4&Zj#p#AR)CdDJJQQre +DI3DBS(E9[k-K2AVX@DH5pqI6%mQ6Y&&IkQB4kaVpk8rIaAh@8KS3A`19@ibb$P2 +I`3$NN!"de$!eX0+6Q1k2#%(PPRa'Ij*CZ#VDRYPjK5&DLZRCTp-`bK`ke0cMRaV +&T39E$[d$cE"($TYJiQhA-DYBj$RZ((Q1d%AIX1N')FGB&0N,!*LPRTXSb5(Si6R ++"QSi@CVA9dd(#%!X'%j'9V6(f`Qip%dN-cK-h0Ga"Ldp2Ej`H+!jYhS9Z)d0M"! +Be2#L9%&aFG&Ha66SMeB*4(FCGN$r1R"phah@V+m%3%-IUBFiG6ZC)8`mralD)5' +k%*Amk"RCB'RL88JL'N6N!2d`ElBMTUCPjb$ZKi8M"B54LNZU[4qi3(`m6Apq$3b +6fq5'@[+@%a&XMq)0L4[aB!D`QUH0C0b@jJ'Vr"P9NkR#0H@CDEUj)MFG2EeUF)E +K!*'QQ4l(I,D9#ER6!@Jpp1)a0Ke8!ech,(&)lfTK$`r8k[j28pA'VJ'Blc-IB3P +!SaT*8$HNpQiiCm*f[q[BPTb6fN5P2*@6j1+J("!e([SGIH,Q-fdi)4)3c95diIV +981!324bEaLXJcYdl4RDeh`dql*EZm"%*Db)8[+[$)RkI'a8U(rSrEpFqB-Y)fZa +ee*TU,NN%%3i2!kpa(f)AQP$3`Eh!J!9jc%!-N!"([J4Kc9qjRCh%eem&LD9)j2` +#l!br$f6)Z2ap3,4lRIiCiVJU8LDF&!4!RT'pkrhj2#,`N!!i[,G&J(!TB,#qLRC +#eRafJfH+&QX&!6YZ5))LCPLI,LG,IG9bYFJP[e`P1Mm3q4pT&jfL"FbGRLib3ZY +-&dJJS-fHcZ@j!Bc1Q2SFe,EkB4G8RcPeM4Fq%mB%M#qN(c$p1B1UZbaqMMl*+0K +1kA4YVh`4&DYK+a*BMfUkVl+#h3!C!*GINITm*c*eVp33fYD22CQ9`GBiTHQ!QlH +fif-0$cK96lUc)ZIqfpHJNpU4)e+#SHj'i[d!a&1BCc'CP#M"INQc3[1hHfr9L4@ +46P98+4[9m1D15FFZRNjDa553!,(aG6[Q(3BZY2i!)1&VJK2k`,`RHQ03I+AJedM +eLfq&a'laqp`TkB#mJM851FUMj'2XkKl&0&dGb+"bA-E'bm[*iCeCYBLA"q0$$Tb +'9&p8pEpJP2$MlLhi)DRmmj51j[XC-!RpfU#qkB,+bT@0[HNMU*,Kj,2Li813!2T +%e4[8#KU1a+Hc@(6Ra2IM9kf0[l5GjphLdK&b-(,pc'U$S,CA`GV'J+#bP-c9%Y9 +8m3Edp9V0PSJhY3q",)PFA15iR!rhT(dhN!"aq!ehqIiKAKbHf`KmaVN%kC!!@VJ +j12Q)X3[rkEQ[jP@jPU*MHIH-!GblddHCIKmhqJQ$"mimeGRZK`Q!F-Z*d,G5qje +MG,1jA0Ab,Mb622%Te@T`&!,*fI3Zaq)l9!QJ2&2IEfFiarlf#N9C&9BBX#94c@F +ZkE8eLC+@d"k"%6hp0FKfN44cC,lj`k@Eb3Mpml&mJiSQApVYHEA8EmQQL2AImbk +C%8pe)(3ah#[U2aZE@`mEf)mZ31Ub5,P8&*c@F8prq#ra2!Mlj%SL'4Gh8lZI@2& +rfKAA$"MrFmB%lA#&q3U&LB4U'KYEd4#arMhU6f*p4pX*eh4+%l(i6rNe(US`C(0 +UUM[d&2l68`jLr(0Dmp+SL%pm!JAbZr-Y0QHpB5PrbF'6+"[hpUHi*mbmq(YpIb( +iB(r"*pf86AUZ-!l)V$HAl',dpB[biK4XhPiIjeL!5F39C-K"Vlh%H0YNG5@r1(+ +G,N)iGfhN'@3U8KNN-i+$E%A$DNf,$-9iY$!#JXXB9%0f(UlRSJk)YaU3!)9Q-9l +m!fYq(q6f3KeHlAT9l1Nb1)&rMiMRj&8bBT(jp)#G2A$ab1Fp`PB)aT`D1("f1S6 +26c!6r6aRcr9f5kP@43340EDIJ(,)EBRUZ$bFB)Bp$DHrl'!hQ%Y-8mmSfIAML3m +IEFL@-m8b)9pah0(ieY1bIBEqVcVNKYQ0+$Ap*8BdPJD+BeNI$!pU@Bj8P"`Pf2E +QT5K*@Kb#Gr58CV@JmK2YA9$2Ifi-JQ-SHpUa,L*j)3l5J#iE"%33)#@jmFZeDfG +5ZKdH'[Y+PIb18DRh@)K!($648I6KkdBF%kccR[drlc513fX%5V0'I8fedac*a'R +kDTmjjJcTbpfMm4AHT6D4PqYYL`F!rH[k0)9b$baE3G1b3MrY6$$l@bQIQdqV9#! +dFcf!)EF%VL12F'fJJYZfXZYQhZbBA&P6mj+R'GCL'dSf1-%0FRm*Ml+ImF'HHPN +PrEP3K,+MJ0Pef+f*pS-$AH8-S2P#Sqda)Df$@rQh%Kl3EJ6QQdG"*bF9ZjU[Xhi +-ZMVIe`aD+P`me228S,XK((,kN!!0H9LGMKXBG,)(X2cNCad'D3#[jiG*hb$eNm, +1CEkGjB@XqbSS+kaTKJ@qNm&*lJUr5QYDh$PHJ0I''f*JM)Kmlq#kPEZ*Hi'+d`2 +MqF"4+p9Rq8l6+*RE4!@AVi@3!1`8rVjR3)SG,l(6$a82Rl,e8hl8&B(XpI#M)cM +-8lFZi+MCVAc[*,"BIQ2,Qhk#B&qZA%)9FKqUXYk@Qp!TNJX!,lGd$mNUlD0UfpP +Adh"381Y!63!r$fP0Mq)&B"rP-&@rf*@bDH9G8IFbp!he3()LEmFj[`'DrLm-Zlm ++lai03DpBX9b8RaUCSQerK"cdG@2'[SC5"0&AL)$DaAJ9r9hhQSX)1A612C($fMR +CiP(GZC'LTDmZf%q%lJeZ$kS5VjNKdY6dX10dUEX5-0q&`@G-DUJ8f&aNYXp[FHc +1lJ(HBlPX!F@Vrm(X%0T5fm[0&(c*5ldY1[(X'k24LEl#LaFf%EA((pN(hIreK#2 +35Rj2#FV*[$b(1XLqNJ8+1QXR'@lrBkXLD&))e*ci0B6M'Q(QUcd3)1S6Ic&T"5G +PPl8UpC,qJ@HSBURlieK45*h&QccXmf2fl*`[h*cfpi`M%5Cc%Mfa+N8KaMYjjI! +q-Z9-$V!SaLTM[ZIf3IFFIV0AJqH+YNYV+aQ'j&GlmY5jS"""@9(qkjiHE%J0LC! +!MSZ09P$I(41NerEN(RQpNC4JGLr[M$,EikU`T-UMk**Mm!4!SBPA6qilBe-"Mq- +AqG2I+V908X6!FMT)T9dd0UPG!9#!*YXLDiC3'%6%T2ZVL[!eY)c'5*eQ"kM"9iq +!KXP-BmMdp*EFRcD&r5SZT[IM%1JqJbP!2S1H4QJA``#p`92C!f$BEkqai'23eTS +%"D6c%X6b@cG5)e@hf-*9PbR1qhMeLVS)9RFRGR!L4NF%`dd+bS[5ir,FMEppf(! +ap!5qAYDjMHmhHRdLi'@%c+5-`,%YEP1rEBrmh"YQqAa)S3Ij#c1UJj+jKMASeMa +8UcBYIj%ADYrmimbFjNdf-!c`D'3H4K!8H1Y5r@B(C"'l#k0XEMaimf-NUG[T$Vh +$h[`pDl[3e!Vl'#C@K@h!#&[XB[4f03E-lBfJQf('f$`'$4q"ZYMSj(Q@F3Z3!-# +&!aq2hpXI@T(@ENr!9Q2-CYDdU,1qS&`CeGdlPX,(DS!cJr#GPP3H4R8#[cQSIcm +q,QqPHb`SlK8%c'"L8LJ3dH&e'bHRNFaZC*6j(V1SSD5'bjKSp81G))Pd,0ViS-j +rlM2*'PmMKKj!`Irl"M1fBmS9mJ[SRDGCeVQH9pZfH@q3!&,+pq2Cae6KPVYCC8V +jCJRL`j()%Ndp!H*&i)Th$12"j1HSG,TkeA%cL11j9!Br3NV-%0Na'`(AIdh'@,@ +M#0lk"RFYiUh,jkc`Uef(M)q#T!%bpGFKeb()L[fY)-F#`SL)X$Vlei`BUE5,VIq +dJ[GZNmddYYkKjH"T(H%*KJ+Bd'S3ARUHV&CVeBrrkcNUlEKV*XVNLSqC5M*b!T' +0#6mfji82iRk*JI#C$e0E%(9X,H98ePL2EVHeiilFCp,hCFIAcqQD,d'&R2BcQ8( +k4""3jhN`UN!Aim8DXa,#hUJK9XiAPU0cXPG-AB5#mbcr6lZ82CB51ir$41b4eE, +A1@c"1Tp(r@rKS@-I,4F1a`5,`E'3!('ir5`8AFb8#"qCSc@E")X[ejVr$Xp8bR( +J!Q3Fa#H+0+$T5#Dq@*Je4DY@M0,j,Sd`XX5LT+Jl(ccmG-aXlc,U[1dSMNLDT,' +&i4QES@EKU,c*ciYcq4(i&eY`2e8[(p,US+fUSRd(#D`UNYXHJB!XHLIJ5q@'NrN +4rQUI9I6$h3T"8jrDj-+kdG2M%*HR06IbE,GfC2GB*h0`UmMm$2MTLji!Lrj+INZ +&),G`!R!D,bb*XP`1aj9l`99a*&qR36bLT+c&LYBF-FX"@D"UPJ$)0URXSc#mNp1 +CGHTKL'AXq$'0Y$PaJQ[a8,9F9X6Bb4m8UTVI*lVK2lh0pdhISkc2i)qkS1U@**[ +E(2bfV40k`cblEG)4EY6"[r"c[JcK3@4T%I1'bNP2`rCfe"8XimbQ%pTe+kB-cH5 +mK'5%)H01SA(5Uiq$,VjZHL#Clr9181&b(AeejpS[X-+QVE5k&c8SGPrqFAA8a*0 +a8-1I5PPMT*Fb!K(d1#QCFq)Ba%9'e@T*Q8r"`0b!$kJcXAR@+&%%C6H0A$Q&GBA +'0QjD,YAB2`'Uhcec-1)!5NqedJ-VLq4K+i8mi"GbEpr"VYUJFS0FY`k1BlaYpiG +UNmUaDPcY1bdNMrPCP"3DYT!!AUAATp[Tbb,4C`fC5BE`5q'U'irZmP-ej&Q'!$Z +6eH'b!X18[LJec'G8+E#J)CP)rj[,U"8i@Ap3ic`&kTCdRq84F&T!9,#d%qPc`F5 +XdZ3I'8TQ#F'bk'94RU9ZckA"U%ALP)HC@6FHreBRLAi6UM4UT'M+4q0Zpm$+k`b +0MJ9KV[U5iS1'+NJTUcJHMDaFMbVAhIfeU@&G6@!dj*)YZr2Fe-2`8fPQ`D9Rr,- +83Gi),&08RI#P9#2ef54kSP6JCFd*rCae(5Ke-Z(mi1#!VpULVpFN@-!,0ShSq1@ +&,M+MiqkHXL1C9QjUFIP%aYVQU2(#U#4ZRTaE5P'-mX(dh[8G1@Rc5jD2Idh$3j& +k"X&-lM1!rR$%-qIr(IaG$pRMZ%K!hU2AqN@dZ[EV*-3[4bP2ch0F)!5Qj2$DDi[ +rT*dr@8I1CPRQea-"(4VZCpp86brNpLl2NETkcJBESXPjXXFI%(*2Q'jJSUUAkD( +V(k9#[LR3U$iYZ`+@*lU6h9epSA2QE#!AKb!LNrleHq+DC@k1iI+Y#(-4Xb[L@aR +kPThIX!9`eU[*Af6LRd%aC8+G)*ap[$FU0p-G(M"f858V2)afR-)$lEM84f[%!QI +U4eNE361!ch555m1b(dD0N`!ZBRl,6UmJ2YVaKIJAT8,q'-V[+b2QSH58kCl0A#, +EZAiqG590(llL,)`ZFXX+AYZ+#kjEQe$'AC@KE([-$G"(l[i3)2XE+FRXkTe2rXN +N-0Mq)3AIHKTPDed,A5jH0k+LaRRiZ%@Y!MS!CJ3TElZ3!+%D#X4q$CFQNX-I6mZ +(rqqYZ2eC!m8P@pmBdNG86Z-`"I)5!`-YNPPr"C6D%AmB`),k)ErhGhN#!@S6Kh6 +2H*KPGmZVNI'c0!aKS+!$(3+K+h1P+(M"3+h@UqLbI&Lec3`(qB!$YKJYL`4V51l +kB[eYJF!fa'A46TLqRjJIcmcd!jTN[&+[GD6U+D@FhCp9DpVj5($JaQ)*H3T0P`) +FeAQ'$Mqk`KCfAlVfe$pT9"2(rV13!+1-1jCIN!"'Ch"hYUU29-Edf%(UeTp)QZ" +ZPSQ28*mVZ2[,cDSpXMd'$PmbJ(H-j1Kqh*eKjlR"c450H$3rM%+X-0i9%BBl$8' +cBE%L+PV#E'AXB4&eS++1Tj-4EJEF4$rA5Vm@A5D,92[ULe2T+6B4E*8c8Mb!kf! +)V+9cqeHRaFUT!6+fYGY8MGS,NH!5KIG%pVCP'm`SAZ`,$#Zfj#650m!LNZcUqM0 ++#CJLI4-&*Gr+!(cl"+@-28j2fZ0T)RKHj&FJ1+YMNC[h`jD9J32`!a#ATDQUc`i +M3B'1LPX@H`FYSI-'i4q%arj!S+2"BXGeV&1UHP3'6I-Phmh@9kpI0ESXl,PE$hX +)iAeb(CBCGRA"SCiKSP@0)&eGQU2l2iJcka1AEMCV)9*"X$E2iC&5MHT8)5'EY,! +caJ$dN4RBL!IZHVmi`9MV0%-*m-eTh3N6&TXC-kqT`qGQpLJTQ+q91FbRFYkjqPK +6#jjYjGiHSG#G`$@8D[UqQ[Spp6JV6l5FTL1bAlm@lILq5+&IJ9G-!51,1l`Gb+G +,6&jLem!B0$+e4ZBcV-k24IYpLHQcAafk8K'aV*XFq6R'*(``()rIHRh[NTZ$rPc +iB0(D'e6'jbECIfbZkJ(QUNj3TGT'[#h2ajST4eQI1!dm4l)iS#lB91pfLch!CC, +bUB`TJA$N)-i6$224eG)@jIYS#22VU(F`%LCi"TAM0F-RHElQH#pB+C+E'D"T6Xl +mGK+Y9VQm-MMMhJ$eJ!JePf)VLp'4(k5a!H[(015-h`TLAC!!qNf2ah3mF93%qCm +!YRG#kXfrQhCUA&f&XA"k8Gm39XKie+XV)aJf3#VSCqLAKZ)6J&9-8ch[)!%Q@k* +eF)15X6"[CJ#YQA*fh%MkXj2(lGT[8(`RP-lG6EicfF`2hcc2%*+Hfa%3jd"'JX( +E[B@3!(V1BiRRKJ&D8hkGDKC,p%6bi$q&$,Q`@i+hBib6Y*(cG#!2V5"N06ZH'"E +!+ef[L-KZV6l(kqH!0#lL0,6,"Nl1kdd`,`V!#N$)@mDfj,4*%HSIQ3KVch$daK" +q&`9bqCaS4K5AGJ@iaLQcqNdIESam-B-8$9Zj%ciG4b1q*llb[M`e3%X)QB)24S8 +V1ZceULkb(3Yl1q'R!Pc20iCr4K(mR$`Ka!602NDSRGKLDh+QHqdZC%4lSKmTr38 +Uf+jLZ6a8M&Q9'Q29Qq+-1d*Q4hM0j&X&RSBZd`NbD)4Y-Kerf#&&%9Ri#Hf!iVl +ZcGa4j4KC3BL,TA`h@0UG#kZl39Spr*5F+Z+GMD8e*MU[jZT%KZ08&MTIrhTp&(' +UA2H'59aSr,$&D8%-AH)#(B8'1Je9)Gf)5AH99MpCf5EAK,Pm+IZhaj5Cjh(b1Jk +peI+V(+R@+ZC*IBL",[A4d%#HF1K-ZRr%-8JM3INlVdMIhD,m$iq!iZb$G0NEJqX +@!LBibiB3q1CaS,22Vr#&,#45[!flm9!CF(a*MI"a9IrhR+RpBS%TlbpL,`1qUIB +YbPKFIRb"9q001b69Z'5[Hlaq3Ec5!c!MA40AMSa23EcH!Cca@rr3M6BJP"TX,AC +`$VmNZFPrhq0H!6GL@q$9EYPp1ND`#lK+3-##0aMPMNQrik+Kk*!!GDhSbELhC2i +lmdAU-6$-*&KBkP4X(1INKVcI,2Kpm,cH1)q4Pq*!-jlP`-q1Hc&f)IV)jjq6pS' +[lBIf[Y'#GCHRiU`qG%!hQlH'J-5I3Zd6-`6CS2T+8a!-Ta3X6IGLHTC2a@1Tcf) +jcmA8+,jdc1c9[#2B4!ME'l1Q68%6-mIl')I"9mI92Qhm!H4qX2E4I#-r$MLX5p` +K"kKS[DLjFY@dR[iiDd53!1"48P%(l6-BSXP%Zr(GrZK1Jlp+$aHP#Cdp"Cc&*Rp +TXh*MQi9P[CPG0&1dT&Jm0j!!Qm1"6"LTD+V,(IaYE'VC%+2h0Z&AqB!8j*6"&'K +VLSd`HAe'rSPh%L[QU%Ppei,'HEb-+,VmD3#49"FK3lPCQC2&q,NhKBkp9NUQh@, +Aml+@2kI'*DdhiMe8a!YAF&8ZP8kS#KR"KdU[e`+k5BjT%`Kip9eJ*qbCp@c%%rM +ERh$N(QSNa'!LZUZA)bkJ)N`QmK6a%`8eq`NqlbkJY3p,(hc(Ur(V[VE0H!IV%jm +923N(`X+)C3dlRTjk[Di,G"FXN[qUHdR8d`C%LMN5m%)&XQ(F'TpbFDU8U2BI%m1 +8,&F3p*jrU0#q5RPYRk%j-p)+mIbFF0f,j%QL%SC6qdIrmG@c5jEc+A%M9[[FlX! +X&GdJMJ+1U'R5F&[KG1&l&+Z,iDKhYEJVLel!ejDTaadaV3)d4,3SqaT5fBT)iCD +rR1Nf&GI#m@T[GdSJ&Cm3jc#Y`jTlHAeZXPG&b@*S,m2kBNqpV2K5Jh'R$YFh"Y2 +9K,-PDG#9B-DH+j!!T*4fac0*b!c&3adJhAeY9L2l+R`#i'@')aL1&P3b%5f0CTb +*dQ8f#Y+!KFrAA#%e9E%eBQDl5dkNHMi["'"C'A`UmV5h(A#LK`9ppZ6l6U!C9(i +I3HXP,8"R&1@Nr(cfbBqYaGKQj$&'"KlTq,`JcV4NaS%LXTH0hh%(T[AkceBa0XX +ICp9NB,3$AdQj'%#k21b%'D-'@"$MlfMlF9d+kSq)$VbdfSA(P"[eQ-M4!1Jkc81 +f-kBc2!A@r1FY,EYL,(CZef-j'9*JjJQ[#F`Xfq6X-q6VQ84dBGYj+*PVh@N&[b" +m!Yb[AS4['TmDGQRGLa)$EMmb+d"Z`,A#[-+($f)c&p30D+294lIfZaP9,GQ6bP9 +VDZDVEq[RFa9$AaP-T#CMKNN*V'M$k3AYkK)#[dCI@8J""ADkjh(mKNbC)T,h-l# +jXMUi+D&2$(@RZ-pdpVdbp'G'jF)BGVe%)QlI&mN0V"4-4mC!F2QrTU5)!Lpd)1) +!(S@NNDk3!,bJpE3hD1H'Je`Q$+4reCBhBZ)ihliFeU"m6f48MpiKm(2p5CJm*SY +LC%Xe`[hQa!ZK@Da+#pj1Tfeqe#bce8V'[h9AfV4!GKUN'BE$AkAeq@9r)S2)!Bf +M,Ia,H8S55pjDmh6+ddfh)&iYDm-1GMYH#&j"%f,e53V4%kAhq2+MK`k"I@'EJ`p +"K*pea8*TlE48GM`T'5e'&"D%TY(N853EYpjq`89*Q1+$2A4YX`X2l*GMZK$eSA4 +H`IUQZM9T8GAmeGD&$U-e,9M0B3!@ECQjj-rB,55m'h-d"S!da`*lqA8Vj0["rp8 +TC64E0)bK[cC8h&@bDY0F`-NeaYK#[80Y298&q`a(K`PCaSHC,jX"1L)(lMAaU(d +FNrHMe8LNE%Zb9*4aD'XEIL#THjj(Y3(jH5YJKf8!Gj&VA41,9a)pdb*``mF`SR) +j2MYFe39[4H(p9R&3me8&r55B+FHkk@MB3BP#bfPYBXbV3b9hT6)4f%"6QrQ%3(" +E'NH,@lA*jR4EH$mAm*hJq'5)ZC9*ciH(ReH[#a`[ai0rf,UpjNQN@ZAXUlZiZ`5 +A`ehdUk8BU[IEi'kFaLN)f-cmcb+UC1T0er#!hike[m&95MF,A2$Q@ra&EQ+9HKD +j'Uf66bCZ4b!NhHb,3q"edT@icIkl$c8-88C-HEZlY3j'cFmR`hHIS)Z2d`hDaK! +I9!j$IU%9YQQPZ,fK"TBUQ$jQBe-iL6HSHjEZIHr'XE*VQidM)[[h''RXj"&a@,J +bG-i&0HT+kFcfd$2*(0fG&@#qYGKZcp)LR+TUCc5%cVjRrIFjKLF*)8Aem4(aQhE +hMpE*EQf99EN)@jY,b-iiZIK34KM)qRcNkAk3!2Y9+&%TqKcC63G,1BC0kl@k9SC +#f2p6[rV*1rU*0F11j1&NFBN59XXeT,aX*(`G8AJ$H`RF%Y9-5RdJKLk9`&Ab2Mq +RN!#2#E4bGB2ic%I8p6N6@Vk5GYR#ME!PZa`0RG(II!lc'Q!82*&1K@r3!-5)fj0 +6"[e4b1Le`aIl+pYkb2063#mHrM2!d$1#A@`6!X&r+kb*F5TUm)ab,HS3ST3iGlR +J%Ei!-SpG6fB![L%Y$Z[Z@biqYA3'hS`FjqG#iiRCN!#)EGSS[%p3Z,2eieMe4lZ +4$a0PF8XN0"qCFkiUT'%PDHerL4Da5QX2,TMIc@H&bq,rFLK3)#QcSV6"2LJDK@+ +'GaFUP#QmE@feA6XYKrNHA[LeK8TADeFl!U"LDQXr&d%qJ3GLU*2PVBSe8ZAL[!K +Pe"BDA'mQEj-EiThV`1SUcC`-laqV%V5aj3IV#$frY23"MclAMdZRPi2`6EpVT+b +3!*!!J5k1f@"H#hKAhhdUaX1"LU!L2!V-Jq@+4%`,0R"B[')Q+Z1%XBY(KCI!jdG +iTAY)qR"pkZITN4JUm$pHaIRZ"*U&$Fa"ISRqJkJ"4C[f(1`#['&F+4Nq"'h"idh +kPF(5BbUjk8T4CV[I@G*SL#Alm61)X3GS!LVHf-YT44h96dreUJTPfp(4JVk+jTp +,jIeXrK2A@PTPXC!!q"KM6MjZS9r"XLUh&(aYHJ'jEP#LGhFl[LZM-`TEU%cUB9c +2KCK(QPP*r`f5ArY#QSSQI@IcL3VK5AfAVm!2e`SAe%YrQ#4Yp&#$d60$VJT'3H3 +8+8'"Ub#DR+Z1a3jL&6m#VeijFE1afD1SR&4kJZHk-Q+ikI#iH&Fk#F6MUQ`L4rV +p8p'f0i0$&!46"S&lHUF6Aj8&FJ22m%akdieVN!!r4BDF##fNACEK8eIfNFS@FRb +!Z0i4T9!894SjmlGabH`kL8VeNAY!@3S6R4J5JRXJ`YM9K`&F0pS#&!'UATdf4+X +5HN%QP!'8FR1U0FM*@lUGM6#B`X$+a06JF%-hZ`PX@Y1b[Fl&X5cUhr9Y0ZihfAq +@&HDM#mMKPPp%YY-B3M&A11c5JD+"*`8F6F4k*QU0!5@59A&Gplm3EjCBVS`j%p6 +ji6mj0rAS(Z16Zhk6'I%5RqVHKB8`&Da`IM#%"`SA"-1`blUD*6#T%1JFTkUIh[C +ErrqrKjej,@dI8Y'liFD3!'U3!'2$5HcfR0@5ASiJb(m`##J$N!#3!)S#"'!Eld5 +Yp5a$J`KHlrB4Xj(Q4DfNJZi-2Y#'ce4"f8S@4kj6P[K,L('"XfHd-U3-qYV3KCD +pb3Z3!'Ue35p8-cbf`2kN3(d2-0!E-*DkAT05YPTmP@UL52!rK*ZAiYIL-Lc$9[$ +)4#p$$Y##%&,`GU"8J3(k1*SZ+TV$+H`QcF49m)4AJCa%3EQ5&1pdh%RiC%%+-D2 +99$kc,2hb'JYpN!!JcmSfjM5q9bFG811dTZe-S[#hqHRD(VS'r$MNqCRe)aLZEE* +MirM)366CD2'(5EPm-5b[c6&pUBh`XC0JEbM$l)kd&m`XX1+mrC@mRK6'YE%kNiU ++qRAF'Rb-!DX'Sh@@9MD9q(9B(CJh[[3F3R"8b,@SIr&c8XR`lSAVMb+DqCNV,cE +&)RY3RAD'ApXSZ5G6hJ-NMj)&#Kbmh#Ar*h9M1rfS,[mEBbfAEC+EIIH&XQjk-XZ +EI9p*"NTkh8CC(hPZBb#9,p,@4Ni@eEEZqN!Ncf6k23j[*STT$bEjQJ`20D0T"TT +k$GU-8`lSZZ-JHepEDdqkr1)Ne9!erE8(@al4VaXcm&4UbKXVq9r`dZmZKip)8f0 +ZJ$eVdV-fEm9DCL(h,ffKia!eMVGBG3Qjqb,d+%C2D5jflqj@-0`HQF("l1)i%Pa +!ZR"T@DXUB"fS`bA02SG1jAqil4`XB1,1%59cB`AMMRK9kF$%+CD3!'"GSV4m9Gb +Q)5r"2(2PkZ4`*Bd,Zlp6'SUE4klDpJ!dG5&cj2`#1HFb4bKq4r,EJ,q4Ld3+[-E +q@,KQS#PGB)I2+6i(25JJk-dqI[40PjGMb,e9BU8PjY-S!RXNF(T@a*8UlI!0Ul) +Ma!M#!FeR(-rr9@Ge8rT8cR&X6"30CMN'biqZJL8R6ek662a'19-6h5Vl6f5RE0i +6IPc4C`mkcI#q6VjTbRKq"3I)8+-EXPL8D4V"AjIhECrTd#Hr*['PH[mIHcAk'@X +2-0*cT&afh,f0&MjRJN$6q&YFB6LLDSp,09e@h('dKc(meGDcZJr4GFcYR-r`,i8 +[LBl(%bQmFQL&HGGND1bGV)fS6!cQAS(Zah(A858MNPK!Ce5'E%CDma$FRj@CrMq +lMRN%d`Z%!IhVr1el(8N9rfe46jj-$DTZr(TCKd'mM#%DGBBAJ8(e3VedLmIcTjk +Z8QrhX0#GK$4"XDQh0j*E%bT+rHS%$@h5K'*QP,@Um#iVXTrpQmQ5b41VMDi$0%H +4&*XIpAJfI'$%(10+mDb064"5PG43jZ34ZJE3QT!!X@edA0+A1+,SHLc#!N,"pJ- +dJl%F[68l3fNPV+[Ah[0)iIX8BeiDf6hb1PeaeSI%2%B#Si,R6ACS1h%KPiCb$`K +KTp&bXbrb(S5S(&f"FMr"A8kk!c'BdIV$Bbfqr#8)SBcZQEIJ2GY[)$bBYG[cNrl +!D!Vl8lK3QH)*XqXJF(I'RSc,!rkCB$S4qKKd5X4CdFP2Nq%GF4)K,)N*0%&p+DI +A%qd@5Ge5j@r!'Xq`42F-8"I81+@#a6(QC5LCVa`TN@hiRd#j"j5Y',1D3E6DAl* +ZQ3G*80FRH!0@29L3!&iQb3PLcCGVE-e0T!Li##m[%(J[qZP[QJ!3aD)HQX19mF" +IT!B0[eQeZV5aP#ZCKE823S'R8PXqKf2T5%B0V0V$5+QCLHZ[`eU"hrX'LqN%i5d +Iqp)ISCkM#ail$CbB*5i"kAhKf8F2FpSqB,JS61('1mRp0dCBKqMAr,YlDqK1pH' +PQ@+#b2F9hNM1d9"!eUM"[jH*SfJ5qEET2fUJ(NU)$bkh!NZ,lAb)!)d$1iZXYd2 +#VI5HHhJ![2UiYB+bJ[Qhl,$#emcI@e3F!lFT0U)ED#*QliSf%$"&AD$e![cj[qM +"eqIQi2Z8rMcaQI&*"Fal#(0ZRq*Z8BhD&d!cHlh&*K)Dr8Ld$RkV(Y)IU%c6A6J +S12UB51T!![5ml*Jjpa@peRUVSP2IH!#PN!3"!!"$!"#i)pScZ#2D-`!!Ep`!!0` +F!!!"-!!6bAi!#akj!!!LZ3#3"!m!9'0X6'PLFQ&bD@9c,Xq!,RKYE!!"m0j849K +83eG*43%!rj!%!*!+J!#3#3'D!*!$E!#3"!m!3X(9$qA8,*!!8NT&S"6e"mU%bYA +[Y1QHX&BMjQ2ahc,$m!MIA$$R'`VL@F"A4pDH)kaKa""@D8%C'RA`LF4NCHCM(6( +Cq'LiNaR8%2m4p5Z`YAR`Bm)BX@"bF6THhaG330G5!cVEkD69VGF%!%,"e+8,`$l +pV*PjG4R`R3eDNISlN!"qd5Cb#i8Y,r$"DB[+lC9*bYc66$Hfr%NFkmV#h6!AlFl +I!kibBp(9a4[JB@kG4rjYTq6[59V*FIMU"U(hK'fhLKAZEF1IEe2q(,JM$YPAKbY +#Q`*%JlAK&88iXK3%UiN*lP&92Z#bBBX2HCBblr(MfqPG1-q9%CN%eSJjfpmq6CL +cJrLiE(e"lcq!6`fH8*J#hXRbA+jKUI)aZI#TUI6*$pe*[bbq,)FYLHHYJfB&+Z[ +'bm'kJ6qFPM-+3Y"dI"6DAe12-,5F[`Sfr6Q%80,PQc`!'2(P6ERC-lc$BH$@qS% +X4EjGh*Q[bEc`)*dR)'H%qDdkHkh%1'C$KDk*b$dDV*`REjF9$fElUrKQ[d&4$eE +B%&PpdQ'6JkG@Z+aH(rj`3JKS+8DDhiIFI@&eR5)a%ZHmAX4T8,ha$0kdZhIQkTb +b3QRT-EqC`N1BXCLl2RDd+@a+3mUTf,)MU-i,"MG($8NR!iHQTJ6kajfB`!Pa18$ +FNKerI)QK("6Nc*Sr2V95UFK-&UMEJIVAlpRf#ZlpMc,+BabY2jcSDQl"[(0d$XK +Q#@UR0UrIMcN`5Y9@YC!!j0AaK*V(Da&CY[4r%!l-P+q-(!lSV9bf4b3%pFF-YHK +h2i2EDmQ&@9cBBjJa15JP`Sh)e$NrLZX"iNlTj[r#+@8@eAaqebY%eE!,eL9l(%r +r,,BLm-Ma9(Q01$URIdJ,DAM6hP#$Z#*d'ECGKQ[6)KX4Z,-kEqh&cUN6ZT!!3rX +bB3XeEXR6@,"SMY2l!9#R&3RkJXGEJL`"1!YS%XLU"`Fr9HaAbk[$Vb'G4H"kLrY +k40H5f(ck0[aKZaYYGCJGfileS(0+6Gk+E-R0LXG,K41`4J0HGJKY,(S)8`"Vmj2 +hYhR$[@dI((9RcB!-NiM!Q"aU80ASqd8mM!MCDfDj$A%['4,$*f4pZ+%F8fIe0N4 +GG-FKCTSI3l8j1%F)d`lmAQ"@DYUkp*d%N86G#ek8*RR%9qh(ah%4RcdF)-`fk!- +%5eaMlm9Tq2qr"YUC)N4SP,-86l)U5'#4Vb3D[ilbJFe(0X0+3$M4T0Eb1'kIhdX +hA0P1[IKS1!QEN!!eb6,pF`8b"i[Bh6K5BJhP"V'Pqf!2N!#291e%d6`U+@i"[!9 +63m+N9hF9P,jV6!&@"9QDkcC%189ld"!)HKEEDkqr9NGB95+LTeY@%%&aI-M4)YK +NlqYc)ZY)iqmVmF`+9$+eLhPp!Vai668U0#h28k`[JV@T,$I`X[k*F0[e4ebCX`8 +pSH8@L0`"iL9fQlKjU-pNE2*F12FAkL0KAk#8P3@$de-E#YV`c9[KaMbTke@0YaP +VM#c6P%T&&+*$LI,4MCMXcaXm(JKq0AJ@2jqALJDL('F-*G!FdkE)RRZjRRJVabN +dqKA4D2U["iR,!!i%0ED4Yp'M23qe`&2%jM)UMJS,2c"e81J8[kb&`E0'&cdJ'0r +$A6ET5D9)J-K%$kN1TV3J(kiT03iJq5B6AER+mj!!VLlE"Ge6M$#Rmie5,)eeZV( +UdCllh0)&"G0J!1aE!@'PQ!0dCDG-Q9Dm8NX3rkZaN!!ATJIpX-38ClaVFMd+,hI +"bl*R@Fa94QFU4D9ejhYU9!18U`pY6VHITrYJQ@,9A+Y9qXlAS-`3bX[-BS*9ecA +0!LLN@'3,eE3k5e2d#51bDjr$5!"IaFI$ecBQ3l85emcTdLpR@@ILlQG0fQF-q`B +2-X18!58)f)PCr%5,-QllXmYj")2JbIrBJV'Ip&a2"NdAFpX$`,kUk)mG6iU`A"V +q-8ehJ&,llIBR#DaRch$)[!fmb0[cI*L[86EC'Z+Z3)(`9Y18IiZ"aU("k$q+&0Y +2(`1M6[i$m(T,GVM+L4cQcY*Vlh8X[1p#@QN6m*rHi56c96Y`f9E4$V"*K*iSK%I +04rVr%2A+JP"Ql!U8,6eLL@19Z2%A8JQHRYe0b498D%b@bDi+dafFkC1TbZH99E, +`mRHkPjFAS+F29LZTZNhQEr6`5NY+&BdmhIc8"p%q!aU$c$K[NY2+4mb#+29KXCi +Y&pbeh%i3IZH&Dc)1!54"mZ8l2BlL#HB*1MZ*AT%#Ma1,SN[DAQ8fQ%IahNL8IZC +8T+eDpA*#lbIi#3MJG)1"SfS)pFU"UZ@Q#,FEdrZ@R4Fm-[)UALb,jc8AE189`hJ +-"YTji6Zp*4-ELAA,)bbmIEKrBV)D$`VE%%pDap[SNeG%HPZUV"(1V'PB)PqjNE4 +'"5H(5X84!9mB!0jj)kUk,cU%LA%[Z4pSkP1JhR*&iL'f#U!,F,frAaMGb`XfiA8 +!f#jF1C`5Yb`kYTD%+9EGKijM9mh4Mc&`2,,8H"+dVLjll&%prQdUYT+2)h5JmEa +A%+me'e`r1`M[hArd`6A%ANA,a#,ED*5NF!9M%MAi8%Z3!*)UEFT4p-TpJe0!S0M +9HIIlhIk-mXE8@84X%!SSANf`%'kq)HILTdk"b#!B8he#UdCL%S6L9I6rFiM!F@# +`LhF06SJ'b`&0#4SVj9p6m#h+dLN"S-E+#NQK(YccYqN6F`d[fpNIRa4Z%a1T8l@ +*l(pe*p!KXK65SI'c2maSbN`GPk['iX*IHT2IZ-rArrS"S)H[H1b8)[%mB!+2e*) +0ZjQc3MGl`+MCT1AFqTkF0bhkH'K@aAHC#Aj12K@'`9[48l#U&)FI3Q%Q4SY9hZ5 +D266mJMT5mZF#jd)S9d!c'j5`I3*$D5')fj*@J+)Z4Y@9#DD1`'434a2dB*XGf(U +&5CYU,eMpEE$qE3d`SPmEZp'9NbNhY9,YBc(LmN1@Ql#iT9LVbLrS"MN[&&0-+@i +"'id`DMc#jA!LQC9SIlfTimGY)Elq8#AL41jLe-9adhmNMmVIfZl60$Y,&5f@X!! +,S1Ei[XAR,"j5iL1qheVA`-[YFHiXGqLj6JQShhhkU63iHj,HNUi@dE-6M+RKHGL +l8(c0H%59DLbB9kVZhU(5)4ZllqRlJqm@f2"rehpYEV)h&X[&LmMa@5jJeED1LRG +"F0Hq8j9q[&%md@Nf$I08-Hle[)j@Kk@8K5@X5DQV%(VJ+1@ES2S&bhBrq1[BQ8( +'"I%XkHSrYP&PShSe,jme$pm'NT4$9Hk(lk[%#pk$m6+a)dhQLjBVXcbTh6FrJfj +HT0FYPf##pYd93ZJ8L6-e[bMeJj!!IjjM3Yj"VJ+lpkA$Ur1!3crK0Fq"V1ipj+B +HK396h!e4bL(!YIX['jc6N!$dj6Ip81k2Ulk5caLrJXk%T,cN-L#-+QN("1GYd2A +AT88T$)UGT,`eYiqL4&ErK-985YMP"mA5)Q(LP`Ec9ikChK9NI8+JMYd$aDdZk,q +TcF+1pl`mNb!D2JpA",!PUI+h0aZ2m(88X`(d!#9FZF+,Rr6+%c0C@lp8a+J&%!5 +c1G"QEc2-KC),21m3p*R)c5d*3rU&m-58Za,(NXZ4GeXLR+9Mf'504LFUd0)-p1a +2#BD66)@-aNAXd[LiI6qBUp5P2S#M`cRNX"k`GrAIdqfh8,iU6r40TlHad-`'+#! +,Y5UJRZfKI`G$TB+0*kh#FA,&@b(r(lJ[E",*,cMJ3jS(rD3eb#`3`h!8E@Vp(9N +0@-AHq$G((SXXIBble91Jj"IFBKpTQmAB1kQE3,$-RIV+33JBTA`0VfiJR*!!%kZ +fS)bph`*da+0`f34UkN83lYU1)Ja&EHhaEYlG'jP*ST@MB!)mcEXQ')FXl$dDKIp +H0)TSSI*l[S"l()D8@r@-5RjZRMj'lcfl"f8"@Z-bUkqr4I@8mZ9BNQ!8-C`"D%* +lhi%3#a&l2`R"`A'@XddRXYNUq,9QMGFVS#Xi-lrcf6)(Nb%JVK92a!XNKMF#E,N +V"Q%"Xchk0*i`)G,8N!$G3IRR&ffECI9F`eaQ&f$ABbLTKhGBjM1r43R''d*+c*1 +F38MSR1e(ki+m5MQ9'GN1"G0e'2bj96%r95`*QaSE[SHH*TU"hfJF'bjMYG,L&qY +JThHkaer)S'NIBhmJeVd&)H$8J!$KhU+*UQ+Ci2K9I&2"5hB"(,l-q`P)61ciJ82 +"#(TF!&5!J`KIPpddXMC!*l$Ehc00HXhL,hCqG'cIe$#1I!m'Uj4["SqTp29$ae( +4ErB&,bPKA,!8dS49a8K%#U4'&fH)j%HCb-b&rmA2N4XlpA!Q$!cpedr4hdfjGd! +`-X9q#IT'rjeaI'T23EaAYi#b1c5`hqXSD@k[98lIZ`c0c-Sd+L@GEe9$VX*dIk& +4,dPdd$dAme@Z+L1UD%3l1R)(&Q3B'rSK2lU&3%U$IXBm-SR#3q2mJah,DB'NZD) +YNYJ@k#cZ''VXT$V"E`jH9NS2Pm&@S'h)8d-BHeU(%18dej4*VCBm1[H[laT(%09 +H)UKJM[#eK@RlUZHa'fm(Kq-c*mh"D'ApZ4EU1#M,+*EPF*Yqli&ClpA#0)&a`MQ +DSP$98Q4"9&%Q-6!mr(kXF8643'F)l6FB4T!!bMRTb92R3'(@(8$i#3FdTS%fUU& +U[Uh2`jT$(4(KjINdGDi6Dl'T#,Y+#iNr,"j,9FC6*#PUA'D,&02UTFk5qS[B$fX +8[[`FPU%3*1&GGLdXFcq3!!8$AF"08GlKUVL08'MP6X@3!'+lkZY)l$LBXC!!$+l +"i8%UY39-ICVm`V6a@4'`Ci$P)eedifadR$FA*qi41E#F[VD*j1[M%d`'4k%d'N2 +a@$ljQ3`V!cS*2e`%ia+PG5Ei%*JHIQB[K!i@B10+-Q&pG4I&@(h3)0CJb5jie+* +iFZHcCSaXqA28+ANd+X(3F!2VRZ'AkcDP[jbV[(D%Q32NQp@K6@9E&E10QqpSSH$ +(6KL[4lKCe&a(YJPl$$NimDh1U%Q6C1TSCYh-r%UemDdCA1C`R-NjP&`Iff0JT$- +5BQLXK0+m69Bre[Epp"e44kNiT"&-aV%+#-3Z4`Up4Qq8Sp[1NhaB6fIA+piSb"3 +qQTbir@dbTeP*fmNbJRhV2k$APS+`@18'mdGHl6jM)()pZA"SVAEqXh)S-hY46S, +5E@KLSpaak3#8rKUf1NfXLINfhci((r#A'UJP!$GU"a)LPmA)XF9c*'-VeF#Vf8h +6jVCcmXP8Dh)F`X1MjIUHD0FLfK%06S9lbKmGGI&P'BZ"B$CBB-RZaPDNY+J8P'` +)P!85Ub#4[8YB$MQI@,L#LhBHSh@PRIH&Nb6lP,[(E,'6,K3hL0lbRQ*-#k,3LCU +3!"D+K)5dZJailX69dL&kJ2A06KcMDPKS"qf+YfiG#+!F#E[$N!"KEDM3V5p!(#+ +[hF-fleVfGZ2TSQ'6!ZJN*UY8ANp"%[-hVRL(3"Bkl@P-%,NA`q`8"r#&(Sl%1*f +*Yk@QRD2q%l["XGa&dJ#DF[-)c!KV,rp-TdQd9&rejN)MpLeZJ)+ZF#TIDLV5*UH +2,MS!C"34Aai622T@!LrHG'ZK!fejY'fQCTM@(fmaj1rhKMAK4CkDbe#U[83V1XV +(VlAHJDmNl$Z`d#B4L)!c8QZBSX0"#fBcX64@dYi8V0%jp@$Ea)E5[`0LFDUVc,h +50lpIT4'I(k(d'-dKL@AddVlG*6fkmk8228qc$r9[b)TLMc!FrX-V'IMDJNbU`K" +pqR$p&Bq`rd+h,d(i,Z1jXdph0pN[+$dq-KbiTPI5S9TRa@%&l"J8[VM1B"&j*Ee +(Z8Gjd3p*36eb!BJ`i1i)Q"qaGc3r`e@MT(SaG-be)6(kr,@@(),'+aXY86feIdK +6LmKMRiSY*6%Rh`[8[#[[aB-Eiq)49@b&,@LPf'*bE5U6YJCIMSqhRjG*220%1#m +#M)ZN434@Cj)8iIEE6#X0LjK21mY'&6,PD8Hl!hDTJeNqiAAZm-Qr"Z8@JF59P@9 +PdIHRr)+9@HcTK[)r6mDP,5S1F*@i%l)8-N"e$L8e,SfA@JPEmDSUK`RSKfk*3)N +pLr'``VEQ3'q[mLhFRBIb2F'r#!#TbIij*Y1cQk+N1-kXF4Cfi*9@0iUZAb@T2lX +QB44IKeb+"jfSh"5Q2aerh8Rk@krQp5'eKRQ)0$eaeBH'iDG21H`A`U+P*6(L4Gk +j)L#%8NhiG)-GdI0mX&QG+LTjY"&"fSQSJVh$pX'*bfiU[&2r'kB#N!!-f1YH#+b +&bdp*PU,T@$fQK&AL25'4G[kVXAA04U*101F!3Tcmb8Tk4r[32E,lmJ"k[EMLii* +"I)EC!q0TDS@A!Yq*hFd%'aXGU%V$'BVfMdHS%"cNi-eIAkKd(GTZUkB!*k!@%5B +&!ie(0[5EFp6GSD$TaLqR1RdZ%'f"LEFq9jl#5BSrjfI)TA&C!f0G[B%N)Ck0k-# +V+&UJf$4eIi,fLRdBS#e2CPIFJVR,@ZXiaN"aKSAYH+TRi[XaH[V9VlNf-UIC-ei +pfAdKXQ"cdH$dTA(bH&UGher5)6M!l[,lh-8*"``r&Zba2XLHU8lNm'()#hK%GYG +eYf,2p&NX)qfi-d19CMpGfQi89+0p)icDXFr#I&3NY!M3%(Pdr2AifG4ALGj`6De +*EC@Klm!"jQQp+fY#$aLc@`L&+@UI(EpA(*RMfGY@hX4Y`La'R&5K9Lj6VQ@jp#r +@p)Z9C&[9$aM`K,m-"peJ,MqUL(,ja$3m208mmFMr*#lD@pHhI'G6pAk+@T@8dCK +C4!+[Y#@RLGqN3'VJKe3V3,mAc!803L!FQ')f"`V4DY3c"rV)044LqDmBhq#A$p- +-B"0HlmC-%'#f#4BfhDaI!YSdBEjQfd*&ZQlDcH9QA2BU(5md,&V[0%&(b*LHJbH +rM846XlS+"N6q+a`YM3R[DXAF@$d5`h(Drm8ZXqITPPU6jk&J-T%GVY(&%`CHf38 +H5`FFJG`Km+LmT'6ekKGS[XXJdNc0!P680LBmXQ8D#02jF)CcCEdaMhr54$U18j, +9,RYkGM%%8I'caJTa!F6!2CaLj9,3[h(IHEf(KpYY3A4!9TAV4AhAkH,6r#j+b0E +!r*`EG5KjGKGMBrLcECJFKE$VUh`1M$#L8%MJ19ahU48$DkGRPZADAR#hMBCb$MC +`DNR24QF2fd0UZeEQMY"6SQJblG+(QA3+*`YUAU#D!LTTGA*!f8qlF`)jFEX'Q'D +V4hkTkDS0$T1INi``CYl5#Y2kCh)+HXb()4Q*aJDbBP*f[-U&jI8A%B$2`LVb&Fi +IGiZii1i#TA6G5Lj+m3P51Y+Y9Kbd"5TM35%A+fdLY-X!r5Dd*9"JJdBqGk8)X2" +![*PZ$q6Xr"@ki`rbh8(8qp"GK'[G"Ah+fcQZ((p9R&!FJR$"a""P0rVVG#Z86%- +iK,3&b(JUE%1AjR4Z9Ga$4dUKqGjFe)5ACGX!i&[Ha$FmB0Z5qb"L+ZdRBi'@K8G +6B*9QXrFk63a%Hi-4GXFSB-K-L$R`[KCDGKZAC4!HC#LBEH'U-`RlFh415pUCZBR +33jkG(*R`IfCJ,Qf52EXL9TrXi0j6%+K@@5&ik)&$*VD[2Le3h#$*$d1*cZjkUI` +M64Q&dS+D[kY4if#"KR9-m*UbCcd,,IG'Dl&qLj,6Ui%3D2E+HQUb!q&F'[2j"9` +dFR0-A)p)kpQ,f8D-6Iai*,PBGEU@IN)P%0'8S*i(ip+*q)r`$A)`ja"HXTlb%Re +MhVS[V$!K1TPh3IrU&f%Fl53''VNA@XdU$KpYQm1*lfpa15(dB$eM[d(!!rU,cpP +4F+B6E+LD5fN`@c#$!JGh"m"$Xdp#C1rk4X[V&HAck-2k)m&bj6"GZqjXYFN#Vcp +3G-jXF9RR'PS2CFPQ`BPANdL',k0iXZ,@!0fbI+F"E@SbD)3b)TDG`L1lYMGL,"H +Z(3dHIf`IIG)#LJc3(4`QLdBMe$bQ61+aq$hG!-(k@)VCQ8pE)cSp-j*%5qh%D@m +TiYc)1hX0Dc)r"QZjYQL,GF9#2HU#j`hQLHahfK&3`R-$Z!M3DPHQdC2Vk)Sqc,m +QMJ*U%!hZ2E6@`qmS"H`iIq@KJib01KF(!DI0186$Hb!R(6MZ`H)#4Fk4mS-`9`` +D#`*ZB52AfRd*j`j4[(kE`P1)kL[H,'M)0D5aDXDf3q,L'ljIhXdfVR6GR9q@NAi +NNf5N'Q23&q`S9PG9SXEZ"HbRMU@&!Pj`BSQ1JQU)*QLj9ai!YL20RN*hZHG@4FD +RV-8T%1ck2Q*[FXQ@PPTCUN3H-j6J'm8bBQNCZ9*%ICcqr$-A(ii-Tmi(9la0i!a +T2GI$X6a%*,[Hle#'M-ljS*!!HHf+A)p[mD`F*rjY3!)@!Nd!-(j"2HQbKH&#ePH +m9$1'mUA'lTbPNc9JJcm5BQ2rZX,X8DXci'[jNlc!-H*2P8SHrHLLlKNAY'$aXDB +,M9m0[P%9hlii5Hc#,"DpiiU2i)kq"-A2UHkD"KTlSiUSGIe"'dpMK`3ai8c8jpm +*9210TC!!"38K##-3"P-N`!0"qKVkV,MF,X#085c%%(,$(Gji(ND*P@)C[ejC,'- +CE-a#Vij%[*hmK'3c9#G8`QaPF'[Y9[(("#i-Ma8T2CKN%V-'*eY*G*)f!b(F&6) +CVTK(@'&Aj(G2fKMmarFiUh0B0B,p[hJC`M!SZEli'+"j`)*A4$UHI5UAk5BKT+' +6)%9EETZI4"J88F!))M#P6fX!UJV'cI5GhJMp!HIS)S1a6#rlUkRcQjZiZJG(NB! +TXS,TVQ2i0C'eQK3%rhmQS3UdpSeYBCNLRKpIdJi2fH)SR&GamS*,3ZZaF%UHDf` +S",lL#28QmhX%#h3[-qqCZ5,M),3qR"jf"[fG6hbkel0JL93!j0b#Y5q@H(m6BFK +eMXG,,*Z@Pj92db(!'r1mmaq268YSV$d9FmBa45%-ePKb3'BBRD9Xl)BJ&U280aj +e@mr[R`CC!j80)UNbiBRGb(eLeLmfZ#[G#TdcFqCr9eJ99mG&l!JL1A-r#5*Ea+4 +[)A,crH-,1q+!bkrb`Ee,i-aK4BULK42G1',!iq$XJHGKD@AC&C5(85[kpCp`)8[ +%PACEIMl@f9SHeIF4VXIKlA!L1'a%4LALVm*K9A*5!%&UVpl$i&1XbraK#12rTSi +MkfjRNB)HC-qcRSZ%eS#p4U204B"b%Gkc*q"iHSdXEPaAHjhhakU#-9PZMGkK%e3 +#iGD'[A"jj1NbH8[(+SHiN8ih$rC%!1X$#ji(Gh0QP8qX-Z6K(FF(`B1A1%3)j%, +TVa5TLXdN&SXe)@rGV94%1E&HQQS'J@pfrC*BhVYX+l"DBlFqB(2qcd8b2*V60di +ARYBl4S$ZfNMY-TDFmf3Fr'-GKlZY#MR-`ZbZPki"Z9A"b0!jlC&`H&L6Y9CGK4' +kjb,ZqhTrX&l&lR%ef[FGcfa-6E!XRhBh)*NUMd4bT"#EN!$$$%XMj3'8&Iq5YLb +)8R[9996B9c-RP[GaX6KKAAU6SBQFD*@NkN6`)lYhq-GDU(q9Fe(9Pq2a+pC0'1+ +06Yj#b8iKXlF`9YeX!j3X`9N5Dl#FB9RY5QTQQdc@i)ca&0T[5+@,3NJM,0!chZJ +aekKVD9'r2k0AlNAX@cS9fZ*$++(I$Id6"'$&pFcjR'SE@5U([jfUJbCbeQ[QTrk +`qNX!0)fSq!C&8NjIcaL1-T394XZr(IXPNmbjfY)5I0iSPeY$93hG15mHZRZYIqp +pT@VQ%bK1+U'&Z+GlSmG,+-)R@h`DC3jS0D&jT6BJDJQ%KBq$C)rMKcHRDF&+TUG +jY8S"11YR$RBfIqLFVej!'e6)&'prA5d1NrA@)ddaLB`-ZAj1THRFhK35ppcMqDr +3*)h)'VG+("IXYVG)UIT&Pm'KEP+mYTm-6"8l0VfkK!C)R)I3+96r+@eRQPbZ!V@ +m$,1C1YV*hN`q2CDa4C)1"hD&4j&9q+32YTEbJPD&6)9J`Ue4rlNLHQh%1!UM5`Z +b2bmj%"+9ZUPTf%r0-GT[T+`+ll%b1[GH$BI[GaGCXeNVYHApL4MMk`GrjkYMckL +P'"G[DF8"1(,3AE4hdTcVU['UF63VQkE5,YjfjQ+A+N&HFZX&l5BB3UbhP93C(Vh +Q!*!!P'XcVSrJ)2MDhI#+,Pp6Z9EYT5e&D#A6P4BfHJ0XPEU3!+4d(CqjfEe+5[T +E$%BiC0E5B6e@Hm3)KhM"'6[S3(9a"H1,)j9NG@Y5`r&,Q4BPADRA")8``@UF#2K +6a8d,-PkGm)k+HVlLKD4+c8Lq@3T"IlRTM3aDZT[P,CUMmA![VNA,p'Q-[hTdqEV +NUkQj-MqIKqrDX9m[6qm(kR`)#U$RaD')[`aMQiNX6@[c6HaLUKXlce+R@*mqJaj +a[ZL6X*++!kqHjY$8#m3KF)qq-Z%"S1`b#$d!B0Qb%dFAc"K*fc4l9B9"q4!ajjC +*N!$C%Z$&q`$!k*PB5G5S1cE!"r6-N`,!PD8HcCeaj%KHCYlFK)!GK95q)EXVC*p +m4iRqhk@c01&8eZ*GfCD'-mXE-Laak#pBHRP@%mVY%LiiI4V3r*("(ASB(TX,r!A +rQG0-4QEqpP@-DIT983QpQleJFd+Y4B85A&l8YC+qEmmQ3RY!-rb!2$@[9+3!TPG +C""jS,A4`66j(0Y8$(6iD8h(cFa1p5B#m0"mpBpM24RK@(H0ZB&Y&jZS1d-Xh#Qq +h`0)!5Q&$"NP%hESGQ0Cq*&hfVhFppB$fM3A9h6p%SArADeZ"[Q(@Z1(F)d`X&8B +mPUrQB'3Ch(JCmJDpRI60hNk)H%5A5lY-eT%DbFJ%p@ULHCGLG59l%l5V1+l1YL" +Vj5BD-8N,Pa[*jJca%cPh-K#6'TYepeH''2QMDFZ0M(BKdH&#Bf5I*15LX%C60UE +JJlYAd52ELYYkFNHD)0`aFiQ)clNNN5$9@2Jk*E'JX@FDTRjVcj1YUr&qD%mK"dl +Mp-'L[)P8UC@QkG&cDKpriLT'lckbP*N(60(`@CSM2F68mBFBL-jb2d@9ZNDK2-# +&X@VHM50K5[$YU6lS+@0225)&3P3-N5P6@QH)cfC$1*j*UT!!F*1-!'BV4@f2`16 +$j*'jcG@#4aim5Gm0ce%23bS*LR3JpQ`k8chbi+Q*"01)NP(ZDPf'0D4a!*!!M`P +Te!bFCaSCe8CGT'P*j((JdqJ)"4Z#,m*b,3@ZlRejJLN,AY(&D@pNK*b)T)jaBH# +RDHrFPd,LcX$Q,phmlEm%Rm1&pJN&DKK`%@9Yp4j$F,VmY[#4J$CQmCq#(HR"k,@ +hY[p-QcmjCNG0HIHL'@qr4qdB[qa%B1-JA%mh@8QYB8EJa'B'(ECTB0iilEcTR"B +AEQ-Db0KeApNCaZ*Sr'HaQlBF%8Hja9%(&[jU#kR`BkA09MVLC`2NZ+U2c(8@fBQ +2(%Sl!fl$'Y@*ejT*q4CS@`mbj*D)dkMV4U9"jSfbF(4lPX1'-QGUfX9[@$E822` +fqJV4'jLp+b`QLY(8SD2FEYY%'pkj04C(Y,(lLaYeD6P$"('c[Q8i,e#ES51*ieN +aP'mY[1YHq,TEj4irq5AK,`$eHCV-E(cHJ8FbAmiq$BkKPe3@mqKN8BI-`h2+`qS +,qA,h#KL5KMjeKT&9bqCPC#jaD*j9jNPhFbC@"li36rAb)MXAdcHCZqUUlJ2CBb" +mm&8rKbrf'T9ka[*YrK!SLr"DD(%SF@EVi#4AaD!#eFrlH!-40Vmi8,5kGdlG,9& +rrSEPPCLe[)YTA$di$`9f#*,8lGjVTIUrQ51qmDX#HYA)lV1Z)Ck5+UL"NQR@NJq +85d0)U[k#pYadbJjk+eb4'&Z'1)V+@jSk&*BKCB2N[cB@BR#Z1+Hdd2c)PY3P#ae +SemSHr)3El'i[XZ'Im2a[hEHIAUb*ZK!#,b3HRAiNYcGjjRN0ZRXQqjVmaNc--bH +ErBVXUG3a9TP@B(ed3Sh'm9(pB1Cahmacr8miCG)KI9JJE@hXL!'fpcHSA!94Df" +[p)%%Q4++f34B&Q)VS+Y'[rMHYDF-),b6Bk@al-'P!3@VaCk%%6066eQZ$Hh2Y0% +pi&FRe84GmhSeD$mRKN"L!KCYJE$$SRFjG,"Z!+@3"!%!!$`!J,5Ka+Qh@5'%!!# +iJJ!"$Xd!!!%`!!a)XJ!%(XF!!$*4!*!%$`"8Bfa6D'9XE(-Zci!!!%#b68e3FN0 +A588"!2q3"!#3#S"`!*!'3X(9(r(GKeJVd0rI0G5c(rZ&qH)39'X#pD,Sp#64@B" +*bj!!1bA*X!$h45M4#Upl&elcXXe$8r50`$F,#8T0bhNTqfT0rL[CBY+KBXcEc!, +Z`4$@J)cf`Fje)0&(kI#)6XYRq%PhJXF2j4diff0bZ"TT)VeBVc3(V!p"+2m[*kT +(G0P8pM`XcRGR`KC,+Bp,F1#DET4jDY#QFi'(bYf6*$IA8H39Ga!d,3a(#4KF2*+ +C0j@d#IYb#M1b`Sh'1'e8lfM'f,%#,b&BmLbhU6Mf6M6)lJrZiH[l'Tf$QV-elZE +i@TVM0@N35!T6cLPR+3#Qc-i)b%ISaffjhM("ZCYC#SFA!YN0f!+H#E*@rp@FQGK +mka`bQV0-b6`GK0#hed13!1F8I`Y4p6&m!*hZ4Ia9d&04CQQ1`Rjr)PKS956c8,T +a`2#ZTP4NaAF'@XHCF2I#IE)%MYYam9a(#HSX02'%lpj#$q+YMAU[3Y"0ZENldLK +&5NDa+6$lQf#MP1Ipqd#$%Ie"*"`)1NP&c%6$Tep'`Lk`J5f1+DN1j3kGi3kjFHk +5*bSccReA`5VfdmU%UcMp+5E6,mMd,l6U'E(P%#r5SlSSm,H0qJ*&DGMNqRXS4I1 +)#Mr9cR"lYfl4ZTiDX#9q6flM$IRLJCl"`P$4l!RLIYNjGCN[rLL1fkcf`EelDC* +"PEVhM'2T*2%3E-0Ec3m61,T)!J*rr6@Kb8Ur94Ycr(&DX#)cemR[([)@-P`+3XT +'9IHIEFKKcL%VlAhP+jq!4,k,$9dA8ihdZ"AjGB33[YK*aAjiqTT590NCR`TDR58 +qH8R[c)5NJmC'eBBSV4DY&hNCj*!!4BijPPl4mIFYcj,G[BlU4jilZ'FNN8SkmcK +KMjkJ#5kiGkeijh8,b,q2h[Lh0UbUA9D3!$*iD'3#jhV(2)`qqbHYDmRreC6c3Xe +KPJI"cL9+XF4VSeDRk0P%C+5XV!26a!#fm&49QkZ"V'm#&ZY&SITUXGhQCFUNf[h +-m+BJRE+eI-9DM0IpY,c(EE(+JedXl2,+@8*N#V+NAf4YPHLdZ*)f8$LDJe13!&b +T@8F1'dmmiSfFB!Ue"QRp6kI@-a0[EcJJLke(j`I9d(Y1M9EM(A4X&Ej2FbZML(K +CV(j@"HEa*iKC)e6f[Gp4JFprT!aL[3Re-$Q#0MSQd'Z$$Nk-6$J@[b(0d,Gari6 +FVdP&8eA%Zkr%rf@(VcbPkYRKGaZfMFGDDI@+GTKfSJf!SldiNS(VYQU@ABXJMP3 +61V[bF$9mdRAQ6@B@[rS98G"`1DddBj!!hZ%e+hq6M&-I@S918Vdp[LFGf#i+2ST +&SLp+3&,G9JhLDqiDlarUI#mbCJC$c5DYFGd[Cqmkh)@Gmmql(ha65-b!kNH!#ZN +P!'p,J+(*,UF5fBN2M9i1R$ArU[B0IC)PRQ`@*c@ZP&B1EHAJVAV"h,bZiCke*F+ +)!MGBHlr0iIFd,D&6S(,lL`lpfN6Nre%!&Z'-p1qMEEX8JHYm+IF$2h&ZPk`U8F# +SN@jSH3(KMm#"1+)5AS'!8bZLXJ*D$9VB[")A1CiEZp0V$c#L2S%!4'El`HUqX%a +PdC9IS2)5iU"9C4lC0bFp+!JLBCRcdj)A5@TJqb2qfN[RdHJXZ)-T8FP[&S5ekm2 +QZp#PI[TdjN"US@@XBQZ&P-f8[$q@G@-UH-iaU[&iJhcYR@A%T80A)SGY93Q#C+3 +Q8hJZ$YDAL%4,Tm8`GBr`X(-Z3-ZB(Cp-SSX-c-T'I@dUI@NhlX(qSXb#08r$HTp +IQ"IS$lYQ@0Q0r0%[bRNm+pR%[$mmDq3#@2rX(Z`09jEUV#fAX5Ej,-j0%lNhr'` +-HSKi%N'5c6F5c24cjP4e-$'X&@'N#F0k8`-X[0lM2-hDL'3@3MqF**j&emF,J$V +D[!#,#MriKb,D!ElY%UNHZkMJS,qkGeX)`AVk3bLTlPbU90mF5%%d)($mBCD(ihS +@[YaPBcQ91h+'V3X,AXB2"#[FQHIZ-T@''H+aBUp*-+8rHP2JUD4-MP6J"mE*Ij4 +)Aj`+T-dl4NQNHmRh)BZl[D)FQ@"(F5-IHGdQ0b+F,5fX1UD@a#(CfhDlJlcrpVh +T8LMSfpl#JVl)*p!6'0bkN!#+li8Iqq(%PB[NfHH)M(K3`pa'P5bk'BD$I#,lp!@ +5+FQ"Y#J-lP%%+PBa''hR@iE3-E2F'mq-FbmB0liUhF4"j3[UXj0b5%1jJ-3$mCP +(hG99NaJE2U+NYbjVMA40V+BBUq8eI(cTA$DZJI-DPYp$5Z(fc5qrr5KP#,pAYZZ +lV0GZJ@iBa[pkGB0NST@[YP3P)!h$IlHd(LE`Iqj$9rQhXM!'f158*3rrYSmKeFD +GIqH$fX%IRjjeSQFEeaq0ac2H"fC!b)CSikCY9lY91JB@eqIS@Fh4M$5E`05q%48 +QHCZ'9GJqE'*'15m)-TQ1Zhr'A9ch14S[bC3NID0&#r2+B!hF[f%a5C(,fVV,"iH +SbC%PG%2K$#1mbPR`A8DN[1lTrlf"RSVX*f9&41K4EQl#$B[1Q*U(J(-B1%6!KUf +QH(mHa5R5EUZ'**,35cH[SM*`)i0(K"b',,`&rAdXQ`ja!0MHVJ$G#F#@%hA5EQ9 +#8%%h!rVN0F)LIA6Lr1C@(QCkAeEUJ@E59MAhrckb6j6VI1k*3iL,!hFIDI8dHAE +Jea(#!+EY8E`r!eNLF,eIKEXeX),YX%U&bQdqJZ(-F)$QmC+l0U@jF[Y1KAGYEk` +G8eCmkN'd(I[KpVdaA,I6B0k(hRhP2HIYMVGT4-rifRKeUB8Y)hX%#[er59`D,q& +N5$D*CM!8$GUSpKhEX@'Y-GT'd@DcijbpbGd!eCFH,8krK`lL-RY)95m#+(efM[8 +mamGiVGQGI5-c#,M!M42CZr9lY`b,Fp16p#X)S%#`K"0*P4c[iZUi@lQq'!2Pl#f +19FKZr-E+[5HcF#[cS5*m1HiJIHQA3Q'HC$FPj)93Xi`R"`"C6F2eA0@"JT1e85h +dI-*"j8kZm'5,MT&6$+bc6[cHa36M&%%+%cVEN!$+2G$kSb2pR"5KCB[[GV4@l11 +N8Pra-DYr(UPZ3+69C&+KrI2ael0MefV3!iQ,VTaJ-e+P)Y1iD`cE!`Y"Ck8Q)Ij +`+(C#h[BZ%"D23NUC',F,i!%4U@6PdVmV%jdCUaM8B`RU66BX`Y-`5"15d1%mb1A +H"Z2Sj'16-FcfbJEpU[HZpbI&`Z3RN!#`+$LFFZ0)4iI*B`mQF0@Q)J2hVeQhH(% +i",PqR)%"CE846[@F3'J2"T!!C95Ii"4ZNe,-aJ3aG',r+DPJh-#kaKEj[4-r89E +E"1d3G84a#dENhh-Gi(GBi(DCV83ie"!(4GiCf2L6Zmhr$l9'+l(J5)6K4miNX85 +VA,KKmf2cErPCFI6A!mJ"2ee5#,HVCBjY9IFJKf$BiQ[HiEU2R-er`aRf$+31&S$ +Ya,Xi"d#i(f-kYaE)cdZrHeh(h@I8mAVEbEZq+&r!r%ARK8'2(-!TATI9r$C6iN( +5Za5PL5b[Lc@L88*K8eNYBEi&I`24R%H%MS+I-BU))TKFpTjepG"B`LlS52El2U% +RI9fRh`26PUMPqDcK8%rhKk-!1SrPVHmdRPHCS$#0j6#B6YFh+KP931LZX+)'BFd +L49`SJ*I`r-%k,[FiNE3GZ&9iU(9XJ!)f@!SR@XbQ`9DCL'3XCYm5m!a*2KRP9k+ +aNR*Q+G6(XV8K*l9KA!0kL@MYr#6Tc+b)V'r%'CVe#Z[ar,rUX0p()JS8'T)-FD0 +PAYZS'@h1)LL"FV'@b)j%PrbbD3&dpVC@UJfXrAdaH*r3RAdq-qI8ch3m$*Uci8$ ++,I1E!&5f$VZN1!ME-IC'Y8KeTKdJ8aN,2$N2m+c&FVM,bNmhITmqc9IdXYef(S- +%I#$e&@)X"-5L[r%RF'qba%)K)Xc@P31ifT`AUA%rRf&LS'9C%`Z`QfTRJk%cP(L +XpNBVUI%GKjYHPSCA$P'!iF!QQ"CE!a"Kb4Gdf9@PEF2XH%QjZi@[U"G"[+CLbTC +2pC'&-3i@!)AcB5UNQY!)$2X8VJEkSNE%ZB5I&U*,AhY$PVMV2%8i0d3k2i#PTF# +(Sk4GXGHY[*A@AdKe2E-68YJaD*&10)G@L9,*jH!(f&*&iXVcIj(R'T8P#&Aad&V +F(jcY8`E2+-8FVr0b8YPh`m4`c&FM4)@q,jemlq00k&!DQ9&EpYaE#E#0,[2`%Z& +0*G43MLMqNNX0%bYl8P`("DB48YfGG@8SMr)S*IPN%rC+MAD)$65DNDPBcmr+R(2 +V0cf,6Rce$H)J1j!!PBF$mkVblA(@U&V9*CUEL+PD-L0p%'D5H+QD"JL$H@laIU( +mF"XeJhMY2-JjaAr)l0#MJcMJZP)4lIiMr"KqpFPTCC!!A()DYrrf1,1bQc'YG'Y +q*fJp5[K4)q%B014PfiPk4iX`*hVjQ(V[)M[kFPR4l&@CjLY#%`Y"*jNpKS")[bb +C1TNbP`%TRXK!Z%RjGE[F"iNADi1`X2S`U$`HP&6lM+Fif!Ae@YCZjT'-hd580QE +`EZbLJ"KG54H+L6-q)V"#i&p3)i"%+S,+[2$U!EF'$UBC)'1V4RXch#r1SjbNEET +QD%amC8B"#iDBS1+U$095BRANa)C&-U41kU6UQJ6l4fib(!a#-*HVLGFkiPqEJCT +`LfT0l!fNf3ZKT4JY2*FRah3e0X1YUJNQ`d+TaBNVA8SS#(ra1frB+i-9@lE%pX[ +F[R"*ra)35(imh+aSY$J+#AKCZUiRahCp`lm`&[XKUKQ&`H,m1hFB`jiDE16q[83 +0GCpf&,@A[a'04"60JIF&KB(Z(Q!A,CdV3,!Lc'Hj+XKbCSjBIBKZ2fcq%Kqb+8X +IJVL*P'Y#9ISZJk6ASiDL+i(&)d@0iXBL%J'GNdJKIcU(qXPFR"mLkElk)c-R+K6 +1aYpla*eML6YXd`2N#BQa+$pZkH8,j%M$eDKGq)GD3!Rer9H,0i$+42DC`'L#jX8 +IQXf)1,EX@%RIq&cVV4B+&YXAFQF5k8G)Fc#TqeNm-3GY-k1pfG+$2Pabe`jr+(" +,c#ZHf[NSkIM5fq3#("9bf+@1bN@I*ME'FKJep`c2XPPJ#lA`AL%S2S0CU&8dL+6 +N5dC'9&H'%XXQCHD5a9IN*kP8acArm%kZrGPm%V@5MjE3Yp4pjl89NL&&DT!!bU3 +ADY1[A-e`L)iqIkbV+NZ3!-`KLFK2@*9!VKUUX+9aK(SeSiNF8"R!#kZbVTC%iqX +KLpM&`0SH%(E0c[8+iIM9b0eDTNI",@+e5`+@cLYl0[P!kGF&Yh`HR$pVjRb4#[A +ab"aLLXbCqTY4)*Mak3UMRFIiVL'jJTQ1#h1D3%S%bEfMP3EDjjRBQ[l@FeH3!$9 +QDEAYZ%`3"$Q*6YK)CI#+Cd)H(N6Ka"1dM(Yr"0PC424%*Qc+h,NZ"MMhGQ9V"D@ +4!r&(rD@GY@q#VVZAEY6KJp61XDh4mbNXF0(M(9PpH$-2`)CRS@,@+k&1T*ej*8K +pkA16J#r[J-J[)&Y&K@-hcK)@X#)0HJ5f+(aB,ZmNY[AS!6pedJhVG8%fQM*F0j- +1%,N1jQKU,IEb0&Xr`eVeY@5l"Z@U*0q6+DSD6eLG3"'!eBBPM9d@GB93*D8c&hX +*Yifm[XCXGJHPe#9l`hZHr4p1*NlEABLq5M3ph)SlG%8E5f0Li##[,f&SUUBZa#Z +,*f8&ajU(f(e3+[#(9Uqf-j!!iih,E%2)Fl0b9CLSJl"`+Sm,Y-i5ZH6MkYEkKKZ +Z%ephme@&V",!V3+Vfrleq,DB,1U%M4*kc2!j`BFqANiFfTNdEeDe6RQ)Z"b)I9` +XI&&F[fKU4ZIZT3$aLeGjc!erA'%4dJ%I*6#m`kZd!B$M"G)@$q1eJ#RU"phe2(Y +DAUS)D'-HH#&5#l)*2@!aN6'AHMX)lkBI)e5X&qJ(qKS@1mYf0YIZ4l$`Q!3fP%p +hNKr5(!d'FqFl2RIT%f("rE&)"&ReH(pI0E3S$)82TYJRQ9(Y1++FN`2HG6DMTm8 +qI"#NLf5)"YHR!!c6ZKb!-Y`NKe"UbG$&'e$K'RIKV"HkQ4jV`!TNQb[lIDSL,MB +F[8'Fka+kG,0"XEiZ$hq`Kf#!ZpY+d@G6#mr$9(P9CKA,"6Fp%eL4m*)iA46Mq[' +Ti39QCKL8!JCA8AfUSX5pFl&dX"iYf#l5%d+rklHpja9QZ8iH0HFhk#p8'P(NqcZ +PhC9h`L)Tq3ba5DqX30B))(SBTQ84[qbr5i2d6,F,&JX$jXfS5QYhprDAFP%L699 +LjJ[9(MJ"Q4ZH[C`@GDd4V&0K-`"XDlE,#54e#1--Q31PGjkcABc!*906VqX0V6# +C#-c[PMD&5SDEJLQcS`,i61X4KMj#rjrm9NlS+"28XI"3SQ6'Xb""jrN-q#C,m4G +)F9$G+0QPMe-P@`[`Q`YhKBJV"6*$MM"Fkkm34RCFhbj*qr#G'(ZZ[ck6cXLb3)2 +2FVAS$jZID2&3a',dDRGd9+,1jXj!$Pre9jaX1)E0hcJh!Ea8L$kf%2AibjKSYUd +0h8NF0XXr,HQJJUeEBYGHYT(f!UB8!5faZUV0-418G6ekF*5X5aGXlkDA8-SYV96 +1)cF*B[@aIrb0c#3pc6%$lRC&p#ALSJG`8fH5aITjaY&Db%*Y8Q4+lrVHTF`e+mG +J3eJ!%Rm&08&Z%"idD(Kb(c[d!GF)%e)Ifi[P)0rcArF%-UG-'PXc9U5(-M'J`EK +4CqN9F0XVH%kd)*c1)lh!8lhqcC6J+TR(5Vi[rDGk5$`DTQZ4QclL9f1HS,RK`5- +C#$MND2DY@DK+9IXDGPDq64fk+L5r$jc(K)3%-Ka8&R#p#AX9&irbDRM5)!&`XK! +U@Ne-dd1MAB('8+$(QcV!bpFL"+DUb+hf2Fa,)dCI$XF)&kb`lS2jh3JL3%Z4(lp +cI)IDUCpAV@!$1!G(YQQA8%58,C!!)2eV"!4dYV0FQq%UVU,h*$lLC-G-83rJV8K +l-jBBf%Gp$E"P2RZJdq!ic0I+K"Z4aceXh&UR3SEkQPCc1GCjCQ2!"iX1,f0H!Hf +&C1ZI&e-*VYNVCaq,3(YUGA+CBaVMjE0[kIaN10*'13BeLY0*9NMABMB2UITf(AE +3+P&Vmr!Ipp1#RH6C[6bX23)[fl'MBqi8F1TSj@JQFhAYKlBE2ZJ0AXelCi9TelK +6+G`q0IJM-ZRMhCUX!FJm0C**KQb680ZH"Nq)Ji[aKU*`T(6#l@SSTJq%+ki[6d9 +M[Uf4DidRlLLZ69[["3diQ*hZ-fq,l&9M%2iPk&&JUjkCB`iEYjbe*l#H0b['Zj@ +#5Me)DE68`k0D4BiLR5rhIijA2MMYKEhM#PlQ3Sd3JkMK3""j-S0&)41`&!Aj1pi +HQM9"ckR&IXiLXREUGCQ@)5e$XRbHYPeJlM##T"04Kf+)KBQa-iU6&,SKV'jc4QU +!6+"EAciXJ"jeE2V&4Sc4qMZ2"G(ijhT*EbGQ&T!!)*0eGG%6qFY(R#EPcrAfpfU +U,3U-ee$edL9)YVrlTc$5jpm)SEldkIaV[-a6iXq6!dLMl%NCeK4Hf94ZA,CN@VY +CE3mAqe1b@lG@PNV,1RCQB8eMF4,*B`"F5*qh$A23MM%6'2j8Sd`V6LFhR2%+@pp +A1Q*APbLI-rc,[fhcLk9'leU1Eja1djNqTp4b15aGF`2&LS9D`UXUEIKYj9XM"D- +blrSUj29R!JaCkZRUVJa,lD[)@-eE(,SDTaHBPFNmBe&)ma'GPlKG2IK,48X6SfP +G"I+CShM!(HJR@VDErULca0-6Ae4N5SAP[j)0%Yb5dAVPld-eDCZ[JkaEQfF"425 +!0q-d2-!k,qAI41r#eJGJBd`GHie`%epJ(UdD)(jUqe&XE[@DiYMk5R!AiUYLZP& +jE&CTVI9b`$N+SF6h8amQG3#m4i3k'[TU%pK6+,0j5bJU(Z[LAI0r"b#Jk*iG+1H +YA9'H5KKB$#SSPU`jdDEM"'Q"r5SQjX@[)G+DlGl"1rP5Njpj4Td#k4T%m(!L4@M +0Tpe3Sl&f+SSeP%[2!C,d)!XH!@(ZeI%ZfVYfDG0M)SekrXVD@J`e#cm#5HG`@4d +p1&Q4fqi11GVAr5X[HP0bdU$!5E#a#BdfLXlkZ1SV"q8'I'6qjD3JZI,LlPbHP5N +rX@C2*H4)+lKE3M[%rDC2GpZY6f`fYU#8a-b'pN%$al"d+9$LeTHbX)d0(djPVl+ +EEbK@B(a!$PedGf35iQm[MhBqG+iUdLThLR#IHU#R`SPENkSU0D@V$KbPPp@jV+H +I9pfMj6edd9r4$#'N6J3dRRC&ij`dUmXN&6T)p1H()lMY#UJkD6J"6[T@CXXBccL +l$BQCcXCapCSCQQmKcfIDB@,FdmFN2q9$@%HPFMI-qSCa80k&(ML42813!$G@&1J +%aAdfcBIMQ5,8i#a"&BadB0%&UVKM%8*lpAapP)+eN9(Z1@%2fM8PJLATp9Bp`1Y +d#`DR[,N-*T,`0J)dmqiJ6H8JBeJIM!k@CSMqRN%h2&`BX%J*a2lSVE(bb8%,"p- +UDY!P-5EcQi3Hj3fMF*%DR2B"h#-2p1MH"qQEFC!!9%Icj'F3(S$,"I(qCFfD5V5 +Xb(hM)LeRTaa1jqr[HR2'TrCVP@,kN!$!@f'8(BC)r40d`ZFHqE5qbfbXCe,R6-4 +F*rJ2a&KSiGl-"%9q1k"J6@5L`RAb-3Fhi`GUiIa`TJ'JAPb9B#E5Ni%D-RKX'`T +([2)amID2Hlc`4fq4a!PkmA&SjI*l!ipP(iIMN8,&eQb[b-rFIcEUC,M$U&,jV[q +RS1ScZD3T2+6HCfSkR#KX-aKjH5N*-M"q#5'P&hRHH9NaSh*ImlYMr,mjF2Nc+`@ +P*X1D!Qc)59EbYm*#-&,Sd8JP$fa@1LK[q585Q!N[%4mc%AG'ELQ)@h4"`J9Pd0" +1&P6rC+Gl*Nd'RH42066iH+ET,p3j9#2N)[T0[qB1Jl0QMXi3VS'2XhQCKf[F9ar +pB8M9ZN0a*#kZh$,&p4eq68U#hkd(m#Y*KL@VTJp[!aQ3!&ahL`S+qB"#Qj5em%3 +d8'p+V'hV[6%$i24+&9$DbM-XdPe26r-)rU*I9`mkUBGr*k10$H$mVEaBR%kVKcp +2T34f)2KX'IY([@S,+5EDDC+)dYiaFJFC1NR0-8ekqIN2,`LmZ1Y``b+m@NeGbF4 +VLr"(E$ScUR241-,8iq8V,HrSXjCN@hJ[r*r,1[liei8"eI#&VAJ1($QM-($,6`V +m56SbI0F@4SkL!XGM-)$cfC)`QVTYdbYapS)hl%$LEbXE,BUq[1'Kc*dX&rcP'85 +-b"@CD6+ifHZJXU%LQYJ@e3qCcfT(dTXS'N-SY[Z$Y,CGNiR@emPTZTJiJP5rr*p +j#Y%06HijFYrZ((N4X[CZY0Er5N&4#1Ur%DcX&9IpMqTC@`[I(#G396)PFG+I8j* +biI$$qcTZQ4*aP8K'h10J)9YTaQApKLRR49!$c@%VpKSNfMHVjG'[j)Q!d@*%PaG +B#db5URPiDTbA0,lNDAAP6XjK%,`a2DIhl,U0TL-%HE4SV16#ql5bV9+r*rX!qE# +(m@Q[dL&r`pc8m2h*+A-C($V'Imb$j0I#U0-V46+*5r1Vj%N"!SG-H`[3Dj0j8SJ +GT1rJrLm6h2)TG5X-6#)BU6@1RIZ9QUIVd#)`BYTXN!"lcr0B3l&KZ@Q%,hI$beE +lCIr6Q*0d%2`BN5L99D('10`SbR)k2A``Bb$jPmrS(ZU))$MNIPU&BGBV-bERCaX +3[KY(P3dJqRP6fej`K8%q9'1fQD#Gf"@Sk'k%+8aci'aLGYrF`L&pe$cTiES&R[V +Y9,cLa5p42HPYFfcdZ1J*IU"6"h2-LLB4ibIlLM-+jbh`'"mRc4aTc*JQhm,a-jZ +kPi-#QRp!CaQEih!eqKTDLJKlKLBam`8V6)`cHjYjB2!pHUV(RqV&"r2'Al1Gh([ +5hU%BRP$m,IU8DEP1!bL*R[5S@Y$Lb!eP#!MHj0UjkRH(-$,1Glk*))$2GqjBkeV +eUDr`+iIPaKr(G6p2,lYJ6*%"i!pbkQ5E+a!3!`Q%I8dDf!&i8(VblV8c*AIZl&P +BL-'!-iaRl"YCLAP6"eYP2Z3rY19"lp[$h,rqR*ZY&GI@8P3k)A0$D%9UX9Tq309 +TZ%IK2['0P--j1bD`MjFM@cbDJhD$*X*6q$f'`L"'"+0N#`4C(X-M$mp[BZE,HAP +6#!(h9NShIT[Jdb5HVb4qQT)KMN*9AFBZpA0+AFT5PRHfZ"-C38)RF8T,IGCqA1L +PAGkI0!Dk,eNE$UqPU&kERp!2jhX+8(L'cQ[NC1lk@,Q-(LL,bih%8YD!*8*LP*8 +mh[5"ic+Y@3BC@!D0`@5j[[0pPQrARETV%qp'R0II(P#cS$T0FY,N[mV2jH'b363 +GU2ZEH*hmE3&QM4C+qmCX#2R[dd[9[9pGmNHARJa$9)R(rdHUqX*%epFrQBEl6Z8 +E%h*dc*ANML,efcc*a"5jicR$"4S&pl)ledh),jQ4G#&qpYCUlB40+4'&$Ddi!+S +-I@'k#C[j9#F!I4J8*elSFF'0MIAF"0++"T%U9RfCU"U*kDEd0@-G3[$FrE+A[2P +Ql"IAAjq*a)B8LC1R#De$30,AjJa*A$m`8[b("$Vr9j!!h(j-4X"Z6j'*"@#dJ"9 +)AR(cRfTe@1cBG@m6Ai8B5'pCi,D6HdcdpJ+$iLaHTrT'J%2l"cdcDH"`QV#U'p+ +m88$NU043+F#6"lC(+Q8hiYi!K5C)P%%[%6ppehJ%e8LYR@NGp*@P,%-,`1HSZPc +(&*+6YJ!'Hf`@R`c[R1N)XTK4hB%@mSJJ`LKZ0Tf+6l'5YhSFC&*)Ibec[CLKY*U +VZI9ea8lPG0P"4Rbd!*bX0*IM1`9!Y2$UPqSNX"Ur`(GXf1Q,`IPrlND06HTMkD* +DBDQ%5L$RlC'QLZDlTTTrAQedXV@%fDRQ'0cT2V3NL'hrUQ*0QJYl[q0()pG0-H2 +,21i#506El-4KVTP[Mf"aURGkZcDSqlVF-,XEj5VpN!$TU)mfM'G%qUZSkVa4Xcf +MaFN',)9ZUJB'$JNmCG69HC*GXfdLH%'ZaCNeBmd`m-HZeSL8mSSApb"i"[h56jG +,j9JS-HKk@BIZip(jXF,RV)dZYp6JDJab&YV5)HSJJ!Pq#h2N$2M5%!+Dhjp6e`( +'hrK4iDIS*Kr`6R,Je&SX1LY)$[*0TLrB5fhS36"VM#Q&-MMK5YBbk'eLNXh3E"$ +6qP,QV4ilV8R0U[lc,$LaE&d@"F'l8Ci"5cAHSqQNMEA,+8[mch[hD-X3km9DU@X +D6+KHECr,8FQhPT!!ArkeRBh%q"AiF32qH5(VYpIUA011%@T-@CXefaAQc"ZpC$c +ac[EY(#-d-f,,QX22Pf"Iikha`F5@ThRd200VA+5cSMhKU%9$rMp%qMY3S2a*R5k +am*-f*V@E08U&-+$UdiDbbBl2N!$2*[-8#V*iBXkE46Kl(3*m*0S3&Z68-3Hm5`i +8JcPfehQQar#HGD$e@q!cirlTqH6&G5M3BkqrLcd`erB3"$F@G"dZF1QVq[@Vi5U +U&JTDT*!!-GpmCflG94U0S6$q6DfmI0&CJ)+NcTmi2hkb1mYr"XJ*G%!-BICP$db +6dGBSf'beEYA0m-0@@UBrmm&$"ik%'4TGdd&NBj[aJQLBLXlEIr0k4Nj+N9iMEfN +QJf0K,XLI"21PC()M2,#pJmI)D-L%,Ti,qfVXi80[XLSB@k9e$PNBj5R*8K%S[k` +0fAGMVH#-E'LINSQ#2c(q32ZJ&*E*KFd0K)K(TD@eaPCk#e10P9i#[XM)9XHP@GM +e9PA&#-*M2IQjS%p3Z1B'@1P$ia-HIH&Eh6[aI9SGIfT!`BXlpUrUL'aH*)JiG-9 +H($`!3Q1T(`(e!cMU#5ec6%)!a5b%l9qrE@D!q-50-+LR,a18amcBDa+@`epQmE0 +Zdpi@NNVhT4T"b,@E'G*k62',@G!,*+bcl19`kD@0(GD+1c6AH0F`+5%BVFCe5&T +kBA*EjFR[j"FRPr4V$MQZiXIYK%AM-6BKi&6TieZ4ckGP19Ra`@lY'FhI'Y)-`ai +6qrr(`E8H,8bebG9RLNRB,Gi3h4Ebial,3L058bDAIXXXkV*Q69IIQ6lIJ[I2139 +A`-I)#)"A@ZUUIX&S12*2A!8NUpa"q0T!-a`%Ed3Q`%iRB)09((b[86rHiE30N!$ +c`L"IGef#h!kB5TQdA6QFpQhkcb0AKMAV1GFlUC+USFUqH2CYNal,(aK35MjId)I +kA1jkJ2E*FI9ZcbIU2QKQRi9-EIUP%10VUkchHSG@qB@PZ!8eR8CXS3M2b"`KJZ+ +3!1HfEk-MV-9b1'$@ZN0b4fd(HXPjQ(lRjr)U@hFFX03UkD`0eq[kQ@AEEk2aA+@ +eh&&4F!P3RB8-4'26TRmIBmiPhJUHLMq,laqe52El43h+q4TSA2MSLP'qacFKKBq +rBG#i&R3$HK305I'22U`)eBDCB8M%kbZb`,'1Vaa[p%9KP-5cRP#km6%mNRRZJh[ +flr#$$!&Xc!,i#QRB)d2d!RF`5hRD+ddYfjPrL2ARYm9iGl6cZ$YR4iG6c-R9dI) +%M4X'$8YBP-mRX9Lh#$(BF'MP-r,"F#DAJPp%#"iKEMjF!ck8*rU4M#ElBkH96Fh +E8ZH46d+qBDRT#l-AU9fZ9`-6BZVRMZQ8Qk2lYM&HLN6dp!C"dVUMN!!QNFXfd+B +%mrc#PE@Tc8CcN41hj0S+9`[0E%mf9f+5p4DVT+-p[Sa6#ZaNE233(&N#"*R`0'G +Hik*5A2Imblk@rNXY0"j8VX'f5T,Zl10%l"S6#qPD('a#*(1C"QL+q#aa(#3&2I1 +e2NUYF!Mmd1*#c+Q9I4ad24GS5Gc,*DKieI68mE3NN!!CF8&i!Dp&+DdA(Y'T0Na +pXB38X[Rb@NQ3!0S#((Nd8LZ"Cr21'+2bJb%!Zlm4BTGaq(NjQQjTXf%,Li8`$BY ++JS,T'pq0KXT,f6i1LE3"jG(!H4AQ*8mPlKj9"X(5(Q"ZEqpcPP(mGMEqdjZBc3e +R0J"%qhKQI[m9JbX$@LH)&-9P"A6)!69!eH29f(ak&jbl%0-ASq(5SlK)aJ5A)2` +AXP2m6BR%6Y&B8-[c0!R,r$!KUQ'XPR-H56cj'eEmUP'8'K+iiEH`pqCPiX`)2h3 +a,5P+rYT6+QD!8h"0)9Lqj9*)#0"(*+,F&,1@ee%@1%Sj5fbM-EQ)6"#YA2%Mm3V +(!Ni$CKr%krXqHP[E%ilbE4mj@C1Z)r[D98GVG$mb'"HMd@UX,LD29)dI*B#4'"& +&Yrd5'1F#Gq@65*!!GTep5+DGU2pHeKj3#ID$0!C%8R+8XL6NIN%1EQ%Zj5AD&c" +jKj+M96qR5[Fb+A*$)GdV-)L8q''bq5X)0NE$ZdkRE0hXhGMMU9`d8-b#i,6XMJ6 +aBQqq$Kqr#TbGQraBj[qjX'+AF)@ZcQ0GTSJbPJUk'*)jZc-cMUacj0#Sb!S%1PH +Lr!,VlfD6Ii8P(T)TfQA*8La&Y!)V*05bZRRNLQQ!RFcVH,Bbl(4DDfPAEABpBZE +#ih`'&3mJ9Hc#P[!(01p(hpAaPcJ),Pa*YBMC!a@JNE-,i"dm91NlM*JFTemMKLY +@J2,rj0e$UkQNfmeF$Qr8'CYZqDGSUGP968SBZqNP2dU*FH5KqKl8Sbi0c1f[#FX +Y9&3e(AUaIF,NAVk(AANbcla)RaA4c$hkDKVNr[CmJ3C,1IUffSFkeQR0AkNQLm@ +Ua[PLZ"5c"$(BeTba5Z)$`AlcF35YA+,RIE"0Tf%aQL'G5Kp0#-SZq3XjQpYKqrU +Z'"22-MIUZAiDIJVG&S%6k`A$Y"AMXDXIVH1&e)K)1(V3L'IZIDXr8f5E"1EQIF, +j8*V"NR+lP)eZS,mF@`V9Em"C'mA6UIr!5q""CjAIAUTD+MG8T9-Vq4TB@h3G6%5 ++h"@1rFa(4Sh4d%FDIML)5CNC-Q4*GAf1jZAB)2!YDH%Z$@"GHcI&@H)UL%XDhq) +DLLIQHMQ48p3LB*E`1iII6q9XSM)P1f',9+F%'#!YqX'R$NbY0!Y,`RA+PKXZHUC +VJ#6K'PUJKb3"1bPBR*p%mmk4EYR,fb-UEBr19Ibk1Yr2akNAp9SF39e3UZ0$mLF +22rr13m`4f%NK11T4Y2lCfJB4RPPD1fPI2eq-KL0@X4!,B!B-EdMR!HM13MNXqcM +QZqi*VTc5L,GVL@G9Q+CVH&)UPZ)Ce6'rYZCHc,pI('a&&p0lQbq!6P4`'jmYM69 +)hjpSLj!!mZU3!%ehhppUG%*-0rK'Ur+cP'Bj8b"LYIM@Ur0fVTJ@AXXhr*aiSB0 +1I2`jABm-HI"&lRr9j,Ybr1Q$NXU`4Mq8aeFP*!8lkKKKT!0)2TqUji2JcLeNp`N +)mH!DQ#4ha,2d$"ZNi&qL'c[NS-Z6m5iljR,lQKG9)0eckbeMlJS0I0jk(fZjYU* +8b[&jHN4`SGHbiTA)6"Va%$9eACU-rNl"mHRiG)&pT!9&q"3V&1[ed21e4VVBfJ( +#da0MPYIPr'PIB,p@$SEcHj&-DKK",N5F2hZ5Zck#RVlP2dTAA'rd#['!Sp(mEDj +i2VYcLrh5M*F*8k9NZeSY8`f%CK)@&23B1-QPlqfJ'!eQ`UCEf%MPC"a-`Zr40Ua +2Q$@Li9-'TERGjcQ)hAiTPbA'P--j,fDlZ5Vf)Kq#r8mhXcbrmZMrA-UkDjf'T3f +%i+X&DchhkaYa5[Y2r%''J)5C"`di'5K-9ZP)AULV[a-l+[4YV,)FJbL4r2R6FlH +ZXB48!B"kGe9Pf,2C%0f&)Il8-KD!1rp`j[XGF4@)6@2c[KN$%p2,EpZ1aFc8P[U +Rd(Q"ah!4d"5XDN'"5X0lkQ[@3Z1L6l6d16$6l5+hpU+%8+fcIr$2d%XbAA2l*!L +Y20b,j#F*Y-QIS*2D&@lcRIA&M%RMcJS9QR*1j1R3KP*ICpVB$bd#X+Mj5%UGVH6 +%C9D&4M*'Y"Dpami+-6dkcb&q@m&m6#G*dHXm"jmN5BlbRXJIcQr8i6Vd"F0ALjd +rhH6F5a!DD"q`biRb%[GFlPRJ4(H%@kZZ"fhlrQGZSk9Il#krXF#KLRZeXac`0Vp +Jk'QI-AS)E,aj(Uf#26R3$NNFl*ZFe0kNElF+)jeZ-rBdLA$fKA2h*UL62)-ARMm +(`LL#IZ1`Z*TpQ2IaiFMkN!#$[9kABhY,RD)A+JNRQi8`A98p9iNL5f4!,,h4-4' +r8dcTM-I8ScB9U-m%6C[A"L(D6!EQ+(5`)k9d+r*h[GiqD5CX"KaAIXL[%2!Kr$! +kc52EKr$#9(l,NdI@P%8(p8X59bNC,2f0B$EZf!)Y!CH,bRc$0iGD+P9@0h-RF84 +*aaMC,35rD0-af)DTA9hZ,HhY"EC+RdBei`+M2ZjP)c+qUG6bLaZ$6+ZT'[6j$F8 +V-NiK$CA*6fVGeLqkHEC@JIC36A`cNqL+&8'N3dKQ`h'MQPB'*P",GXA(VX($Mb9 +aGP1`J$r2rUH58QkeN!"I"#)T#KIPBdDGjPmJFkJ-QAI583`eBMUkdl1!M,8QEh5 +KD,@QMq'HNS&9+1)cRRCj("dlZ@bM,bk8)TLT&+KA4)YLC)0Z3k$KU"F"0RQGl[X +jcjMqB(pP3qH1MIf6ZjbP8!$JbT+qIpaN*)2H0d&[D!HKR+JSUZ8Yrh&)1@N#q5f +aYV'SpE-MEDfk8CI+E-b0-k2iQ15afA`884+49(pS6A!Hm+q6!d9`QXBN"Uc1H(, +ARCmF8*P!$cm(lK$lG8HILL%'-JpZ#`J9cpdF1C*HXerSGRXB*`PLLD[F8YX&0aG +R$Vpm+Fic,VlUr3Yd9TY2Xf0*jYQFUTM)5V88kHr8Z&ipciSh1[)S'ihH5+$UmrV +H5@C`P(S$-a3SY,a#DVT'5q$CJ,,Z!fK9[`2Dj8pIf6!9I5Pc!!H%T`DI'k*mE#I +Jl(*LDDaBK3KC*cN#9@#l,+F&1I#!b#k5MF"MKjdlcf2SXa&UG*M@XX@PQ!&qR[+ +TADfDK6T!`%-%phZHf5L@[6m#Rb!YQT`A#!A5Q`L08aMBT(09dGSQ[QE&jr24Zhp +Nr)&h3rP[&qGi)80bdq")5*6T3qk0pkDqYYVQl9'hFi![4I-l&Q+9cpM3KkSh8"% +hrd@XBd1CddAr&hB2J*Dj*r)0-I&FD@b3!0&N,V8cQPCZ,cZbd0remh+Kr`-p%XV +VGr6kV$Tb(6X`kbj`15mY$3"j+"*VV#B4*f''eE`#2bFFfr-#eb@&"N'&XP-bd34 +1&8!-J*6,02r!P5+C*bNiBJ4NqGD9iL-)ZXaMN!"TB3JG9G9U$,4@BYf1Lr'(&P) +3-XqS!ai0YFSKT"1'C5HP'IYk6L!%a%e!rqbKX2`+!`RH-aYBi%J`c6ehpJDKAT! +!A`R3@!JhPI3I('q2&Ld`dc#@bfVQAMpl%MFC--)b0j6THbUGU@!TF4cNB#"Cd8@ +M`fh8m8X)[5iGqYcm,SZhLPaqK-"q[qpeNaA[Gfmbmb!a!%&B(klUL()Ld9ar"mG +E1UC&QFDE!XZ@&N6cKB@28$G93mJZp$!3Ik+KPeSL*XdF"hCC@&HVmem+%%hAD'' +&4*Flq+Lq5VSSepP(h5QYQ6"&!C3DkHmThZk[`K%IiIABqSb#GkDr)4pH6Z40'#) +Jh#f9H1QLTYK)FA318MU''X,q[0SUHK4F1p*pKG![k(8D'ei68Q-(+kK*e04Q+pH +eK0$$U5DQj0!`)bZZBLmU+4pf-8RpUH(m0%f5q[*hkidPG-NSek1QR%RK4M`r*Pf +Mk)Z%bl8pSd!,AH,j8(dQLLcihDYl4pF56cP)m9R9,J[(j[[N,V@@2BZ84RGci*[ +m5IC9a586IUSTB$9kbRpACJMAQi9qN8'FHi+i!#RI5RB%9TEY['(fM+M"&-Z-)b& +K8RTpdVebHX%`rPf+aKF,(B'lBHA(E%FpcC&De&f8U8YH[2-6jVlRIVTPELq1FS9 +4,JkR!Lr*S"1G1H52[Q*X%YhR3qi8CFCNKFhC*$)MC+aNP4B&L0f&cfPY@fMQI3J +N!63',SBNkMf##G6eXSmZ9C8#*!D'J$%SpIIm4fAVqXFMX$1IUQ(3U[ilVBP"dFf +Y&R9k'jF@M$!fI-GMkjk5UU6f0V13!28ZN!#`K%cK1fHcpa%c'-)N*3(*PKE%f@A +!$e-aD[6,lqX8jB`KXGNcZ4&cN@NE,1HrVpZ0kU5HJ8ED*QlqI%p4R%$)TbcpV2) +([)9hPD9@1Ia2$bpk&)"i44h*1X8mfTeiqclLLcRYAh%bJ#deaBE2(0r8BUdfQe4 +(VU"8*@J65-VRX4cPVi9PADfAEfY8BpZa#H+3!+@3"!%!!%!!%,JMfVZi)pUl!!$ +F(!!",&d!!!%`!"$kD3!'SDi!!"cR!*!%$`"8Bfa6D'9XE(-Zci!ZH'eX!!%h0P4 +&@&4$9dP&!3$rN!3!N!U!!*!*!6S!N!-h!*!%$`"#`G8,I9Aq#(9[MSa5YEUl5UX +pY*Q1mZC@MAl29r$e'2J4rm[eF[LMC)4Jl&H"X@*aBC!!jGX&-%,"e0*&TEMEM'a +Ap)XDl+*0iq00A"9P3fJ*)FB3UC!!TepBrSpBCMc#ckdj0m'"Lm60!02&ifLCTr8 +a+"T`hr)YJNiAa@28a4a"+lhPV[!FA8-p%VJCZ*+X,i2ea3QDM5aiBR,`A!!`+"T +[R*-l,1@FSqjqr8PU`,B-fbR1'QZ-9FV6d0lI`IrS&KbhRXCrqIkVmhJBVX%GK0p +mNAUT1jfjI-$!!pJHdTAiqd'$a`KbQ9KQ)L9dl6A-[Q6Pcc@&51F(l0kP!a8,TkY +8YB%hBrGEJ#'KH%S@ZKFTQ[,VEIciK#P-69@fNFm0eCrVHU-d`@F-QpT9D!ZlZF% +aMN1c@4KZmqVrTM5G'Ul'MjA[FbRL[DUV2Yp+Y$mjR-ib"#Zm-C3'&CQjF-Q9`Am +%429Tk8mp`)Ph&N)e([fZpk%YA`Xp[ABec)&kIVciX5(&)2`V4h*ckeQFGXjqLak +R5C!!XHL@)"6qI2-Kc'GaE'F#@A([T0q2Y1H'$2feM@@l!rFK6d[L1`BZpUYp@KB +T10jjXIbHQRbYZM-Z1@j-(J'j#[rfQAf#4Dbj#bH3!$GG'0XcBAFaFa6Jl(M&jK4 +LI6*N"*VP2&YDb26LM[Q4$'-Va"b(fA8eQ&"+B9a!a,TrGT%3AeDNhF4#RjhfHf8 +de!"lMY$[C2-ahX1QA--49D!TN!"!@11j95Y$$@JZQArN+$,qC"@6S+APebb3!$m +V&Y*)#XL`&'XmRb-Y[DE@!["R39LUF@-FjEYGQDA!EN'qR*HTSF8RlY-Y*bNCGUe +)rTX939pR+"0IBAq9eL#VQcj9PL(S%(L9F03$bX`@Nj1S-Z(m-Ph#M4P*)a&`qM" +22&4[q$8RGl$*l-qBqJ(EhcE6Ib-h,EGa(L@3!'P+(N2LcU[*!"-a9FTV8E$4N!$ +1(1P,8IS'Vh852crEYkB0)hB(ZF4Tb,SRPAi5CNe8N!"jh&!@QN+V!-"8lREclHa +U1@mb6!@&T*5MDrL`rVPSl&#lNBYIb!9S)#9J[@L!r5$#E5h[,I[5`S2aEj*I[K[ +Ck2KcrCdH6q)#PbdZ9PlP2r+SYdKKKK6DG`L'p0'fLXV9L(RqCG"`CIj63PCUZGL +rI0ia[caIb(Rd4TTb-)PS("1mPC[jcJEUA2*"99Z(LJ2K6k,UYHb9-BdY4+9)R6E +C-IEdiREl1h2J6EQF!QB5jB52E&rmbXZ*FVidVY"mTKV%mYac#!E*r13!XMLhJ40 +JHmk2rd4V!kTJTEIl4X5*FiJPBS-AYYe1YH03cHF*m[FTpT(EIB1-#6X08,3b0&d +[YKA&mlNiXDfNRd+fSlr-m+m64E(-eqK+JkBiL#d@Z&,8D"#A@&)M42qrBqR# +ee$j2DAT%,bf)IqU-MRJ1*'0'LYY6cE(lCJA2JYP)&R*+qr"Tmc32L@hEMfJfmbG +[Z0SJC3DHLaNSqlh!bf9EQJqU(kf1RiA%$1++F@5,S!KC@b,NXe*B*#IcSV5VCUF +0+5dMLeH%er@-'V4CH-Tj*ak@HZ98MBZFB)3J!D)eDr5d"qpffpm)"QDd#1LJPk` +qTYk*pi!dSI%J!B0%H6(fCZGP2Np0HicFd+G*%41XV'X5JQ@`pYNh'Q[FJ[R-Vl6 +d1K0-$MM3H958i"fle8b`AUj2G"DYceiLAr98(jRkh0BGY1G3P[r*c1emqRqFYmh +hd3ChD#m,rM0HYE,*icdiL(SUHZa&qm!0MlDKS5ELif44GPAGfpEc[kh9k`F2p$- +TFjBaU,D8ETkSF,hqQ$P4XEU88236KM*k*I)1am8S`24qeb[63Kld'3BB$m'DP,K +G*-PUV!)VP%[LM&5D3,EphQS(r(UkIbPTeEqG`134R`Lc8JfmDSE,bhU*+34ZNEp +![2@0H-a#[1%LFJVkf!J(QN,"P[XX4!`mlI2e$'R*Kej$i+9Rdhi4)kSBc+F$YVD +95AdZL,mJa`ijS!j#)2pmL[lCIm%2QiGbMK1GIBl`lf-d[%(e8NlIaIVNG2XY9I` +r6&9X2kEmU$k,$AJ0`-c!bIED2QYCr*CT6,5BQkl8dB8P-&lpU6lBYEhiH[[5FL2 +AhaKIMhj1DdmF&+8G1rFaHFd[M,4KK68YSHrJdf@j42``r84Nfq0k"TrH$eJk1RR +F`6$3@a9@1eA`AhXl"U&MlJNPcelaib!!X+ZG9NkGi*LYqaq9L(rf2(YFKhDcamE +3pd)Z&[5PYH!3T0P5E+E1S8N4kE8cMMXD4Feja#@VGNC#LK53!'Sbp[R1KXTrY*H +(aiHj8q[FhkmCBFBCRCbGQP,EBq6IU(3dcTeh#R!1j3BMK@PMKBI$eB3H`1("B1T +$Zq)V`GN&RjNC8@)269$ade5JTJ#c*6IhkATMT9[,Y@irJr0i2bZ0h#T02FQ42+e +rF*!!P606R,I`32"*IkhmjB6j89Z%r#e24Bm#NB8i3I4YX2DU65`JK#[j49m!Tb' +#C#,KJAJL41i8SIrlX6LbMMjeaIQAf-DTI*c"2GEG1`(lXI(elDV$mYV28VcBEcZ +Nd@-cadT!3"rHF*DA)ThbDP6ahja&V90&'NbQ0U*(M1AMYa6r#ZVeFc1lj#TME$S +[TYK!iU1Rmr"3[EJE62ECb0VEBHLCr3[@!9NND,U@-CCF,FIp$XL421qf&Z"Q1Za +3(hK2-@Ki%XM"$SRQk%mf(Gic6D*-l&8HRc"J6jir,dZ8TNi8V)ipheIS*`513h& +Zr4)b9f06&-QE`,MB3h$(r-lGIrdSKaeGYiQB5mbYbhiLLKZL$bXC%M*kN9mPpXZ +2U[D+A[,GBHkP4[Ai+h,841fQ1hPVHPrlHpjFUaDfeAFH0Nqr6k"6Q@TTaY0U%'P +i$&#)%B%!4(*d#"rMUDY#KSBaXM4ZbIrea!pj8r[`ih5eGh(EZB*(%Ecj+`+LU4e +@pbdD(A,IrfDC'6jFAUhP`Dk''bq"`0@3!2'UT2%B%j!!Lh`MACF'S$(I'*1P!F2 +$Qr)*8MlS"(Vl-[dX8M+$"BZf5e6)DKiZcHrD)i42j,RN'bl8QjcA[`b6effTJpr +GdpDD9R"Z5[Y0"a6$FUTQ8f,BN!#,YV1hCQ$eTDEMACAX8`XSJdB$266P%2J8p3U +cJJJh(EVf+9(Nh*4J-99eU4d6*Ya"'FE10miEXZNI#eD$rfM!R&DLVNGmr#@$[X' +XCP#`p[rT#`rS'6ZMT4aj`rhEeVkV95#3!)FHK"V4T3VL!kMGR1!+XD)%*,3#Qp( +cqN`hXp,0DrCG8R5ffF,GG``r%!1%4H(-lY[S%HFb%0(ckcEH$mD9VPcm2K3X43j +,56qmZpKf')D8XQ68aKq+haZS'Kp%S&pj+ep51Rfp1S2$b`@C[Qp%%Tf0P6e-GHL +IYL6h,$5*1kY*[I44cL5Q'CR03dZ'UZaEk6"El@Ld8[im[ihdkQ82NYce'ddY2M3 +DrcPh[RZ@0[LdhZkId(X8U5`THChbi5UHTNrPb`Y'FSp2!Ufd0)TE@LmVG'#mQSY +cHM&f&jHiBa3h%qNDcAQM#lC#D@1KY$RdSpIEe!UE@U[5Db9Ypa3B#6(2ICPbED9 +Z+m[mp1$K[B2-MT!!rhp0Z&qA&4p1XC0r6e4DajG1&DfFirY-("LN"0&AQQ*'YIN +09SHhf&a[R)`l9*Rqd*,j&+3@Nh[i+(PfIF+i02`,"aGI*XBl-4h-CAS%3EUq#Fq +EH-q`AJaKEK[D#1m6k1C2eQ&Req1e0RYS4S&BbeSHYr$H`1e82'Bm1d!B+BM2Mh, +UU#GkPS-HZAUrFR2HJ3F0#EKaT8S)Z2K!-T!!1ZV+j%3$&r02,+JE$QfGlpEVQjA +!RM[E*r"fa`Ma@%,XY!c636A5@4M(61-HI9,(eYBMIc4NYr&qE'3aA!dNkhrB`I- +"&lYPqBUGE&'@CJFMMCm6+N'AdRiCqf0(Krc%MTNE`@0Q5B[JYf6E,%+kapcN6(p +CXdKKriRBc[YkKS'QYRXqr4cF(C6kh53M@-D3!$RGU41"FdmDd$j*L$K)%#6N[Fe +E333L$$djTVZ!XSVRIA89TYA#fhd044KCiDfU#!X4*UNR!FEU5jZT1P$%&J+`[&F +&[G4E0mc$6X8LDDD45i9a+,Z#F!bq+qDV%(1(31TVq41R-QD9rQYZE6TZ4'X"['G +pZXe"pkJd0@Q'rVA!)XSh#pp*Ye&))3eh94+L$qN%''l3PAbX8HjKCV5c0kj$"-U +%&&3,k)[@'k#90L$i%M3P,,2Y0HCUMPT$'@l@mVQ0mUQJb3F)h4cHVP#iZ%S(JFp +V+%HCD6))+jTYkR4dNbaQa3k,Uq`!l@fc1[HI1j0lS03R!8CN4aC2$RCG8ZeJmUh ++(-SICRFCmdES,@),Y6YIeA!)Sl*#@cJ-#[6G,TP2L#fDE[Ua$Pe'Vk56)!#K(@- +rLbcV8*!!`bDU"A$QG!jYc1hkYL)!4M"*aETbIlfdKjkT9h!4X)2E)FY'!2PUY2k +M2+hpq8$Z891lB2dF6S[#63P#Si'4%Cqb,9r1$&cXLkd9'iGU[B[cp%`V#AJc[89 +NN!!m#P'D3[Q3!$LdXJ&aB`-,DTKh6!C@,fh%Ulfb!bEXDL$`,,V1F1B6K4)d+B+ +bi,8TlchY-4JfJ$1!X8pURN'P'mIl(+j+HX8!GRdp@B!,UR!I@k$M`10kG,fV1HY +`KiL!DqS%8C(%3+CdJ(cm16ErKkNPGTJfeFEjHBjUNiK"p[DNG#(I055!bQc#`Y& +TY`RkMqHBKPS+a'8%9pcbjH0TMK%R8jkFLJXUS5Q-d+$'+XhYF42dmc8Tl",M#IV +`kC&-BmJ(PKjj!4Ed'q3B&HhV$liq&6J6Bb%(j3R3I3L0DLJ1dr1*[I60-+m!Aba +1h#K4UmjR@l@P!(Ai#JVKVB&3+,S9ME6k0P#miH'ARGH'`pilLI9&&+jIE45'"9! +U&r$$[4i+NqT%5IT"bT291cC1Rj!!cFqBLUAP)e9)Efm09Yh[*'NK#V4T6mTYNH[ +Kid0RR[P%K`@bmM'fPkk9#DRNB[DA00-iBjKH4Y3&BE44,0PN)ZmJ(fZe$#G`d[9 +j,I&i$"rm10H6Vak!-RF4b5#YhX"-eE)e6!UE54&jH8FHFj%Em$9Mj)`V,(8cEkG +6Q!8)"YIlEGPX30Y#L)020K*YQ'XI[`K!i-Yekpm'Em9Bpb&p1XlV1cfXkc08cD# +8Dqh3GKE5U3SY5U`DZF988BZ2,8$P[hITmA)M)qpV()%AC@8R+@bjFmQD"4dEA!K +6N!#)"GNcPQ!Ea65X6Jh[kpDF&jM9Z5NL46qp-I!9BDm%*pG'L!i4#[@&l1k$&`! +5,E4meC)KXI1*[L#SqVlXSGq08NYf6j[*(GZa[@m'h0(KiRG*j1jB!Q8hkp0f8TU +16BeFq4lJ#-,Fj4I$,-6C)Gq#P*Y#PrCCB[qIF(M(4Gk*L'$Dj"Kk&h%F-,TZQTG +6+TQA2lH[@*80DAIQDc@5mQf[X8*R8SjU*SR(MGE0(IT+22XjRYHRYZhFFj6VJ*3 +XSMhKj6J+0hB!J6A4RPfa,dLAbh!)JeRmY*f$YZTQY(rQ"#SDeKP%rr3UNXCf1Nj +l)R%(B9ThBEae3aD%9BU@$JemikpMlN!,[epU5L%NH4M+KQV#!(*["`T5MN4H,`E +6Eh)YKhQmS+QP0PLREIi)(GSbjC!!+$hS*kC5i&E*b[m9,3TX0BM!JD#X+Ta!b8$ +$%#j0'Amlpa@M1mK`3LD+JUdDUmVl#EIk'9iB5!p+PZ1)NDBk[,FL*5)+cFRlbdL +@*AIG*D!i("%hZD[)2FmXeeQcFVG2T98`D(ih*[Jq3mkSTmS)RYU&%VS'`6flY@% +plfcZXGMKU+%kmR1J@0P0p!&pa%$4KMY@EHYkBh[+HD[5pB9-+NQhk,jTLrqIFB# +8%446'GeqjG*'c$6BJSq)MEV[i*Nh1hQ9`E)%QeT0&hkp-q**#C3'6MG5SU!!qDH +PFh!$*)(q#N2i1!`HfKZQ+QV1AmASjR"$jJ0*l51X98J1V-,`I4DMJjV$T"N+$U' +4Z'KGKV@+r%,'IKJTbf"-##"q95$l'%Pk[l@[1p*d&2,XXmVP5Rp8QS'`XS6Ae%4 +FiYEY!jPTN!"ZA,*FdMpY&(m*KdJf[iKEY`'IJidPC-"Di9G3fVc[eED[J`CBI#R +Q-eq5rj`)MR16)J(m0DQUc&k([45p!-TBr9cB!XCV#I4bZNqITYaZ%"-5PQSZF1L +G1f+E'*+P$%PqTcT+i(T"PGj-eI@*h+fNGjk+X,+`ji)#VVSVp%"Q4`Fa$FN-++k +BNiq-,Dfhp[VZfbX(dS[l*X([V!fjc4Ha-USb*AXm[GX!G$Z8L-+-ihMXQ,)[!kb ++FL-@)fkUR"3[Pl0Q@405Z$mkIb@Da+cmm5dKRrk0U"l-)EEG6V#6%,aYq8jUEd1 +c2[6d$QS)24!e6I'rZaf-#QfVUmeB@Pb'FKGcDIa03@lM8eX[G5I4RZ%-TUUKr$r +8Na#DlUd@3qfmBKl$r4e+jdmfa`0"8$k[eGhl5IUB#2a%U-qGbNd)I38[)cPLk&G +'Xi3YK*6-2d5i&XrGR#9S3b(1aH!cRr#`dTdTlp@--c)*pR!iI'421*)f*0*`0Ap +J@`qUT,M[MR2kiRdc+"l(QL0iA[caYbi$bKq29RILaq@A'&rJ2IH2`Zp&c9YUZ(k +j+a+bFT&fE-KrE9'KBVPS'CE2PlXQM!*ErXU60["D*Kb9e98Y4G,rPCX"Ce)%&m% +q1pjr@-0PK8jSY-PQ-6NF"M1E%-D%4VUBZ4b4!`L8#5A9&BjG18&1brMRcVY8e[Y +q-U,f`p@I,A-rLac)Yrk*JTAQVB#%iIleX!fUlYBQmBm3Xb#`'+L0+2Vdb2""f6d +"QSBQ)Si%d8`Y228*LaE-rDrrj2-!'iKG,-6r`8BZqT&23*Z)S9h1$rAMX1$h2eQ +MHMBD'I)#N6Hk4*S[kZ@`**Bla9YHG94k5"d9P-lU$KAK20TV6T!!!JC1h5Dd@M* +je!0pAM0A`"frX[9K6VpI"A3q"G)XbmmDLX2B0ZP#6qX+Uk*U6jdlLGU`ERB4rkd +IDedYh8-4VfjT*mj`lDbr#FFjm0h!L#9Pci2lZ%pd%!39fST,em"fMRTbqNK8T9+ +"6Y,N*KU5HeX013hY`$aimV[BMkDrBXSkNFeBc(#NIU$a%rNGr!M+kF&X[DCThXX +SHH(c%hD#*EbXeLDlpa"3@G0QDAam'08Z5Jf@h(G#jR-"1D@0#9+[C0iVQe"''Qp +#G@kT4%fc*h(ibjAY`#$qerB%9T!!hbF,cal4,V'U%dCL5V`kbD'CLYZN0kmJ$V, +'r44IIZMbG1KhRMHV&dTUkJK'@X-dS")I,#BYL*!!HmL20US*+3KD"`-V$BDlp#E +2Qrpj%TVD"&0m&FQ*k'P3b8UBU&*Q$FRG)"9)rP&iApDf0SZfqXmJl+Iiij+PDD* +rPTlVL$T`@G(AP+RAX6T)26bZM$40l*Q8-l,0elkhelp&TT3GaG+&9PX9%X89Z%D +fpeSYHpXl0mb%"aiFL"A-Eb`qp3er9"!!)hFikGqKKI*(*(H3!*R[M%pqP5pIPcP +8cX9!*6*rpR%hECB`d(J`T*cbNRB[[1A@TTP`lFQc#Ej"eVV3#*`$,jD*T4m08(m +V5Z8p&@rH"hUZJ*5li!S6$mH803Q$ERJi6iDR`%$Y9FqV,36f3E*9,K(pC+-i+'( +1#*-*!(5cCIk'eV$V1l'1b5B&mQ![9iGIk"&4V%-Z'ZB(ieSGJN*"S3,$qd'A8!S +(Ek#5KQrpG9BN$)FJYcFVkCa!M2550)&p&p)p'lc!F9Np2`N98SM$P#IbJc%cmR1 +`mTY%XlE%m@N3,BBB#a'PEk&((%4HRVVPk%Im,F5Kfi9m%D'EL)m[(ahjXRR@aT` +Y62eJ"BmPHX2qM`Li!CcESF@$eF$1DqHUjB$UheM1-FIlA+CidPQ,Hi&pq"PP*E1 +GJ0JH#4%,j3&Jd6[@6k"+PVkIaA9Shb&&eEI@i[rMYHefN!$qqph2,$PXBE+QlU$ +FD[&D1A5S2a(b'!F%*ZM86NQXG%@p3eG8dj`Xj-Z!6c88qDmR2hEG2('UmG-6Xc6 +HEclFTiL)bk@%S`Pf!TcjF'-ECaY1ISa#[QUhXj9GX)dR,mRrY-E%kpq*NjZ-See +K'F8NJZA#HlA+mNMX52(b-S-a@Y5$J3q3!2VUTF0ai!FpN!#G'JPFKXL4YU0icm6 +$@L`GU*k'MLhL3r6q4A`,#1dPE$kVZ(bDpBHP9DPch%X4@9p!Tp1kd3!99+&AX6e +64p2)dM+#NeJaBd3-2eh1J6r)f,bL*`N@$4(MFirKd!`qPSI8JME`IPEMirVF1UV +3Q`!Be)[-2D1ea-6deXT2AZmUe+rCESGBCk0P6Hl92V)EF5FC&mU2&!'h#E))l6- +ecRL8B$RL%C1Sp-[9X-IQR1X4Fi1Z8e6pd#9iXDLeAL9Z8hLTB8R"H[+X(`p"PCj +%)Crp,f(A"YP#pBQ9K`(43Up0E!,8Ym*BKAeE0$8"rY,0Aj!!#Kp#5%JU,ZK$5Gj +A[3N4``VQjkmJ-+C2!'MXSBKHbEU+MpRh9I"k(5$MM)aa"8ba)`1I5i"130!hm-c +rQrQClRJ-EDJD)331F"AHr(k4P(1hJh02BrNh-B%62Jd8bXXcQjpTI2*c49$NZP& +P(8FREhlF8HTZ2JAN@E#B5eG%SU,q)p6qqa"BU)$aqPfU5BXIiVe9K%NeYadfUN, +2ceGpIJSiT-#R,HD%pJTTG9E8Pa5Sb4if'%dVlq-JT0$"AKX($P`kYCJ!154($61 +AJRDJMIU!pP#+'rAVkPDK,224f5S"kYi##XL@RU*e$3j2F80*SI(rjb)`LcTbVG1 +HQr,'H`$LSbeh6GpJ98cH!R**!F(TUcSmpkV'9Vk$aGQNXh&U"ek,&&e*!)%,SRd +#`U&b@a$J28CH(GPU%!T,D6HUCBYr&CR*P)rKb!`NR)$B+%fRQ)Fe658RFLIR8Y9 +FVFSZFC,2ZbHMXIb2rS2#LETKc(6jmc1eZ+XB,&GIJF&Qlmk(a6X'hBk&PDA,24" +UhMPA@aiJiF%FKBPI[(lFK2-66-Aj!82N4NYk5!kq@TDM59Y[fjm*Q%F*Pf4K9kc +fB,1"rDKCY3k+H9mSqhSp*hG3'TpK2"ULCUdCJ5qq*Ta'!c0EfH3Hj,LelZMa%@- +*4*!!LlVlEhMQQlR`D4%""e[MG(MHfDNhBG5S1(jY5C&dqe%YMTc%*&#PJ`*FJZ+ +`MK2((l5Z'[94d)LLX1G&@PjR%AHhjMh@H"9A'Tr+2FbkVV+deM08p6RE8Sl$62q +"+B@02AKH"6RMhdf(cG-hA#KD@c-IjBY[Vkj9f6+Y8`bV8(QNMS58d%fD1$jjC"r +!TRACafmrA[)G8Q9jSb,D`Bp$f#YbUKAELT'K,dUch)EF1,N3%XKXPZR,rm-D@Pe +Q(qla9d"N$D!&Bb#!Y0*8kc-8+Hf)1`%5%aKcP9'(ClXqKViUq)r9RkH9f@FY1!R +XfRRDU)A&RdmZLVp525#FYjYp%Tk1e65ESF*JhVIlC[[J&0LJKlbfB!mEK3%lFbe +Z`3&P@$hfERG6bVRN)@E2)@@HmXB)rmX9mim&8$aRk,0iBEM6[1TA8hCpV"PGbIe +Y`%(S"VfcUV`&S'qQ((HMT""-bqPe[YcUNjj8ZUCA5CKHSRVI5+"%i,!SQBQ$ff+ +lP6&cN!#dKbcMBebi-TXIa5hKUBEB`p3#$J`J"$rE[Ibj5K&p8!FrX-IFQp(SM4% +5aPrE1j,K$!R&cp+&[H`LGYRp[Tp&hkFK#lj30+-)F3+&0d211[j+dl+T`2*2&HN +6X$VhK-GppdS-aHIlK+*Rl@`BKk!,k2P2NA*UL&3D%VZld$SSCK&VF6$)a2IUa,H +`-N#DZh1QJKI1!bc-ilPX"0E4Z1R[GK`4Z',!6m[B"9qh$5Pl$%@f0B@V63PNjN2 +CXqe8bVQRXd35PS3a5-a,I2Na`T'#3!i))Bp0%43!TC!%!3!!-!"!!*!*!3l0!*! +'!6!!!)0Rrj!%!*!+TC!%!3!!03!!Y[&1mlEa6[-!!!%`!!%YG!#3!p3!"E`U!*! +15@0[EJd!!GZmD@0[ENe"3e0"!*!2J!#3#3(Q!*!$J!#3"!m!3X(8iHr%)(JHNZX +l)T0$PMe1&X9%h,U"-`j,RCS+U(NFRSIR`'$MA4ifZ1eNp(bc"k[8Tf29`V5Ebi- +dlUp1aif&(6j6c4PRTLP1eK5a-h2EPVY&cfClKmZkIGS2aXQ*%PIPjC5M%Hph@9& +a(ZfDKkIUBkh$)JJi(L3&)ZG6@!#PN!3"!!!`!%!!N!N",)d!N!I8!!#,Z2q3"!# +3#U@3"!%!!$8!!,GD)G+h@L(6!*!$e!!",Si!N!0b!!@JdJ#3$NPMEfi0!!(EMfP +MEfj0380633#3$i!!N!N"jJ#3!i-!N!32!%,"e(hUjNKc6hS*X&!ZqFG%dkqC`#& +3,a$2e2#THbFLNpi5*Z4VJD@If`"I'V#EIfh'MSlG""q1a88iE&-14)Qqr-Mh6Z) +ZSeCSpTee"5pRNpe,5q3Re3-HYimLk883BP`hF8paMJYi,IjQFS4aSC!!3[jdX&9 +S8p#SmYla(hQ@e-dU3+@3"!%!!$!!3!#3#3%YT!#3"h)!!&"[rj!%!*!+h0)!!!% +!!!'253!"MNN!!!4X!*$cI!!"!*!&D3"M!(d!R`3#6dX!N!Fp!'!!miKF9'KPFQ8 +JDA-JEQpd)'9ZEh9RD#"bEfpY)'pZ)0*H-0-JG'mJBfpZG'PZG@8J9@j6G(9QCQP +ZCbiJ)%&Z)'&NC'PdD@pZB@`JAM%JBRPdCA-JBA*P)'jPC@4PC#i!N!05!!%!N!9 +Y!'B!J3#L"!*25`#3"33!5!"R!31)-P0[FR*j,#"LGA3JB5"NDA0V)(*PE'&dC@3 +JCA*bEh)J+&i`+5"SBA-JEf0MGA*bC@3Z!*!$6!!#!*!&-3"R!%8!V33%8A9TG!# +3"3S!8!!F!4#)'P9Z8h4eCQCTEQFJGf&c)(0eBf0PFh0QG@`K!*!&#!!1!#J!,U! +#!!%!N!0p384$8J-!!(i08`U6K!'ME3$X#h)$Y,)b+b[M@dhH@qpUpkCZ*YH!-3" +!!`#3!lUe$)!!#@NUrZ!"94)XqdV)@`lMjA1kK9'1XMr2MrqZ)$NhV"Vi%FU'0AQ +'BU0RDr#XAMm&lZ`,`,#T"L)i6&Fq[H[,VD-C!m8F@8XE1!X!N!0D!!%!N!9G!(! +!F3#X"!*25`#3"dS!93%6L$T6Eh*bH5iJ)%PZFh4KE'aKG'P[EL"MB@iJEfjXH5" +LC5"`CA*QEh*YC@3JEfiJ5%C6)(C[E(9YCA-Z!*!$EJ!"!*!&D!"k!(`!YJ3#6dX +!N!G)!&i"*BK18fpYC5"TG'9YFb"hCA*P)(0VDA"`C@3JBQ9MBA9cC5"dD'9j)'& +bC5"ZEh3JFh9`F'pbG'9N)'*j)(4SDA-JFf9XCLePH(4bB@0dEh)Z!*!$@J!"!*! +&A3"`!(%!V!3#6dX!N!G+!&8"%iJk9'KP)'CTE'8JdPi`db"YBANJBQ8JC'&YB@G +PC#iJ)&"XC@&cC5"eFf8JDA3JGfPdD#"MBA9dD@pZ,J#3!bJ!!3#3"D3!M3#i!0% +%#%0[ER4TER9P!*!*RJ&H`!)$k!#3!p4"4%05!`!"%Je6#TXN!$Z+L)S9caE3Fka +%E"$e,$pr2qcARErRlXi-TeMBB58U@)999@,P[r%%XDS&#l*P1diJqC!!(`&8**M +k0Eb&Tph&fGe0dXKkNVep(bj$h-@Aak8,&[Q01&G2PI8,*$a+MT*"[ZKdYI"dDK@ +D)Mi&jNl(,(@,TA1"CHpm&"bi0FV-TR9!6`FK$%aAP&QFVF'lCA-L&paq$(JIm$a +!SNrM'Ub)p-`20hNS80Z-b('VTjc&BeY4ZFc0eZQ"Uj3hhmRl$1Rr92r*E3#3"$S +!!3#3"9!!@3"N!*-%!Np,!*!&!`"%!%J!k)JC9'KTFb"KFQ0SDACP)'Pc)'4KE@& +RC@3Z)!#3"%J!!3#3"8F!@J"E!*3%!Np,!*!&!J"&!$%!k)JR@@pe)'KKGQ8JC@j +dCA*PC#"KEL"TEQ0[FR*PBh3JF'&cFhG[FQ3Z!*!%$!!S!#J!YJ%F"!&993#3!`` +!)!!)!+)"(!##998!N!--!')!NJ$`!CJ!K999!*!$$!!S!#J!G3%m!)G993#3!`` +!4J#Q!,S"eJ#'998!N!--!#!!#!#L!4`!J&99!*!$$!!S!#J!VJ&1!,9993#3!`i +!+!!S!-)"T!#)998S#J#3!``!+!!S!*3"%J)!998!N!--!#J!+!#0!4F#!999!*! +$$!Y9EP0dG@CQ)'&c1J#3!`J()'C[E'4PFJ!!"$0"4%05!`!'G`e9$8-L%K(QAQi +3C#dC4'Vb4#3,%&QVTLBRYcf,M1"fjmK*Yc06mTPrGlr[fiSm'pr-Yl9!NYA1l-R +N5GLq1j-4NZ9@j)QXb1mIN6q6RmQmfGCf%8N@%l)h,FNL+%$L"rp1@BD49%3iU!X +lH1)RGL%XdS$Y8-@K&RB5AKr2MQN-Tdqr@5Tb%b2*lEeNEa2deYr0KTa,b#P((lQ +rdKDbpHCeqFBN#8XTDGMHT"F9Nj*A@5m3r1$*iF)A(Ra+`bCSd@*%bYh0[UE$mLb +8Z8NZL1FKb4cpaH#,'S2Z2"A0G593mh5B(ilNbH!U(HDq*03V2L&LN!#Glm-GLj) +350pE&JffVadV0j9c-)PcYTmmT-U'cCf2[lLr"Zb,Dr,j*UQJ&eL!@HMeXIT'U5K +XK+Zi)G(%4'NH4P'P*SBS*l2%Ke)*Td69NE&*%bSLi2'$"P$iBJ#e%QfCd)!P0"& +UFSY0QF0BUD3IT`bXGDL,fZ$B!U8fSh08@--BYZrp*)$#,J2%1@+BZ'k&r-qa*h( +XSZeGPi*0bi'TkX2@JbVR0)ahG0E&J(3EJ`[@YV@,-D*-cb(Q-Y`6mPcZfjMcBMp +"cGLljK3Rb&aVTMai@-PP[RfUT+62k1U0klXYd-Kcq8@f`RZ!4-@X%K,E)89)*H! +)2HGQk+!L4L(61rDKE[-93T%lT4&h#Yj6*Gq@)$NpfZfT-bIQ[*a$ZHi9U@$-fpT +GbR)EqIHh6JN-ELhIr*F2iT-R9S%)rHb*!9X*2'JQcVG5aT+bk)"66"T!8Hh@RKi +MNZDb1RCPrpLBBZE'f'*+5Z1k(+rRjMiNk%bc`$2Y2dPbk)d[lP"05[[rh(fm5+9 +i5KpCGN!BDPI(P8iGH))aB&$'@AMak[HhZkICP"IAk`20U"30ED$cl3ANPB5bhE" +dKJq'UT!!'MJ$K%Ef[#TaY#Qi5[JiZdp@*Ek(V6S2"5LGMGP9XcSTH`kX!)Q$@e` +Lj!Hc!YeF"G@qBdCpV(kpX(EYJl32qi0AAhd*'kUV,i&`%M,25lL3!)9HJTA-Hq- +JNiRVb1C`%N0V@&,9LJXedG30VZTedYBKmQ8[pD@$C2LX$T!!US[$LD0[BBPS9ak +e"Bi4i"NpQ[B5,S$!l!aZkDY"[CV-MSM(ZdcHrYqi$lHRmXQ0Uj1Q&hdZmV+6dc$ +Q@CReZ"0&fVV&S"Ua`C3d8JpM+h9[1peJ#QP[H2ESABrbfDQ9EXl,)rR"Y(aV,(D +K,&e(qXHCLJYTG`ceq9R+jqIUrhj)D3VcIeGqcX4Q-IlfpqABR&9R,NpTEKEkTP6 +FE&CkmZ##0U6Epj,8cI&CH25LN[RmcjI[Q)F-e2@eAFBV*qph(["`34I,9E@$fDI +YZ+ZVJh8&%Tl"cXY,fjl%2ZKNB,XDjI@RH3*a"UE`8,`*ALRF`jGi-!Gh[Rked&R +$@pIN$J#3!aJ!0!#3!r-"AJ!"!3!"!*!&!qJ!N!18!*!$2!!&"#"[CL!()'PdC@e +c,J46G'p`'dPdC@ec)(*PE@&TEQPZCb"dEb"9EP0dG@CQ1JY9EP0dG@CQD@jR1J! +!"b*"4%05!`!-3`jG#kZ#*$lU%1prGjb%8-8Ke%4U9$M4)k"mV`1cHE"X35+++e) +@+mTLVcDH@@K*2-mfY,@Gq([e)E3@F+Y3`CU6#q4l%rB@IfqViqmTMVm(#i0NeC) +kXl[86Qa45-+m*-Y)P`SKT2Fr)CeBA(YZrId!$HEQ0$%"*$3M04p9j!kQI8Mr1XJ +2KmNe8STE4UDQIi,S@Rhe[I@qarqjqdZ#CYHDLRYFmcXRh'Fqe)[)rKRQcr8Z)jY +$mqMAB4Z*`8GNQ$3LNF,eb%X++LNJ[Q-))Z%`N@8J`NC%+3H8XKIX1QSI*qQMdQD +IpGLhEpjV%lmY1l+5fDcpH'C-jhq['[`3jSrETKXX9fHMKlcNER4riBTCqG'#)HT +h9+c"*XN$@Cl+I(h)QjMblcphCF`KE5hCkEmEJ'dKrURKM#aIRB*N3e24C0KHQ)T +l$%Br@CYXcVBTrfSiNkeV5'3-b4AlqD@&QA@GlC-5"V-KqeISpU@)!9VF#TrPGVe +3`$j(GLp+(M+%)bJKr&Sfl6c(iZ1Y!9iHNp3EPSIpCePFTPi6XLqMR56Ea[SbUjG +DGG,V$qpI@A3Hj0jCf4[JHkF,BhCr0'i62[6hH)6PrqmTD$jIpH[T![HreCf6"(c +N`HmpTrP+(EbH[''!b&!IJmY(HX)"[R"cV$$bkT!!BFkfqZ%`*Q+HH1mQpFh)rJ@ +qePkBpb0ELS5`[FqP*d'Lda$-8qj%Tj%SG+&FF'&0$-QD@&h34--"6@3i6E!+&5C +N6k*#4QZTHTiUAUNT`YdPZGKX@*2jFEfX5HRlGNQ6`Y[fJLBRhkjk5j-GMr1P!HB +l[3'Qm)HHJ"HPEDQ!T2NIX`%2j1DEYFhii,)JXp(b1Mbrp)q9Zl25JF%)$&*Jm!+ +$kJjf`(I`)SH&YIF)dciHP@*rMBUa4$IDcXH3!-q&V(Q`BSJadb$'CXSYUpXb)Mq +,Xi0GD)T&6U4-SpFIe6rLf`lAZj!!4!fm'%+q8%hL1133Cp,eVX%T8F2L###cAI$ +mL&00G&-%Cd*2iB%iCf`MfF-jf!FJ1%J4[MVRbX'20Z1CcLbH@N1)6)kDFS+SqQb +1EX+TQJDrTfh#kJ*5aM-q0k+Q%VF[a'CXI#96N@%'546j5+F6eCZ`Y)TX2A,NUk) +B-Ej,R0VL%(mE&PXrq-#p#2e$Mh`2m[mZZU6[&E)M(T+mmZ5*C[*Naii8P6'D6(c +bha3TS[J5ABK&@0UBMc(1MV#HAk%1$dlX0f$d-%mhXhTHI(EKj`HhGF*SlVcm3"f +0R8KeA4MGl##9e5FlJEb)E"IQpI`h[mJ1R[b#0H)%!d,9%Uh1GmIjmI'(P'YJ%Xl +MTk6lU'PlpV!H4GrmYK0%M4LGSRTmK3Gb$BLAff+Tl2CbF&6Y![$@m5BA+)6!`8@ +ee[Q9(MN+4[41XU3cmMk'DQ'S6h&HI"C4IqZm$K%CM(`cNh-UZ['2M!%2")E[(Qe +ki1c3Sd5C@fSUeH@m*6B09&BcS)f1L@L#PQ*+KA6-TD%G95+1T&jmbi%QIa"&$XC +A8%pjZ(#6lN3Mjf1EiJUFd@m[mhpEDRiY`BBack+-$RSC#LEPF![d"pU$S5L'jPl +JNJjCi#!A!`%J-IrFfDFJj'I2C[Bd0UCE2jZlIl&[h22GqrIq+,l2YIaTXma5M'B +r@GG*k@i'TkPPB`@qB46N'fV8i#e-mqY#FQQhm,*pdPaSPhIj$G'iC,9Ub5XUlPr +MUJ4eJF&a@NLbIaHiI1&RqABj*aPfCDA)c9$b&Q1&B+d6")mEj`"hp!LF[E!INQr +i$5f+0$%85TjqUk*%EUa+@q*c!aF,QlbR+TRT&K*AHmBm`H+'b@!Ybe[DD%JNC+Y +K,rT32-h-5[2H&`Vq&@3lX4p3qFD#JN-be"TjPN2HL'*jq3e('@KA62r,S8m@)G* +`Y9bQVCUKQ*,F46fP#De(dpG(,*GddTH@hAh9Cmq89@fhA6q[&HaSDHi-`A&rBc" +SL*VAklaba4[#Y3N[eaKF#TAbf#jhZMBU6rSp`@$*6JDqIde3IqrP2-(&8*'2lGS +HTLKVm%m-dEa@`90(@8HSq#r2kiERdSZ#C9dhN3qf5G9@i9,MEQj4F)61!R+`NF* +EQ#T+d!MBVHi6(K1%BpVk5r4F!%DirSj!pl[YiQ83Vp(a)p)(#6++Y%mhNNJ2e#* +CJ3JADBr0GlNJA$EL+aRZ3114C2lUKK@1Nj`-Cd`A*&$Smk@bIplmk&rjj*%N!V4 +E+8QIVZ9DXkIkqYr-K5K(p'2[p%4qhlC$P5dE9Uqbd&iR9pd`'&Kc0*!!U["1F`I +#QD4#UF6[J,+V(BCCFebM0LLP5'&(NU-8pp2f1U[GXf#3!0bTkLKeI+$XpBE#8R' +ID@5dE+#fMGY9GNqZYN`D+Xf6iI+JTG!R)B'`%6K'3j9)bMeQTe#4CN8`4!JVG%2 +hqIS((dfBili2!*!$'JB!J!#3!`-f,M!28h4eCQC*G#"648%J0Li`!*!$$JB!J!# +3!`-f,M!$0Li`!*!$&3"8!'3!L`''!!%"!*!("%X!N!3B!$`!3!#`!CJ!!3%!N!F +""`#3"J%L384$8J-!!iS08`UE*!"rKN@`h6Nj%l$&$Pe,6NmGf`%9!pZaqYJ-9[A +12LLS@(eX`@kXkXE!2f0r925rrfq2mhC@'FEU!!ZC03eF9Shd`Bj'pkj6'Z`%Xr- +S&0c&iM*#YY5j)-Pc#j!!hfq#GS,Td84dcbPjXa2G[-RZ+i@%-ma,@ZUD8SSG#ci +IQp0r"2"krMRUbY2UD[qIAfl(Ujrp3rrlNCBP!VJcDU1#E9E"5#Dm4DYXM&@eAPX +qBTZhKHeK&AhF&mE5@NbNP,3#F4p-ISc$ekiEjSHQ'HT6frC0h3qk%'KDJ#F%b!# +F!%bpqLd!rZS*!a&r!2#LFZ%#%"b#J!'#BQ!Y1)Z43BcI$%,N%MVLkQ15c,dSF4p +-hh6j4F3VE-XB!*!$Gd&%3e)$!!#!$9-,@b!$!kCJ`kTUXc#`!5*LB$G,XGYCPD! +JBX-HkYR!Q&8a#f-UZ[HR8k`+#iPMb,ELGpB!8LMpiEh!JNUia8#RBdJbMUrCpbB +L$VrTa[llf*mk9dmSTT%&(C'kJKQiSm8DVUKU*k42-JV[4Fi&!*!$6!!#!*!&#!! +d!"S"'iJE8'aPBA0P)'PZFf9bG#"NDA0V)&i`)(GTG'Jk!*!'#`!,!#X!+k!#"%X +!N!8G!$3!,3%BL!*H-3#3!cS!!3#3"6B!K`"+!-%%!Np,!*!&!J"&!#m"2iJCAM! +JBA"`C@&bFb"dEb"LC5"NB@eKCf9N,NX!N!1U384$8J-!!,B0@`Y6-!0hFbeQ"Z` +CdmT9aMFdilke99E'2fp2lp9kYqiprq)E'J!!m!d!!1Jf$3!!#l)Y'i'Pq!GfCr[ +jjDdYFp0@cGpCf*-4E6ZY!bFUCeRCbDlbH0Gh4)AJ8X4rJKJ8[N3-RI0#5DL'!59 +#J#kS$Yl9"F#6K4bJ',6dJeNIl`L5Cd'q)0q+c@'mi[eVN`@PK4)VLVPbh1Hj`Y* +8H1AaB3%!N!--!#J!+!"r!A!%Ve99!!!"!*!$J!!Ird!!)!)J!#)%N!!!*JR)!#) +6j!!L)!)!)N!"!##(i)!K$r"!)K``)#3Cra!S'SS)-M++*#BbmM*10!Bj*QAd-K* +P)Cr`)"($!%!)ri#!"!B"!!)E!J!"!!3!!)!)!!"2N!!!*b!!!"*!!!!!#)!! +!!8!!N!1!!*!(J!!Irm!!2rrJ!$rrm!!rrrJ!2rrm!$rrrJ!rrrm!2rrrJ$rrrm! +rrrrJ2rrrm$rrrrJrrrrm2rrrrRrrN!-rrrrq(rrrr!rrrrJ(rrr`!rrri!(rrm! +!rrq!!(rr!!!rrJ!!(r`!!!ri!!!(m!!!!q!!!!(!!*!$J!#3"`%!"rrq!!J!J`! +*J3+!#N)#3!L%!L!*#!)3#p!$q!JJ!!J)3!!)#)!!#!N!!!J+!!!)$!!!#!J!!!J +)!IJ)#!2m#!J($!J)"Rr)#!DJL!J-S)J)$!')#!d"L!JCI3J)'8F)#"Rr#!JF-!J +)$rJ)#!"J#!J"X!J)!!!)#!!!#!rrrrJ(rri!$rrr!!rrri!2rrr!$rrri!rrrr! +2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ +2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ +2rrri$rrrq!!!!3!(rri!#!#$!!Z"!S!)3J*!#B3#)!K)!K!,N!!$q!JJ!!J)3!! +)#)!!#!N!!!J+!!!)$!!!#!J!!!J)!IJ)#!2m#!J($!J)"Rr)#!DJL!J-S)J)$!' +)#!d"L!JCI3J)'8F)#"Rr#!JF-!J)$rJ)#!"J#!J"X!J)!!!)#!!!#!rrrrJ(rri +!$rrr!!rrri!2rrr!$rrri!rrrr!2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrr +i$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrr +i$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!!!!3!(rri!#!#$!!Z"!S!+3J* +!#N3#)!T)!K!+8!2i##!!#!K!!!J)J!!)#3!!#!S!!!J-!!!)#!!!#!J"q!J)!r` +)#!F-#!J'ImJ)"U#)#!bJL!J-!BJ)$3')#"Pp#!JC4`J)'Im)#"``#!J2q!J)!'! +)#!'`#!J!!!J)!!!)$rrrq!IrrJ!2rrm!$rrrJ!rrrm!2rrrJ$rrrm!rrrrJ2rrr +i$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrr +i$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrr +i!!!"!*!$J!!!!8!!!!)J!!!%N!!!!!R)!!!6j!!!)!)!!%!"!!#(i)!"$r"!!K` +`)!3Cra!)'SS)%M++*#BbmM*10!Bj*QAd-K*P)Cr`)"($!%!)ri#!"!B"!!)E +!J!"!!3!!)!)!!"2N!!!*b!!!"*!!!!!#)!!!!8!!N!1!!*!(J!!!!F!!!!2J!!! +(m!!!$rJ!!"rm!!!rrJ!!Irm!!2rrJ!(rrm!$rrrJ"rrrm!rrrrJIrrrm2rrrrRr +rN!-rrrrq(rrrr!rrrrJ(rrr`!rrri!(rrm!!rrq!!(rr!!!rrJ!!(r`!!!ri!!! +(m!!!!q!!!!(!!*!$J!#3#!G"8&"-!*!'"e0PCc)!!3#3"!G6C@Fc!!*r!*!$"e0 +PCdi!!rm!N!-(39"36!#3"KaKGA0d!*!$!8P$6L-!N!@%4P*&4J#3"B3!N!-d399 +c-J#3!`&*3diM!!-!N!1!!!%!J3!#!))!!`#$4P*&4J!$!*!$J!!"!)%!!J##!!- +!J`#3!b!IU5!a16N`,6Ni)%&XB@4ND@iJ8hPcG'9YFb`J5@jM,J#3"eG"4%05!`! +"!3e6!Yc@"T2hdNE0440Y!,6j0bkmfddECX*X[UX,hi6GX0[NhAE9eA9K!!NiTBM +rG!Ak'M5Q0Klla*eVf8k#LE$6%2V!XqJ!D*!!aElq",i'!!!%!*!4J3#3(S%!r`# +3()%!9#[r!*!DJ3"8re3Vr`#3')%!92q3!e3Vr`#3&S%!92q3"93Vr`#3&)%!pID +3!e6fN!3Vr`#3%S%!pID3"2MfN!8Vr`#3%)%!pIEfJC!'9[IfpL[r!*!1J3$ep[E +prj!'r&EfN!-Vr`#3$)%!pIEf9[prpj!%JIrhpT!%+rm!N!U"!2AfN!2mrIG@Ij! +&Uj!$IrEf+rm!N!L"!&6fN!6rIrCr+Rm!N!089(p@+rC8+rm!N!D"!&6rpT!$9[r +iphmUI`#3!e48UrFVp[p8+rm!N!5"!&6rrrD3!rcppeC8+P53"AqVprEfrrp8+rm +!!)%!92q3!e6ip[prpRmUN!989(prprK8rj!$92Mr!!$r+e6rrrEf9[rhphmUJC! +%V&5V9[D3!rrr92Mr!*!%rbY8rrEfr2hf9UXUJID3!i&rrrIfN!2r92Mr!*!'rbY +8p[EprIG@Uk[rN!CrprD3!e6ir`#3#2mVp[C@rRrhN!6rJIH3"2D3!rIir`#3#[m +Vp[C@rIq3"S(fN!Ahq2m!N!cr+rD3"[q"pj!$pT!$prMr!*!1rb[fN!2rrrMrrrM +fN!2hq2m!N"$r+rD3!rIhq2H3!rEhq2m!N",r+rD3"&6fN!2hq2m!N"6r+e6rN!9 +8q2m!N"Er+e6rN!08q2m!N"Mr+e6r92Mr!*!DrbY8q2m!N"crq2m!N"lr!*!a3Ej +"4%05!`#)P""9$@99%3!K9Hj'RckIP9+A1THPQ3[p@HHXJkd919ilR0"ecjZZ,P[ +Y"Nk#VV#Y"GcclQX-A$KHA-'"#b!1j!a($*R6`fd),X3[m6M2QjaRL1F40-C6ipF +JAjmh-ES33mJFfrVqqr`qEAmG!b'AerIr14e@0K)4!J'3""%"N!-43Ji!A32IQ[E +j"hUL-`Km2d5"rJbZdI4iYUQE[`3Tm6XAhiZ&e28rqjHmNSQ(K@lSkfQ#6r`iVi5 +1%R'3!"ppNiMDBVVe&PPM2LpJ(+*"mm&3LHU40Ie0Ta2I!E(6NmKV1Sd&"12cP@Q +J+GX')Y9EJeDr$H6H,`GrpKGRmP13!#bEXSf"1qIEaTUh[$@iaYbd'mYIm@8%bje +mf8Q[*dT#jjHGTGF6*F&@[Y`*SR$2XV1Gr`B3[)iqlT-J)#BF!mrN18-Q*db"*Xq +Iq-$d9ZHrJBj8$b*c9I013I3G00mrlfl2%H2BSK"2V[aQr(XLJ*m3IS+Y18,qdhm +2IfTqeKB%XFVLV!J0LIqCqZ[NN!"M++XipJ#IGMNVq'*Ia'@Zre0pE#iIbXiNQ11 +4SC&2Ba+$fJQ#RIM'!GA82c-"bfc"+$+J6QE-GGQH%Vl1l5")aN45M)YY`T4rCDT +3TH)rIjhk+cA-f04IfF3j$*[aXfAd#Ne&V[$T8Iedj)V%bPk-l4X6hfMqFD3[fLH +#H8,PN@r2lqBNJi0@pqIGL4`4AIQImFqaqFqaqFp&X11(k5,@e[)$GB"[2AT(3"d +`@mceeeYLZT9(L*@rFMQMYKmqBGlUiUmUp-GEIrM%PDe(j4`8,PBaG9H$6N`HFKc ++EC!!qr1l1q*%0'hYYpjL69*@L-TL(@Jkc3ET@%K,bNjT*8+Ta0chAIBL3ZcDBCm +eU4edkBrm4iR3f818(5LU1JkJXC(AY0Z",GUp@%D3!-QBE2[,'f+d'b4Jr)GXZ4, +jimk$3im+-C9HAbM8cpIjYh3HK-S#%2[#D,IjrSdE6ldY2$!)Mcc3&(-QCGFq%-% +lDdBrd"3Rlp8(*jUN!'8I"PX@-MqJFJ0Vl#C(elVC6UrXUXk3!0qXrNM1PM@b[rS +8b2jq'c(081e*Q1rD,,#CSSebGZ)lIp`X[#!lKa,q@25H[Ce!m)r0)U6jkFYc9-m +i%*3SNq61qEJX3iP5fer+bKaGJ3&RU&R&Yd(&F5QbFT,BJ$pkMJ6C$d4"`"Hq[*5 +,FpMPSG@fiFhr)"DKJN',eRi%H8ePa*Uh#2'5&M&XV3-&8hmBJZH9#,CQpr`'&F( +"MV5eAJUqL*41(T!!Ye"%5B'E)JT"'T%IQeS6D6,Z'e1TV-L!N!#4!G&CFk+l0Dr +*+#IY6e*dQqqhLI43jrD%L#AE!S,)fp(1Jkh#E(VrXrD!HHLpqZZ(c#D6UIkcZ8H +PPf&(*V4(!LD6f@3IRi@QRYRPp&Nqf`3KYL!Yj*!!a,5*[c5EfJ-ThlMqk&f@KQF +c[6A24N)[raKECdbGMkT8*4iL`eQ$P+dBX#'Uae4&&M'aa5qU"kT6cAR0KjYbQiU +XL"b9LM)SQPZDEFeh)j2M[jSdeE1UCmPMaT5F9'6)&0kj1&%h5pM(UB+HY$Kpq!R +&r'5FcA0L845jkTK2'QUc$1CEJf[bQMjX["HIDBdR1aGrZaJN[+MT,6$@)C0`ciP +ZBf!#i(Cec9-!YKY2I*UVqRVMT$aQ2b2,qNXG,V[I'+S('8qILIHTUc%#TYb-P&8 +b[5b2R8R2X)Fa"5Sar9hRiZ+06qeG+aV(q'IT8hY9UXE$TVc'[UIfLQLMUA2aVXe +!r$Pc@NKJ-3F(c-JDbPY5KjqUcKNrZ-B@0beZRR[iZG#8,GlRHXV9I,dTVrNQ)SR +JCbj8r%AR$2-e!hXRqU$NqDC&UNI`8if+HE2U4E"8dmqq-9Y&mkm03lqkqGGJDac +)Dbj9,F*N)reSfGL3!0MB%#3*[d%%$Eemq!*q[Y#bIS'Ipl5XmpR3hrcV8r9pBPM +B"TUIT!`9LiA!&@GSIq"8Yh*ML+VVejLE(cG1VA%eEm@f2h3%l5d6$cGrBE69aU$ +JBFFLeH010CN"-ZkRc'NLp-CIJXK+ACF#a4QbNRCC+4X*3"G3++%XAh0HifMcaeD +H05Q5c8p6&U*))ZTf96q9X0!,9202'l*F$-6r,MK*c)mX4C!!RSH#a!'5QR2%pUU +jITZ`V4&HFhh0XEDpILTGIA12a6E4UalpUpF5BZ02k9rT6qq`E$eL`f5Vf(L&rT9 +HZGkb&5$R(DrC!V2S3-KFVh0KiF2"bp[%aU[dVr6UcCDYafcZbJFI1AVcj8fSUZI +fr6fUeEmI&#'EEfi["Vj`JMePK!+)DHXq#fAiQkYEN6f()YP4r9&lT!Y)cTpFLL[ +Rh5C#B`00(jVIfc(30-hmfI*MBelcHmZ2E3YSd6Lbp9K+mZBMK`HDlMCr(fac`IE +DBEIjqmYIk`PXr)$qPAl`q*'YVmdk"P6kj-J03!bIXd#YE'i[Rr"aC2T(fq6)2Te +SDDiHb1ECpiA9$XS1Skbli4S!GJ10NdkG,N,CeL)*iY9!I8PmQdMZfbD3!$d0%M) +b5#R#'QqAXf1kpKE''#4'H3JjIdQ)$f0Yr[rPl(BcYYdKhfj3%,)NNi654&YNY,* +kb-$-+&LX,848PKd`eb3+B1e"Dj!!MU!UQG&UTL@Kd(aX9T`ZX3AEiq8bAe8`[hB +Gc#F9c)G@CeBp3`EHG%CKjXr`c14F9A(car5aMUN+9B90c5KiJb,Bp%eT8UL&ZUN +"L`$!d'rUK9('+*'-@mRF35i'10l5,Tkf109'rh5,A8De@8'C0mlKRpmR3RBHr2C +jLG#YfUrTMZ8EJp04A"[GB'k$Se*)bM*Y&bQh)%[&4krYQkcVpRNCQS@%D[2(&2@ +b*US$0Ia@*jVS3QfVNX3@ZSb"%pdaRRdEp5M93eQAD#KAQ2p"$NET'[G*QqfTN!! +%8(D++2lTk'G0T2(m'P5JM9Pb8Q14A@XdMFBe!0XEdf2Ym4ia!X80Bc&P68*p&A, +HiQ%dCR4L&-fjaF8k4,ID-E$N8AY#$MSpRdY9N6T@J8,%L*rcB*)eh36+0cV$)K" +439-5-+XYR+&,8j%E%La6D"Pb#TKki0$Q80mc"`(A@+-6'0&FQKqMkV2YJU(l +$iA'C-Uj"dNrLF!81Z0%mAIcSq9Q#60-q5ch3I(1+'P'NYJidPe,60H#I*D$%m92 +G8+UEXQaq8@@,+iBMXq+f)$+P&0RMFClj$NHPj*l!hX"6JmdhVHPV,ReU#!Ac`dY ++8$$2j8Aa@Pi8#c&2HqhT$P`,T#MEIVV$FU,EZ9FDLP*8BL9mX2K4)l+$[$3"0ip +LMSaKiV)YcT9Ilk!YUCe()i0ld%*3l3eMQeRTf1kPF@5Qj1pcdp%p)M)ifSe$CPZ +CZ4i!5V&#JAaVT-!d`4#Yi)LD'++$P4!GD%b`5cVCTGUT9cIDiPe#3TH3!,9j`jd +-aX95TNDUYNPPY922,@iZYEI-b'Yqh"iP!)"8f[a&p5qXAN,qd65+,+H(,X+959Y +FqF+q@AQ"P8c!r`T-#0R4MA!dJN'*6E,$q%TY6''+kb4'Q*ZDf16EUcpkC9,)+2! +3`#U+AmN@VEm!)Q*!%[$+AZ2aJeQL#i)5*+Kp09'mQ*e#F2%daGZcjAA1VR)%9h2 +"ZH*(@X'%+"-,jJiiThbT&%qQhDV2V1VKJCXUp3!82YBre2QmPCQVDMp9p64p)69 +VNhBkKZNJQql56MX`lC@QcaK%E-+dQddE4+c%Y)p0'd43"QD9)A!3H,[rCUNa$l* +P)CBI[$8)%Q-KJ(ebij!!Df1ca,iK-F8"N!"d!1kl#akJkPFCE'A(8'N"XTl9,4& +,EFpH!I!VLTm@%2L'*dS,(S"Sf6J&!NNV`#""!-mXiI6CJM&!(A*2`@BU9YA#$QF +"6(AK5#'1m1-JMYP-ZDTaIR#YiQ!,J%"CC3&"Ta9A%@Li!!GUHA9l'4YYIbHlS-5 +4@e!#0p'Ya-,%,S#iC5$'e82NCH1lY6&Fm3NQUP$dp+LUT1-&+HDd!"TFqkEM5"d +jQNQ&#hc2!NdMlf3A&G+bqCZ1h+*#bPJ#-6-0lQ4MTXkqYUCE`&$d$VP[(3"j29" +8P#F#VXrCDf4,(B#M@MB%lq@ZK-1S,2DL'BP2UfBJSUU+0T*j#,rGSh0S,YZf%EM +e4&e+mSl,GeL3!&@q-qD4(CSk)XbMmDCr@AH(46H"V4AEm#2lRkL$`*hF[E!%"*' +[k2V"51mJTNX)K'K#d5iRRHRYNBjAiG+QfJqRQbjF&4ZKCQ6$EF*VMh)(00AK6C[ +m-ArqPFM3p,kFV3i`1pY*(#'jVi`*QYTA"[8Be"FLTFaBT,)i@q#UjmU+iZ+kK1E +j3aNSb2)AU8SLK#C3"+'aZ!'99ij3hFX9d3%aHjZr"!0PB"pSb#dUbK&&j14CClK +JHmQqRU,#jRRF841LUjqhp458K)%r343iU2lfX@UVFdEdLePaK4Rl*8FPU`5)4%h +[aMQC),P&cF$XNLH*U'4D9!LRJE5!j*B)-NmJ6iJV"(M[mcCpJd"mS&9#6SRmCBb +l)jEX#cC9Y'CENf!X-ZF@f[#cUENTZSM!-9@*[4eQmCUU+-q2a5998BikQZXHa%3 +&&ML5kq11L&i!4Sl)N!$KLZQZR1T)Ri6+FbkSl)!*&6Nf1V#NcMU`T-UFYPC0fk! +U(f3m&cCpNk(U'HefmZ$PEM!YAR+9Q'j!-dbBhN"$626K`#JBeI6#e#3b!&`1,,P +U(9JmM'Qr`m8V,[q"J$&MM@[*eA*H4qh#hF'Q2&b-,[!5`)j6('##Fk46*T!!&Dp +G$[%Q'NbIZTBm5S$)#6eL(SFE4-M,TlVT1)c8CFllGc34NkJBM4NA&rple4T-,,N +bi#Vd'TJ)A)2B'894j9EY`VY!)5LhN!!UeH@G-pDqASNYl5Qm@,),Ri@0D9'%db8 +,R49SU'TL`R[#U&VM!JU,(kfC+&kV(J+BJ!+ZDkfDLMKclRB["cmY3(%D$F(Ba5[ +D-H(Pdmra+RAaSfSflHE6Y@cDRbED[B4Lp$`!eY0FK3QJGKlS8P3BL4'$df#f(!J +3!`*bd`("Ab#Uk89d3(LAP'Lk8`H"fX#5NMFY"-`3H@+SY2$[MGlU(J4LEq%QU,+ +1M"""-qN3QQjl#kDZ5P1&a66Pp(i1!45`*dFMmVka8)#D$-5#CJ+Z`J8pKCY5iXX +YdP804c6G18PM[!E6L%T#GC1dY@+0TPXK52#Q4f6SiFB$2&Y!e2E!FCj8dS*$T*` +pq$Q+J`dF2"UfFc,bNNG4a0qd"UqA($$R)M##Q4#C+#hF4-!DSZbSRP43k-G29#) +9G1f0jTRkQSXJDXSjc%NP82[AG**3!)dLC$'U'Q"1@@C#XcI01%N1fkhC01`mQ$G +)`hBUe04b4+HqCP&KG,+U,GIP,B5,)+V%bAf%#-b()UpG*hE(pLUMc3&6ccQ(+Ue +flU+L&qE5F8YEVK#&d@Z3!-e4X!c6cee,bp-)'#ke!+$[!KP[LJP)bqmQ!k8,i-V +@8h#&JSp,f*1FL-PI++r+rFVa,+U3!%A2SCK+A5TlDl"Skk(VV%)#k-T+p9&MHJY +NU8ZN%Lm+ZQH'$5S*j$Tkl6&5-B,e(K3R4`RmjX%kD8q%[CLaXj1QPB%SB10&d&& +LdNFTJYU*m+!@5*+DH!&3E!8J@V`&PmLpTB@M*kkJQ5A%HijHTmmdm2BV-@iB!&8 +3hB6NfkpSZM(`*+#q1k!q9(5"e43iSN56U@JZ98+a&@e-&lkaVqd2hjM6cma3Bqd +TD,$f&-dXjiSjC,"@,fd+SQe`!+H'9BXqLR5#4a*DLhc,a+6,afD+0aX+*j!!mBT +XF5TN81biZ!#*`2GDji`Y(i,!*`cZJ0aCPS18aN"l4m"Arkc6(qd3UZ!KZm2Sae$ +Yk3MP4EfS[*ILilC[`ZZb8*CcQp'QCDkbVc4kLAQi)r#pD"$-&ILilI5k,($DMZb +@Ya--L51G-rj3HU*E8J@2M)6Ne!c`N6GGj6M-+54h@dAe*ClC(1fFkdJ,AEdYB4X +609m1*XaB!,$mj4bRQV+j!2b[VDlC"r)*$ZH!q!bc6TKM[Z#Vkj!!hJ9$p9EAT-Z +8$`*diBj24!J*HKEGXeG9"2GPDNU[GCSF!&jbjAX)[!raUfch8-)L$0BPcV9L%"+ +Kf,MT!Mm5!M1U,8al-Hh$)LK#H1Q0GSP3`*UE9(F&V"(AUbj4aS99q,Z%Geh#kAZ +9K2UMDIY8SDXRTH&DG9GS*E)B[VF$"Ab$r1D2NDNkFFq%5$Uk3KG[ml4d"ECM$pq +)J[KJ6`,aQemp,mV%,IHNKG5L`T%@h*AAKkXVF(c-j!5CZ9$Z[L%YQ5mm4RpYc0j +k`hRih3hAPYP(hMJ[6J[E'hYl)rfhLh&M!+pppj`(IE%##MiJpbIJP(hiNrZU1Zm +LNk"#9FU'SfAeBTi49`%AbbL)YM#94&fX(GPUXfaMpld-9m[Sl2P1Rf1qXb@fDkK +%b(qFLma&BV0`Y`%eZ3aS2ZLF#rC)V(4rCXSC90ka[11Tjl()122l-rZaU#150KE +,lFD$F!i3#rkI$*N@QfmlQB&&B14iHYCY@*MbmSJKN!#4FMb2&R9C@0pJ6%F +6L'+M0hT"(%35X*ESKG"q!,lHL#[Q8hG&IhQ#-Y0M)0Pd"8jMZCXUB)Sb$"b)4'r +!kZaLNEC*lRi'KHAAhVApX-FFGF8pcZ'SDjr(UFDRbeQ"U5ki6)KB"Dj0'Q%1aL# +C-N3*+D*cak9'8#YAjC,J@i05KI9#RGf()b,Qiqk$P&%q66)'-C``YhLFSZL1fF+ +qkq+2C6pHcZE'l#[cZ[eVi6,-c@-ic$cmC"i!MFV!AL@CBKk4D,UL2i[L4QF8Rf# +HGp)P)9J88b*'M61j+q"rS3j*R6j!)"eZqN#1JfhTljD0M'!B4DBK9+2fQ&hU(cL +X5%KAJBr2kAea,+DZ(SY&TH'b-4`C5`,&1%a&(pc4J*`QGlq"*U"SZB'Da3$ma!K +q2J8B1@iFUBj&ADTTpP#e)%2Ed53m-,3@jTU5e![!86q5`m!T!T0i13SMI2Qc@%M +cQIB#[j!!Ek!'Y`H#SQqm,&T0jm8fA0,M#0LpeD&BU$T)SZPeSJR14IFQT#X36&6 +eA%55SqJA`p@r!'X&XCciJ$-dF)B@cU#@YP$YY`rML[(UU,eLD$1FDdS46"D*D28 +Yle#L-8Pm"6mq,9`m2lkfdKA5*U2Bj+hdLJFk++KF&Sq#T@FePJVKiBcEZ&*kU[Z +NJ*ZJJ%[4k89'V4rNrP)%C56HJ&R%Hp!-3f)cS9E([1V0)S$LYF5NCZbDjXGJ!0j +%(BTP2mr33l(#!,MRb4@NZCU8DVT9MMX6P)PSmm"phHmFRZdk#8H-b3QR6qfjUck +f5kf1Z+Tlp%8)%,lE'S4ENeVe1"VDGpG1c4)J*d6K[,q9*`C"4T+0SS`hb"6QG$F +19DJHI`I-UUdBq&@&A-![9M1F+QX3E-1UH@"V8Eh!$hk&aZb#(p(Khh#RM@SFVM+ +1%0Q!VXAeMr"V2GTVe4XQV$CjAD*35BYhb+PZ(T&"39KiJDZ"Lq-L8',CGG`*84+ +*-X$Z'D#,Q[L'Ak4$r08Y5(cJa58M)**jf$8Y#S5R1-*UIN98p4AIV%qr@DMi"Bl +LX"C&+4PEe6YdD"irp!+rdS$FfYA9[!VfL3eL0kh'I[Fla,+9)YJBUSeTJhqhhS$ +i*VGbC6h!)i%ENl'-E9*Y)dGe5MK%L45N6@mZGp-2)D%UC3-N3BLV!!Qc4Cr`,ZV +bLEaC9-6H15JPpfSDN4*HPA`K*IILT%Xhb'IViT3Y-@+,NpNL!G#F[5VP+dUUL!E +@#l2LpLJ4(fLi26%V$QFNIh4)p4-3PDqFNT,&PC*V**TH0i-jR61AkM-iT+`L93L +[6K-lA3$@cCJ!)[+kkP0@*)@M#j[I(`2aY[RY@I(S)Y5Q)9@aIBSIJ6L@+'&f9ca +@SCr%PRCe!4elD"B)L$Im*4Qcq@JV!$$6`S,J3d6ii!NiT%3RkM"PGB3Tke0*@Bm +ZCmU+5JTTqK3JIEeH2DCh*H88cPFUTm3(e)G8Il+hD"RISUCmi5HN02Z"F'9YEm" +KHhR++VJ@VpS-bYS1!ACN1M6rE0AUfEi`A$f2AK1Z(JR`0TJV,aBj+DRNG6J#m!b +-BmBGU@I58i58r*!!#Qdb4mR4,$,a`Udm5Gf),6!j!FFap5rpI#)T6GLh'!-+8V% +K%GcN8R@NGjBl1L3#@A4JE,p`p1CX5K1YNhpkIr3+-Jf*M&[$QqdmDdPZ&$iXTV" +!SQBN%P0IB`'jVMG['S(UiiVQ3p4$f648S"m3)e0GlNeH4ep1*,T*p-M#2UKfei3 +LSX@5&QK[ZhCQj&+XeGEAkRpeL8T9*dCZ30k6@ac2M1*ci+62H`15iiR)T8JI+TC +EGhM0Rmffj-c&pEj*8qiLZYKMdermHEFjlh@3!%!QqdFcNF93MkV%CeVmHNPX%e3 +km(S*A,X3m92hbR&lLc3P%H0q-4HJM9UD`X%518l(H,0paqM[ZH1DPYMZ`#YNCc( +Q(hVNZ2EJ6$P1%3I(0BQ`9dY*$PPfP4V0UDRpd[&@kBL9CcQ@E)@B&PhFAY'qU'4 +ckk+5Kl!jN!#Rj#L)9#"$PY35)`K266`Lf[3'b9r4L`k@f40Y4q(8ZNK9[$m3FfM +Cm[jp)@Ic-MDEJUfe-P["ii`YD@"6"`d*'C(5%4XNm0iSSNIhi6pl0(U%,bJ4kXV +SdG(Hr&'Dc-JjFja2*Ke(l6l(%53L$HLc!8a1kjJp*bY$#PCIHp'4r@Bp*C2hpj! +!Fm[ZcqS$I3**3lRKAq`I1Q@Hf0dlf0rC0pMGeYFEi5krA-MaV!YRQ*!!f+U%[-5 +%6,6e6daqCk*ciUaH$!8LJ&&HYR#cKBm[cNZ"c#M3U855[DTJVcVCK)DbaSNdM+J +m,b)`!TZ8(5qL%j[&FM4pfSeZq8CUCYSZ8XA#QMkSH1VkKb+6Sa1485&'2%-TQFI +6-qA8R&cl"HI"P12Tm(#@MjpC5QJ@@FZ`A9iJq,BKLDYhcl4Bb(5@XZFJ-0U$#SM +!UGHi`'i0hpT9UU6JPP'5Z'C($9aU5e$C3e@U,b3!iaddDe@0))rPJM@E-MX1@bK +a1JQ8a&hH$AAeN!0(*M@p3lcB89faPN&X4CMB@Llf%lVZ"'88,1$J9"-AI9N[qR$ +FILm$C@TTm3B+@K	(P9ME[V%b$`6aKR`qPmpfF@0"Mf"')fFX8Y'X&Qfk@Y8c# +&b%[iZ@+-0Mer1,klhY+MZJ4h`S!cY#I`cPR4dX-ViXF,U4$pk@$h+4K-IeX[4ae +Cmf8F+03M,dZ&NrT%hG"[4F6i$5Q+10SPHQ8MDc2lcHrhPDR,l$el!h5%6%0LfZH +6Q)VZ)l9e)+["''Jij,c*FBL1r1JX9ACL)d-)P4hbSbFkpIE,Lh"Z1"@d-ISaC"k +S%`2C%[!LE38")%,'2p6G1GKr9VZPqmch"kJ3pj1U#Pq(UPCDaiMqEB8E@+DGK&U +MjLb"KKfT+kB$@4K*ekQDkja41JG4-QabSMSUP0M`iVl1'EYf(Bj$PG'f[kJYK!* +)5(1[dZdDj1FSd&FY3kBF[ji5Lqi421K4`ZX@%%dd&2J3+G-FVr%A+aep6hq'TY1 +8Sfrh6%I)@G%HII-IhJmH$99QHj-1$L0TUMU*aQYp!00qq!"9%*YT8-rih1#pR0( +dPXhh@5(FI0,*@E'JSLG1bB8GV`(iqF)dD(+$XEl&,BPbfRLNYKL1B-2,F1b"NEJ +d5DjY3h$[P@qdAB5JQ@Sh06paB4G38$Yhm'Kr"K&qM#+m4pKP554ca5"KmdELA%` +Th2SJ4K,"0j!!3&"j#"Q"8,kULG3%TYG42-$`%YH3!1%G#+MGGPm2("B,lX8@e0` +i@L6"&A8pFDlDebJVieB3Y!E18SF4kQ*Q*!!ljm0)c[CfpNBQfLVE#NAA,KL,4er +Tla'1E8)MUGiqpXkNDYI!E35dF""S&i#9ph[LpK'j691A3&F*qU,V"d5BFTZf#Cq +%b!mN405SI#hk!QdK&8!S,IS(2kq%JZ$0""5'0U1hr-*`13lhp3j1R'SET@1G%pr +"dH'TrYcdc*6Fc(4C!k216-R-6Fdm``@U#3bf6-,P%Mr*Q*Ub3*&S)2S1%Gk5-Dm +Te`$JApEd4VicfMdi53X&3Q5XF$5F4S8HL$6#82KG'M,h$YhHhcRChbF&0lL!"F@ +i90$l6@6U&CrJq*[e+D(CY2JX2I##lmfC-d1m!"1aEF6#,aKR!4hZXVGNmDMd5bT +%!KXTbM1Kb"B8&r@'3(pTX$Xbe'Y!30U`8c)-J'39,k+3!+KJ5&IS1dri10,EeMX +a'AE35NPAr46PZqYjK4KeC)P1*cQ"G6E2-f'!50ASX[8EEqZ'J-&Z6@mRhhLaqIj +[N!$C*%H!J'3kZqXGlMHTS*C-b+p'9UipY1H[21LK5Z(ZCA!c3l&5JHD$'i&'BiX +6k2l-Nf0aJ&*[5d()q+F'+#,PaYQ[FA'jDVFf3[faQ)RF9Nk(Ll2bLN,kG-liPHL +++em$#'JSlrU#1pMeGZAe3$IkGi1Lm`HpU-+h#EHYc1Y5IHMdIFm&9eNTBSiMBY! +jKAU,AX&8BCYkcrCh5X'UK%F(LZb#"UVbpG9'dC8ICDZf8l@S0kGM10MEfFH2&9& +5*4iB66e&aGYH4DFG&J+XM5SCf9dk&aIUNDUlSYp#H&92r-ek5YMP!0$"LdJ*26X +[%"H*+9lF8Q)EC1`8&40`ER)4JF4FEa9bR%KeY6fF'4HqqCRMf0-cF5bk1k`)4Y5 +p#1@JQ8*A)E1JXhQq39PiI3b)3I%4$9h5*1Zb$DrPU&f,%LU9Y`L-r2A'MVM4fh! +S4hU9J9H(CIIR&QafP+VG4!e(SYla%NFrmFP,@Al1HM)@f[DU2*9[X8T1B$lp&[C +jQqF$)2C5Kba-56fNS-)RSIaLA1$Y3IBqSQ`F4C+qD*a#aFZ,aP'U`)3q+,1+%de +!1AjRSUG1paZ6%mkc-Y[Z-,pJLLG3)L5QN!#9DZq*4eqM6GURV&0d%!639JNiP#e +l"#lfk#Y0A!cb6)hKB[-%A$&B88b!#,pq$bN1bZIJf%iH"FZNLaQSmc88a5MkB9C +4A(CKT@8m$VD4F15NMQq3!!9fE`qpAXQC1hJbjCd5NXUYJ8AQ,"p9hL)6iqQ*@k0 +aRjU1RQ2Sp("8pR63"D%HYdc4pKU20VL8kPA"&,$4S!!pf+,8!)'b62fNZ&'eZ[i +6FR#-@!i,+k(M*j!!eQ#f0,aVS9ka9%em205Yq4c8`[l1XpfR4V8UT3!e"IFJYHQ +X[)l!",[1m4)9+hECFHKT@RLX"($"YHUhJ`PdQ2AdNGRm"6IrXrD)V[I'2c+'pQe +a8L"3p"P3i9%p$1H4d'i5[c*KTQjZCVpm,`QRkL#k3fhql*-MA+Mhm*MU,-5L1bj +*&#G'kXJa19bN0$Rh-NcJ'3j))1X&"3JjT$mM05J#02'KB5*%%c--%d'DD$4-H'P +L(KH1ETk3!'cXQH@ADij`FTAP(4j*(N8NA6V9UCNBZVfhFc6bZ9kChb"PUSNF8ii +bUm+9HAm*8fC9Q$,lp-UmrkB15CRq5XVdVe+CIP,QM("P$NU#H#0LG9@bb@hLjXY +@(kN4jM9S-#m$mcXF-2GX-3$QP`FR*NF48TN@p*8pUB&AR5Bb+jIk9G0%bp4X9fk +DIP!c-3DJIdm!%e-0Cr-L)#bie2I%i-i)pa`"iS83&9Mm&j))qVb!0`jE1-XQibT +BE2''E+TqN!"XlfaXQ56kDDRD*N#VAKm-V[C2ST(GLfUqZh2h"!2*898(rDbELLJ +9,ccbfKd,HH5Y4-&2Lf%HH5LL(cK-N6Il@,DK+[G3B@2P$4XL#k"`VC8+$KDmk`f +QFe8UhVicS6%SVNK[2Vbc$&4[KG3`5+cMKBA(ZJj94b'T,laUBSLf-%56U+B+&H" +&PQR`J1#)Z9PPHpU4EGr0`6!A-VD'2h%p6Ff#,TVbSb%[IX%V54f4,ZP+HX%#9RX +,YSbA%K!h1)lM1MFh(`5@QbbaqDb*8H%B$+pSl91X`15Gh8R0m*kiT"DY-8%YI`Z +e-*hdpdiDi&K%cdidi8Q)'SN-4r9%4@6)l`H`,8Z[8'JA@lA03$H+G*T#mISmVTV +50QkMN[TaNH%'IpPhMKZ0&h+GG"8c""5a1JX459+0ZHP5!Epe$-UMcBa4X5`"8XB +hQMTd[h%XY+-#YJK,)+B$!bq-ZA-4XK@E1RV3"4G%64Rp64eN%YX%#CI!Ih@pJT` +aa-JCHS18'VNN#NdK5C3%*KP%m@V&0m!ER33#-d,'N!#@N!#KVl#MK$MN,%HP[A+ +e5VX(9G'SeFp!X"+JA+(I#*Ul(USH8@&03Cea"I,DLJ9A-Yb9))*M)5@!)J"!CHZ +*aj*5d#Ne8M9*SJDd6@8'jNPBkaXB&HK!%T&,5kYDhm$(*Rbm8Gj"cIbB"'`SA!I +rm%"imaq!4$P01Rj"#bl3m3YDV'U3!1RTTd*a89+XC"F0aeC+6FV+E($mf%3-KUE +NGrZ(9Y#5C0G'FHdi[cCU9@X0*FLZ8XGD*)+B*2jA965T9c2)F1@d$eFTH0d+"#p +5#JD`X9VENBP0DX8QZC,mR!cLCQ)VQ0KNR)[pQTSQpH!qM)*"qdbB4kY`$dI4!%" +*JYA#a`52-i9l+V2KNL*L-!#S2b@&-rL8A65&LeVj492m)Z8P8G(+,[(%+J'$dJ9 +IIi4HKJ'LPH'`pEYSC08AlC`HIY%(fSdB`$h@c+jaH[JeIPa$48'5LBl'+[40U'G +Qdi38N!!1p3raeK)6S0B')l99L5)bmCQJ+4D-&1L9A+8AKL,cirkKX"*c[93`[QS +92&S4VS+&r*,95[reZfaUeCF9bq'AIFc9EDKr@E)6'lV!S%3a&G6!h#r5a!(K1*Y +M(hmekK2rFp+2K0e$NDTB"-1j'He`k!J4Q,DfI3S*11a45[Jp@M8kG%!9Xd@Z4+T +',id1aBJYb0N%CkZ3!"+)lklD6BaqBYapDII3p,0j"(Dfb&8f0c+c&!P'9YV'&%J +G%2Z&c4hTE4M-%[i&(M4re9i[GpVPLC!!rZHNm+ITNb'"FPF4'!pd",S#Ji(4`-Q +!-E!RF$N`,p!8Q"ji2h"(B'1J0&!B5SBmSIE3TT!!+D3*h4[+#Kd)eB@q#VdBQKf +U$pd4fKJU$48'Nm(aB%H`+cJB(!hDJqR"Sm'&`GTJ3h"QF'j`Dh#R0q49Ha2H6Gj +"lkMAlNhh([A@H"GiArI1m-laAZ[Gl0hPpVY(h$Vh,,IC[GZGi8ja@paAhBqi&lR +VhAHiRh6[m[Pp`ckGEjD[clIEGpjh`(ICYm$Ai*[TQq[EkYYCjLZE+NZ8fFS1Pl@ +9R5ilAlDrV+TXH9PefHbbqV*TC6HAh9Hfbarb9rK(r1hq(Il$ISGrYrrN9+(i"ra +8M6iE%f9f0Mc%KrPXq"SI1YM`Th`iaSBAqE#($ErL3jN0(q($&MDmN`qpE&K03pm +Z0UcP`meXq#)IhX5'Ar,Kh@ciVhci"4ZqaBF0E0M-Kl9Xf-5(#pQ`N3q2XH%52Na +M`m9mH)i0AqI$%fbiL!mlfI"Y2R5aiFriF!FErT)2@pP`0Km1Xq%,I1KR`qNdG*H +`iIrQ`iIBF!BI2Xk'rmD(FpR`2rK`*KYq`SF[B,N92aC5kQkD)J838`0R@-L'A-A +ZBfc)PHT1Bd1Z4[FjKDKD,LUI-8J)k`hJ0h`iaPjb"EPlf*!!4i&ECU+UY+)U'!0 +AK&Z`)BmLlc1-rDIk,AJhXUZ1FBBlf(!q(ll2f1[`Xi#ccfELH(4iAe5)Hj%c,&G +-r5ZIXV!Mh*Lm+@c))m+ESEMJ+'H2++BZmLQABZS$2N8+q!NTM`Z4&3a,1)0H!G` +-[AS&m-J1NJ+QkC8AI**YGaNIAXZ'cr(K((E`(rP`"K[bJ"9mR3fjq3BA+&#B4bJ +%,f2j(Rk@FiBp#UA8FBBXaC&MI1Sd%mN$5l#0$EN4"JmVM'8CCpr''(M!$UjNL(1 +&"09Xq#`IKYM`EfNBfSRP2qX4#ch!KLrai6@+DekLDd,[+DB@mLPP!(L%6p8UTVl +&TfS88r2je"l&e(rbU5b'eXrjeIFbKZrLj`TRD'--A2QK``a4(M%K'f-r3NE2f8N +"Ib$ceaYe++UimYpS+P#LQ*V"TcDcBa5C4rM8YBSTESk"paA(lZ46qJ$!83qmU'$ +J84pBVTML35CJ88`em+PFYVfMA%L-$Dr`BB30Mr"K(aYHiX0CE&M(KcSfr*J24pM +`+Kp'fI!$'SSL0Vc-Ke[BN!"(1dH0KJ[jm(UQJLp*qB5Xd"H!h'6%#f`iM`qAXH% +hqA!q'riR(k+,'[%q+bMfB[&2V)JaXJ&99aP-Q963jl-A92#dX3'*FV%"AEQ*(5" +$d,%Ahm*JR!d)%68E8$AURASrmQcNNJ5Fj)P[fcNimb`Pl#@ATE#%dj58+N5*N!# +mGNU%b!'BQ4b!ZH@Nm,CTNe'2`h0L0(JqZ-"VN[i&Cr2&L,F("cY%J"qYjNIMk"6 +['Zh4k@+"-!Z0Q)BH1kH*h5*GR"HA4D0i%F16BLD5)4c!FTV)&FI%#6&(I),"FY( +!*kH*qF0MiNj5,"De@"c&iX[B!AaHM+AMXbb@Ldp6l$`qcE'6q#b*RF$RpGKZI(i +@dq$c3Xb"crq1pH(c(l($q(`5km+R2VB$RmpLfr#C'@[(jrXa'CmjX4&m2Sa0i9- +BUm#R11E(jl%B[+c95%,T0LXf,B&lqdk+N!"1#qiY#m`&@2FkYP`(YqfD`-eLIZ$ +$`,@"RB'YJFf"dY"+84hb"8T##&LL+E3b8!2!,aTU%3fKP4KD4,ei$UUi4X`9'`2 +ca@C4,,B!K23(21Kc5!lS`'3,Z!"-QJ2j!8hJZ8"ei(`J"U!bM3[i!XM#!6``$iX +M&$La1)S&+C'##5Qa#JY5ib%X8V!iKX8j,&l$JY4BKm9T,(j+J41,+eL3!"S[B@( +#!Pd-"TCLm6%@T-DV@(4Jm3%@#5aU+("LF4',&Lb@Bj(%iL8X3PJX4'5@B2'h@$b +$a9GBh)I&GbP`BM%ILjZ`3*HEiJiXjQ(a)4EIT-#*a50Bc-$L@eM-aQ)"&SeBr!D +,@LcH`S)8X!J,8X$Ec)LqB%EdMpb)rSNEdGhFL2k&'p'eh)LZi8Ed"$HL"lJ4hFq +0D$-hSYpb)lU2'p'[Z4%pa)hSB@j%TGb)rX#0k&IFL*lK4[3eEN3lp8B8p#,Kb-r +JeZj6MiQ[5blVS5d+`eVZV+!1"[MJ&5HDpcJqMB[k#4GeSej8D!C%,@HLhQHLPLP +%(A-Q)-V-"lIb35Yqf[(6JamNY(,+-4Y%lZ,Eq$EIaU0m'b9m'p[j0JVij8AmFTA +fmX1i[*PGrZrXmJj-@YMN[l(*BIj"JNeNDD1i#AQ(@j!!I'BV%MK9SkYUS2VB*Bj +b#)QmJS5Uj58Nd1UBT)H2G(a1ReQ6KXrS+ITi*JdI-df*'Mk`d8GFTQ0LkmX@cYc +cXS@rp%XIVS`2UGXh@JCA1M2iBL-jUI'$,dS(4"@1TqN(H0AfXZ9l&QF+&r"rRI[ +j`Z2X`DZPB$T-%lFm!@Bbm(USUTSCkVmb3feNKVUB'@S$-p6Cc&"rb3ae1M28Rh0 +$IBiEkJaZU2r!$I@IZD'qa`heapa3jh*$[BXEkKhF82r)$I9kEUKriSEkhcb+Eq* +4I$12i[r,ShJMMq+Y2)Vr&irL*eN8Rd!drF'ZU4a*d@H&H2fSFaYI(('ZT-@ArqK +-dU+f'TRH(JMC`XAqPBYpR)[p#a2ViadK#8AA*8K-car")T%+3#B3+hNh&P&lP,N +h8I)%'h9h)KdT1%E1Rkh-%B3bHJE1`39prM[Ri)lq#"*demU1fV*CP1&lEI5FU3m +GYIQ-dkJB3GFpIHLiai6N-4hLX-l#&chY&NVUMXl0(d&LH$KH&ab$!pJbkQJk*&5 +02&(kE"Tk"AFb2eBGJ[#dD+jj69()RR,GKh&06j'hVFF[#ZECFJYU%rl4)qPVRfM +Q5G1e)TeH*0&[4`,'BqCkUPM-DjcHrG0L,DrN&L`50YfLJZRYL`TQNaUT1YHlU&* +@T%HQa`P9)bF!b4QI48,0HEN*U2&DC!+3!(-SUEF)"*!!(c@Kql&BK4cmed3V%T! +!bF%lXC!!(IU%D3`dN!"FaTV`+SN%b'V6ZjbiJfj[H')U2#DM9G&C3p6[3E3K%pc +[[$I"ZQf)H9[HT`l[d&P--,&fTX@q"3kZKekYbKI'H2dKqdkmfS%Z*,ebk,'k+SX +F-VY-,LckGIdhrV-ZqX[h-kENQH(rIRChjN-J80X-"L12j5Lkkd*d*+Q,-(SJMEk +M,@h(6jZPlLU3!$LeG3+G[lhUDUh$`-m(4e[Vd(e60!FGVP$RL0qZbqq@(HM@"4e +PmBRcqGfa)QR$hmV1cNM2cRjjachSi1Z'HdiHcmM16%[00**riq"qUI0@l9@H$48 +rAbRqlm)N#dQBP1#%NTp`pY49XUGe([c2"mmI,iGTL,Jidil1J`Z86*8fa6R&kJT +XkIcG&"Lq4EVVH&C@6LUl4N+UTBpB`e(AXJj*DYChH!)N9Nimr*2@eMTNa5$KkhB +0SA+L1mG23`N9C8G+G)J6)SRC,"hPRC(id6&%Gf9@5Ibd"9VaYJd3Vj11AUIidGp +Cr1KeLrqAKr6L#m4kL-HV`Q,T'1qS"4dTj+p)p(iQHNC"G,e%cbJi,"d,&dS&"K, +lI53DRCl%4f+C(+KT&VA26iKDZ4p1K5ZI0iX&Ub(3!9'LYBiqB'V&JpQQT'f@A,0 +LC1"iV#G",bkC5iHPC*jk-66%G9155bm81m+c9TY%,9XXSm@Yj*VA5%Y#MaeD`!p +4eh%@L4fCY,LQm$b5ha44`FXQDr&`U`9iI09)*cSdJlYUNB,Cb+Xjmr0JNkjLD0q +REkJj1U#NT+04e0Up*Jcia"5kJe`3D43,IU44U5BEH40T2TK'l0a35MEQ8a,a'L- +p6'@RqC`@V8*pKe[i88%)8*T&+"8b*U0ML*ccNFcN4ZHJj%iVPZAMmA&)[1N`DhL +'lq)5**AIAXHFlKq#@9SdB%'QF!6+jae@5Sb2&U25@%N2DQ&GJ,&U(dlL'A*Q5NT +1LR`K9qj05aqmN!#9fCpV2*JqQBkAH8ZA%S[Z)b(H3#Q`G+QfA(VMM9l$ZVpE-G* +Qe$$e)8Q1fUE[XUqGh"q3!"#JA&AZS+lIfcY%lA5`C2'1i%QjLGZT8N(@2Mjh3G' +dZ#JTHKPAG!ZkQ&[(PEfCG6@a(0dG),%[G6!JMT)JKH*,p"d2@YFTe&kb!V8r4*Q +e61epA1fl&'VIaGfI$@V29kKpPelYX[3302m'+$cer2'8MQhbQ3X(-V262pSJjDX +++9Q3!*4"*P0hb$9`j4l(`qjQ5JNEYTIQ5mK59b&'RR!+L+efaDNcQ5P+b5a,5-d +69fNcNpCKmkjf$L3k4eT[id8$3"d1V%5Y3CiS#KRXFP#[!!P3BQ,SH&Hl-+UQ8aF +V(6mD8UQBN!#9*)3#"R8jT4Fc61El,*P[Q%#!)@'C@`D8d,N$)F&8iGHVSZ3j548 +P6c*9Y1K9)623GRh8`5lfKfeL"cT`iLL[GQNIZp6i0lR8%!88N!#BXUBqlqE1q3U +9YmGKqQU1S"4*-EV+S$3)5L1R3%PPmTX*6H)#XJ%[+V[,Sm*E2m%l[Z9*KJcGjQQ +VJRCd,1JPTbKdM4XeRq-GF)p6*8#AVU"+UR5"SBS5J`k4hffA"X2jh5K3ND3H`%c +SiTc`lKKjN8+2A[A+P"JqJ%FlqT9Gr['XiLEK*cIPmUV2Re6VUdmaFYh9*`lei0$ +*eMT5KZaJ(Bfh5L+qI[Nk0U`A-X*958@9Ile"M4QL48+h%T!!)@A2Ca&D8MA+A!2 +p$,QNS4"Q+TmK6NGJTPEUc,D'$*&9aBU-BG&",bSIecIrC,rk4MXHdUKm)@Z83b2 +Fia`HHiPbdUU'`%e--"VrqJB"KP1a+!G5&dXJU[kBi3&l*##r,Rc6US8V8&5&DAQ +iNK69d'D&DQ"Bj9r-,QJ2QeMmlIQ'aeF+E9*(rM#Tq@5Z6RpN#44aHf`3lV0TP%` +'R6`qd'SQJaMSTSS'"N[UYr(UD59RiP1&#bR!8XFbhcBbK0+S)6JZ`KU#84b"%J2 +(U$')kLR+#ccDFY+`AIk!6fhAZ+d[@9m&`eId`,2q8TiSjcB#*TN+1U8!Ji++"9i +@F0X"b%AP&KkFef#6(GaX$["Z9R9KL%P"f,)LNbAhLYDD&88(SMKB[iJRqr2[2V, +F)JF86&%bjjBD*AM+NdPMdbPb`j&-Efe2$&e%1T1*Y5hA6&VX*BN*Z6r-*-p,P4S +[T0GT8B-+9FG))@G,q3X+,N`KUX2P+d3ec"9#fapAGSj)#'N(%26E1KkSp+CGSVq +@NSDU@JbA%ZL"4&%E+6$S,bqD@IlP4I2SFR2H6li[48249M*[UA2jpZ`rIc%FMVC +SU)bfQ+j%@m4@B%+E'0V[-q0T+3pYI66[U&'UFDj&UFBrUe&a*YrE5+,i%0!XfER +0-2Mk[BE"eeC@,[,RUX1+I)"d8T(rKhRAU9ab[TY')U6L@9%!QDqVU'D&XD',fM5 +95Z'ZYVK%T`@Qd,5"mp494A(H&4BBG&j[dS)0KK@TdX9PkXV&G1%AUdfp[YV822f +8e)Qc%[3U-CGAeFj0eeHek#CY[DZp4mHPSkY(1"jBS$B8b4)"XTfk+@fCAT84D[H +L`kSCfapT&hL-ZRIkSIcZM!J9`qhRb196$KU-GAZASVKE*aRXpU[DJ,41B[ZfjT8 +Ki586MQRdKA4XF2UK9*0Z0C%P$bK%XZ*cqjK@*!ZBZiVd)T8*h282Q99@0P*h@3d +!JM*p!),3M'49$#r1YKpY9e3b8L@arD61,%G45E6`LJ-A8N96XSXB#CKbd'2'"kP +c4`Vm*6BC(3+LmF+,$5Vb`AbjI6Q[U'4qe6VTXUrI9dj9GEZb5T!!*@3"FSdU3#j +PmBdQA,r5c)%%J3BY"**)"U6D'#B1REj80VqLDa@ZB,`l-A*2KaYB)%diMZ@-@j- +-R29dAU31c*bK+mpHqfbNkVPMH8r+F#AcTPAZYS"AG'Y`B%DJ4#Gd!+TEfcUQfYd +cUM6G*p&ek,A,TeHP&ZZ#mjGc9R4a,,',p[EN9kMiRhb@QTm')&S13RfHm+i,T-H +JpJ"Fl5KVki&,Eh5E@pH"VUDKp[R(5$N05(L988&Jr9G)b04@CJ2ap+Y$FXXTG*r +if1*YlZR(6UkmpPP%NjGG&HfmQ2$L-6hS8)k-2(8VM#U+4jZV$3mc03$+h)M819% +*p!$b#8hhrX"lMB,qH)(SeMS8j@3HDMQX)h0pKff8H!2'9a9qIEX!dF-[0AcXJe* +LeLdqeP3qcj[+KBUQ-LGe+*V+'BUQFU'fU4b8b"-6$pmiLQiSE1Jh#@TkV2PCS+S +"JXrK"eh5THP*j4HSj5cEdBD@-h-ccXJ(Fc26M*QTkCNC@ErI8*)&+l+J%1Vb%-T +dmD'kl4b'ILZ[SLDTLJS$ZhM9j8Id460mY%6(TceDm-0!XKhQK(XG&ArjBF9I1#" +U%,Y2DY)45D)kV)KB*&8GIr-VT+-mbk#&AkF21[l1LbFU&lPrYQX9'hYZa9G3pfS +dV+p40Yr+Qjaiq(UASB)0UqBI,YQS''a@$+k4M[jT,2bSSH)ZILKFe(DK'2J9!ip +#E$%*L'ZVld"22RpXIQ!@,F+VG#6Ii#Vm"C&iGi#)e@VR#IG4B1r!NEi6hAKUqMh +iS@%&Ef3N%'M1)@JPH0"#iJY4cB*5Kjk8)+Rj3XkCl*2(cf6+pZ-AXN"`)N*6DPE +QmC69!`5Id"pBZT5G#!m3(!bk[M5miIZVE9+&rX$#p3'$(TK$)XTVT2l+AVQCL53 +i1l346SQ8m4!i*1$h(l@S!q@pQ+Pi`36FS`Aqq4BS5Z)`8p8L20Da%!mD$b0q-c, +bMR#8$D!ADe#dVJEB1%!m$2'QE3SR@@cE0bB,l@3Rl`Te"MTiFe(Q(FLE5)U%!M5 +%)V!DA@hQVNKPP%A*(hc(0fF,fa`5T@QlT@(G2&"$i9Sb-'+)Nr*Q&+($&8-3d3G +@8`[)V!'HT4!LJ%',kM2F[$6DL6YNIhih*fT,%c0j`jfMVChm3QVf6RdLU&ZCqB5 +)rQ9K)AA++UV#*MGMdULF+QU4!NI4$UimRMaCqr+F4#SS1Ra#HfA"9Vj*2FZ8G,a +J*dHN`J#DN!!T'KV5P3SaG&)C4Kb#ZYj8&#AUmJTZ,F&QHp2US1Z+#MN1V#!21*a +N4Jp*eT)SHAFKQR,*%%T5a4qb9N5U-*!!5"3N[(%$#FmS9LpbYiF9ZC%QhNQ0IcA +6RN,41-)b&-Xe8MSfLH0fkY6'6k5j969HU%*mSNj2%,fVAX'X*0V@Vc))DJ(MbN3 +R42fl,0((BPADUK$C%16#,f&NSB`9NldF0ACrC2(2MmVdSej0TCi0)M31'jMc9m5 +XIiJ%-Lf3!094B@hK'5#5Dd!dM%"3LG5U*8`V!I52K"GUZ"#Q!UkDm!Bj2k`Z2k+ +)R2I3i*0e+b#Xk6GA8EjC86@k[CLUd8+rBU"@$)55F*!!U#RAG$GFdBX,G#Y@Y,j +j,@CTQpH'$4G*64J`,#l`Dl60l`*Aj5TY4@LUdPH98EUH9kZ[qfUH#(4+bL,N$Dl +G'ZU8[jLjqY"4)NbUf84d"B'Q-N'i[)KJMb2!jQl@%LAeei$BUqNfA++UV8b3!+K +mHAPJS3%Ke3(&&KAAU"D&AA2hDNFA&mLV,",d@h[jPh-9e@JK5m4F5*8l1p5L80R +5X!$eFS)+erj9&QND6GhUL"5p@2kf`T9AC+p8e6#e&heBcRDl9U$!UA+feX&HGLQ +f0PbT'(5Y,UbJG!@4F@mBfUlV3NqTI'A9[&Tf%BM[#BA6QIcb'fh#UlZBZ24Z[r# +fCqX-i&581T6(G@%&@9KNM2e2*H+BV&ke-C3Ab9*#DriJ,dNPZY8$fBUL2c`59ad +!bJpii8&)pIi+#+JH1YjDm`TB+5YJ4@68$51ldKpmScbJQNeGr,e#RG98ZX5kVPf +IM66jaJ@1"$lb5mT($T@*(UQ"J%iS@hN(eKf"QijZ2E60r89$PXMd*Yba8+YE$Y8 +F!H(r56NJGBPQL*C@1Rj"S+YY'r`*(k0+68H%"*diUL!)Fa9+V,TE&iPA296GU6F +5qqiE,#0K*#diRC4AU'l@9m%Sd2G222br2L4AQ0pZ3iAFq[-j)(TZ&KSXKQN5JfS +-Q'Y@`@B8p%RR$K`b%A%6VmGPhJ4RcDYaBY[H"*!!ZC,leZS1A[U+h[,r+RfklS' +VeTN,UGP%&MPjd*lpS0k[E"0j&@5RTabrN!"q"Y2C"XHbX-eXIAqp0e1Xhmc@rd1 +E55eh-kRDc4K!)b#fHq,KadT"N!$edN*6PeqAL#6UfL2dq+',rr5Z@5`P02"!E%` +!E3rBVY+IPi3reFE"(B*SLh01G'mSXMPRZ#I(G5Sq$0R6Z(irA8q,F'6cPHJQT#N +&`P''F24h4IM#li)`P,YaTU6FM62A4lNEcrmjPEY"KJ$PEY4)bYfS@9rPFS6rE-T +G$i6ek#ESFTCK`UpPB'+PDrQPpi4Gq[IXdT`c'hMKBeIrTKHZ4b'M[p$djbNZ1%* +rTd4Sd`d53T,1ekHi#%IVce%JV`pDUeD@fNVG%(BHI#3M*r["#aQCZAT*ADRT[cG +QJR&S-&ASRB%mA@`$IFL-#V@2$Um41cc"&2HF)`k[ACkeKTceLD3Z#qV#QC'KZ$N +A2CGIMMRVZq@e('DEZ'H$LVCCCc*cde0q(qD'V5IhM8XAEFHI8P&CP4``NC3hjXa +-Kirala#T3rpIAV[#,I0VShLD'@A4)I,3853qDq(5M3M-23j([`I,LF%(+3VT)@q +cV1LbD5J!d!C*$Y6m$d2!3l"+X`ihq)AYKrK6YZ+5U25FV*`(-e2+Nl9+89[+%AA +3D&bK+&idH2QMELXii%TrU)"a@#+j4Y1%*cM(S[B5-(`#)RAFFFeLJp`,CmS4+CR +2$6CTLSM-Qr+1RlRY`8T&N!!mmI!6ipbChDFJ2C86Y,kV$&RDLbJ+b"dI3AHTV(l +CFYIE)"M!LIh!U(,kFqf,rbUArEmDbQIIHk)bX[FAVJqbPRH9f1ki*rYXCQjQ#U` +U05FM-h9r1M"(f9P1J8aAY2jCVNJ0[i,!D[bK(A$L!J!m61Dr3RFD)K63&DqXb)T +6%EfDS96mRkT*CFA@+SbHq&06bd0NDVd3HAi&TD%"$id8T)")P2im"'41@T!!!%9 +&38%GR(Mi[LaU"Z$b`+U$9#SVAPFXkYIPL#S[51P&SB[bJaBGq2+1Tf9RCHBkdmp +R'dU6X+M5&f(&",`-d%-iLRY,9E`$6LK-6Bmhj3ijH$`!$jK0XTSD@!`!kF%Peh9 +"C1L#T+p6@3be06Kf21["ilmrNjfEJkl#pkm51qP31`kKhpbF$232YNTqBa$X!f! +rQ([Qr!9lqLS`Zk""(%Ci0#)J6XP[`d$`CdpJiH&LGP!KNlY+#AaR%@i-6&DjSZk +"U*b$k4XS5e41r($r94j)eHXEA"H%*9[D9%iJA5p6HG#JhTHlHpi'X))r"Z)L(KH +)2bI#+rq`S5l,1r(I-Hr%(c#%H9b(B6aBVQ')p61-"cI--"lF%-0iX"c$U"`&Qmp +TSk$`Ea!&LS)B!!!`!d&%3e)$!&D`$e8,,#N!+Qec[jGh@9G%A&BL)U)9%G(8M(( +-'%IIppepbI2,b%c06%(1,4J"`S*QTXqlZ`)LRXh8'M1RF4c(DFbDaM'RS(%FTm` +m[aV(2$HH1b8cN!-MT19qRJ9F2(I6I2r[ZVl[ZmlcAGF&'ab""%%3"%'3!%L+C%3 +VeYA9r@Ep8rTj4l$i&@M"-f#1`jb'k3V$B8*K,X0dJZPlX-ec+UE*63K"8H6*hDG +bXi0(@j,U0%2kK5(Mmp@lkQ3M%$f1re)YTPmRYG-mdLbM0RSCIdmp3"mRcG'+T$c +k)1P6EE6d@f0-Y*R29'FB*G'2m6qSMp"h5BZdE#QGPL3Yd"kAPKU24QIaa@ST68p +k3hYDqV2a9(3CIdfGBRLM$r+TDJ&05jUYQD6"aZRS&qVi2HUrkHkNJ9UPG)D'*0f +[h5NpB2`cqL`IT"kPQU5l003$id6d-@j93icbk$raSHTYG%G5X(CFDU#8T)He2G* +$a[24qrK`GB4a+[SjIUpkNKj-'URYPqBD1G&lq6IUEKU@0%UVPh*TIY*#lC!!0-m +i('hKN@SR)c`kUSirSbE6[j)kDcZNCZU6p(GYXr4()bJkJGqZCP#rT,pUldKr-r+ +M-rP2DRpMBr6Vr(GU%rdPUDr@+1fLRNNrehk8AMAHMVl!HkZI'cHMEr![e@rT0dR +GYB[5*iBl1TEr9pe#rdKkAdZ6)UK(dSGDM25$X5QkPIG58qPbdUelY-qN!FCAd5[ +j1E@EX5*k&Ap#rCkH61UL,CGH0VC&Im6rSqkNCj-kD0ZPVG3qk4AY6DQMm9EdDYj +9$6@14'rJep@eG#8T6&XMVD1V5CHd,k4VaYI4khQEkL*RdRP0Pa+0qk,MH,aU0j4 +S"lGC9-QQ*A(0)YR3p$#8rJE*0)i1d10dJQj3R9%ReifV1e$hH0f*1M*lDJ[c!NA +'Q1*PmZKa"e4lmBc4ZVEDV'X56,3jML2Z'UGVc`GdVE4BefTKXQ!HJ4N0T!NG#cV +(`93#-f1-bcjk4Uh,E[!mPch!4l[XXV!(1*!!ii6eF#`KF)AX9$!I%(DFX'2BhKQ +eZZD"C+03Ya6UfMKCef52VTQ,*52k$Vl-mXI%P8%a34&T33Q@2dVfVpbaPZEi$@j +,3r+H&bbhfHmmLH!mEP%cSL`*jjSb,9rp'1-1HLGQ[f9$C[+TrCC'LeYV,EFmGhL +,l958B'TVbScj-HB8XVcRQ,#`$HlRPZ9Pdl,l-S)XQI%@06E'hC5Tr+p!RGV*qBd +E0bd'pqMF8#f'a@-a*,Z(d&0%G'JHXKM-@MbUc51ZqJSHc@2Sh+0D22%'#Da(e3` +2j!Y1b-%3M+Laj-%!aXQiG#"aRGM$$8I&FJVhX"eL-B8E,VB8dd#a3CUKBKAZFGJ +p6#"R#U*RKl5UC6MMUMlQH$'Y9NXrchSH&k3QHMKbF8jFi9aeSNmQeh8,0j&!@VJ +U"P`BX0KK9@jb*6)'-R%e[S,4`EQV3J!h+6D"9VR&TCQiNPLahH63J!TP,'+hHTk +YB&,Y1&GXJN89+cK#fC)3Ee'iKH&F6LB%DkYFU%69kL@b!CKGGVq'Z,BIaV6hbe" +iSF9X+A6CcB9N-8YFZ"V@86@"8I&[0e-KmP*,S3dp)(QK3qc5a8EX9bf&NQBZ9*d +3B5Dfh9iSHLS1a4kc)PJj*)&$%C)Nj-aLT0S+Ui4,BTQiUR8Va)!&qhLeHPAm6!U +L*YCK&L*9SCTr498Sb!X9aQ8afrbDJ95Lm#fD-%SE)a!q8@N`!JmS!MNe4P)`F-d +9,mijJc!8&NJVk'H`8RCJJhVH,d#FqrZL609i*KFLVQK8)B('5cf#&C6VIRDffbQ +1aq[Pp'rQ@X@UGU(GGBY4TDh39,9C+JUc3KZrI*5fJG3,SpS983P!CS-N44-Bb5` +`kV9#k)-"JB-8Xf)c#aB3#cQG+R+l@a)lmCY#0X"Z-PaF8Ca-[-)9KqBA*pC4l!c +TAkG0UC!!cpC401b1&lZ!mc-+P"fb9E'bSTaRbl"m9SAFke9EQIS-(FVf#`HLf[( ++i)!b&SXNqUJpV%Z5DVI!9Ja!MH[Si)d"&P9--VRLr828$X%QfF4!#B8-BXCPNCJ +Xa5kKCNJ5Yc#V#,'1mibR#Lq@J!iQS3d@FrSAB4JQ3f1Xm*!!5S93PdhX9e!cE@! +9H-ldU0,*8E'D)l3#Ji3QHLa8k#&cS6l!6+)$i#rd@$#`L)(`S+,%#Mf+6E#+UJF +fp3SlCP[K@1hBSYUa4@L*J30e)C6*%I)Ff1k`#CN!CE-JfL@a%M1-(f9ehLp11(6 +')U3*'4AU++L9(K5[Kid9b,R2b8BZ*d-jl%)2Qa#+#U['3jL*6"*c8Kji3Sp*BTl +3"$J")H$U*C0($4-(j!(H!hIRB4X%a6dUSb%1&#IM8+qc(F+B&$3,lR1bNCm*'BI +J8[`4KH84CH"`XKe#e(Qa2-(PBJX6lprZJ'T-*dHSAa'UBNJ%QYK4I)@+b+$Bb[$ +aINj&V)2-46jmUN#l(qmNprG9IM)1IimQQViV1DM9M@m)KqQ`cd$IjBjVbJMDN!$ +C'Z[qbKd4&2@1HX9R4!ADV+X1Qq"4dHrXZ$3"Zq"SVr"5a,i1BeB[G+*pF-DXk8" +I3(ma6,#ZIIp*J9E6!)1AU*VMUVBU"CdM-+Q#`FY(UYU10KJh$$+V&IeMh!Q@mY# +J+T@KaRY((GGD*!P+[,IHBEbh(*dG-*PBjk`kB19m*5VjpFd4qE'C#HZEd2$-$)T +3%kZli'c[Z+3Q0lTM-cGASB@Xfb'V(cVGaF"iEbE'mHM2KTQVDmXAUApjDl8VbKd +&8VL$)Rb*-5P+d-*Kc2%@D(0ba-#BFaVbDM$'Lq5FpC!!Ge(9hJT@%prUN4U4[cN +Lb"*cDq*Lf0BjMGKQKqQ'VHQUYM9DI@,VNI(DI"(VpLR)&N2XqX"aDb*m1*N"dC( +S$")$if2#Z%H"pV%C*N[A[ST@Y6HKjjYR#ja$)eQ"a'INEfj+hKPNLG$b'5P"riq +2JRmGc&CGfpC(G@l2C,b*'8'CQpf0JYQHc`Lmh[Ki+rJM`1Z%k3Vq#&AERURD$V- +YcKe4#6ZM,"Rfr16$qN53!+Tp8U$iH*(MZLp!I$`F5`a%"l5H$6HqSk[U6%kEU2+ +#GlDP`$QlNTfhjFHkGqBhlib)bY`Fa%3CXiq"*3k59X0Nk&VbBM9aHfC9J3h3di) +bh8GM-f1D0QIL25JM2h2c-3LHl64QGcC#,)k*TH'U'K%6P0Q8A29eca)6#ZSi+JD +hmL1B9&G66'Z81lQ4!HEX5'0f#$5C9D"0+i3T-N+J8-JZQ(#B4L1NG@*,D3VHSei +*LJK+m!@TPZ!eECYMSQ!hVG&K6'Y&abi'aV5V'+1b6ZX'dpm)`EH2N!$,"HG$ZSj +Yh8YLhCF%bQNMaJ+8dfSFaK42J6DP4!b-+6PB'ppITZb(NBb3!,jBZbG-G-%c)Ed +Hl'Qc61LA@UCNLV[DL8d*0DC`jTkQ)$e6%Y""HUBJ260mA41%qlLQ+IfCDpS)30f +i&DDji&C)T*!!q&+Tie0G9DY1,61Q&V&9TfCKe4(S`"p-2@k%",GFY8BUd)D@q&H +GHYbrkNbBAM$GB@l(1HVP8&2"Xd-RiQpD*RYUHf0U(iFa&38ep5HBhXC3V$2dH-' +!SG+,F"K6KaY6Jl(rY3*Y1X40Vc@'3UfKJ,UKi3AAKNDfA'hkIQ2kF@0SSc'dpHU +',mCAaNNVkr6`PT9eHU[$Q!iiRQiA!f-kbQ8kI2PdP-[drXE3d1UUQpL8(l0c4e4 +-%'TaFe464Qb%)#lErbikLf"'kGVV(94RIJREF6iM2cN+A`l+RFe4b8&Z`@deh[$ +Uer+[6T!!f$IUM6I1'N0R'd-""N-M&6j#i5X8(Uc`AbMm2`Tr9Z%r+Abr`[qUm2F +8RX1`II$kTr!5KIpFiFmSh+l`@)8rc,Lr9hLc`MFU2&lKQa5q@1&1*V%E#mq`m5k +&rd2KPBa29[K#d3EQ"8`SfLXZKGY8mEVTB'GC#Kr-a)(lGB8IB(Y1-Y46#RmEE3Z +&$m(l)C0lJDda6q(h+Vb0(53UI+h#rkl`q3VIS[!3KIGN,I`4E"c0dV0(%DpcZjR +'AS9(XT@Q+IbL`[-8IPhKhc*"lCL+53Tr3H&r8rKaTNUM`Kp4H*V#Ie6i#B9rTr" +I-Y3CTKa@6DjDVjB0VM"&XIN*KEqLm$mVr*,#PbTmS-,raA4UBk5rMHRd)91S31& +&,,8+5bF+Sjh#cbRm,BA2C%Y+6)-%KAr##L"Ei4d8EPAi6S8(&(j8i5UMb(5&peG +i9jCJP1AMM1jp@GUQ+,b6`JH`ihZCVU$qJi`klbVm)CD'KpNDKeLDda@q9q'V&,j +%i@MbI+c`'`Vr4Z'pf@,$fImCTNS$)`d5Xje"c$T'eUX+Ame+#i[GBRTJl9HV3'3 +$Sq#2,*&h-pB[&,j5i5mceLf-q[XBiF!k@q%G&Iie9'I&%`jC$(TL@6R0B8`@*RS +9+im(&&k[m1F9(UE`,eN#)-+Qm,-+(k68289FLVCd#SmdA8kGIETAkf"ck*'C$Ad +E8dUkVTja[1HZB)r6e5lRpS5jT9f@6crlLAY3EG[k@I[lCBc-HRREiU2G,pB8fT9 +hFc[[Q1mpYh*+CBq)JAPKDclBehrMm1cf@aH9pli3%SL2QecIThP8@EF9Vjej2fe +)dG9eFdlpP$NL[F2f*FFq[ePR063ekI!c8I-+ERdflB8I0Ydcj[U'hqlj5p2$Mh9 +mk`qhrIc(1iV2klrHqmHJEjjqm[Xhr[RIf!H@AI[k[C0rIHI"4rrcdG,IrqEEZf5 +EiaH(rT@mm1#!VkEqqm1BZdGI@I[TmlplrD&(ARRcZcqpq[E3FBRhrA,hhcF2HqU +*9AqqmapElMp`kBZ2RrYErVf22lYc`BN[EjLZ+8hZPfJ8,dUBH)kj#-jS%AcCSM! +a-"Ce`aLqE&%(Q"l'd-'UYRN(A,IN@1RiGk@[$k)*(0+Lb,&NM)Y'31D3!),%lr+ +B%#ckAEUaD!4H"C!!,haA9Y&"GVPS$MV),VmlBRb(E'aSX+T&e--8`@3,*iGF"YY +Vc!ARDd`9qG4h&ih[l%D0CG*-#6RKjCV859SYAI-M3+Q[ma1#-QKV8%6q&a%*34& +X,-4pi*LdR41I2jjKNF2iEMik0@*J,$CMM(aUX3NQakM"eC8D0,TV4,iFU@V00pA +,cFI',[$D*!SXEMB@TcQ-aH[4[`N6CY4FRN6SqHCM%fQq6%4D1f2aG+0QCV@%Dj! +!i(pjB'de`62)@&TSe!aqBX+A#TphMUAeaP)dj*H@S3rD,R8CGp&DhjH5T3R'dNc +MVY5*YHA1953r,LV'r5Zd(*IfQdK"q"[M5bG$'8$+d[PLB#`&G#hYJ[k3!!*Y5Cj +a9d8$mbl@`%5R%DfpeTI3l+Z-r#frJQC,YSe9Xb8SZ58SY5ARa-"BdJ&M&rTpB(S +EGqfUd)aAD"CDF#QNpHZSC*q@am4H%jB-E0Rd@&$S-"EN&9aE81VEC"%(aJ),cP! +,&TbY'"X,MN!*%'S"@N%,-SblaVp5K&Be6-4HTl(JR((A6)Grr@l!ifd$"5`Um0( +NaUL)r4CfG%N-GVSMSTVF-Hc!FUa+CepjLbXNRDZ3!*3Iml1NB"GHD4EJl5I5)JE +)b0"(IPPV,1L2,P)8H86A,Qi6(5mZ9QMfFi*$GhjEkkYdrSY6fVq'fEq'fBKdSiY +LLZbYDfrh%Kd[$eDGpSY-3XH@p0ML&eJKrTb[q)UcDUSm1Ci!,fUER`ccm1Bp,kk +D$20@#M*%SU8iEbX-2K5m6D,M*d1#i!!C@ZLDrk[S@Nd-XC,CQ0FHh5N`D*CH@#i +kIQ+XBd+kqPI`,l!MY[PR8hTq`*KIVQ[IMLc3V2$T9N#L&5l0'UTUq5K1+qUV&9A +#L[TU4E@`iYA0ZJX[lEembl8C[[l&,9IZ-1DM$Xj(-Fl[VQXriMh#'Pfa,TbJ&Fl +35MlV$SE"5j-edVqZG3D6rXU%kAaaT13,*@-K8RX6E`9@N!$8LQc"#P@XH2@ciJh +*#Z#fiJZA&CA8LTc+#RGUlBTP*GrLUdVYLbbqK8Mc3U4jiIX`lq*b+li"@B2&kPj +ZpL)I['Y`eG*HhZ$P&LmAZR6eGM"9[jY8[*PBF,8c15-S+S)16q#),)IYBhZGX4a +@*ZEiR`AeQM)h@j,cm8dP)MECR4p4EXQd(,1m%l9VCdc6KD#U6bH6VY,LDdIedZ1 +rb6"d44fEp(9TEXm+ph-VfIeMDe!9XBljhqV#',E+9Fe0-HB'-qLI1mYKc*eHS(d +$p$HPZUCC98hVjZ9iRj@mr!K'kldm&E(3beHVfSd5,`r(9BpCAYjiRfdI1@LhFDM +`0#k(R63hR0jVcZP8bA2-1H'98UkC'cGZf#HbqUJ%apJ5-HUL`hF,!h"4f+2F60Y +4Pah'+!$1+2qAaNilla-j-@L@M*`r1FeG89(mS5R6AH@3!0SU'+T9''%-Sr%L*aG +S`c!BKZpRYYShrAZkMNdQ&I"K$[pHBaJq%!a$NfAB4TKiAB[(Uhpm!NbfUTfI#r- +qM"fQ4(8k8jMJfbG4ZKVH*lS)9J#!$d-p(6C)eqcp+r4Vra,E99m9"cQ-&(bq5)& +M6GQKDk'9AYl9bcZT@Q)0c"bBpM!+$0c[U-q01UjUcJjH$MrPA1lPPe8YmkUUfBE +!c&(2fc,rCm"l2Le)e!K,HCIUqL'%q2NXIVlla,YF+AY[GcQd22kCdAZrZ!4ES2A +Hri94Pq,PJq'DMBF[1M3[6PqY1(feaHNX"bk9IQCdVcMYlRXk21Y'DTe4+(Z+!q2 +-Br*'ebiV1Q!Um"iXIEVXUC,(XKr*HM6pFF[Kh%-jHqYh0qcCprcqNkHH1re#jEr +2r[2-RFG[+rr6dGmI1b&&l8K1#'VHh0LdmI@-Gc,c@cG&a,KMdlEXq[(#QpXqfVi +cI1`-EermpZD0X&PYekjfDrpXBZMeX#[SAlTmkpb!,NpfHk*VarD[[2bI$XpfHUE +c[flrBjqrpre,rpreqq[RArEkSFH(RrchrArdr(R[9l[rj[-[Sj2Hr8@lAdrqjFc +IIK"kj4A,aiQcTdfC1[f0erjXQ9'hk,[&5jFXL*`hIq(FkjF6EedkeqA*!8pd(0c +ej3lrH@$)rF&hK!bYZFYD4rp6'UL+`kA(hAGN`jUeklpHpdAUCbZr@[lpLP@VhlT +lUjm)BqABbSM!0E[0H6jqf+IIm&RS2c`UCIL$$iedMVMRh[2[$4adGha,'[cdYjB +dq1P[2M6iG0ClPMRMDI!(AaTm-fTBbX2$(aVji)Kl"pmcm1j",@J`bDq`qQHmL*q +iGME4Re6RljfHb+mPEbHI(hq42em"i6irbHGA*p(BIe@lM3NN5lrbVf9UI"%J`B6 ++QLIKPmCb0&kM56IaX3LBN!"-RDZS06'k9IaFGD,-CC4N-38`hFY-BbL24P-Y,D- +L62ib83(ZpML)ZmQHTM*kLNVS-FUQ4bL,(U9d6!fcd'(+T8183hZTRRC6!qfKII3 +mlDH6Z,[L146h#jLAqfrF4r42h*Yf*afRfkLFrS5ja,qRBjKBKS++SKf86!N84-f +dQ4UTL6E5kj4"le!QjH0'Zdd836(NTPK+SbfdLhkN#r3QED12D$[Y4+Rr[`KiQbl +5Yh36mpV#U+k0VY&9kNEYk9P+T&#k$Z`9mU-[d@@k4HGS!(@K*m(d"(@PMQ"pK9k +Qre!(E1P%ce"RqKIG6RqN2[4hkNYrSIld1qT(IkA2k8[U46p3$rU3!$kKrp,lp!r +U56qRh[3UGDII-)CSc,kLGqNAe)jq6C2TPc56INXI3)mV@19Mr'E60*T#8fNk[8' +[dCpT"Rk,k$YD6%YT#5fJ5*T(mfNKcBAQPj'#@p$k(00h!26Y5)1Kmm[3p6rd!!f +KqbQBlU!3'NSeG"GCU8lj[`m#+QCA1-K&1XA4IA5%0Y!D@N[Vk@YD4ep3+Re'+qN +V@NlId`TD4D[T,GVD!J6qA`5-"`(FG+@4R@cNT2-86m2S8rS'f&RN4cp-SbL&KY1 +$p"#0"0-)ZSIZ"HYl0*!!"Y(Gf2*5)2!6rHdP38!`4&2Ga%$J8qM`(Xh"Ed)3q!0 +q%`H"Ek$Y-1Ml-$3@qMi)IHm�`$EHq'[K-&!6,@m6Y8flMJG3MQ'K(bPV2!44L +G`m)()Y4QX0"1"&-F#aG%1*JY`Q1$4FKfLT!!EN+`T'YX8-N#fj!!(Xr#C"BL@CJ +V`Z0(@'$(MrGRB4B,)d5`P,+JX,#D"DX)KpH`d)@&%"&b%eL)CQ'*#(Xc4DM[)m, +Z2"E1L0"J&Z&%*a'NXb+NcKEK+lEjUd%L,%pRB58,&eRSaF)L%Ei[BS&YrVk4K9! +@2Q'"L9Le@)3hfl2!%[EQjb*XBkTX+fGK1`X4)Rc%52N4)mTf4[VYM(cE@H+hGfD +KK`MKM#MKp5b`!JYRL3r[c3)MF6K60-V&`Q84GR4PJDQ9c!k5`ePiQB@I@'!N5'C +-#5B@@#)6f)BJPZ`J4TUJ15``GB-Bk$6[&k&a[JK0TePJfjTB!63aj6BbdQr-BS% +aE@4-'fqb`)Tcih34-SkcN!$+!P-dJi&A"Q2+B)4qTeQ%r+-X-#$,pk-BD1EhC'% ++#`aS@XYBB)4VCD$3bTC[hFS#+kV@[Lb`cDf-P+d-@$Fa%QpbXm"8fF3)YiQ"a5C +@Y*Z'La$"LLf#JA8%+lB)"XSa,0Na$&aL'$PL'2RF!4BB@Gd-V0fXXVPC*A5c",[ +lXF")idjKJ9AD@%E3@!X,$&"L@@*L'8M&XNS9biSfPUNBqaS,E(-D+q#d"KBBZG0 +fX,#,KA-XX%U5aXL4aUTPfK!4YM#PYl#NEQ&*hF)+D8Xh&KMKYV"Nla,,m&d@i@N +XZjKAf#@NDVYkb94E+&0rQ(D&XP&D+"FZKh%Ab[*0Q!r351pE+"F(B#S,j6&(#q8 +m$*DY+C5,qK6+*4d+j82E#ZAG10MG!fC%SGa`$!B#'VS8bR[+BF#`"m+I6i!"m[R +EBAV#c)5C!C05+1mR,"U3!1A#5&N1R*,PNM4ChKdYbmrhPqApdfAj4*JXUd@bV'6 +)XYjCPZq,Jh(,mK'6,'m!``CXA1Z&k5(,kl0J9X)XPZ@[JIbkQbar!8'THE,mfAi +B#([VXLb(Mj!!jDKd'!L+kLl,1bl+FR+U,!H9`4b"!5+S6CDE&9RH$%&01'K&Cj0 +9PL1JC%3cc%qb(0-H"XTZk3S$j5jdJ*NXbeRR22,TH)rm*jG(rRfj4ck"cSPq(YQ +eh52VPchb+S,"!G8@bj4G,-YZQ(E&XUFrc)KL19!+d`rQY@,C["AQ!Nb2BRR-l'+ +jGP5aA03"CNLaA&"B,"qF85`rA9mXPi3AbpPGLZ9(MX0!B&CHXCbZ`-b%'9iX2ei +#FlPB2R`'jL)-0ZB@`C6$""I,Kl$3S4d`@1a3CjMHaA*1*FaUQ$DB2M!3PJ-&pqE +#5$$BX"H(HaFAbrA,BAE"32(k16$cLqAG8'Jh&QT)+CEh4"6,*j'`NpK`mRdB,(U ++B"B9bmp"NHFJr(3C$!5IKS)[R),T@5aAGLq@cd,aIiB@bfI#LZ8lSH$a"TK2LZA +Ec$")f'hlBD"%Z3N''mS(&mY(Qi[P%p(&XZ5#Z3N68L`V5+4b&3E%GZb$@3H$MDi +!$)MSJR"A2-bjBMQZY9Lq,keB2J,PMX`YPMId,CEAG#Z@eqE!J-"VSF"k&0JA8$B +9KCJ+iCqP&X[,)Ial,2jpHaJ3B3819m&3@8#Q5N!k`I3-b)'iJ$`Z,5#E!IhQ9TL +DJ$aQ)mcmJ*bh$bB$TJG-5%!H$FE4R`INfJ$-6CM*!APC,Fa+Q0N"Z3M#$`"a!%* +-%'BD%C!!#qB'C1pV!IRJQS$m9'T!cZSIN!!IE3[)k9-#XJ9#$Zf!53R)$GN"qIP +5Q#%"qH64J(`+R4F'"q4+-0eT#XJU&(8FJjNCN!"Gkf%J3#q(k3`c-L$(V3kJ-X* +J`j()J,`"'cEd#mKVHJINp8K3+K#Ir33c25"[KH*EV3(jc48"1H&-3'l1JpN1dbH +!*`#J!5ZX&,U`G"d9eG1ir5iq$R0EF2%'Xd"j,6kLU0V+VCLd@AK86-IRim4X6Dd +edK8DQA@@mR*SA"NB#lcf&'k+ifZmL5Pdf*a$biT8@bQC6bND0r!9"Pqkqr)m6)$ +1+iLr2j6#McH3!-8VAFmV!bGC625S)Q4%-QE9PYQH$VViD9q-1*r*J8l`*Xj%)fi +E&CGMGV0ICLKN6S#c#Cb&akqRTqV*9+R'Vk1F0A5i6)hI5Xql+Eh--E&dqT25AGM +T(&qejkl("k9+Re'KepZK1d8YGp&6Q1fC6DZD+6H2(Ld6-h22P0!H%q%k2b6MXZR +3[K$(0,Eh)d0FaK$TU'AdZfPhmB-1cFMefY[ji,$ZBPm@&`pTL5V`hF#dEHY(GEb +r9NBPARSk@h9UjC4HJPBTT4p4E9Q8hU`kbbLGprBRE69E0Phd$+&Pfah"H(S4Ek- +b[21i9#IrJ)T1UFiX+X,N&Fh2C,XM@1cY*26TiJhV4(8P1C4RSR((UJSH*rZmB5P +dEdNF1dRh19R[E8XK5dNfQB[`aP@06aFESP+cUDb)$TV8@hP8j+8X%ceI5RY0H-& +U8I#pr&[mRDd#,+UJiDES&(Jl42l2bq6ENC18LF$jP!PMD9%Q&4cM0rL8#3qT,T- +59LBPV%bb@CQ8SN`kq*C*BA@CA"&PX[eQGC&-CN@5,BV%dE*)1JYeiVeKRImh,*) +f&)QjN@UcD9`ZlPiG[p[-*P$9JPSAP6Cm0H+G9p$[q5JU,e)((+Ikj94C4)Ij9FT +ZS)-jG$L9ZD2"STkk4$@YUDLQ%$K%YGh!T(MFrYE9Djmp(PAJ1a5+p45Hk30[@mq +IU91Yd#R+R2Dc&+rpQ9be)Pi[+CZ!bYPHRM*4I*JS%palA%6M[$k&9IQ5*q%P#C1 +F0)lpj$*1cKkKV'`U-"(ZfcY8kUUZ'!bdl9lE,",qFl6`Ri*XhEcfZD$ST2L`Z65 +XC$APPG#i)Tp9QVhA8kM1QB9,4B&M`S0!q-L#@c@$DAHp3Yib1T!!+cBG3'RkJ[* +Fi9qAB,CGUMGd,X$ChJe2V2-Amq!AZAfTA@b(AT%0fbP[6AAL)iA#REfKN@6*UUF +!GeE)9Dp(i$'Y@EQq1#eLK')[mFRQ)NDiVPVU+mPVHUQe&rG3H,R3h&+NAD"!598 +plBLUE-((RcZckA3flFQQA(a)bUC5h$'TX"8`9q@bBZp,i`GY2S0@Rm&bRm&aRd& +@Y5$G@544F8Q9e`l&iSG,0e*aGP81l%GGR""PDUa'e45F&bJYem)PV5KEYEPS6,D +r&('K954CG'X+VM-fEbB&XKeD"9+l)eJj[ipUc95X9LN9MPY!+JBiaJedZ'&'%0I +[,6F0ekqAi*0XV@p0U"AYKbKmXbV1Uml+Eb%V2jbH5mY+bCY&HFGT@4CcZr1&dL( +LYCK3aNHU-9V'*kKMTJP%PrUV([!QAh`*1VKKU%5+0fIj(Zcheccie63DYm1RKG- +'3BUphLFP+lI'fE1U%8LiC8+%Uk0apKL9jG+M*F+plLQPJlP89%)(c95QqJX$j#8 +'V[j03e0p!'dm$Y!fE6)Q(EEJr0@PRjj8qQQrp$-YTCpfK9P+d)aV3CX'I`Bb+Il +R+66-'Gj!P@Bk@8,IiS&XCQV)SLB[0AMTd%ANJR5)pk8lDqR3$NV&U)3DDZPN,9A +@1TLVQ-98&Ge2a(F8eZdT[U+`lY`#@`daaYN&YU'$'6+k`"CLqC@fG(r4LcLaTGV +Yr8U-[XHAF&aRFSQfp4JqLiTU'I%(#FAprZdDr0[%b)QDF+KSUdqG&[@Z6N[I4iH +mkQAiNE0dS*C+&AUXK%Tj9dC#kbLrB(6RLkp5j+qG9A9h[ZTXR1r6CRj113+``@e +pd%"Y1dfjkI4d,TP+k'PcPCTq2lHi'T!!aN-1i'8fjY*D[EJPqe,p"ASXTpT*iR' ++eBc%h+3IS1iUF9AYkqD,PJU2mS(5qG&m#CQVmba`IScCp8Bl848M5ij5hQUI()d +GBiDeS01`%S@+Mi01&GJ)88I2)fXfMIG'm%#iSlkUaZ,PTF4&HGi**-+4Va(,c5Z +4+'rjT+HK,(20UK5jTmpT()qVpLi6FcV`FRQqq$cQ3dj9Cc5LG4-hJ8paa8H9mT6 +Uh'5)hqZ@m9l9Z'#4+Y`rPqEMDd*Q5)ADe[h5afi6jCYSiaP+A8%rPP&U%IhG4+R +VDDfAi[*)VD@M*VV65j8PG,)Hp8p8bU1eiL#ZPYE@8ZSqHZ-B"9A5aPV+Vb@h(fV +E!EVkLREcB[(9@26k!a8XHQN!qA$4Z`"8U1LG%eq64Dq$q*4-)1'XlAKr1L8FVKK +PBP614VT@'#pk!N6I&9q6@EGrPFK-mIQC`@qI!QG0,jqkp[pAD1hr4k%f##eiNFc +a0EdUjK0TqFQ+jYf1QlT1UpTAh960LeYD[-d`p[[X,@BHJ4@c)F)F%dkM91#[6dq +3!-@G%BU%@l)NTfLYPIM"GUlr&F%jGfcc1hb@XKc',I$+pC+L#9UYAMpiPdk!,r& +H5a'lafZP(8c9YFr3[[SUS'S(-9rQ)'B@(6aANDLf&YaUU1r'FcVU!ZV$I'aS2fP +bRI0)0#QZF5r,UeXQI*mrRjU8(VIJ6mjQ8lD*LXj333Q0,N(,c5%iCM%fmHdKXfS +NURHkejNb0N+e9"qdUTMY0H'"DV+9jV+UkX@XR#kU9SVj3Z0#GHh8,PA,bX!8Ida +$R2keYVVXDfe9Ae9lp#KQLkISfQC-hFR0!4#ZIS[4m1"XPG(Ni#ISI1+(&@pl!5m +k+LAZ%mD9("'@Tl1`NS@,,24LBC%)haHaF*D&4J6Yqe!GB-UkQ'jT@U&U+rUViZj +9EG9L(6H#BV"2GEkeQZ1Z@GYE2AL8`rP@-)mU9*aEMh!$Gp*ZM4E4pZCCR0RI[)M +R#EcCAYMqh)9,3*!!E(mc"2eYH@+4EH8kV[q)jEIeB@'i#"pPLm12MQ'a8PAl+%2 +9$PK9qdF3SAhdVQlrD$B%IM3AcdRBVQJ(!"2EXhAlpNT)aAdEf,NGmje`Sk*fB,* +Uhhi1c0XlBq[f(N#&UlDG1@"blNcPN@L)lZb1E6YRL@dl"q[fm(T`KLrARH%*20b +MD1'pJCb-TbD%,q,K!38AP-3$'U)X3%9G&LJY+N5hlkL&P"d@)@@(5mH9*YCGM2A ++9AYb'64)hSFYb5iZlQY2$YIYb@N#'bEXbm,q*'`da#3[&J4)-!N4#@Ge,F%&-EQ +U&P5NDd(T+ZiSdS,Qk2BJT0iH9!0YQl0dHr0qE'dqaTpcf*T[BJUBV6Q&Rh$B0Zr +JKad-F*E03#2JUK$D1&RA'N'bCGe9He-@"$5GeV8QV&+l!ffDQi+RU3p3[B'+!mm +Jm'`dkrD0A86[G[5Q)bNEDlLP9V'phN&XH"hb4MHJY@h5R4RK()rFd$+FZMe$E-Q +iA8HcA,#p8kVEhcN+h$[`Bk04rc-hkPSQ!$C[Z'V2R)'66%"e(ZDPjD-KNSI#bMq +Ufr2MF*+r$EeQdEZJfr*C1[*l!MG&i%DKC`8e@N&RVE9HYlHka(#VX*N#C`HZVqM +ee(%Y5j!!Ga-$qNhP20aKhj5!XdeZhElTCG(VKGlRSJG&mZ,%*5faA%54MJYDBPG +%QJ#HL-kL**d4Rl-#MCL2ia(L)#D,(F3FC`Fafh4R6#-QRbMf'!'!-3#Q')#Z-fD +ZU$afG`"BGlTZG`0dRHieIQ`'`0TY%8GGG+HlRm"UlZRJ5K()B0dHD`ClV)@aili +KPce@*$Bf3U$Mr@J"6V'I#maVIN``0UHCG(YDJqJG4fm(H0*fLD&6GkE0%QTUD80 +dqaDKe4CSYH8)J'T,Z%MrPM!G9lCBYlIZh$+CijCqEFX)-I%@VJ[3q52Q$)l$%c8 +Z,!G0E@m6#le%Z,K0K'pV"I'q&Gi(RmC8,6"II,9%jedaVe3AAfF@1V3EZ0A$Jb- +1Re-B,+DDkMDY'jFG0NaFaPEl1YeQlbp%fB4!Zdf8V`fe`6B%25GUlIN5(JlGcYY +e@la`FTMDU0Y#+d8hY-[AcXI1m$U3!$2lFphfL"RH5FYDSpZb1[-kKrCS$ee,amh +6T4Y9Cqi-2JpmKlE"Z8,ER"*GbeQ13Ar9ZGI$&cBSfZkMZQdhUbblHk!l3Y5c"RL +VJf@U[F%0E4VJelei!@fBM-llURe21HLpCjZ`0iAY"+BplGCac"BeCDJff3db1H9 +f2!V2#I"dd'fHrX"S(Y`[G1"f95X'43i)HTAUYN!r!@Q"erK#m*T6GDIj!XI$9Cc +Q([a3VD+03Dj3"-p6LlRXbp"m+EUUfSTB05h#4-iLj#8&H($+-U6Vi!add,4i'RF +EeGj8YC*`2)i+b0(`&GPG"*QcTr"$$YXMamAJ%6II$B,Pi9&@d'6d4NaH%+k@TeX +iZ1cT-`%YkFah2ei#M2Bi2N2J`5V*+!j,AedlI!DlPQ1QJS!"jq%Ch#K8l,P&)%- +Z*SrRSVD22SCC#m&#dd0EGIXK!Cq(,JJVUXkKhVSY4j5M,@He+2UF0KcPp-'L16- +C@P3rqpjFS2G+31rG)G"lfrKQKlChX@kVAbi3pEZ%r2TqZV0q$UZKpB#f[$6-LZJ +LA-&ZiB4f)c21JbYXb16c(,D'&!#QE8m%#YLfCcK3fMj8kRe1ATHPD2X(klD6E8, +bbIFj@Q%RJhAE+3DITd6@UMd(PreF215G9Qh2#6hYTq'ME+I4KR*STbrUfZP"UL9 +2YEe`5QakJ@Rh3Np9'i0XYa)eD`amd&R-`Kd$Ara2e,!aI96Y6"Jkje6YcJ[SS05 +10qLfimbr(TqKfiq24"*Z-qZffjJHYiQm4#XhkEEb8)%Slmi3JhAY6ihBM`TlY&Q +JMZ*6URQNDMXfA!$bL@cGGZ+8+-36AA@E*$)m6@T%9`#m6HSXMU5"ZUDL5@VZVGU +8VB*&ZDVE(#c[FJ9BU"GS&pSRCN#`#ilEG8k8[@X+FiJZNAATH!5''91-pFr4fD8 +kieTjH+RL[#q0Kq24(8H+4051S%6-+e6RKVim('@fBC!!EPXM()bf"ZfFY5)VYke +Gai*E,,N@V5%c@NRVd@Baiakk,blUYLpB1bL9Y5P5SG)i9*!!cc#aI4aUjr*fD1d +FCDfICKED#iIerAbKl)TXIJJUV-THab["hNF4hjc(+DV051'4$Ll(fH5HF#1f3*c +B1NjN$6CcS3!@FbXEe!L#MYQ)QSZb'c0IGqD&L)D50MS06i9$&KJ)%h92GbjEbD2 +JFCE0aUHl-Mi-EDJ$YA`K8!GUG+GT"%-9c'8SlfZkGK![``&-a5q&K`QJCT9KUR- +!RjUI3U++RDU@MH@+YkV14clJ#e%"Xd!,$qEf2iVRGAMJFG1RS0-C6`F#!(QJh5' +dPJkK@HI*!GaR#lrBJ'DRh+SkpjeP%Tj('db'H4iZT"!ZiL6F5#%JpC4!B0,i#`# +TbT[Ll8Leh@N5%ZlXJ0IeH09jfck@)GlQpXI*V0U9)hmhFJ&plk*qfRkI)Ic[-EJ +!!q9eSNB4hqh81!!BEJRq#FmR`-h"BDV0F8a84FG-%9cV4AEKQU,Ep*'L'lGDYae +Kl[K)*)##Y@[Aj`V%HV3a[XB0Y)fUE9ffJ*TeZ)9k*F$L&'le9EA81!HZH"BfZr[ +@p-2[mS`CdXS+Xhc'M"XGDfTU"PP$V0D"6ZG8Uh@)X1Lr)IV"mf$[(ALM&8`e9QX +`3`krF6l8DMd(4(b`04M)N!$je[&r)6@I6R$mMIqNKTe'KJJKLd*B$,''Y'1pTG@ +)EaEAe$a3`e3B!K3dZhqZdaRLG!kXi"JiTH8B'qkZ%D,[UDQjafkh$kPC+)*!,I$ +h'11pLqhXEh$0r8jVc4$r%S1'3X*`Ch!&dphIER4#`0de)l"pF%d&q[k4cZ#DJ8k +VN`Ppf#PS&9)c,HbFe6NA%Thf%B`XGl`@HRQi'&FK8[alr'SZB2[mbh`RYJd88U$ +m``*p$a3%i[l[a1JKG"qShVP3p,kT'-kYk!ak@$"&9LeA3Dc"GbbaAPKqde&9&#M +ep"lRHi8pfI'16P,M!1Q#X1HNeekqjiG,mCFZa8Ykr+AZGl#rpm2#`JB-[4b@q%I +TR5Zhhp2aqX""Rl-JZ6[1NAD1l(M2b'($T+dX**r[fL8XV223i-X$VPdIf1&@fp9 +ZYhTh[A,pNl!`UAR+$e1Q5-N`S3p23IJGJR3Kc1Um+Ze%H$)86iVGpRE%AIp(rlf +p9i"c66!$pprqZB,FRpl`eJMXM98hZLIpGXKVm4m-LVr4+IipK+XhRl"qE,eae@Q +pmF1hTdCDjpjB"H#imD(6H[-pqbclC2Xm+iSib@TGB,A1XIlDrZRPP(01P&pHHHa +$9b6P!FR9mm-KG`qj@rV`0a@G[bFqmdV`S2k*9r&629HZ5j0l$T*5T4U8ceT45(m +G)MdV"8PEZjbAVSNbq&CBQehDBRr@6[krfb5Z&UNjK0QmmD'KciD'GR[Lh-[SGPh +je`'*eb@(X1Y#TG43IrJ`Y&GScm6VV`,p9ZJRLCmN5Npm+Dhi33e)dk3Nb"XRCGV +#L066E9IDK(`!!"`4384$8J-!,[%293eP44%!-@AZ3lpYEjBjAm,,$2Q'N!#6[)3 +jadbbiC%d4b8Z@4,R-T+a4!RFI-R8C"2*NMA'019kF$%aK'JKKKBXPd-$TDIaq3` +X8+XHJ3'@`a8[0r*mV29i15)8T)MPYPb[f04prRl[Zf3*PR,[kAhq!4ZQ*q9"%!4 +!%!#L!4IRm4'G$LmqA-KF8)PNK!'qrQI6#bh1aZi@2YRY$6j1PIakU[aLI1'41jh +[rIf,p4#*3eUE'RPf1QaCD(,k902TFL3G1!DH1-f%9(bZ(jeRSipam@1B@&8)ca, +l@K4#KqjM"FhS[%2lm&%YIL6%$lq[$HiadFdM1B##IR)i1IK19aFh(#8A*#XScD" ++5+5F10cV-!jCIK@ZH*QhAMX5qZq#8!%jU8C[qH#CpDP@ERNR%&Ul0d5Z3pehHhX +G'GH2l`fdq9BkPBelDLhcZErlar5hm8,hMmr[jp[lR(pfD)06rH5H+b($6`24R%" +6fC39Ie99C-IPPpbp(M6hSfECJHp"9V$K`0h9cJVVU0'UF$Q,AT1KX&pTNN("C"P +HVI&U['*&IV`q1a$+jEhEii)Tk$QM")IDp)RY9STGB@d6`m1-M$)#4rd11'bKN[8 +l`ME9AlpML+ZQihYmX8"-hG#NK0YpCP0qh0[iN4cK#8p#&[KR(U%T%Y@`LPKC1Im +-4D(XhDC)lel2DR@$NUBQ'V++&4MAaR4SlZB4)5@9#DhmXj'`48dJD@A9"T'mLkN +Q`eBbP`3MNjTJ)"91(56-r0SESjcIEAS$)J@QmVT9'CmhqXcK(RMVJmN+DMJ'Tla +FUj[PJ$)R)'keH$9aHIQAIE&*DIMrH1'8RRA&NediCr@9qklNPUdZJ*YFU!r[k"q +E&9,(fq,YKZ31ZYGbYI0C(cV#mRJU+I3jrk6e@U4P2IfHD8cI#ZIh!Qce1E80DD` +H*,%kker`QG80kK@6hC2`pSE0fX6Tc9a!d8X*51Y@(K[4A(C-bfSl%RdDDphP[G9 ++P)TIpXP)h,@VHe-4II$"CF5F-`5+2$4*2)+[)ZT&XLmXAKUZ"$krq0*)F9TpU6i +jP0m'*kJ+CX,%@c*6`Dbfqkc)DPU2PCqa8USbUD61PU%a3("NT%HG2I*0$KaA5)d +KYGVVL)p&2DD#!dX$S68&[AYArAUi3Ndp,iFF40!jKdG3+k)@0A9e5G@N-&)4&F) +9eZhI&K4GLJB`f&Fmq0b+ja8fU1cFLUZ98S[AD(AQreA@kPe[3[pkm6&X6mA'RhV +EI&C[Tqr`I4G88rh$Xr+4SUP)4V54PT&N"4))'9a'-G3bJP6!&kQf&f%f'U%%p3' +&0U,NiQJ#9Y$&FcQZVG#e!pq%+`!mB53e(&1$J6C[+I4P+3*6rA12I!Jb%S3N[VC +#14"ji0G$&DVI6)PU$R%PdF!5+K$*%q5QNe*JDQAcAP*%eApICR1D!6P6ECjUVe8 +effp(hM[be,$2T#k)YiCl`hX[Yh1N8pAeeB)%9+[M-LP8CfP%QQD*!5RC3-J$SYl +fYNRT#%2&80ZX,%q-Z6"ie%mI!JqJ)j35$SCd``5AZlLB8U"da)Up4Q%Fb35@3"# +)88"Lr$X$BerEmR`bb%JQ&"V!4*d*J5Q2GpFKQHH%N4J`mClqH*1k[pImR"B*T[* +RR51C*T[((`C`mS*YGYiN'[`F,T4QB[SDkIe'5NeD#L2hpY@C-'3Rfdah[a,4lbE +%33N-5F5E6!"+h*!!4N'+"F2rfPIRlLmHSL[Id3pa"BNpRX"209e+06SEBI4Y-!T +)*-EKISCaf8E9Ai%Fh[d5*Z"GfNRDA!chFL3lHE$la`$'9QaNkijq@N`(M'6MPMS +FV3@VXZ)M9+e*YB(e9'T`bfp@',F@)UddZ+9ZKA(,aC8ZA+I(e[K"'Jlfi@$bZ21 +$0$TSF'kTD8#([G#fj49em)1ddkM3"SX44*Q3!""Nq"a5JcYp-pkEH5KX"VTVYLh +K&L5N!V`['JYEB6L189US0UD2m#`0D1lI3+$D@"p'%UYqNK61CjeBb)A&[5F@F[q +MB*NDE,PNFHdIE,R4mXR6MT4JF6hY-"qCliFkq,@*-ika`CBpP[pB2pM5E(QRlSf +a#XYre,da(&cl"2dGHq,1JP9[M'HPr-eGU[8VK'2JY3&-+jXl@)@IN6'lakaD!3E +0a[V"'CEH,Umh8ES)U5hRRa3)2S0EHq0HVjA5ZYK816RSfY8fa"2RKpJf9e-#%B* +KqGC1G5EUp@R%K4&DU0U4'8Z!IDQP'rp9RI&Cb'b89MZ6dGND9e1$cPCX@fDmXGZ +jXIN8+MGH2hV,a[IUrcpl9BZ!A%[*Za05S!0$YD4`[U,2HGYmNieeCl8PPF[rZ-6 +%QC'1B8%Qd,F(L+b*Qr1#Tq`EebcXfRMX9!FQ1DCEZp#bXCQQdFjj+JT9#LL$'mr +N+Ui###e`fiVXDUZ`me[Yd@hkU6rGfj3NB%"m'ilSlYDf)pa8%5Hh'&ANeI+"IJa +ZU)U@91b'STJ'Ypb'3*Uj9U!aQ$4E#ZFS'1#3!)dmZ,A3hCpZ5H%S'F2K*pJNFK3 +2kciTR&jX'a05P8LGF`dFE9mLiIN[A4KZI2mCBY2Rh1HQ)BB#,U&dRk8L6BcdH"G +)k8EciNPf39QkB*3(pd[,)#kF-2'TIT!!&X"e&*0IZP,h@6J"0ddC,J-@`@CQQQT +T!kRke(cHAAS6Sp0d5'S1J+`iC5Yph00[)&35%Lf&1Kd*LN)RPVmAYL36,5F4'&" +!fi#Vc%+5AdC&rNIS+,EF&Xf"%GQ[dj'cJaLd4*(Z*%Fm'Lmc$Xq0AL6@9F&LXlL +`a5PUGT82Mh-b9"+`HBM5`ApmKS'K1Pj0V!N8Tqc1eQJ63dTlPH[!Y3q3!'J!%R* +c[Xd-qI*GEdrekb9K,P+A5ilb4R5j"X2KR9(hHp)c*Q'q,iVQ'i&%VUpe&`hK(8d +m-!66dS(1-pX%da*IfKC*,Q"N`X5!q)[kf`9d0*Q%q"K!J12NrXQLNcHcl6Z)Ree +Dh[)#$+T+,%$S,VKM$i,&Ye9B5'DVMTNY%D82CT(*krjD9cGkl'!@K,h&$q)UZUH +lXh923A'bRUT%-ia)(N2S`DILp@*kCM%-XqMh0$8'G(q%-"b,qr'bH+3%UQ(+-rU +'%NB@D+rI6"#qJ*UmA+T4!9"DY,)S0(2rbS3EG$@IHNfqMS%Vbhie'9Bd&NGMQ5A +r)GY%a059A8D#C`S!AS'3!)Y*2bdU1[2kKCpI1K#JT8f(,@Q,EH-35)fYTLk2NPS +S,He&9cREPHfRT8Xh,IY`-ZBVmclZbimqq[0,(Q'J*YVMdi44SAB1C)jd22kT1QH +9BfdQr5h+E(lYESIDHIc55'a9`GVAk'r4DpGNhPh`T50$`EC3UQXXh$P3iqk29LF +V,$HMkekZ'`SXJ,1ZirJPVI!,ee+Z5qN,@bN5,R(GATXaeVfiHh'[,D2%T*lI(q2 +*3HGk-0R8Yha1MKk)+"$J6UKRk"HhE$lSSFf(5N#i4TA9k83(VbMMA$*&I"F*,[1 +3!(J9YpN2)3G#d`NHX[0+K%CpFRkr3K1G!00XFG*a&*Cf'jhKEUFcB1TL+0DReE` +cemG(Eh&HR8c&3&j`9"SfTe@UR"#S%N5FX-bhJF3j)6UB5%h)1)bG&b6'X89J0ad +G-(A%`m9-r-YTi!Kql2ID1)PM0[l8-"U9UYkLKdT2i-mL`V5*C[YjN@KrcP6r3S$ +6U3+P%RT'rAEUZ'NS0EkK![Zm+14a'18QCcM$PX*9Q@2f,8&+EUQl@K`!b8+E-q$ +'))Q"d48BG!DS#IfjcNX*I`%Tdh9bD-`[Eq"bGLfU+LE@b6c9VQ)KN!#RRKMm1aK +%Ak@UA&QU%SaFGSCTqESF'@,pICPKSh2i1PGd#'B&dmC*-"%3+"0!eXeeAbD)'cl +Y3Y-56&BjL%8[%@A9kH)h6QMNVL#I(&BMeR`Xp(f6&Z0b2YVi1U-Q'B(K(AM%k93 +(qSdmp&iH*h$!'I9R#@9#QlhCZReJ-$DC1#(i1h34+',pp`TBa0JcE3"C4-G!N!! +S!8%#B"R')TY(PJJGk)rb8+YK`#&T`1FP!cjhK[dGI24l4Gi36C6&YT)#,33-'hq +H6kINd)-EG!G,0Y3rNF+'EY$Id0r4KPkpdJheBb2(eqGL8qImjcB9SNKA[("-k0d +!FXU2"0GAhTAp[ETkDS-hCVrPrDG5Ap9`LiZ)Zf)M-ZD9A#rPYi,K-&q4RkkSP3h +j&KFPGh@kaBjS3MVd4KBl8K8@e`JlU(--"@F9C!MEXSaMUQ!PdG`h!S3FX4aH%H0 +0"S485L(N-03bM4f%#RP[KqH6+#pr&8$cAIHZ$kprc%eeE-SXqbmFlF+469m%238 +4i[hkpB2[emZMP8,'G'T8M4&!ZlA9!Rj#Ajh6kDUjGC51MD[dh868h08bBjbN$UN +DkFeAMr"#RXGITJ#SDZR3Ci0K0jp*QpBSPE0G&16eT52HfPKTbCq)b&dkR8FS4," +CbUj9'c),JrGX0YR6@p'93b4*qQ'3!-)$r@![ih-@'Dk"'JTM3C2bJR&c+5H5(`i +mG)SjRmmY',hPI9FCiZYQ[ch[0HhRVJ)&KRHfDbKdlbYR(2T9!Iqp[ej6ULTFF@r +0pD8AK6lq)LA99,*!$3AD$#ifh5k!+f8)G%+U5qC+GZ$P)!*`P,Z-HCbkQZB,ARi +r`NjNIXIAr"YcD&1(E&Hi%5jDIU1kJ*VARqYm(%liAGi&8*A0fYZEiDCmd-B#E5, +bHYiQKq+e616EjE2GFBiUaV'T9Z2lpIIRRq24K(3i[PkQMh)N--V4YAQJ8'PaAmS +HL+%E'4llkK8K$S%kUU6%`B3+AcQZ&XCjG#KP(f,,([c*+b(G340H8%3)9&@ACiI +'qDSVaG0i(Q8(Z0iia"ejRhkcX*!!!deVmaLU3"9X2K[%lc5SP`,eh#qUCrN29-p +bK!ij5e36Jiec53dP`!ec,&pr!XB(A8cU51LUA3UKP%""L'db[5U3!)LFPcS9m[I +p%hi1"0(b9X3h6I*kDaH"qiidQCVcer6U&qHb!T5&&EH*KNT14Daf5K$GN9E,$FY +,QbNXchbjmK+@pqbPS`IBdBZ-V0i1E&+C2K1TdV1SC'V6bqGTF'jL63%0Am5'rlq +21ea@+U`Faj%l(,@F%K90kmhFNQDeda)S'6qBPmGp*UmFMAhIcN-$&m5M0100bF4 +j8RdQL2lc'$9-5LNNQX0jl-VhCAEFmRlcGDlc%39'fq+!f+'4",6b"p`e9VYXjjG +*YB[Ze(I#L!'Ce9k'(Q%cL#249ViIC*4pPq)`"(EQ@NSc,Q,*)J-TNb)T,,`b+A[ +6i9"0)LN&TjbDcZ84XkNJlYHXlLh`l&,0F-RYcTUC1C!!V[dYpMdTM'!jNM(AUL% +@NZU)Tl3ferCiUrEmA!G3l9T[k*iVQH`c,0a6NqD)#SDMNG!pVfehK)-dLETGRHe +Ykp[p5%IKq%6Rc)DLR(k2jf44cXa-ZrZ!HdF'5db@'d`S"&QjZ`'*%VK,bGRHF4[ +RC6P3!p9RK312"mZ@I9L%4dc8cY2[,[Yd+3m+TUeF4YSbTTU2IqL0q3*FIZ##qPN +cA-Fqfa%HL1cBUdCf1)V@qIbEpUkk-"a4+qr,R29GM"HeUYJ1-(*j,E0DH'a5m*Q +MbP$%QK89!R$2RpYlB-mM(f*5[fN,&c`#820*eAVk"L4'j"I``-ELap@&&$a,X)& +ERN6p6+MLCmeB6YG3(@6JI,dp&kJ)pjF!jrFbcT[f)%BIhB+EZ9JJm)Z9j)*cpmF +Eeq"MHGV5DS6CYGl6#A#fCYQLeb0peXK5E!l'h(hD*4)#00!UelP`FF($$jiaS*d +M*F'lrERXbBl#!dAD('5#V8J,jdj+N!$rk[l(AL`jQChY55FdaBE&`[1jr#d56Kj +*d0G3)$'&9$Zm%N[llYcFSZbFd3-dNTMC[eSRP@ER&18Hc8R2034q+j+CAd+"[(& +jr,$N'(9`*!+AF-9()%P)3,Pfh!3RSLH'4ePd!26eY1#bQbZdZI(h8$@,'AD#p@' +BSbHEEDP6A$*)Lf'58RK030UhF$FIJ-@C$eecSj,q#M(MBTk&a!+B4E1eeHc$)eC +FVG@`MjhL4jqiS&fX'0-fXSpaFF#`Z-!RINa2dDX*j+&Tq,I-A,QjJ"hif985Z)L +F8JL%-2@XBHX)5f$X+bV8Jq&93BLY%&**(R195aIpXf,KIE[aFY"V0L[-CJ86+jK +BSC-91P(iJc62BqPj46hTlHj#YZXR$9XMTBX)3C%BQXmRe0ja"FQKTm2Q2pc++C` +eJMBa`"eC'rG1),!qcqrEX1&@hK4J!UeVEpcrHXeC+eGI[p"VAf@'d3TP2+"YFfA +&`hP+B59EA-X@4l"BH,h'9iHPADXki3L2C-a6@5*`2im(*[DV2+qbK+hbCXhV04" +eQ&,8QUEk4IC#aThUKTGk3+MCR6Qb!@LrAmhJ3JQbIeqkV6YGfjYcp-$0lEP(M88 +-VZYljZHQrmLHRTd$H+m-jaQDqY+"MNNNq)#Jb!G`Q5QeCfFSRa+DfXTYMZb%'[N +E-aE4DMAbTN-UM-lMDYL#E@UbZ(BiiKVmY-+X4b`1LiYYq1i8R!9U6#US'ZNMI$1 +IZ1lGNQ%+IKV*f9!bb&TeL'1Na(EZ2*UaHb9hbf"ELdG"a&"-+*lX*F@626k$NY8 +qjBAM$-+MU($Nr[1XSH,$cdH['5mELdJ+bR8'4BYX,PDd5$d8V3q[9lJV@"Dm-43 +,[4Uk&0SAI#K5crl')QDm-RdbZGj8q`LZLBF,3TDIa$JHUr(h08JUK1BiMla+bf$ +6lA!kqLAbrZ9,Nj4'DedTJd4I`e5rU(3mdLT0!bB#Ba)b-#%@5DlDUdiCQMH%T#' +F840rQFG$!8`l#+DkFKqFdrLX4Q2HLm"SK$b3!2K%c)4VrZ)bjDGVIMqATX,M-"e +p$Ehj8rhCad66`%1r'C)C#Hhk*(KY*C8P9r2aNXU%S6*3A&PG-TLV`NLNH(TFarZ +@*'KmFRImUQ!!q'`!(J9A*[3fS0S!MZ#D(`E!(cLdRQeGD+9E0r3@a&6VXC3f8la +%X)qfKQh()KTHDV$Y0-,@["DeAGbbDYhYf,*UI'Td0f(,k!'%QkJj@JTSLC8#66, +NR0rTNcmHiT!!di#[d%294*8,Mr`J4J-'P*frl"L5[APLm989L(Kk%3p"A)QTA5B +)(r%4eHje,lX9,Y(BfIP)L8%8%Dp!c')%-YE96$0@3c#B3k8l(%Q48j9L&m[,3ph +X`[rF9G9-lXMq%B3#CLNrMT&djh'$L+B`%Bfk$55-B4$$RA"#U%b-JGJPQCD($iV +1C%S5+K"-mkA1FC[$Z+RB[HY)5X6-2MNlZeGEG1!jch-(MKTk3`JRid@&-bIe$b3 +LpY#MXH6UK2"30YJ[UHV$pGLSlFbK[BJU4PDE("#N40Fa9ChG6b6"D3kjYUa(Ej' +YiaM#jePhBref&+,QB9Xidf[#ePIM@R[Si)8T&!r5d$G[5XU-aA!a8`S5Cm8[T3d +`2)ClC@CQGhC4)Dk3!&-dbDAZR-4TmcbqMm[QHBJaprDG0KKfFhTfh,6EU&h*IZ5 +9#&2-X2[%%(XNi5)5dNdIB4h+)KMp,Gabq@EHa3@mc$b'Kd(,S(j!(h8)63dSRc3 +Nh!65bdUfiM'*#-[4l-Q-SKdP9(mXh2KK'l@D'L`Nr$Ap'bCd('D"6'%(`(8'U') +6Zk#[G@FJp)QS#e'[#ijQT"GdC`b25Y)I+KDj-pfC-!0Eq33pHNS$@YmE4`T06bL +XIG&Qp-8E"4Y2'+G4N!$M6EffH"JrS@MeiENd[GM9+3BQ(m@)5A3j%TllI$hr3-F +!`!Qmkh)[Yd"jc*FlZ6XUi00GPDM"*A`##[($L-N!!APa$b-Q'i@TH!+%61,(bY4 +P08h*c%D!GqNVMFFD(C-Z2*!!kE-N&F-##9dp)mR$$)3-BF-p0+6+j649,XGe5mJ +0Qj5,"diIJ8!qmBp&21(EbLeRPa$#i!@%JE$D*5Xm`%KT96X*l'I4`-#"K4iSd+h +'Bmd8I)-+'1E9G#K0M`[G$56c@l4!-SQm*RHrSGPT%(NC-NPiPRY9p1,mQA,HBrN +lRP6KPVrVk"(",`$15EirQFjlZ!f[!Gk&ea5hi"APjZ6R009PiBfCQ4cL*+P+-N' +)aibR"U3bdbNeT"mAfbp(F`l-*r6YBS)f"N!aJAimASCAM0*p6+@I(qM(jR1%)C8 +K2IrLX+f['@TGP!h91%!mZ'(#C)3HY[H%mJ3i)CG"J2`8VYIB3,qRe85J1!)h$6k +mRk!jm&ZUk'Z)EP*0KZEpDc-cf6m#2-5'm$`@Q#%ehiPCXfL-jK8E)h(BC!C"863 +3dJ#3!(f-MQZ)k9'4+f0V@1!G@cR$'Q*i914)3qkQ9*3*kU[CamaNZEkCe25&-hd +'-hPhD62CQj)-V@C6XCN-cdLKJ,mAYfTQkG(*QD-C'HN(CQEqlf61C,Yi$AEP@E6 +dq'61I!1UP&j#L#iYfEh5*DTaMl@[J5e"BmViA2E4R++V,0NT,DREV@I[$'XiFeS +i@l3[!6'iJ*I!B`XY,9SbiRfl&mr-j"E&RcX*lM2aM25P4c0QdTFZ!4-ZT4h4N!# +SKCY&$54j@1hSEN"iQd`TACD`faffbfAFl9P[[5!IjRC2L(hX&$rb2%fU[8P"d+! +Ek9&%%K82""XmVN@0"1DBHbQ1IhL"d$&b5V6mFN%m*UCUGbZD&4pjeXQYr#A2lAN +mfU4'FK15F+4TY44BhVR'S@fqaZ%,iZQbPcbVe!iehc!&'l4,HTNdRK+@2V2e3V6 +&@L15R-"3)K`9M468D#pHbUk53191D3'@lL`qCX[G,1eVp64Z1acI(&9-NH)V5La +am&I$N!!r'0#&kGX-"E3Ic5d5%4lSUGe*SE))kd)J"S8bKZB1p#0`GX`3rQ9!1cC +Jd$N'ThQ,IT!!T9LjYFULEkY8I&UPiT+KJX3,28C[P`5a1*eM,2K%`Bq-8-'548( +UHMA4NN-@NPM-BKFGkkHhmE"Ia&@3!$[RVK,#Y4'ipH@F1AG[I0["PK38ZaM*m&Q +@8,ViZK0h8-"FU"Z0dB(qdJ'rhp"4X&5`UjF(UiDlXJBN"!f%eT6"Y46'[fj4I4e +!CEqh`iZ+@IN(3Yi)rU8&`Lk55!$cpeUT#e2L!X31&B%pNIfFKBLdHq5(d[iapl+ +GKp'KUUL-S9)`j@HI5rQV"'k@L*HB9J1MfQLL%-P`f0ca9a5XfH8Q+pca'S4$QUF +bl6GS$kYrHI0601,-8aHfEH(K!i*[)3mRLD`&,%85D1@Q0%D@aP6K58$X9NHk+"6 +`,2j9KYVjC+Q!482)!"'!X!'PN!!hDN`"(S`["FS'ie-SK1+Y30P'J$@8T+N@iM' +1j6F-h'(M%AFr&N3mK0iK6`V"YiN!MJG[jQ&HKQDRQUa!U%+C*3FGT#aYdJe2SMX +0&`D*3%8S&6UCN!##)FPPL)A(J'B)#MJBkPl#'pQRKVfk94-*FY,f`LKmBplDiAZ +LEM6cR80elj52&MkalhHfdCUkTh%@Fhp`b221k,lMhGZ2fcj%cF4M(efdeB`QE#e +CSlFqAc[kj*rZrA$9RrpfejQ,&bmHH[r1dEZA2AVXZdh22*krr2FfZfhMSESpYUX +2,EFe(+UcG66822hG,cHh2(@miBfIAYN+!!"(DN&%3e)$!(VJ%&80C&B"%$%elNA +r[fh1-9FC-ZaLV2ibPQ84RhHKLEA%i*JLbl"UTU@'FQ#PX&QLXN-mAJmIElU"2'q +!jP$#5HQjZId5QT1U9#A2HbKI5h)-d)45$YHN0!&+%mSK+D@%FJNPKSTlrrjq[cf +[K[6fHcr2rrIc!"ZYTbJRJL!)J%!dcjH+4h8k[-6P,8i'd"qrJ-a9XX3A%@"*9Mi +G6"K')#U9T-H5N[qrSrK8*6e3YQRQpCN2TE65rT*pdNPT[mcX84KCHP-9P$&ec,! +jZ&eApN%NBIKkqY&j)8R6&E0+@UKSp"Qq3"`r)5Jc6$-[J!8QJm0L9JDdi!)3b[@ +Fq8X89QD2G%LHM*2)H)kDKJ+4R$UKaU,-SPH[2RP#K%aRSE6TPBT&A,)(r*&L)!R +9#0!*0RqR51iBQmV$T%`M)V`kjNrX0bCq2ceJ0IN$$JaSPkk)d2aL%ESH5Z`20Yp +4T$dCl&MJ+pb#aM%6KJhBRdNhA"Aal-TRjdPG,LaK@DmXkl&F4-Yk&bk'5-JeK+C +k93AcXPk%-'&$l3RGiQI5(4d[&c&*Rpf4kJ*6eH2kXH[(5R0T8-GCBR4NGUGmf+$ +8&8MbF@$CR,)emB(cdG5jpU[a4G!KYIZ3!&#YFiAkNmNN-kGY,$5TAQKU+ehD`NU +Ab3a4jNeQ`',`UC%ZI(lb"&M*PBH`U9i%TLeA$*AC8K*J-H4-@N044,JU+l10p5- +G6(!Pd6TG3cE51+rS6TUGk0*VU)m$55ceBG"H'V6CFP#CP5RDQXCc3b)jq"p5ea2 +QbJaD(*U`U$AP"S#5`)EcJj9J!Bj0RJaXDKMLL3Q4DVq,YeKEH3LLbeN6,K$30p9 +@mVCk5Y,j3PM-$KbB!(UprrI"`@+l16JS'aRp68bSNR4-chIK)XcJG3B"m"U*cDR +'`HBd#h'UU%GBES@C[`KHHP`3a4`cLqh-IQdrS0@m&)TRI`eXE"2q1d5,5##I-LT +FTVSIQ'+2MJLM"Y(pX6T%8iJ1a#4%@a(pBU`0d5&%Xf0f4*1)TXG#)d#3!*BAFi1 ++!dJ#$)kY)*3T8$GL649@QK,l`B$V!fUc5N2cAldH5TN1EI-XN!!ABeZC*CrkAi3 +QNZk"@PPY5)JIUVpQ'R3f$ATMa!VbQj3KSrpMQr$(($PA4A0-2kpB*'2qP-PSYcM +J!DNK%(FIdMU"SFeCIERa%3J4`SrAN!")IJmCIl#@pQIZcG`,SDG0-bkf5qZIQkS +Vdk`2Aa&Y30hqXA'Kqp$-8Dd[XIml4BHfBD*m+EfV46PmN5AU#fkGI$55b@iU9[@ +"YUBk9Gpd4AdrZr,jF%TNTJIm6rDTHM3f8f2cLaUEd6K%M8-[DKb5kQ33F3Jl!8U +X*9@RRJTBQcc1b4&jFSpkbRe&A4SQ%$0+k)&5dK"T4P%0&H6Uh$D"!R)S&MHK)C! +!41'GCLJbaU9aR5lrHDF#!N$)a6ZcZV%j3i()iNKr4*L4H$0XNrbXmJ8,cQj-5Lp +V2h)j-NkE6N2Bp%4Ac[(&YNC#Zh)PIdBZ!PDcp(,*4kkEmQGXHG!cc5H&-*fDZ+[ +m'9XHFDT!dLa*#m"a'1SpRa,$lDcpLZJ5SFad-0HrBa5HLi`#15!qPJG1H#Hr""3 +H$L$mak$U2rK,%HVEaJL@Pl5q'Bh*+k*G*!**83b1LP$MED[Y(L%&((Jp"99[IVl +(M[8$RCKJYNei+K$(kq%BG`0-UI%JL`LV8bUffT,dL2DBPCDZ#*8@ila)KdJmL![ +NjU3!BT8-pk(!b!QICH,2[dp%@@#4"rC0R$V-,,6`H@ALX(ZL'4-e9d5#96+VG)` +D9Tk9Qb3d19CI-N0&fFB,`NF,4Lc%JfC[X4T2VXE&iX%NIi!NUM`j+0N@j-N1QXb +N8[(TjmmRla-A96eHBfScAMI8)E`'e$Dm-Y8@1&E%eABJfhr%`P(e&&iPDMCH4PA +lf(f3!'[1iG@MMZ-98irLG9deif95ac#T9ah&+k8fiP@RAX4J(5UVcRXSfDjH#S2 +TA+bkk2-qJpPPYRe@JqhXr#Ld44YrCr"H93hddF44Sa#PG$%qb%8(pDSAj3XSaie +"4%JCc)DLamad`BKUaP+GXZ6#8ShDXjZhdJ[LDk"(e1dfUiFa9&E)D#S1'30QI"` +2AHI0K3SFUd0#YfUh1940"l3(@SMd53a4'#SdaRIRL9#S%*m&SIZ#`IcF*mfKBCP +S3!MC!B10G$(e&#H-2*ak6KQZ98NF([!qp5rbJ1TIm2NVp4NH-,miG2e*XhVmb4l +2*3`cl"R"+qUTCe@J$9%-+Q,j8*k!X[T2VLVGp-CD,UVP`&D'E+KSF6PH38$8hAY +`K@lcc2!B)jbiaQ-8b9E6QCK9,YErA0c)4ASmZ"!0ISM#CESF"&[pKLV4$,(k(HU +mCNc%4(X9a1TY!20GmV#eKh8VQ,NC&lVPVl!DH`Q,iEM+aJM%EmN2iAhjr*1hp*, +RCLl%Tq9j+Jrf53L(V0$0JE2$LXMqPlH+U,6ri(B4V8[qilj8adB8RIKTaK$,Cjm +mM!kCqc,hMDdH,M2ei3Sek$C(fQqrqGri&iL2!)fdKdeA4%FJ16DH$lHBGMf"MKq +LUa8r$[cBmF20caY&I#Z+jVD!#`Lb$F&8`m(81SmrJ6bUG)ZD")+i"U,m&4'rP*r +[E4*"$6*SH[`d3h&!L0Lk#m%jqXTpb-V2Fpe(5%'b$9E0Rrm6Jme'Xi3-l$`HP+l +jCebc9qi'0XULi6Jj#2c*1N[i!5)G3*EhLD3DabX1P)QA#!(Jp"5BQp8@[)BSU,G +48'p"8"r@[81!e#RmcN**&P[!mTdD'+m&F1PH#qVQca,4Q0k**)eKG(b0N!""LT! +!34f"G+0k,[2)m52"jSfqf6lM964%U6P&c5MJGR0J+m'V9ReQ0hA!UdRpbpqZUL@ +ke`0K1E'$cIPl*A2I0Y@)j'V8[6kMN5DmLFmkYH45FljhI4%e[CR[6CPaf$i6J$b +@-X9M83dF[Ja&mh-,`jbK*[!--AKf3,d*N!##bP%$Y`GffPQH$`E0G"1#4NPkS*Q +ATD3d!!E1p"Q0r*NbV*qkFCmbH"5$G`Epmh`(*JhXRqFF'!(B3iKb6e#0fZG!G0j +pA*8S'bcYIMqTiM0+Re(q0$UNJD`MMf9LLKb*PKal*PIUZ!N!32"1Q+kUd3"BeCS +k9FS[9K0BM,b#4Gem@ScL3p*9)C1*#AIk8JFhHY(3U*Z2T8CGeCfqpHr1hSG*RET +"kY#*)&BFlEK@TAXRGI"0hbd'TN8SC*ImIS@ZZ0U!,#1"(UEiD+$"QdaDE(rp&k5 +'"c%3N8%#'9T0ZF16L1"jc8N%"T!!)J!)6d"3AqiBHVN)!D`YJaf[CY0V'lp#0i` +LY(HL%133X53ki9UKB@H4adPUc`A4,KjSQA5SfANS5'Qr@D9Em50d"[*BT&ZZ*)" +G'ZMEUY0*rKQ0'8G5!bDV%`eir0M1e&J,&BY3f3BFFZ&bk5+jcb`haS-*MM#DQ8I +"$+KVN6%qXKkAQcS+F30"1m6&2GJ6LcKS1kl0`bFAj-jJ'TTCV`E6C-%"BN0Bf5b ++p)$L&!+a+&3[G[HS0FL%lifDqRkU0V,$$[qRJ'#PaD214EUd8,@fD`Ze&i%V%6, +L&D(LU5C8`-%UG*@$9HJq,Y4#eAJp(#S-ei@ZSSX9BY2&[QfK5b`@cfK%4M[d3XN +JYM2j#HKEQIK"2a2&R36U1j`%4Mde,1*'%(bEjfb3!!B@a5mim%dD@,)0,%dD1+B +-,%dD@-,!fKF0'kGKEp#JcEC"QbF01U3-f[cL33RTKi%)&J9BX'kM4,9Rjc5rSl$ +'5Kq%Ha54Iic%J5M3!mMQZC5rP`Yh+YCETEV3X,0S0MCE6P'2-cU*X)-U3$T@!%f +V'V-#PI@5i`f+(rjiZBL"!NMhmaD"BQ`k&pQ'UfSF)Z2dIL#eTJC%2iHJhmDCDJD +k&DGi+&bb,@E0DG4p(QMHM5PU,aIY$SM1((#%lPDF&*`k-)LR3eaZjq#`Z`ICAKb +!M(1MEMU'XX0Y$4RR@,+T26[RrV55G,N)9iVYB9f1%[4k0"i,eYpQCMT`0RDL'!& +Q!aAa)0C`i"`,"*,Ti2E3*D$E&Bc#3i@"CJ8T$(dG'39M'k1+S)")G49*a!iMbrP +$2Yj*@!6ajFaNX5AUH4$qH+$%HB"UG"kJrZ@&$P",h!HS*Fi$e10!X0V*"d`J3Bm +P!CbX#Cf,K5``ZXJaJef1S*!!YMBfL[#)$ZbDZUD1IRp62$YRfCD83@T!3L%6+@G +BqqlNl'Td!fGA,d**$PDPm+"!%md[&kA-Z$K[32m04TFKS*)jF%BQB5Bd$kcb5`G +PaF[PB"!AITZZH&EUb$q$cleS2#H$I1K)82ep85b2!3NrFqb0%%PZ"X+)D""a)2) +8)NP%(YEGK)!Ac$r'))KK0[-(XeEaXa8,ldQpm`I&UGYq$23H#2kQJAmi`c1XZ`C +RL!mYXcD)3%AEF"SE$MGe01RPKHA*-8(C(+XLjYUEp-aqATSc*SkR[bK3#h@c#aP +VS+Ihr[L&Ekl$)-mJD#E!3'PRXN)Xl4`6#*,2%2Jc3k89"Hmf@a'm!m@RK-L'VkI +hqp%p+lYbHCUQ5bj1XD8M!2`Mc"a0'CK40GD9P4ic)dJFZA@$Zi!eTH*5LI`cc2" +EAMc@&BXU3aeT@SfP(@0GcSNBLSF["VZf,aDM)YS91%q&U-[bU-K21LUbeU1X,hJ +8YSlYqC!!)*Ri'F#2!6mpB+0ST2h-f+h0d'@#5GQ!$R2"S$5!DGJQ$9"6PQi!6AD +PUBF)fmJ4h3"q$2M*C$)hkEZBZ8!J[1*H!Z!)LY6p-qZB!BR"kSMX9P,rlm1("2% +0#LcT#!VN"TTk3CPk!D54%#4DJ9am("L!D29bm#"%&QE'K59UN9PPV&6!pDc-D'f +U%pHGV!Yi3QB"*CST)h1C!%Z+fEQ*PeEdC+CE-Vk)iF"S#U`aCRB!4GM%IJ3aU$2 +8b%J3VqL)KJIBHY3NQ)9*D$dTLjahq5)!8FP[#D3"!bqSF21-M4&+RiM'GAaYlLl +Lr3+XaABN+G`lp6X-4AIjH-2'T0aX-AJ5`X'3!#cHbB*GLIG1heeH4BKLT(!82pR +i-4S[6EV1J@$L,Kp[i*G[d`Dd9&30%-+pbL,cA6lMd8QG'NY1'ZXQ,EB%*8be6PV +f"j[[mNNH5lBXXiJZMUYMdXZ*Ki4$SfBF*,CD@)l'&Pe`#FG%KK,)EcIkY4pTpeV +A"**K4m$rQMq`c1%`q)C#"ZmeXdD0Z0P8(Hj13+X1Z@2'XB!pM-j@G*iA#QbPcQZ +FRHZF,+BCl'3lS[YkHZFmrIP`&cc&i3J1e$L$+LA!cBL3!2Y'4"r!mTaJFSEaKJJ +NqcXH[NG[00EeX`#!!Ja*0Q2`L5lrQR[dja%),CB4025$,@0GFL1$VY-&9eINc(J +6iT@chY1i1pKY`lTTM)L1XQ)!bdE4-Fr@9)5QdU0Je(GmBPRdN!"JALbid#VMc,3 +IQ@P@ANNHbMjAkBU3!)&Ze"AG2-R&'Lki2$[RlP,1f%3-FYBQCTHCm8HlF+!"KIP +dh3UjN!!lbYQL-I[#M*HcRN+"F6-eF&QeIqA5`#rq8qM4e'V,@MBc%qj*bNa#b25 +c%N#Y`dmMILi#a)B8CC!!`pJ5E%29J#5pl%Bl1MQFRb4Q$5PCDcm(r)lcA#5`LN1 +IQ6S"4qq&iehXc-m**QH!daiG%h,bfIYd1Q66K,T6lL#GH1X,XG"P11YecfB(pic +Ej3'ZFN%$9@KBiI%T%)d3-jeS-0*eUec+H+`!`Da9bRJb%a8H#V#CF&!r$pNK,"8 +)[HJ-1ZEjUQmJ%pQU-1EM"fTXM2N%rMIMIaXbbmeJ4iC%Uj%M(BM%j3AAMi'DJ1L +f$i&&fASmh4KfA3@MjDVJ5"YqV2KTK@+K%dlXhhhKCN5L8%)akNKNjfbVEKVri[l +ErbC[N6H)BU31'd`jYbGeiF#SP!%4,m%S4%4R02)4SSjjMkkV+PFD'AGGqRqq-B& +-#3`L#DiiTEU('J#JiCm9c,%)$i,Z+I`NL0#r+ZqE-!5Mmai-)9N1JDi*lXTG2L[ +rYqS*AGUi!*J`1F@664d"2j,c(r[MhE-KkR`j08$XRqX!&iHKm&dlJmcAlM@C[`( +@4&KFGZ6j'Ab-VCS1lD'f(`S"*UkQN!"CZGqkTEL`6a93%5Dj8JJ3dJCm)-q'SCJ +PBm9J"5CcCMS!rp'a+q)!-R3()PI%H63H`*(AqEM31r`CI&pQed#!AJ''qA8Xj)* +CFjfB03LD6QC0D1Y4,SUL%&jf,N$(32)SC369,ED!T%9@,)1#8KB&TH1#@DmP##, +A1BKmHm#`hHK-%%j@*5KHj1#)M'('*8H4&f`m)bUef,(Cmaamq!I%hSaU&''jS5K +YBN2!(US6Ia8U-fq-RG*!jK&h!*(C%`Jd!b@mh"PXIV"Bf1N`#CR3FB9pN9!L+96 +MXjIiN!$YDD5L,!(KZK'I&qNc439EJJZf[cZ(B6CeSp)p!KF*L%-$ik-%JPNRll! +m,(N("X224@+4CJ5B$Gc+J!qP9hchqjU%YNm'IUl+m+D[F1X0I'J2MA9SqU6NK'X +hD`kPNV`S$`LPP2ekr#Lc4"+SeL3MUaC'9L4mq&RG)LHcbUkbECDCTahj*HNb'PH +%Y'Q+N!!'GJT8YP#"Dmk!9I8RYhK6GXSThSaX)L%J#mLc&cqZEl"#I4c$)8JDKXY +1FA%"NE!1Pi!J4!+3!#`)fG&mcP)3H[U5,!K092NCIQYRaaZUH0&hrl[9l$!lDT8 +k-Sj"3F2-4hm#1K9(1"Tkba[b8L@3!)GEK1&G+E6$*eF+H4fZlh+(@2jSlX!p$Se +&3DFj+PIkDiBkTq8ITZF*8fk-eGe#ABj0X-Mc(QrK4KH8,k`JI`p0-d#BS8"b(NM +mFk(QTP#"C["rrEJA49D4C[b$bZrf`UfTL*80d[LYcb3*PCLQIe!Ch8X+lE0"4a' +62NmD(bQFd(JdU&,6Q$4qk4H&PNd*Ce9!&*26Epk-qh3k!AaP2iEUPH*@21GNG5M +9dH54(5@iS,c4*HQcS(Jc(3U%GTk8p0L5ZX"A[FQdKjQLVA#PL*P5IQFAGU`)k*h +UlSPG%*AF8q8T'&STN!"[S%!@#dha3$0PNUB"I$S(rjAF+4iL*[TKG`CFk&(mDm( +!d-"pD2QmNpIpb*)Ul)dE8"df066*iXN+&*V*f8"B'')*)dM6SCJIb6*e`N'5FY# +&IjKZG+!c!rJ3-Q1EUFSMXUPVR`iQ-$+!b&3MF49JIdm'GNd(9!p1YX"'Td-3XXE +XmZAijVSrIZ'Sji($$r4G9V0clXN#m+(S0[80Yb,Vbq!J3LJiXh1qDSE)0a6G@j+ +1!N$r0khZ!FH3!-)LdBFEG3q%r1*RaTE*MJ0K-,*iNY@RD6F8!F`fj[ZiJNFMR0( +[rPG0(lXVSR!CSUTSC9h)2(leA!X(&VfT!mT5IibVG6C`"N+h1$YRdpb8S55G&jb +*#U"p@l,(p-`DfI6P#$IE*c3E-9!E"LpYDN"P!$J@2-e94j&jTFUJ%0EBKDNTcUL +%,V%,cXSF1,E,RH"%-"-C-DJHG&[Kd)),L5heF2l3HH%HC!!ClVNX)#lZS-il))B +Z)9E328"'GQB&X3["2-T5a+6,DMd)HbX-"m`G8Up$BaEcKjMBfMhDRRPpKAc)$N* +F1l#C-*Jq(B&B[8MX4q@p*HLS-3h&%KU`caQ"A[0*kX&Y3S9)%CV4D#d64IMaDIZ +bHL#-Bm!&2F2jP(cR0Af4*$28[q56%a"CJN`+'$h5rUL*'8jJcc&+CA'q$5T&1GP +6YSk'54he8Ur5%8i-b%3QQ4hhT3*1'(bJD2l5F6KIj(aee`4f&$QLJ4AMH&YmFpf +BripIS))h$8%"&HBf2F#98#'3!+HCHSCEkjf!PmQ!Yh'U"H!GC@6CiR"d++"R4e5 +)Rh'@cYJj'IKiQDGa*cL-)LRUQ)'b9HUiQbSC)D1H&Q$J@1Ek-5VZ)31im3&d5Q2 +`Bb$6p$!"0KV@!R3,0$d5CAqLqfFdML#46$fhc*`i05,$a`P8TllTUdiKkeN8Nq` +NjXA#5$"@LDY5r1Da$#M%A5dC2GSq5V#qHAh$43bkFJ@@p9[@!XSZU2f8J,$q09E +lmB,&K'JE0[(bP-#BIEJG&B)#M36#pRj')'!S2(hp"JHXjPJE#+dMSXc9q9l*imP +`'L4bJ"&`-YBkZD2*6"e4*FbB583cb9@FQ8"0$4C"TefThL`((R4qGRCG9k!9JrC +5FMZ2pGU1IAZ8JCZ6q`!kPfERE0Ji#Ga-82UBf2N3!(H8!&92J(U6UR"beiLQ*d@ +JZZ(,NcVE+BP-NSH"&@#&bN@-+$E-CH,+J,YK[KY`0hc#J2ZP'ShI8Kb!baa91VX +X8)3@UqmVKHJ3#4mSh"m`M4,c$-TC2p$+NY49pAf!5c15[80NACHAGf'TMUH,R6` +)-RiYF#**2QP3hjH6F,4,'5$RXTUR`LQ&R8`d+@B@&+6UK0&i3#BdL4LHb3,',iG +'C8C,,`XQQ(#9"R$)9iYTZ!-%e#``B$i'Uk"aU9&@*%,%4JBelChmUU9IZFYRkSR +&&a5$PEJ383P((9FZ%SB!I0c8!G%e6*[BK-$BM'*),q'JQ4FJhVl24,0EZ,YeMXU +13C`G6#MC4a409i5VkBVSD@TJmCBckCaeK%"afTCaR-i&HBXYkrKbqX%#"'[IB"F +08c%+!5$@D1r4Q314$eSL"VFTJ4HB2M$c#@c(LS,6JDVMel#"bZG((c&`)PKQDYc +1HVU&cL5hc2cHk#,"c`@bp)$j0Lim&YGIJ#*J*YcT2hhPUR$TLS(8jYGH&6fkD4! +#&JCAcM#kXm@R+)2%fe-UaPYF1R8#B-+&,E%q8I6E'TYULjCdcb*3YD*"6TC)+bF +J-Z[GPA)f(*QS1'r)b0[kjX4,@9a)2m2Bhm&EYNp`6b5'(LG[[XQ-`-0UX0j8lC6 +U51f8i"AYP1SV8*0-#FUL"4"$MVKS-Km(5&cT3f22P#"-E441UBDbl8B`K+be(Je +jD2#aii10+EqXbF0$+&-GF[8$&YhAa-$m@!CA69CAP6N(@l@#83RrB%S2@#Z,&`" +a!+KEkB+G*J6`30Z9`LRP8h,aUTqbp`U'Q9+1`q[GeEV"X1++D+`q(XMmb''G(kC +Ue2'hrR4lF9#0R(#c0CN)lJZZ#L)V!*)iTNZe8mVIZSCAr9[&3QEhSQ&9*V%eL4b +16rPD0VEQ0KU-K63f,E#Cf6$%D&59T6)j%TU2b$Ej`l--bE10#`Ji9U'+El"M4Q- +rh-18,PrQ!1iqJ+[#-ZX0`FbU6#PJTh!jqd%,Xj9$"L`119+2bUL(F"#'Dc%k(%2 +cIkJ4R'QIbQ*)(fA*89$12hClPmAK8BIrH,UlbU[XIKG'"JaJi'09[f!A,$m8hDU +NIY$*JRH!&9e$8C1Xb14Ahh*b[V6,(@Bd'ZVp("LCjCaN&6pFjr5-KTrSBD4eCAp +P&X6DVJQ1cieFD8b`1bP3@DZ0J3RP@&DJQC+&QTlS2-k1TPN6%aD-J`)q-,'ASd# +P3pQ9%-5d6q8&$Pd!TjLMIrf[@4p"b%CdGXkQ0'60%(9Fc"S49Pc+iFkkb8",e@D +5%ipK!Cf(IRi[!fG*qUdNS4b),j,*PRc%KQ53!)3kbMi1FJ6l8eQ4eIFHQFVUrAL +Gq1hHkhiYR%DNMYrZPE)H[#Qc53,edQ(Y'BeIfa20@Re6K1dp`K`lIPR8#lMD&#@ +b1-ZBiLcMaG%@GYC#SP`FID)mI(IhD4mY2rkl[6i[9qk!5rh&F$MAPcTGXNplU+3 +(KM`FYppK4UH8"6B+-dcXp8![#RYQVi8J0pqCJC!!Y,@CZK9iJ4%""9krT+eah2[ +a1PpYVfiq+Lb0kYkXYQ[L-0XabX+U88mIpIb"bK*F'I!e",-M(*!!dPB!C5l+%`J +!#j!!)5KP!5bPC9,3GRjSfmi2,EEc3pYfiYM1$hNlB!+95UG,UR5PU+UbU+3AefM +@,EVp'MDf30,+'e-ICA8BLjfCk4%Y+B,58N*ke*k8Xp6NS&(fZ#pF%KQ5HL60H(, +(AXZQ'R@0,ra-hC!!G)JEA@D$@@jHibXiecJN(HCPYp%',2m&PdNV`B'iMPqAGRZ +2"6(KMVmUc!8P""Gl1Hb@4-$UA$hI8')30d,D3iCImfG*5BNB$fAe'YlMci+5!R% +dG1U`iA2qV#q"le+S"+jb-"Z#KDNP8l&`cNaCV6+B"K+VjbG,`PJm,Lq@@LkHPaF +AZaFcAABS"JU&EX6eX!6%(9kQA(8ZNMh-ef53!'pdT'!QSLk#6#4-U%LHAPr4fDK +RcV(6[YVRG&[[r&(FHmI96qSIm%VYpBp[(ibdrrA)AYq'Nj)I%ip&rA01BZ+[3)c +51lZ&2qlGr[R[6fhb5[&,eTf$dALjR4-iGI#1D9)$1Tb-0Xc*T3j*h64d5-Dp#5R +iTBeHU50[eGE"QSlb0AGA(I&YfLI&-6dAdmr5G,XZ(p2YFHqlEfaHFCGAmPc@EaZ +Xmj5hh9fjalF4#YPHAl5Kb"[Y8$SiG*[3`4(hrMP[9F8'Vq3IHIcH`C6rVr[1qZi +k0Q',-*DPfil*eVMhm*RhkZji9fTiflTLX,%"9krif2I!5DQG0YUZE$5-DNIG)Kc +h$QTk9p0'9p&'ebJErGbfd628S99AK!kYFHr5hRp3DD0kfQLEa8E2f$BUkGCKZK6 +hrXShH`0[P%MZ)C+ICC,60[h+p)4Z!kBRiYjp2FpAF!)4dGYPSU1#IpPkaC!!!'d +B%BAi%GdZG)c%[6VGApkL,DqL,DqK,A1RGL*rqaam8*FDh6*dUBPl2cTqacZmE8U +!Z*)!CcJ"LYJ33iHbEBeZ,MTSiYllEUk*VM8"cYJ5i&(G9%aqDrFq[rPfj-Qd +&%ANcNB2VTdMfAP5b39,BPD3Be@e"ap'ipp0rkrZBYVq+YZp-LR@F&)f#%b0KRh1 +D1ShVGU$6H0clmQ[*TpD5(!hBYTh*LiT%TA([SXiR$e!b2-(*m%Xj'H+8B,NdDA( +F@f4qhEcqAFPqk6FihPkqNSq2([cl0!@%9bV$,BYl8qI228IN(L*b0a1j2k*NKD1 +he&k8kr1b%d$Fpp-&RaG[mS(-GL+c95(c5L,F5LBFKY`Hppl9j2Kh)Zm660jIbZ5 +9!GE$5B&TZq,H8)meiqr[5L[TLL[P+a**1`K8lFU!1q,H$4rFkb95$K%TQjA0V1- +NBbF[D@A45EVNTVM[YhrrfY502T!!d%iNY")*2q*NSZhBLml5e!eahe1rqkpl@D% +jJB`V#5KA+S6F%[G1q9llAC-*5BM$!K9JDRlFZrJl2cM$'b*#VP3)Z8m1(KD%A"I +h(6TR[AmYK'a3!TfmmDPaErFrrE6Mri+3!02LhV+rIVH8%j!!VYKJ5fSR)Cd*8a6 +h"Qk&eM-KmiC!(#DN6"b23Tbi3XDjFGrhk`Ef-"RVl5!1Nr%VFP"r!e2ImXV*V&[ +b,4FK[9C'HMrp2MB"emAriB['DFUkZ2I-2brb8K,[TL4Z8)MhDkRK$lkSRkB"!![ +rrep%1I"b-GFB0aaf(5E#Y8FEA[G&1fJD%Q,ThD0f)XC+*NEjEqkH"A+FN6cr![, +5*!5-6plCeX2"Tlk9Vre6T8$i[5rD6P-faEhl(rMrZSPBZiPB$ECJX4)App!d%'V +4(rBEQ9"mTCTf3kqVP`J9MkjmhAPa!2!lrc)h5!4B58Mr0dkNEb-5NM$brllp(Pf +lPDrp8`A4r-&*T+eallB2(PP#B,1E`+E"LGjrlp`m3'[,AcA(R#5+aJd(A3ITfTp +,+rr&H@d%HIrH[h83mPK*S2mE*ARPDmXNf"$hVYq5rbe#(N`Ncdq26%VBZA([[9r +kjYd8h(C6F'Y`&j@fa%@Jl*U49mSATf4E15RCC#)"1+GpjG4Y3X`V#G4ri`Cehc( +P8L$#iSHL285Q&LE6r6C!pje8L)"%kD[6rC'5VSf56Qq*,U,fd`M)Ve1eq,K[eX) +,2hi!!Hl5'YV!UJRSBL@QfQRUpVL[l0@Chb*Nd8!Nfqe'&VkcES,FrXXc8iKN,8b +bqff)`THVN!!$5I5[pRAA#%fd%CV3@k+*D!-1pG1KZk"kq1[Lrq2[48M`0C6JUpa +S`RI'$FV(F[rp35*F!a&ZpeS)K`"fDr$Yp*p)1#48@Xfp1bB6cSNHL"`bi4E(IGp +9qka-Z,`eK"j@ZG'$M4`!kHcNQJmSN!!e%'VBVD!'5i)JS$fImICT#K`Y($MZPj& +$R+j[#rK[h&Mq')235"ZZ[a*AQd8Em&YX!#"8GmHGIf"5%-(L#X&1m[9"-)m6V(p +jpZmrBP*38[U9T$ccTCYI(46qH`C&mSj"BBHJ@6V*35-j)S+V)2)2EII1!HY@fiI +-3G&6AVp`Y&aD9H4pb[HSd2ECqb#XEUJAPe&r"1+ebJjXc)5pY1UDldl[h4mGZRr ++ZZqmDp3c`jFqLU69ZrCH@[@Shc!R&FSmIHld0#m2R0$8L,[hj2S5Th&S`jdRjrK +Ue+LQ9Hck+1%jIRUD6jRJrGfHBpHLRP1i8U-bS9brjD4lJX(PF['86%b*((31SE8 +B)KMqAI'aI`cfAeT9[K*G[G(92rhSp2`D-FHAm&jDPI"Ni8T43r6KDZ&Xq0e(*kp +KHM00Khe@C`-M'fj+H(JEdBIAfCT`52I*DeR(N!#ekd%@%H*mfLk,6!Ha8q3-V'L +4@5YUA'%Ei%2XYA3K8M,XMbYC)&3(NRcZ"DS3G01pJ#T"&TrHfHk2Ek[M'UAMcFP +AN!$@Z,08ML*TM6[EaCr1$"Sq(RF[IeXGP#-G2MGMSiYC+P$(6PQA@TfR4MhPAEZ +kjjbYm@`kHm3,&`6rC6AUap+a1[r'BhZmEd2pZRd[JPXV"cITmEGbJre&Z3I[Rck +3!0,B4E!rkYrad4cI`IZR$TbGhbULIYG"`d&HH%pC+!pM-#a-Si9)4r6aeh0jJ#p +J`A+!2ddDi(0P3HlqDlPl[+DMc[rlBpV$pX18LBY*(6[h4M[+Z`MT[5[&m4QR$qr +!28Qh-jpG8VBFH4NZ(ElSKYIAh9jL`4DE0%&DEcP"9im+Um6-B$0e!+*k-%DQeqD +T&`i&G+@eH4r0qUqr%N12`+ZX%kB65RmcV(Y@U(JY%5'm[LBmH*8*2ej,43GHD5+ +1PdkdMl!$YGiB5Hb(%i(GB@9PceXYVPB+r-PU[mNDf`D'+"Zm5Sf!BB'&,A"Rc&F +Z%Ld"fkT9BG(S&V%C3kl55&8E&9BIe(hk*Mm8T@G0T"i*k,[B#2*&X2MK`+!C5JQ +SrC0FC4fUb)Y`R`M*3!-Q4TVG,"UK*US6cEbS#KM!8bESf$922!EPlqKF%F*")6T +NQ!BI"AX8lV"fGL4,LcP-YE1@J)Nm2`-40!bLi3Nd*&hb!S`$`9X198B4JEYNl*c +l`%"f8(`36E&ck4*ff@NDccT8NSA0,qPH+X(&3EI%lB+8kV+IP"h18l,$H8EIrE1 +qaUU4*rTQ,@&h8'-0MZM5TGe+f'Z&EYD5kfeDA!%"%kq$pmpDXUD+e@R'1*1YHfS +6Xd(p"YQeH*'KX$LVqr[dLVLdVLb&L(jANlLS'(-X"j[d90SL`h"Df@!jXr%'2i- +LLUX*LINiiRUR&P'U0X5-),&QV[K[B@Zq[G2Tj)%"PZ$(iXM"$rM9K'Y"TG#YU5d +qC5M+m[@MXReaLD(S'iJ1[ST,LX&F0RQ*b"%SqXd2&Q*L2C6k"fL3!"RiH'S35LK +Flc1kEK`JXa9%C5EZXX&b9(&1T%i`ST39-Ghl1)%-pHa+#V0Bl5"bHF,3K'h"G9S +Q$60jYl*KJHl[bi[pV'kZIH-k,E*a1E!bhbKJ)RErL!X`*CP$51ClQH5%!,P+NS# +lQ,ll*&MpADai'ra-RXE+K*H,%LG55Q"-@qaNj,I99[aF*MAm`!XVZETeK"aCh+l +VTk&1rC!!'dd4pG@!#a1qVLK9aq3Z--%k`P&8GDR[@j'f'#cEiE6&['3S8"GQjra +fUNbZS*V*UPNY0lQ(LE9#8@0RiS6BGIVbmA4P1T4RS45j-B#B-BGNJMZ)F'l6#$- +"hlYQU&r*UJ%fE**RmN(*B69jf26!pc,GJkJlPF9a9Zd`b"#c'3$$9BfTHqA6[Fl +VbX0p68Y1D5Pj@qT#2KVZTBd!a15NU4'B3R*[p4e@LF5QIRZ%ZAFqZDijH'N0!S, +kDMdEc+JMBUJb-E$3BL0qf),iGLG4M@aIr0XQUGMbNdJkCRD6G'QG*8NI5l-Bj+D +bZ1f&51S'*6BkmpX@HG1LALC+%jXk9Z8ZE'cjYqF)TEB&1QN`6%CeUBA"1%b9@j, +'BGZ@DVNYa`3M%aC''k4*4KXm-+U"J"l32#1lZ3iC8iTD*SN"V`%ifmB`aER)KRe +rqaUaQ#f-rX))dVKpSqD`P2bJ%fBbcV&LX@Nmml2EjDaqkjkCkNS0)#Me*6*(e)c +$K5"@F"@c@%'b*$Z!ErFCrBk@PiZBU98$pDA$`dU90S&U6j%ARMTEY%ec6M@1f6[ +%UTmdIB2Pp+5Mii6JTBc$e8*AIQ@J-LJ0!+J2i[VP(!fG4V6qT6c48*PhKBe9kbV +ITSCVD$M08FrI%6h,d3iVSRX`q3H9(r2N"PhP6@T)S'%K4q1h%Ch0dIC2%AdINjX +VCr,NeEV+'G5`!!fIFM6j2+,&(0@2)PT&PhK6ZF4Ve'"!`cb10Rb%k&b1fUFM@N5 +6TbQ6hl1XFL!jfH5UX9R,&3)GDpi#,!JY9caIFc(%,S@hlV98D%C)b%eZ"i)h`)Q +UYM+9AEQSe&6Eh5HVkef&9DH-@6#%N6,PhKT)qEQ!e#N&T%jha939Zp*AG49ANUS +Z[94B1EhU[+Zb5JXe9@ePh&"Be3ZecM)HLJ2$bKk6J00[r$Y6CTmFIUfrYZS8&M@ +m''"c+0-R'%b"Xfa8-DDF8&4iNNYb4+h)S+pjbj[bXK(QD)e!eM6kN!"!YZb4Je! +&V8QXrJpI!L,S@kHMB*c$THjd3,pcMcM0f-%BfVN(,[hqe)R)LFQQ*"4K[h'YbUT +Q9P1Y68R&4'`2mb@KT(*F&Z@#"H1XI6b-Dp!IadrSNSMZMhSP9HZl!)-2NTV&ND5 +NRZ+)A9*,11+3!04c(,&+kR'1K#8B$%@NYHqR3XVdfVf-U!VRjI&JDj!!Q)q@L(c +[&PrS0)XTdGGVa#2H'U%pPR1'(FT,2Y+HYCqP,RI+cL3#CRE#1pbAAX@%*9$KLbG +Ur+&)M6m1"pDpaNEYDARB1Q6(0K`,83@m'Xf!H1SBIXl@3*M22mY'0$RVp[VM8R[ +''6K@6Rr)j3mpe112`lebQI-JJ%+4'`84+Lm3jmJ!rcNiiU'C2V*0(0AcK#X&`PK +9a)R49)[11H)'&a0341Z-N45@H$Y0%E@C*b2##RlTLVQU+*-VpqXi+RRF+)YG9&1 +b)A'ldB(*"SL4cm*JK!k)r%1q`KZjJIL#bPPlURGqRBSb0L*#kPbUDR9AjDb2P@P +F`4rSj8IiJ&+8PE#eP9$XVQXKYam(AG(P(N4@IV0T%NabjCr-6#Fc9Rj8hj)(Y$E +TPB+"TdJmF'Ek4"-m6M&P4-#9iC6PPYQS#JRN1ES@Q8!`H($GA3%YiM6()V&*PiP +Gb8M*M,[-9-MRS(SP9eAM!4*`E4lM3Y3XBL&YhiZlST!!f$2CT0'BA'N`b5iHX6T +6BGA8J!-"HbSIdhMk*A29HmI6X6`03DLfq&ZSQXNLA[[J)kE+#Q[!#QF4N!!5(Gk +6#LZXf6IKS"A5H2Va`!+&%#4J#X'19-,Hr4ZTbqllV2akM-dpp5X"&pXT4dHr"J[ +S1N6Gp(4"L+@TB6NM3mIhdPA-R'&jcKFEj5`#98&'*31HJ%68`q@q(D*`C2+5+i" +V6ZYq'qK`'Ll[#,!61JkJ`P,HJ%2H3&"dQGR&)AA#+Fj$pBk,"P)34r9`%1ZNDh! +P%KL0%AVh`'cDUU,"f3d9B@3(DqXcr'J(pqE2Q@SV'J,MMYUUE9c-'AaM`S8P)Ld +l6La4K1VP%+LjUNpKeEEZmkLFUEGpRZ#(466C#*LfaG'&5cG54U644RU(E2kHYmM +GA)pBZ0UhQ@UVTJGS!$41arEYf6H0c8j%+Lr3-%PX4DYN+C-)M(CkN!$$32TK)R# +5$IYX[bdEq&RfLhl4260aJMI3l8KTB4iL"$G1')NJ4diX3i!D-K3p'N(eQcN,I3Z +pF2(HbrpAl-dr[G1(c1B-GK0V+'D6A4!3Y1j2lSj("cJ-lk+l&Gfp#hd4VFD+!e# +%m!'6K`068BXKClk%kS"9dr#+9Nfp![1I&9Dm)K81UMMSi1eMbkJX%hN!!F6[!Q% +i14$CPTe6Ck4Y3LaPTm[Z%`S*je`j8@&(TXCRX6K9FBlR"lKmdMqqr6D5DbBQPH- +R$i!L%+PQ!9#dGfpVUUf`@hD@HQ")[PMUJe'qVa"J`E8+9aU!N!$j#DlPSX'8!c" +3%"01pBm[q`8qkM'N"d0kQMMMG6`ljj(TbK"'$+((%+IB,GIpU!'JGFlD"4!!@mQ +P2facklF9SfPfQp-*)9aNMTr&Xi&b)#Z,!%bb!%6`!!`#q-Ij0HYCRM+KfQ5p1Q# +DT`i%HUJb4*`B$(&L-+5`B&@bpLhmZ#@&lGE)Mab4Xph)'$6r4kQD'BJRY"#Fjdj +%V,)j1MbDSl+LjABGVP@$)28F9qH4'bl9jRZ[Q#YDM-h1TH-qAR!qYU6*Bc&%jqd +#)+2aVrd,1h3bD3D0E9fa835"'hJXbQ8T%iiI)E"i#N3F!!`h6KK#5DX1Fi9m4-Z +UQq%H(pGYVd8(hEB4&5)YCkAaS*XI`(e``J8k,4beC!0X-R&K(XcS!MZ(Lp)Ef6N +2A3BbpXAm$Sqa4Y2AK-!lD`Q+(Me(E*Pb"U4MR*&3b1mjRZiF2Qd(Zb8k$I@Rj)S +43e34Xf95!FHZ6H3k$aFcVQJDIY'%&RN#3'NZ'@!DNee)Ki)`F9GEN@#"D[PmVZU +*+VJ`[X*9j$P6Y#D,hCMpD93T*%)6MV)"-XX#L60S6L-86jJV%Xk-BQcL8(SD#ND +cGjq&fB'0,0M'U0)b3"kX)+ifL#c-,bk9JdJ464HC#IdbLD36"R,-SB'UL4"#T1% ++F*-fe(-QmrQT2#bb[Th1J4%`3dK'L0*24j9"mIJKUXCDrC+jZ2I+eG$eL[0i'5[ +10HPG!@UkVer)KJANL1HN%MQQ0&3MmS8L',TUiU,0`aA)2EZ#CPj#%1d-a+pFpEa +GFBl"!Jl3$3M1+CMRFU%!jNhEUI)RVV4m)kSke"DEjPm0&34UD(V+kCkXJ-CT621 +"H)Zi+j`Aic+B0(A`CYRjGr8"5R#KYY%!H(5C6"!kDQeND*A*X,4(*S0k6LD$UQ8 +bU0P-"JBCDRa'hV$k&i8!Tj9)VY*`$Sm%)e%(6erjRTXBS3fS@'0*M-X9j`"UmkK +DXpkC9("RR8#Jhd54PHk`5-5e%!S'lAiLS4bE*a)+alU)&#)d5S'd4EPNjI,CR+9 +Q8T6Gb',f4KN(J8A,6%*fji@CrdpK(+%B&@5QXAZXdc'@6%-dJQ'aN!#c!dj6+L' +J%YeF)+m,Z2LML$`CD)5cEKe9FANR%%AKme`JQQ`%GT`ED!N0TqQJ$KaqD`I8NIa +kaaLA&a'd,Z+R%3PehX6QXb4%"b)'*0imr,b'kl1$H`QpQ$PNa6'GLPQb0VVF8H9 +b@Fl,e9j9fh5Em'V4lH!XHShi1L0`cebBSq-(HQAR*0Jic5Dj'NFLM)mGQHQmFDI +c,4d`&ML+E@3'kRLEXF3V2@NlD[[5GS+9G#mMNUHZSLL-i"1$228q#q)33Tc%rN5 +Z(K0S`e$Y-+M3l!4-E1046CGLCU%HE1%)1HC(')@`ZC1EJh!H&l+!rkH`,1$(-X% +SMJ4-Q(i85H3L*QN0M[Nb+S-LdkL,N!"CJ[fkSr`"Plm"F[k2+!B+-V'eipKD66! +b`dM6,mJ)%5bQfR9IP0dbXh2XMb,BlFe#%,XVFk*Ce#i*U(J)9G9DBDLb%kLCX`C +4b81&hl*!%J*+Z0J-!D5`f1`UV%LjDSX$3A[4bCLG*S%(J1$kk%Z(+dZF#kJfG"L +,#CPpTViU#j2MJLXJ1Bf+)G'5L'3bJph8Jm)'CJ6!DN&Pr$DZdQaM"hCjd*b8$CK +!Q#0$+BE-IQBSe9DFGaB+)-B4"KqMDI*J2+8V!VCLJIS2rh1$8F"-iV%R3!%rk*@ +CA&6PZH2!Q+h+-l,Cq0r)2bmGUNJK@2Ib`kf!3&BKfqMi8@A&HFdK+FN4ia"0FAi +b@k,%iS%`'jd9"YN`-*+JHB5I10,eFcqFNEZiDK-A@CeE+"V[4b@+PL)#S#&8#rN +3lUFEYIYXdkUdI94!ie%MA%!65h"MIHGXm`frTJ2U@6'%`2%QLVPErVrK`5mdB3H +!D!HBrSf`S06SA06kH,P[@9,Ji@-dc)a'HjrRYr6BVKTHH,#4(JMS[&30A8U2ajZ +8%q-H`DG6#L,SZb[!,68i9F`X"M5b5r'N!MKPcZ1-4i)GQ-(J,A#b8Q'+T5ZYJ-e +ISM),SR)4d3%63'N&-"daJS3U8j!!,3bN4)!S'%dX06L4h0+YPJKZk@)RLS33N!" +Ne,Cd8FcfF+qP[f5d&d19U+@r("%@8jZ9c$!J24!D8Ir@Yr49L&C$6Q5eG+(c%,j +@8cZC%)m5)eBId-YS(-@pPP"'1dm#QB*)TXDaVS2B,0a[C84pH#+LCY5qb%K-,Z' +h(X4Q*L0Y%kiDL01eie5Gp"dX[4VJb3YIK%32@e4&i+(MmY#H(!9j`5c1dM*'AN[ +,eSDmTKeAN!"APJN6!pQZUV3KS0!f4PjT3N&H&b9dCq3PEbaYL"GU-p-N4Q",bf3 +%PTDS2CbQ`43K)c"dZF!XiMqA+eH+!"3H[S(#H6+V)L9)c(q5`B!UUUFCl8j'$$k +A6@$#h$Z"#92`!NbB!TN*dqKaXf&b&[*'Q8L,GmTA#RfiGQC-cS,m-cqC'C1c8'E +'6'D!T!M!RKF6*KI3B$Ra6db(L04Xj06-TJAGc*K'*c1Q-H-3YP91CTYc@VK+!a4 +mZL"!M%h!I(`%JBN$&#X$)"TXYTp4M!J9Q2B&f$aXh#RUXY,,"S)!60fd9r+!c#D +!iG-EC8+S(c1!SKTT+B-6M0K[UKeHDT!!#q@88LJ[X"A+V6IGKA*VVP`SVa@-NGb +"Z"L')Bqj,`c!,`Cf5h"qHP5qSYL+kMc49hU@IP*lH1QR$)B)S-9"-eGpB)E'dNm +JTZ9"D9eC%3Q-Fi%2mPP[#&5l2B5+!q(aMZGkiCLI[+A2l&[3@lM%#1E9JN1&5q5 +TMpHld*("Nif$9G3%fR$8!)l+aS3D$$q!53H3!%QqRR&S![K9bq!ReFlk'#EjUMR +Cj16#ihG+h3NChJj!33@`d2$%"&dqcb*")b3'LU9@#`F62&+L9@([-81+c3Q+c8L +3!"(mA-+R&K(T"+XJMcb(5Tm!L5*Qfq"aM8m-YQQk4PMe95A"30YEpeIF3%,2`)C +Z$(lQC'V*5Npqk+*G2k+5X1QcQ&iZ6`ISlU'KVNGB*8qXAME`aTAqlAl4#%@VAcb +"$Mf+1VZfJS*6plrcJchKlV"#YhMQ5e%I0lJ#hImZSdiD%L`k9!+MUMhG06HkZ%L +,S0*R$&@IZD(l&6C($k&UXD+UJENVCY,)&a4EQ&N&K4[-pX8Z)X%rV5dFR-lCj-( +0p*Lb-QA`lGe2ZJVI'-"2YJ'4`5!QDieC33mk`X4jbc!UG1PPCjl"IkD(U*BUjQq +@G9GVZZ#DS'G6995j'Bd3l3Z8CEZmCDG)rhJCYMA1C*,S-C%C#0"3,Z3')Ucb4T8 +e[RLV6&Bd`15k1`RdHcN*('aib&Be5-NJ*a@QLF2#Y8,*e))PCl8a!p1)f6VZfHj +NRr9lq-'mJBZ+DYeMS9L[IF-S+mYC'3j'VN@(iqQacCDX%'3qDb[k%6"Z)1Y3@@( +')kZ4P0eI4k!amfDkVBMHN!#hL1T+5@6Ip95*$Jb[aiFX"ZS!`f2X+B#c@)M(Nbj +-4-6lVhPMc9'$p*!!Q!QcDl-"hYGHJr%,RZJD&*p`*'Ui8#!@L[IaQLeQ`J$6l0I +39&KJ'K3,Ecf+LK-,*94JeLf$m0S@$Hh`$Sb(fD$'Vk@1(Ei"FeJe$N9$cX@"3eL +!US89*H,AYq,4FCU+Baiq++DcmQ8J!XY8#`IbNY3"Mr(qT+jV,4ZBrErM"RJL'1$ +*"`[%cE8XAV2B+#p99KL3!0b'@d!j2%fUV6!m1#K[r8e%U[eiX2PXfZ,r0X3!S"V +UZLC92'X'@f#Hfh`A+b8jJ2*3Bq0UeiF&iQ-8j0Abp0@Gh'#2`(Kl0BZ[8,dMLZa +RHS#0fAQiQDHl!NhMTj1k(B2r`C@4i6USiV'q!a#U#YGP$aiClH*L4*l+,M6cBC! +!i--H)a%V)b+U*cF2hmXGRB[C16[(-m'+Xc!KCVXb*Jc)9aeLak!N$a!(UL,#Q-A +(NlU`HJp0A'a$D'Z8'IQ61TNXJ38DRYNf96p3-4l'$+DN+5+'Bif%$(B$D*!!0F0 +($bVP%V+$S`eH%1GGcJIZGJR,*LjLN!!%1D&,F*q%QCN3-i&2@D#D3KR41ihF%5U +5k*%!k)kY'S#-rFFTDkTFHKe%,MiJLJ3q4G%,,bB@e)cV!X035Rq[1!X[II%T[&c +&*AJp@(`1489@X99fLP*)ZePHF,T(8H#"Le4qJCL13kH#AA9+FB!UI10FXI8PZ%8 +9Rf-e[,2"D(VKibBlAp(5GpGbL$cCpJ!$0KS&JX@GMRP3SGC@$-"N8j,0[pUBd$# +8FMXQId+a-##6!BH2dR81&TI`85m9L+R&Ti)0I"`I05B@B#R3q(#IQ#SCL'$XPVL +Nq(&jLr*9E-5-8k29cB,'d(qcf'kYlCL2P@em&pYp#1jVVcU"Gc"hBN)KD'9JB%S +-pcDG3pZ'8iCr+8ppb$NdN5k#`&Yd5Cr[lHI#p#(E3G@6$m)!+bfZ'VCGe@4a9D[ +&95AR%1`+fEU@kmT$fSC4KX89`jCA()f)Di@2M[Q"CQlHm*J1&8D8l2iLcZiVQc" +CE-*+$RL,"R-Y$2%YN9d3+"296`MAiBU)!Ia8idGk')+r-0$V'P!aA)N"5MF048# +*#fPj1L0Sr-c%crX2Xj%h%ldqaUY"6!@l+@%[e1RH')KP!KL08)I9&PpRG4KABNZ +l3e*Y+M([6Yp,jMHbh5Se6$d2G9TYm3&@TehUhZ)Gb)Z%f0MF&Yp,VMF'D'!Y@,% +3c0l)I!N[*!-%0B$K0r*"*S"K#3H!Z&PpL%'5!cp%[f)@0`$)286bLr6`G8`RpF8 +MpX*f8Abmd"rXB*@K%(Sm6*p%)$b+[IJ3ZYd`DVlp,YfVZBZ-l14NPP',M&CNe%4 +%MiM"Kr-q(a@EkC92T,f6Ji5-TRi`im9S5N&'HV"6Me-``L#a8B$+$`NB$a0kf-6 +!SrkYq0`cK03)5C!!J%82EF+V1`YA0"XCkF+!4IF*"83(1BYK(dDfTG8jZ&0dFek +B46JBV$X$`,)2lV&9U5kch#l8dK$T#,LHBp9PaA1-mR'!ScXb%6%lf9kF34SRpY[ +c'r#6$hDM!3kHceiTV"bU$2(V+fPJ-Ni(ff`61`kj#VZcm,2C9GPGMCpl,9P[!5M +Krm*'e'ZqcLqi%SIH6S(&Cbm8rXS50RXV'd1TmdJG(h4bpAH!arXlMm(SPIKCDI8 +f21kRZ@kF2pK3#c)3[NK(cXPESBM(80Mp$Y5CC*E9Xrc3rGh[C1l*h%0rqN$1,Q( +5$TIf`e$8VRQ8!69qQ)[(-C83Zc`3D!fLQPY!V`%,&Bpff'Z%Z0p%CUShc-e-ChH +Qr[BQ-[[S4aEjReiM"kFFIa@cq%`RCC&r#!6jaVXpkX[[`Q!k(Xm08c!`IU%@`AQ +BcFr-B`HURj8@*ZA,'d0e(Q@B!VTi"bjH@iQVHNBr2#C2jZ%,Na'P!fq`FKdkM+* +$$ffdYK)!i8PqQ)Y,5DCMh!(#AC&ckpKb@ApYpfBd6e-bhCr3TK1dk8jXqTLbk3l +DG!HaN!"`L6[HXffl3lR@GP-ZNr+@%F2h@!`2GXJra@MihNQ$[jLJG1%lV[,JPHZ +)T2)@MR"'Q6*")QfM6"D29YkZa`4`[`c!23I!+i%bEKJJIJU#'9LDKX*RMIL"@F4 +R-r&6!S-kbmCB!)&lfCqAmd36f)f"FB#ISGF-C'1!@l`[9Q1TJ$Ebi`6e%p3lCpd ++8[cT!*A2ld#aEbJf@4J*+f8$$mj(c`1"R4mQeb)94e@N$%Aj@'*Q0-$96L3!H)- +)K)Kq9XV9c"2lS&!S8pK3-DRfM9`8jkA9afX,hmM9P8ed55)(G4K5$PLKi&d2P3% +BF,pE(04ajPj-Rq6FP-19IF'i+(h`'KX&iJ0Za@RBdJR$PV)4KZ8l4TfXX#42C`C +BBKp(q5(`,l!C(("c,dbU)C)5Id5cY2r"+A!SFd6h`T`J'fB['ak#!CVe-%N,TXR +[@!'UJbD,JF01@AJ%`Zr%)-jK)dpIcmjj(Sq*i)S)EN-@Z#JB&Pp*JkQP`Up!*+` +F!M$Jd84TCiQaD5HR+cY2deC@mL19('jA959K&2Ae!NSF[UE4l1,AME@5@#m6)hD +jLIimKH@ER@3&XcVf)ED%am'@Z9Q@Eq31cb-`Y`,-6mEmNXHB*1*im[HQK'Z@X(q +2(r89KPR1'[c"'p)MI5)"0""5K[$r%5mB4YV)*&Kq!!aHqd3#N!$c'KadlKNJjdb +2l+aViCcT4h@2+0a4NYd2A1RVhXP1Q0hES!TbG0r&b!6Ahci'SM+Sh$-p+ph#JB$ +%#QI`94kH"@(cRNr`Cf#FX(c%'KX"TZ0YcX+6,R!aCH+(ejJbKX['kS3$TMlajhJ +J)bdpbCY2`+#X*'SHimHFKBQ"ZPfj%"5JPSpK3f%8MV83H&L*U-f+5`Q%`lr$aDf +*KfJKKXL3!)diE2jGjBj3$dehGdLEaJA6#,(cQrU%l$K"(EN5[,!M!h`Uk!")DqA +((GS%kE,EB4PYr*pc'@dS)V8@4YUQGaA1HPCKb#59S-qQQrL26E"c)"jE$C2NT8a +@ed)jb&@F[f@%@mGjADQaa!PZrD[GJ)DJR1c[%aS%efXb`#dll`Bi01ETeU1jR%& +dE&#Ba`#QcQ$0bUR[&$fid-BB9e"(iBHF9D@!V9pl`+BJ1339@c-(bkqqeYmM,J+ +&0-X6+XirZ"",'X[++%)!a*UlmepL30Z#$hhh#K6U'`qLH'&fXc-*AccY*3K+,jl +Bj#'$L8PbS4XIrXrUDM,BaApbaRMbbF'fX5k0aa*8&51M-&P*ACJ&kZGT-6)kT+Y +L%*pS-06CbA3YPJcb3cApcZbTK8(e0q9!J-5ELjqLi$L!B4UL8cNjMH@Ni*fV')q +m-IL[8*8Bl5L4HV5k,E&6pUS[(Zc,d'f)$C!!DpmS6Am68lp(8b2bJM,%(p$`#M8 +i)!cm!HE&V`9$-"AQ0qS61"k2)#S5I-%fq9"-(qAT8-rPDFDA$Ni-N!$XAXb%#aE +miZG`4hK%-pj45q4S5@5!4&CESjiD9CQJPN'Yb30RjL6F%2RaM@&E"blqZ)[J,NE +PXBX+XI,*&$NEF+6+1JKLSfc)$K%09p*""%Ti9L#N59fb%q)@I,a2D,U0rY3GHHP +kQ*9c3p)2kZTAqZP22XP(%UEBp#bZmGN`CrfhX(XBrDNX#MM%HVNj0Rcp%Plr'H4 +U39[Ck*,m4jPSaKZX0%f5VlCd(3-%1iM+3-8",KJD[$$'$cD!)@dZQ#"FcQCQmmb +(H1KI92rU-rjXFY$LNe4"BjIYq"JPbq+Qm9VmNj[L$QSDN!#*X23F(AP8RXL%B'5 +*C(6)c&RAMcAM2rL0R%JbQCC'U)YG*Yl5&[kN`q[iBE"!"[Q-)Y1bT)jh[`rh(Ej +bR#CFN!!(+0XZGbhE)9qKE)1mqE*mMBI98*Cr5SR6'*4Xq"G+-N,L6pr3f*bNCE1 +r6E*4V'ECqIPTXmB@")0LJRN`UZBB(A!UHC6r0qe@dAA,(iBD2$,K%D)c,eJmD*- +HB!!`M6-#J"VhBk1,R9[PLRGeRS'mc!jN)([VHf(f!+BcCbCNShp!PHbJh"EX(HK +!bD*pX+J[Rak#d)Y(A%eJUj1MF(+#!I"HYm,&,Dc95ki-cQ$+4JV&Qf0c#@ca"mJ +`#adUXm9XDSR*2"L8rc`A2$4kXDk8rc`BrZ0Ji,kh1"r'VH%J@SE(0m2809GdI#D +pq+(%#@c`2!&$+4P6LR,L$"E$DADFd4F!i`I&0IKX9$jAdDH%aa%AL$BT%fKHiLC +AJ"YL)9I'JTlUd+L(#99mKBH2c5!MJSUBX(360T*0lY9I$(!5hi5,CFKi(LVH69b +G#B!%BiG,0c(c5Ef#T'hM6fl1c[Q[I$JIJT9*"RUh)AK[a3r-Uk9YiJIPik18Jcb +8GTYQRQIJFB(44jp1*)Sr&N0)*K&VBaG)F[CDe[h2$VMl`I&'",BTdeB319B%G8h +-j[J@)cFH2"MLiPFQ&8r!cr019!QRKHIGaTpD"8bi*A(dBSM1GV&VjR2mm)$35Il +c@b)HHXJ$2j!!+Lj1XKh6MDKF2b%)S$LJLP%&iRd3f*(94dU8Pl-'qYQTI#BPf4! +TBcK"m+MNj3[iMqHC@+L3!0&8IrIrJ%"`(GPN+-cjeH3BI)kb%6ph6Kc-4%DD2SA +&2`!!-BP"4%05!`"B)Jp9$@C'%4!KiqjKrffrPUVdjZqk[VQHj['jVUYkUVCk3I0 +%GP)h"Zc+!VeZ*V1cb*r(e[+3!)lVQlQ&%-)9lHHA(A$+M)K1McJA$K0VN[%mkf3 +HYa"Hcm*kK("k!b1%j9Q(dB#"*YdNlh`c(Z[[hprrph8G),ql*1mP,cm!&AGH*2- +J-L)5)I%!%5)'AhPG*Q-ar-LqCJ'NQ"c!*L')CV-(JC2-S[20R!1c&,&8JZr0qr1 +q#52iqmk#M2G`pECDKMbLd51Y3amCHVZK48lF$KFUBV(IrB)9$i+jGMADr*`4l'r +h@haI,j*'%1&V@$'3!$VG3"D&JAKK))8c#+3,I1N**R'qR0U+J,#d[d@@iSMNQ$K +F4Yka2ZGiShr!2`#`r@&r($qAeDh0F5L,bQK3@RaM-0(+iVm'I"EQ!l&N"+cJFTK +`k@35*Qc#G2I$E""9ifAHl#RqDeZ%Lf9SP9)$-MJpFG4(,I%a,MkL'[&(2c,M3"S +Y[YDM,QA4,b@h!L#Z%jG$)#S[5Y8d3Vr[c#R(PeXFh5Q'2B1c&p9G9m3$fZml-mS +$RIS$fR6*8CIT%CIaF6+LbT-UD*qdb*i0(EjQGF,3E#fb'F&d-d$N%%((G3LakR` +CBrj4Qm0[*)ZeU58Cp6rXD9CVUILMYU@lYJ%jEKQh`A#VM&"r&`##-#p$%1HMj5% +5b%2'aX&Z,k$'M)!D@DbS3(m(PYUc23a'$(r+"[qKa90L"&8#+92@`D@PLaQ&*2" +5K(&fK("@jrR#mUhGNd&1A5$mrLahGlrP#DHa(%U`eCPAHiaN@cY!iqA+)aH94k* +B'YKlIc6Bhf@%("E!ZZGZKp5GMhkNDJAYqIZ65@@"Ab`iZmY)#PLI$,5'$C6$b%* +1DM"$ZkfpXGehK8d@#85Y+,,VLqj)JfA"Cq5NfAD#LLNRl@dR#[RK(!F6fFLNa$5 +9Q#E&G(+j#d$#C!#AjV$$bU$*'!cfcqq6UVYPj#X)%Ph-b2#+dp1Ke1PBc*FdU,! +",Cj!+UX($1R$aXEGV*TU[$PThAQLX14G[Y0L,"'`a[#@YY-#k+6ZSVbX!9+bmX8 +rDe&65br&k[aCP`6jk9l@[9$VeTUk@9K)h@MH1)SSE)KZjX8Q8XjV-J`$#MLkHD' +CP5J(a36hXrM53F25SiX,ZFVd!K-&a"[%e%V6ZQf`IPD*Na&-cF4d3N`RT9jBkej +8#UXUKf,k,+Y2*X0G*(Mab-1+i+@m6SANB`(jl+1Kh9r-aU(ZjI!m&m2V&R8E95, +U8dG$[-%XNKld`+IL!EIjqc9)K*!!`,E0meDDcQfhB01Y,&iBAVH4cjNH,eq'J2' +EFcNC&U$JP#CPf`RHQ(rH*`Vc)G@Ib8R$Nc45E4dXEM8Ni%)Zq%PF[!q9j1+H00' +P@A@'HBT8%J6h$!`(B"+JPFd(8%&[QSP@!CBmZY$[FT8b+2+p*a)&A[8R+QCdKXS +VA-a+SI+(-9'S(VdU&a19GSmZ[p%#SmIPTUkj!P)E,!4[B#U#BYLN#,N5e@r&%DK +q)DpLF5(r5kZq2+hLP0EibNkPkS[T%,@H''#Bja9@&#J+L*+KjpS-EAIQ6TqINkC +3[6[R!Z-Il@kRi)HCSAXC*"b8`+I+@%)+512ZiZr`D(iNfX3"@2Lk9f2QbENd&pm +@j1,bRr2B,dAHHpL6Z46&6m@P)(jFkV@V+*KR0Nk'5+e!A,'[BG2fM&4lMhe9I9T +jYI,B9j8VP&I'XDqqkPCHK@KVMcVZT$TiLlj`!`+TIj%aVk%09F1N["J+Xh0K#i2 +)jQ6TZ+faBlUdS1fqEd`"k,*Yl5cFbldEUaTl0eETld,eEk8TQ`mJ0*Mb+r1,%1( +`4KBZ+h-#M(-%(Jq`@[@-U%9A@@MDC)$)%SXcKDVHj@dAT2VD`9k[Hd9jR6rBkkp +Z8PjlMhN0#(EcJ[)b41c'SmaBT&IH&)Nq4m&9'*9Q9iZdcc`,!U)F6N)SCh)jb)j +`NSi)R`'f!da-%2U"M`pKNQ9@1@9EBT!!hK1@lG"UH)N*k,d4e&0iJqi5P-jb&9c +'ZqJ!p`&6S@-B8hhMNq&*1mMeZl,e9-2A(aFE5$K,V!$K0'(5GQ&k@+`94G'GFc$ +CCFBmZY'+l,Z5`hmE+K(QbL#%"R`PV3SK-625h`&J--SGbV#S5+M3Y"drjUr[389 +SEb%p2r@hBDX5r0NTF9h$56ERf8(#Zl3jZTi$qkA0N3maUIV$!55eB!k4-hmii,2 +6X9BkYY9SGdZmm+'6e3"3V6A1piiM`,B[b%K@U$L4CK+Gc'U1GiJ8"5H!(11r2A" +EQ0Tra5&HmDSi!(-U,GE)`0Ld9T+CMC2*hBAaqG5cJKNkSU3HAQE'Z[,rhNHaXD, +Sl[8L"$(-(q0cUN9bVV*b)66h8UaD(FF(NcrF$Xe9aYDTLhT4c"Dd&MBBFAKaFQp +p+,pGcYR!S&C(mm&B+&q1@e8RZQ"PQKKHjb+f'-ZE10cJJVB3X59@+G)UraIr,r) +rq#pkc(p"j6m0r`A`Rhj3eS)8NL@icl"XK[29`rK$d%+0`SSN@&!BY-D'r!q(&%1 +ZqBG$"cAN(CcDC82q,b`k'ENah+SNkHT51(blR+lJb3pM#p[qi4!HZ$L-BqBLUAB +Tbq@d`C1rM5eB3jCB,#1,NmrAYl@(X-$*AD'ZGiU04PS!F@NA)kU,Em15EU2U6%U +B#Gm'`Ci!0&GZ0E@3!'V4T()E8+fTPVq'TFAU&V5,)69j-FTTJYLk@&e&!#a-L!, +DqmD!k)Cb1j[G)cCf([%iUA1YT-lPSXlPSmjeQ6UAP"G!lKV"f2mEEa1klIreRcI +18rKG9d1TdIrI,j9d-bZ2['PDm+Ki*0&G[1+44cMerX,GKYJPP,@dlDQYUL4AN!$ +*j6#-C230p&K1V)DjXa0Kif+CS!)aUA$LDV0m!r'B9#Gi%Q(&MdP8&Mk6&["`%YD +dYmL2fB%MHLmN'B+`JQa`JT*[K[R&8N6L@$im5BG(eDJM,Pl4NNMaah[Aqj*f!QE +LH1dP"@kH3rV81TMb*6)44M#AZT6kfF0PIrQp*8lU8J@1fISA,XGL-USLmIL&2#B +KGi3RFqr+k#)+F-1!akZNi`%qI"GK,C,jH-P-cTCcR+,qEPk'`1kC2Jll+SpJbVH +#J0"fhQFfiia%3"Q-[FpN,m[TS$qmaD$a#K5+hBJ6l,%-,T`J2M&Ei5Dl8RK5R*4 +MYdjm2)$$rq#6d@SiX2`"j-aJmJD5CJH"5[*aUScZ"DRE-4PmrMk!'CYalaQ&4IJ +R*Z)6Ba+ZR4X"rMmFaa&F&)!mpf`M*RFU%TEfXGJMA+"YjiSLT-6,1-$#NAr!RrH +cpP3Hi48cY15d`Xi`fi)rQf'"1#aAj6-K*E41$BHL5iY#8-[hVLH(`I98i+08i0I +)H1$S4ae-bVh8h@5NP6SI!!J!$HkX[IL2'TG!(ReCHfqqZ0Uf"),H0S1$'3+m'(h +eFm5JhMIZI4IKq,#G`6N!H@&M"Kqd43BbFMKNJJlaCZf1I((%FV"$USBF8MAd%&Q +LEd5qQ,k4iXL3!%2UKKa5Gm`KDr50b"[T'bQ1$MQNGXJKY8-18BIYJk39,r*`[G, +i%"D*CfE4`XRQh@Yhh!H-Q5($K0[,H`K&h&(m4&8$KUI"3+a$6DIb1Ged@'3f)E+ +*[HXpeTQPJYc5[[@qmpl65l(UB6Yq+[[cLjE8'"X`3ZVhB$SPF#+p#G-SChG2r0Q +(2kX"#qlMp"FcNE&pB0m1FCJ%X'81kQSIM'Sl6(NIEVErQ*0NF+p%Z&X2pQ%C`ZE +9"VTVE-AZ0h[206%FD&16U9ZX`(cj-a*`h`Sea`UNPd192FbXpBf$A*8a#HZGiXl +HGakIlHi8ZB1@B$-V0Z$SD9QjApRk034r4R(HGXlh'LkqST&IpqVGJ3q(+ep8la$ +8$F#!V84akpe!J4ZLU3'P-b5(JrZ@8(3DG3)%eepYjNk!)Qkp5JR6c3dM$`Bl(,U +q*4d'%UPiVJ)!Vj1AC@'UllacbZ9AHh'jebG$KG$cpmR8V`pfjiN*lXiC#G$J*T6 +#IbFi$Kd!4IMCli+d!VDeim9*Aj)!V*0[R8DDpM354&h'I'2A`MIi*6VD'"DG3"% +diFD,`MVKD-mJ13`JE"[IASbmqU8l1$)lR*@[EKSHcX['*@3N#(Thq9I''HChRFr +1El2-GF2-p`"X1&'BFTh(cB(&#KNE"@bL0KF#cprRMFePXh,$`+bf'"`$40+!bbj +-k#rplUcdE69#+2"kF8R3e`&fEmTXh,d*K,U%#68"q18-'[-$Z(PaG+0D83KFL4c +qNNK))%N(pm4#J$l8m3FSjM#$(lM-$Ha!FS+"LXPLb[lZKUi&Qe,!0Gcpi"$&&kL +K4eTL,dVTk&U'V8l,@(C3C0AEG6L@PIAhmY9P4I+YHp8PSm'ai'8j-eCG4H69,!l +DB-69YIK6``'@FIk4%XN+IF!lIZ5`0''L,K)3a!f$,QFbd+HEYQl%CAcMBM-[JAS +IJ1LQ2,-J,SB("KmVAhUTZY*Y'Mrmihe`9iE*FC!!Jr![LFlR%N&FV"bJ!-1UV6R +T+I!#GN9hrDREp'lRC8B)")%A@i@EC&9Uj!&-FBU&`q4KDj0)ID,DCk[h6!DHNC- +%SLkrcNB)V'5XHLqE0UTC,N**``A!`'SIUbjMBM)9b@X!K,3YRHMm!iScfrMhcXE +1ar*JlFIK3JQMpYJ*CSVi1#4-ZH2'Fl`j*!6(P8"DK$81)L!M4$Km4%EF4$`Z%ZQ +i8Vb4#-S0K*rR2-A&(q1RU$K*(lZ+Pr0(eFe&APd&9[#R8PEAUBmR2N6T`dMLJdB +ITK)I`[5K)[%K3KpbB`%e!j0ZU5j4ME'!1mSL9jXaMG!dP@-'l(GL'DVYVbjcG*X +`%Pm48VaP"3H)r10'B%XRM-lekrY5+XTd"aGq`A6RbC3Y&1l1IpJa'@5QVkeM8U* +T!94`fdQ!T2&6$8r0XTV059qc%HIdYT1C`adrCPHDl8IHJ"VY)MADI&RUc!EFDm+ +m%BpFYiNf*'8Y40(+bY'6T'hr$ETbZ3M4K9!Kl$)@pT6-DflV#iNe6@`$*,Ca%YY +8'M[G5f,V)l(G*E%9Np!F*,5l*$5940DV1K,#1T83dd"#3#X6SXNQK&+!8,b+8(S +53M%63JN*S6LTQceUJ`0lTK$SEpp`#ijphCj@JiV)Zh(,Aajr+GClr*ZQE(VM5$f ++BGjTmAIj*P+hf"Pf@Kcc0rJNj9TMSm2#h4i0G,3V8R4PYC5KFe,H&lJ6#3J0US( +CaE#MBm@Yfbp5S"1T,VNpS8!ZJ#Lq8Z0kJ#1X!2dd*R,#T4X11A"EBjAcI#F$d0M +L@(A0kA1fFjD@kPUR*@U*eFCLZ+Pc@N"ZmMUji5fT9P)CmB0erk(!0,N3Nd-B+c8 ++$Za`JUpM*hM[GQDA&-8A4RGMiBk4F--NeKRe-KcPN9SJKh9b@Z!+[A3UFe@"i%D +-m`cZ*"j)#8C%GLU3!&h&83m!`T)ha@[P%1[",[,bI[dLR[Khm*Q+c[lVXl%U9"r +%%+!U&l'G!DfA,Di("!!*J2#h"!HQT9C-)XIFjIa)5AL'[mhL5,Pdq"A-!!N,%02 +N[0J`B#[qD$9k6c89VUV4SSF)CKX%c$L)3P-M0$%T*HM-Y$%mpLA*F@dT"4dAkA@ +4(Lc&4K6BeS!b9Y2K+Ib-b8ba"5a-d565`a[AiY,E6M9mIX6e!!T!DVZJ8Zjb9kB +IUmFe&P6R#KZhh0FCjS+*p'0f&JNN6ZJ#$"j`YPq-I0,0,LKbQq(bCb*VI0(q#ij +ED*!!j&c92[dc%IJM`BB2D1lc%-#a46KA26ccYVMiBhd`69l-DQ!%651Zb99'dM1 +""b$!aeDkf%9rBHCYU,`4Q(8a2KESifdm-KTT`BGQqM#,iKRPK*U2652$bkYYh"e +L)hIfbiHS3Fp$I3riTF'(C@6TUBCAcr,PBb0XkVajcaL1cFLH8`f,0[(+Hdhf'2q +%"j!!DX*2mYGRC8ifibFV%Icam6rJQq32q!8H3JI62pZP$cpKHGB2SrG0*$DBF2' +2IH[1rXJDN!"YG[3EF5H*E+qQQ`QkfCIKQqE[L`ILp2&!J@p+(k'25b9b&6kfd32 +&p!#Vra%LqpYj5QaZ16hJS`IfL)@4&X%Li)9AX,ad8k#E'Z@K$a9RSa(h6G&)LQl +1dJhJrQLBa&SUQ*E'pJ8l'CXT)))q'!K5bNiXX[P0c`!BLYA-"U0ipKRaiRcE15C +!"S$cf)'f#lLaRfVB[edK4M+bcl!c('[B35EHcc"4H[r(&m!@Ii[%Zjb2`jmf((Q +0(3d4,Uc&iKjDl)ET,m1&Yq2#cX*mY*h""3D1!!lBH4+9RT3!*J63J)I,+4QdKii +Z1p9`Z*6"A[6L,P)Ga9ae0*l`XY+k2F[`,iU-(CIf'DiX1`I9C#dJa0IJJ,6$(9G +8T+Kk+cHU-ZcS0#[J"2&q8mH4*JiJP)SGGHQ508-Z28#'Jc5pCq@9b&@0&aLQY)" +b544DBU&`JGjFK-A01IQpJGJb1Z#h2Jdh+P)1!"PLbcbpbUBQ5#(B!H+X10,%5FM +BDLGA+IlM*UT8r%UNT2j`2EE+$mCj%YZ$4qU84kV%4iKE6%a&0CLiP&bhAe`F8ei +diKp&edSK16$+AH[TY528YC5ZRS*3&lKl2Repj!&ZEJpfpDH[d+GCdG'I[JRfmPQ +K0TjqEH3"%e485[@%LCcq9Qe@@"@UR,r**mMX6P*S59*%-&GX2m4++-dj+bZDeic +[ELBhIb5k*SU-CHfc`d`b'lYmSk2ajlSDfUHM0pS,J5hh1Cb#!SL$Q!@Hlq3JllX +S#0RTq%##('MAdKScQ)UEp!3h@10N!eLR#VI4B*QGbma[lbib9Z$BepZCf&-3NC' +Gl,6ZXiTQCm3NXFX+8Y6Nk'%4$G(#D3f16+1)NVr1pKrFS`f%del5"U#+8hrr*DN +pmSBaAf3diT*rr`B1#3qQ0kh@c+#$5*`53"22D%KF+Ha$E*JCGM5XBp8ekcrT'dD +hUk+%bq-JAbBl-[hd$$p8N!#q`XcmMp!B38E`!f!-2qYN819dSmCGA(+U-eQ3!2j +fRh9brYK,9A0LG)**S09kM)0!Z'+-NrbFCRAf)Z&N,rMGVBrBcL!je'rK"2eSF1p +I8F%pKH+Z"32D@3MX[Xp!4$EHH(V"cNR,aY26+AUS&JmpTFiL"!`HrK)9[YPiqRD +TXI&`24FjhbkB4N!j@MjhDqpIJ4312TlK`fEC$DP'@8+ITLI!20j#8iFD@U,aC5# +dTh`bGJQ6@XqX%GLY#jA"ZVUSK9YrHC*4"A"@lfC$R#6h"RDR0@"jhH,XK8YR(CN +%6+jJ-NQ1YY0LN`2iU)82S+BepVF!5IkZ2&C&a9@(#UGLAcHi)BK)jeHP-@i%iqI +BN4pX(X6[4&&RLJ$RC'"X-SZ1-bCcP%k[B4FICJYC@#!!PA!iDhC($ZA[rQ3J-0i +prK-81C0ldi%NMA$G)RHb5VeC%%'!V@#6*rlM-U$dfS,SYXQ#RJ3q3CIm'KXAXfL +LBBI-kHcDUBEGebPY,RdU-lPJ[RZ-HHlBAV2a(*b&Q2bdJZ`!NZkr`"8pFT+f$fJ +EA6kR'SDpep,BXF!%+YIE)R-)fQYl6kUk-eA5m3D$(!MC9r*@I!A96"aT2Yr*abS +A6JeHH,DF'$EG@@!2QqXB#K-&QEZ-JX5$'8-8*UIQEk%Spp"RTm%165K1DR$-l(* +iU85c-jQ&bQpQPCrZ'J43dUXA,c8(+,0+"Vkh+-Pf00kja`iJ0bj3)bf#qQ"Nf$J +Re!Vjl,b!B1(X&',&0BS'm6iR16(C55#l%,,XZKK9P'NKTiZP)8l03%afRc[U@&3 +K8iK6pECa-f'P%F8H0#GPjALIhA"10@cCUC!!pFHj`abjJ)*!)L'69je82'CEGq1 +Yfd+0rd)GjimrE&+ea4rqTKZEV&)+[C8+c8`)2*836M[%MCH1*[&)BiY-6F[U(8- +#P$T&M44QlLdb-cbDECm*BM*QYRm2B6*3aV#H4Q!(,Sm$P@hQK!J$C-2#F6E5eXj +"Uq`Tj%f'm+0`I"1TeGmKL9rPadH2q2!S2T6JS5!%9CHGT`YDp"3)1C@@NXS`f9R +,hdi0e1&NaZj9&CrkQKI4c&jkMI[qAXmP4A#2U`jf"MZ(VSVL6Tf4T9*e1FrhRPr +jU4R(CIjGQ!-E`bHhf!3f@(b&a@lPS$ZHR$M)Nc*(CB3UEP'Y-i"PeEL5!,S2)d% +$EVJIe[YlI38BS8PXKpdGAE633G5!6(4Da8dP1X3jU9iaIQl)Q)%bb9k@C&SVb1" +c"UN2N!$p9T!!r9D$Qjr"PElB22)A-2Tk)`q'Ni'Y6@U5!XKkr0QNZ!eCS8!DXI8 +H928pE+f((!JdGaCE82(a(e%Sfe$il+VQa-([X`+MlU8djbI&e5-8&aKA(mM2M'k +`bX!$jH5d-"EEK$reHY)Il-FrSJP,)iH%k(VfUkEL#$ZDJmX%3)ZDf(X!,lI$4A9 +2V"`1ZVYLCHbQ'b["bjGM0@#(NJSM*L09KYeKDE`e1i$MAmDIrILcLiFmq#@A,KP +bk8@q0#UiR8M,bmhS6YDaf(XE00q%2`Jc1V!"Rc&C2A2(VhQX'c52I6MJZ#1D,S! +pAIEGCA"@NM#P'Xm`rc4LZ5F$J$X5Uf%h+U!6Ed&"m'4X'jB+*eTD#YJ6S&[ChR& +ZE+Xb8e[H#p!cDalm3EL)Pm'BYY2&[-V&A[CB$lDK'3'F,Z03KCZ1mL8J[P`KVMG +"Ll1!&`F$ppMlNmY*#C86%`bJm[GRpG""-RYG"c@cA#JTGB$-cd6$KM,4)"-U`TP +31#UreLm%CYJFV0UFl6HLL9qCEcmfe!SeC#8bBb48N!!"&@3)&45V!N(K-+S5cAY +U(#F,pJfhTZ@k$iFSS[@k5jAaK'c0X2-+KcRVL95[SHkbU8KdPhC5MZh$l`UR3Ma +3,aJP&02laT65A9BFT$XXSqiJJpq!8XNUAD*4PF%2UG&0bf9*,0"U"YlC[%ccLV4 ++a@8%3BQZpP#-p8,Pa9B8mR'S0b8"fL-DXK*m8b"SET4!Z9I82MVk%`KdYATh*JM +9qJRqV&EpZTS-RP*8IKHk!NMCG+RZQK,FGX`V0[(9iN!eS9D$c2*riU%ZiHL#D&T +qc`ECmTGRBbh#lC!!#dT4[6r"`k["HVA1(!F4Dp'*'%*J-&")A&`hi-!1TMH2elp +3QJ2XJq1FqBJ0k9X0$4EfE4KBD)9$8+KaB0Sq#YJ'M34U$lA%eR0LS-%bf&JrGXJ +[ICUrhrFcX-P`beR*a49Tb(Y#lQK$h[FD*hPJI%&+64fJMf#YBJHHjm6Y!CK"LVI +#D5[aq8J,J3+fV%PU'bR%-p'X)$T,-2%frc83'bRhRG'BlH*Nmj8J8XeKE[c168h +e)jd-UHiM"dY85EKBEV%mDQ1S&daI(SY#rc%5Dr1&AfQ&@iC0C6Ce'C`!IS*+lH3 +'Kh$A+eHh1DGkTeDf%URjH4UT%8N2*MEK9`*d`$D&R*c)-%6I"MA3"RIp8R89E6q +!lFGjFfJqe()QLNl2-)60IpaAi+B#(MXqEH*2Ck,%a2ifYNC0dI3K6'8NTDL&M3Q +P-+1$hP!$M9#F@9),0P),YP-0[qY6h&RA`,%G#T*!l3ZLBh!k8@E9diTkf*LQ(-4 +&Im%APDq6JYJSe!-,"FV"aL'rc)+*c'BY[cQ1#Za5&)5KQh'rjB88KFcmMJmUJEV +i3"fPT)ASeRZS-`pPr-S`,)G9"fMiD1SFXT*6SQZ'0Tfh@NPeQ+3k8JVBpeQ!I6i +#qciR3ZHIZKR#"$PUi(5QCi$#i`'#qel*"&9R392J2Yk`$[Jj&DE5#[D[hG("i"j +#ead("rFL2RD5,BVBfMhK*)(8dMi)c[&3-Eb4Mc%!%!0r5'ip!AECC3Kh4bZT&6r +"qaG&FPpZBP9ep9hjUH+5Pe)!EcX65Jabi54)#+`q'm!NNTcIc$#Kc("6J*Brbm+ +k[,+`k%qqM"RFIp1`F!`,ArQc,Ia+VE*3F6FP'$S0`-JF(-$3")"KYDB$')$#P+C +H02M)++Q60Lj##0[1$TVM,mP`E!m)`q@-R`I@Z#`jC-i%qc[8-35mafp2C!,p(D2 +DFef1EJ5[28L'hPF5Sp('il20ZB#MLer[r5[peE+1k8q-`1&1GYI1cMFHAj!!`H[ +Fd4Z26mZJTF!+%iN!0*!!Q'#DKJcGCRG,J5kHJi-X94B@KBY3i+IYbGFcr")B +4bl!DTN0VP50,P!2VP!2VF1!1p4!89MNU&GH2B[D),N+U-[Ukk,UkHrPZ#e6VGV# +!&NUID&"pB"MQq+(J(XY+'Ef$0V["k!"DM`@8*N-i9!3pbND6rRk2M+lP$@*,e+" +-f9)9YV5Ah8FE"aDH`b3*XV(cQ)dT+MbU%&bSjI$3V89fdGD#Y$8E05B#!dc#U`4 +TX8'dCY[e3[kLc!Ah[M0%I+(qMTa@hZhSf[X1a"FkI$m"98"mR&,Reh[Id9me3(b +&d"@0)3d#55$!b#'#55$!L+h2Em4[KX%qlm#fA)12-LbQ9'Q(8Vaa8BQT#[)B6+% +U[+L9UK+PUU`H@XJ9`HKT'I2ImE&K*p%(l1SB9hB1eGY`"aZC`8ELMAH`N88K#N% +qaD!Q@'$ehf+h(eldk2qq+$2q[LR9QQD-TaI#C$LRCm11EL2Hf,f`PhrJ'&$#30c +0*+GI'#jA,r'(4)9#kHBbT%,#X6##kUa-E28i0pQPVD,)j$ZL1-4@pF@mBEGG321 ++5pfMkZ0`NQKc"cCB`#"S-"YZ`,XGkE8iTmV8#KiJ,"YR-'l1JV!RqL-iP'%5a#5 +)53!6$C-`*J&-2[i4Zj!!S5%&*KXC+-43,H*5j80$0(*BYbSTUK5D#fKJDV5FI@a +qf5h2"&3ch,#-94MkkCE2ZD+E2J(D-cEaB&#qH)%"2aJXYTedacCB"SGZXUE"5@J +md$$4`)#4NFqih1EhE9IJ'Q!bf&8&jV&Jj0GrKjPPT`X*DRqX8SFri&jh@53C#Rj +eN4e&j3k#)KQ!21hLBEeDPD3aZ3HrfXQ$E,Mh(,%CB6aFldipBJ0T![RDbSrFi`( +k8Kd33@"k"4a"Qr@%BI9Q2XaRCa8)dd!)Ka3e!&B-Ge@HIMXp$M&8&4c(Aj8A`0L +piSl--9KIkad[5[hm)hF@!r)K(2'1pb%KbMG`&X4V)bKH'0dcHF1"C1d&ESL")Ep +`f2T4)jA@Z++1#fZPD)JeF88D+5j3$2Ph"`eVeTjUq+0G$0l0"AKBU-2R8'8AX`N +l1`Y,B1q6[XHK*T1qVj(5V()q!B)2+0f)$eKqE(&B`+C9Q3cY-#K6q3bR'b(SbAN +-3[HHF2r*"XCYKbfd94H(i'fGKIbcH&LQ%2lKZ29qKKNmiZBl5(K11(""Jcp"S5& +YS3e@463&B+I-*eCLif212!r"KH-GqY'm@Br@MarDYTfU-!(@*L9Jhq6Q[JGT64B +VGHJDA6J1KSJCE(Bc3DS!JE"%K3!N9km53,+[K`NY[4UMbMEMj9VaNU'jF&T$b-& +"VKK85MmH0pDEF93`!rH85LjZ`maBe*j*[QLVFM55aGAMbQ8[+TI9Ab+a8Ce6AVi +f5GY*[%4$K'T6H6Q$6J9"I+m[Fc8"G&CFFKHlZDYYC2F[%iqe8YSja!*#Gi&S-6K +JRG4q`%RT-!'1#9G9N5"1VdbLL(ap$p)+TDr[35*&I0!LTS9FbE(%3Uk@NEMPLX4 +jqkdh#PH9E@-BYBf(A!m'#aTT+3D0`fJ5bJaK5QdQf-FeNhmk,kdc!(%if)8)2X2 +X5pm$[A'%Z@J)Nq2&JTNd`8cf`M`HChALCcA*5Qf9mQUPfrPhhX+iXGbAqXf$9eC +%MEQViamKJFkT"5QI02U0CFcf)U%,9U[R58ScKihlQAj12I-J3Md[8Z+i8L6Tf4A +Qdc8Bd"%-U'm'J8LYm4crrf9f$IRdMj8K(cre'eFRT6i!j+GhqAEQE4a@*3Bpj)9 +[MD2DfNb1@%'`PCY,qM"%SC(d#D$j4EAA5!T9`afNUA2U-LIcT2%GGXh`HkIJBT' +#'J%,KdpS8L-D%%fLFBZlP5HF,#2h5k4Ef+%"BVRHakNaVZKT*-E!H#14VaRRehq +H4DG80iHd@j!!#dqi&aLIF6h3%er#')VNXrFL(q,2$EGm0KrjmjPh)fYrL@#h#F& +5bVZ8a!Y("0`8dH"0p@$[r8K22m3GI-[G[JF(%AXCLje*%EClV1$hR'S)Aq*'h8F +*rK0Uf2l*hhNcidEUB-+2G"Lp*2be*2)6*(!-`'PpL34H*EVJPeFS`TiecZY$0AU +h'lhr")&(eT!!`&&XArjD3Z"mkp-&rZ8`#E`'S(Q01rphAQr[jmIK+"!qHN0`%@G +cl*f"H`'!d&ii%I5`U+TfdZ#LCGcJ@M%-+3pa'1c-Se0Gd98qQUSN6)5A4lk"#X' +XV!Bj+*4jHqmGMVa(*S0E%+m80T12V$*-RXK$F,@Q&"*prQ$Q@@F[Nefi4+bD6)* +N9@*jbq6(iXCGr(-EEL#bc@fF5#j)Q"8ZpU0D0L[I+"*[0b-Yk&TJf0)$eIm$Tk4 +[2a$0#J&6lZJ64JL5CNb4%9B*%IbSrZ"'5!T*`',,2A&R2a%cKf&b-j!!MCrcD%8 +2UGP6$D&C%0)8f!!(*mpHl64k"B(KKN3mq1IQ*f&drHXrciNUEJ62"UGIU#rY3X` +!iD"iSCHGj&%GFD'eG+&A-*KX*AGAA!J9MA`$&h)FFb%E1R3r*E9$aNhCJk'%HrQ +bQ4Hi,)1TNJCT)AFi5P#!f$qN3Z8%QQ!!JPPEaFcDi!#MVBNKYTL"#Ud@3pRk3X3 +Dl4*$d[)2ZU!9)UdM4SVKacTh6MKaC2VGelj[8iF(3hSmF!mEk-B!!a63-j0QQ)F +&+e@VX&,A%fa8c9!fkNT%6@&SiQk2b@bGSi--3@hXQ0f[6kIc2+JV-8e0B*VQ&+D +TC*!!68*('l`T-33$eU%`5dd*CURfB-`5&dB4#N2,-'Z%EX$$h2B)*Bl2'jM&9$j +Vp(QG#-9MG9#4Q`"l`(c51Y[192HPXprk&`$dh8c+2'%eKHDA+IUC8%0&R2aU`6! +%mUB9!M3"VJPia8*(2),A69P0BD1U"YNS02j-dU!+8m6XR#B@VISJ,&Uemcbl%)* +4UrBd8i2&-0a[SCSL%d+jkk`BZTk6f#rH4T)C-,%4JiCD0R,#B3e$CVGlV+PfC)% +I3NSij8RK11%L0qTkS"!#&)AG58i9+*aB&@kEZ8ZQ&68$5@$KSkYC$38AD$$ET+H +BLK++IGfX+%L2bZ3kC9'+d+)8SCq+81-Lp!mm86'R+D`JP%YE8b(23I-ac+!e8@" +T$+(Fc`aKkj!!)3Xi(1+ZM3&T6eCFa4EI36I&YT4!kh6EK8cH0BA"K&2XM1cqS`m +F+kqkB`"DSC,Ir-ALeA%'[$ZI#EcjZ[l"0d*J&!qeB[*Jd38,GmD-%'mqmGJFP)T +rF[l0#r`*3iP(hicKd`m+8UKkHLL1*JX3h8qV'&b$fQ-e&&Z@pfM2K0jm[H%d*S% +hEk3GS!fQM(8A2rmE''3hM+@Mq21R#9E0j)%Hq)&[BcMAf$TFj-A#94!jGZGC"dD +RqMFBTYBL*bZQVe`k1r-X(VU)2jIGX[lc'0b@h%JSZA!#DDQ,X3m"ZYbBi3%E2`Y +RqC93'4H3!,UkM!6AFXqFG4i$YTchqJ'&Sd(#qM&q$!b0C@d+L4`dL2[9YFFABZ[ +Ka0SbIICf8@b0Mb&k'KVCJkl1JeQTcX4MCZ+a%$m'T`5k%)BB5KcUf8Q,3@$-#qj +("90"fpa'$mqabffX&Bp[JcSc8#d3P`K-Bdk1Iq3"Zfb1k1T@$*1VUeZmQK&$#@2 +"#9,Q)5BRV'!63`Ac5hIL*4,EcXmN&[A4Ll!J0%FY@kQrrM8lpfPT#ifdKH'M&ND +(,%blS#a*@jJkGU%m0'4KbTPS%NH[0`ejEDBGHb(Y@2Y4aeiDXY!qH#`2hEjm[I% +CIK'P,UKr-M,iN!!BI)6*@3%TD2KmcKGK80aX2*@2`-R"jAHdEqLBVYh3-DXCbI6 +"4hKJD,#'la%cc1""-l'+M3K-mX3#[LZ+QiD#9Z#%m1+9Q$*XX4JqPD$jf'-mJ'a +Nkfm%d`%@ae3krH,9Cc64aAP!F5B8!"e#9f*i["jNS)5'$m&3m-2,)PP",#Df#a* +#!r(HP1B)'Mq#'DVbrR(IR`Sh&Zi-LJ+&bT`SJmU%dJPHHhX)#mSAj1f,Lk+,,M, +VY1iNA%iaLC36ZbGH0EZca!M1mN&*mff['-EYKBk5Z`6lZHj-Rm+)"Um0(LGAZ9e +%@&eJpe,%("Y[$`Q-MMV`K"K!&1`5+ZcY4m"aHZdBKTA[4e01+#pfKZ@$0,'efKI +FfT`)JpB4HdrJL-YVFHGT+aS#PHAN`S2U4fXiX)9SEXcNe4`(*Xa%9ql5+b3[L'+ +5Vq'Sf!T@R(LBKbH'SM66JeCKGQi66@%Ub3@fXQ#U2848dJM)jJrk([5h%lPTpqe +0$f,B#)R4l(GLN!"iU'Sr$`-[0[69%S)Kj#pjq21*Kjp-IjJCP0*&FQR'j90G)YJ +XZ(MSprqFrYAX-aA5S[ac"!$""%PDHC9GTL*R"IY!JhKc+M8j+L"#r1-'&(C8RIV +LNmYb9ih3fk@CF5%'AZV4"e`DSr!'KTNbK5(cJ9k6"pR!F"Y64LMGH&1CN3H&%dA +1lhpNT1jDVP6D1M*jZ)jVlMiH9[ZZaGEKc'F!qlDGH$B[QLM4P2jT%*UD(*E5e%j +!0%qYQ0TTfSUTPDB'TUddG@*Ud$5$UC1Q18`c0-eLQU2T0Nbc0&h%G"Y0+c"GT'N +Hd`UD$Q#DTqNiTJ-dRF*dR+BZ6+GSfSZTLkCpQ2E5G!61Cpj-J*S,bAr9-S'"MQF +(T)NrG[baiNmVrKK'B!Kj6T)BIF@r%Q*dINCKj+qc8H!I+lLJUaYGL9CI5JaTa-e +%Z,XFQ&bZQdH3!*0-U3,B"$$PqJXB[eDErN)RkkX[69mKXVi@IpB`@HI3dP1-fcE +HN!!lJZ(K[[M0CYi%[d,hlY)ArmZhE[rUk-@q@Gj506IiDd2hMS,NVSf&b$8J432 +L'QMU8H[qH+h+K0BhKim'%U(E$VE-(6[i-LMc)%,e$U5iLTajiFVrXCX-P#'50Uq +Mf2Rc[iJc#$kSB'[TXDi4JJUU,Ab*kZYS%[F1-aI968Xd$'Ce&eqZQT2"cIpaY[T +kE)3ZraUr4KLrJ%2VaD&Va`5Vb-2J`fNp35")`5"TVK-+TGKZR*(1AU8"GGeS(!- +D,IDamfHPcQ#k,%3mTYBl"d0mN!!M#)Z9&CM,#e$U$+&Uf-a))6"9NHA468j[2HQ +p*e3X&+,#NNFUa(!r[UMMP[+CeH4,Jjq4hNJD[3k%4(b*3@Cba@P2R#kB5L0b"d5 +K1-jb-99I)ZC+9ZpP9i+K+H+VeM%aC(0F$"Z#4'lciIXCqpD1`Me@PmC!MSF$DdB +UKCf9-830TE21FZ$Kk1C('VUQbaUkCYNGZFIS9Re',`r`Xkc$YcLUZBhR,*`DG*X +BXQl+#1T&T@bcNNN'#ZQ1e#J&G9*FY!$QkpRM8[X#,S1'V0bJ*FN!&)8j28BA&i0 +"EXrTDBDVj,6+AI25YGRL0!A,3#%FD'%J(c*CA1mA8&X"$!4F*$UQY3dGYm8$ERT +J+#12I`CN8KPLA-XTLI,aa"%Q-3Q1V9r#b%([bYR'GMJ!qihJiFlLDfhRp1SU"mA +"@Yf6XcVB'#SQmkr6e8"SJ6lm1am1JQEA#4T$DM"$&8(jp8bH!hJ+pPbMl*C8LF5 +AbB'R-3m)(L*Lb($QhQ2hC"KrN!#8H3c&"QH3!,!R3fj5E&JQ"RHUi$#0Nc[V0M1 +XNj'2BH"qQ&U(la3YQX#Lj&','0lP4CqN,CV!STiLmj'23%*)$6VU84JEqfmaBa' +lH98-')N+"eC4Q2R[SVU"aK%Lp@pq,Rhi*$%iU5l)ra`Ub"*GN!$4'``9N!!J5a4 +"KY)&'Ee%$a`Mb1KV*%L!6Y&C)FMS91))Hd+3!*c35ZQ#I,@cf$a@N!$4CK*N5JF +4Y3q'#P+lN4"NL3,&L*4@68+Bi9H&--fMK'Q('6Bjf35Q#Xrarf4U'3*q8dMFpN! +ijN`H2h%5P(d1"Z!C(5USrlcdVlpL39@@TJR+$N(K(qULCFem,*E'$l+8c1+VC@P +,QfQT4NZYbP,l88Y"$QRT"fP,VEa8(U+P2FV5jS-X[8e,h@P,HfKT%beY9CCDMc9 +),"AER8YEfSUPGfPKk3X[r*pdbFh9D3Y,XE!8F(U,q#G'%XBFeSfj@MGQ0U%Rdid +j@NE'A$,8Q-8!*3@#kiaJBTK(!HeY93eK$S"dHVCE[Yd1Y[6Vf!)(35(ab0$"4ki +Z-ZMhC#G",D2-'MpjA3Q6@X(X4Mh0!)4i!+U`Z3bDM+"e%0`mIjT"Q2cN+3+l@Yf +'#&)m,*JJ"4dD(@IYSb"'RL3@[j,r-5eC$hMAlcSr&Vr-iGbm%XkG4c2f@p1ebfl +jAS-MJVEKPXme'ZcYKS)2&!9helXX3cT-NE2h"e$`2'3L1bQicZFfU['CHh2YAlM +(lS2-E0+4hG2lm9#RH'J1`CMM!U8I06&i#QeZ$F+BX-IN&006F33'!ra"$d8)d!R +65k5V-*aF"4-*cbKh,F-&*f0lJQAA2jRTRr!c*9MjTe)S$%f"EDYd))%('F2,%)A +*!!+C1ANUT!K"bMmR-8Mj)B!XFXb$!9r2`('&#YYbUU%f3d[Y[2#E!j`-%CHV(FA +a$IqmNekRp-rrA%kI1d436SXXp1Q9Y%mc1+Ch509kKe4VLN&S,Q)DlN`N"j2L(f) +#9#2KE1pIrpmi4+$K8hR4GbMP&MELBLJcKQ25i)8J`GE@CMc%Jld##"l$[bV"+6S +FZRjdF%!fIV$iTlCca6h2er1!1G&cl,pbbGcbTJA$)NZ62k"j-9`INCB8,NZT3@# +Frr%MEVL#MmG!jP&,-#CPXFRrh-R"AV19&2FFr4TG8I)rKmI0rQ)a0T+A[mkK2J1 +K'@8aQLC*VjDf0BKI@SmjKSG*6BQZ#fJ!#6*b-c(45!30J!QZQ)!jYb2Ga)dI5`B +E!kF2``8!!#-E384$8J-!9q)293eQ4!)3)H,Z91r"58kmfLZjQ#[$k#Fj,aH#(%f +Yie+UJ-DF*cfZB#RMZ[%8lNk-r2i@N!"5amfF!5eMhDiD0q0f-PNhQdN6'`aLaY" +EkeVMC"a$l@QXieLEB4cUd&3003FPS[$hrhl[ppeh`1'Cp0PRRhPq!"eQ2L34%#m +3!"!3!""4,j@*[fKU`KraSeFSN!$5B481A*FXl*'maYH8V$&P0li@53akdN3GL+E +--E2PNq8[P9Pl!Cbc)d@IcCmB%HfQ69D%%KXA4a*(HX!#39VJCaFkE"jBfEKVS%` +%Tq`3CDrTE`C@0LfQJGZQaXh)P-kiD1Zq2BBLBUrZ*)9pq,3#dkC$#)GD4FIA)a3 +XkM6PI[BDN!!*)0m!`QikdABZ8[6&*"jS[eejIY+Pkm+2-@i+&Ef6CMDEkX4jG(! +C6CSpF`b"@a3l3XpQMMehpCddeUP$kD4A1RNLL8JT1[@JNf&JAP[3j2j'%hYkSqc +TG[ATh(I51Pi4RD3-kqehdL+*I@pc%HM#d(ZB-S-VkMhm6-HbaGS2a``&ADIMjd3 +Nm@#Hp8emBZ+I"HN$2e$LSRCF!U+dF6-'pQ$L88aXia2hi'Gh*0'qJclS%RT@qe% +h3X(G1F)6@5Tek&c*TbDQ9V-VNqTmqrZEQKJka"CdH4TES*Y@aKBid-PTE)&MHJq +b"@hL9EDJl9%4p)(iCE"iV,(JC,p`a50mXB38V*Y`UU9MqLJqD0JpTJ[ZKaUX0p4 +Mfb0,6iee!$PH9(NqDDJBImaGD62LE@Qdh6)SZbkdcc`ce)`#MB3@F`,mLCQb*bE +FBp,41!2PX`@fpIY9l-M%VMpJ#,$dYbrXhqGEJLeiQ4K"NKHP*'Idp8AVdU0*bDL +,&Lhk9NSdp42R@SM15pPTC`rQC'JCmNT,5dNqQaaG*2Cq!3reAV(f5N&Qh8RV-)k +eap"L(0HZJ!QpK-43!-cTX`lcaABF-KK#&CKPTi%[YQ51D5($'H-CCbM1-D'%iSM +pX0NYNB6Bj!DldT5B"qaI&1Xb#RlK[)dZA1P)l`CVVi36jCM*6B&fS'*ZcZ!LSM! +i!XB9r-U8)rcBF%4dDb'JKK&LXY-"8T*6Fl*e@RT@0Mi2T#GRTICTfGSa,IGXhCQ +8R"0489-TI1"JPLiRr8`d068V94Q+CZZ5,bTMNUSSk+Z%H@9U'cA#qD"Gd38RRcF +l5)@aB5YFYD3FpeJ9UQT9,M%X3@@`@&J)m-#0dj&%3EC@+0h#(APer$)#3(Cma)f +QZ9H&K435pdV2GAbGrLFe+5aUma!)&`F(RN5iI(HPF)"-RJjh"Q8UC8LrS39EFbb +Y0&)Sb%2(X!i$l3$b*%$@&BL*`cT%S*4Rh34e`i#(2cmU(5aQd-De@P2Z,aBU`kD +N)`+I@iPKiL0b&UTji2K-J+EFGcl&"+m"DS-3U+S'iU)TGdiT2Jj%LZDXCBSS$Ye +qKeHMCV$11bG-Z6%62QlLLSM5jBrJF*)kSI-Xh[%"X0N'pP5(6FGCe"'2[Y680-p +0$j1VH'"jB(&hbiY3R,$JM`-CINPP!B8"JY60d&)cUjdLi9@$dhS#b+6'@rR)8Q, +lf0YJqd,1pK9!0%YXlqY9f&lUIUfC!T@A9T)l&-k))*Kre-LZNN6)I)S*K6dNN!" +P%HY68(CC5%#3!$[dippp`GbPKH*#0+0Li8+Z(pFmA-Jpp3ZjYCHZN!!b*"lkKiI +0R9C,apFjbp3Y)+!j4-q*fHLm1MlDm6iE@)m21YC"BJ%6&r*BUX)Ne&N,+5k,bfG +6)(D5d2EeR8e+LQCRD%PC+9V@J@3YbkbPRXh@4Id@@F`kNf8q`fFT)T[N8l+,K,H +EA$*I+lk@dB@P"kB,UN!h08VC598G-U)4!9#($'$*Q*-$()HDZ6&N,JpSNm'!"0# +8M1AJl&S0F&DJCL`*bUH83HEJ!Q+,AVLjDI"$3`X2qG$L!AlG9QPK&"ZE-mFbZME +8EQb1cS1LD4J&890Zi,Y1X60aXB-i0R0`ITmH3cLl(T9,3%lM@Kc4Y2%SB#6"6a[ +p2`'3!!QL3((,M($@$h+&JQ'GV0pfKkYSRC2efd+ULRMhDl8%$N'SYBlBL8!"B%S +dMS`k&(96KPcZP*CF6(DcLIG310rY9M1MEC3rYF1C'@hpeCkk&fLH%NV'3)KQFX6 +,fqM!`KH8!dfM53@@9a4J#G,0JfQVV9hm%N&X6q+QJN`9B()488&RU*Nkk0V""Pi +``48E!%T%3Dpd`1kK&IHZh59#9,TUf8I8,90)8k3Pchi$@1*ejd8A18XBEbV9qqh +aTP)L0A6Yh+5LA[%hr"6!iSGmq%TBX(e`,`FEVRD`9kTYGEMQ9R(dI#ILSX,-0a& +Z#5N&$&Xf6SdQ(6bE(Ud*1Cidk+Mr!EQi2$&#!Z$NC9DPr5CXPEE,cbTYP9p9QJ[ +LZ!EJ$3Bq*lF-,&qfQUUh&dh#5d"`%F,f$T5iC)X,bQ*3L"!Y8,$3f%FRqiL`Mh( +fB@!IHTMkM$@9Q1SXb,i[AQ02698EQ+"U"Dbd"XbeQ`i1F(Q)LbL-!XVcXIecY*! +!#JDam`amRL)'C#3dG4`N%SQ62!bB-aE)MHCQTIj%bmR@"P*6SYNjkFkS$SM#[RT +'DfCT69*CUI)l5)8`221#d$2Jq@Rid,12+IBa34mG1US8Ijp2a!&9I[85#*YKG+C +@)LG%d[&m9fjANMIIPA8"fp[P9*!!ckJS+$C0TU"e6JAj1Qd9&02`l&BB%'UkmD6 +MfrM&fk5,0mNZY[#,5c"KN!"GA)+I5TRL'f8ASq0R1qMLr-9#ba,LCR8eK!$+Xl, +6I&rq"KLK`MT%f3je'G42rHM3QRZ-!6E,''!MUbi6RbN-%11&41G"0XN13Kd(*3B +"!pa!*9G(+XeKCD,Xk)qeb`HcdMr3`T!!rMBCV%b,eZ@N*&-Y+*YEp96r@#iR1bG +Cl*A*'Zr,R-dHJ0qRLI3h5#%"Mr8jFC)BD[5BH`c'FmF`F!c&arY3d+DM[ZlRK2C +A5c#SiDF2"9ShLV1GND8M!PRF"a-UNE5rHqdhGk#3!2%0%H%NSpj8ep4%KNf01b& +-([UJd-5G1kaJ5X1VdE@pB`Bp&NNmPjNjKSTKplBCPm&%M9YN6,5@-Um462I9f9, +Q0B)j'f-bjPcMc$cHN5U$VG,&YlGb3Y8S,DG+MF)ldL4#Y4M-di,M-l32K2jVcAB +a@@ZZL"pLh4*'!E*!Y%mF%GiEDVGlGQQLia-JIrC4F(&6dq3Y6#cmbd003TSk1Kf +(PKifm)G&d`3l'#NcSEejDN`eaI+e$9PZG,eT2pjlaI1PQ9p`I'hiUH!cUardrU( +pMcVrFZX#E9(hLiDja[Ie$idq0h9la$VaUdGqIZIh*rrXb(rUqfhrYirY(acSf(I +SN`[[QLk&V[Cm*c,QrZEij,P[jIdSmmr2rlp6rrIC-r'cPp-cSQEGaCc$(ac-cFj ++qZqT+FN(dRjFpj-6Ih(d[lhpakklVpBfhl[jrCBrZIA6krrPKrrMfY,TcmriR`r +mml6rqS0rrI$[h[[rmrr2TrrlihpmlHZ[[,Ai'fm8,AQRH'("V*IrBH2VqGp0r)G +Yhp[mRcIpCYG(ZrrqXErCmGIE(klmhDTI"*DYH'(GccEmlGTr@r2,2Epqr*p+rqA +qAl9qEZHrPhhjkDqXAllbdBU[E[NX9PliaC+AjMA-RY2B*-P"9KTUX!2C@XB"AX# +f#6IXRDfGjMQM8Q$9%4S9Gm$30cMS5,5rl4j,%q5SpJPH$%TB%`TVNTK[5G8I&SD +T'k&la,BS[UjYYp3*EqINc38JPaLV)p`d[KL9dDJBlcQ-Qbk%lTiD-hZid`C#-e( +J(KX"8RZ6Sd1KZfE(lAFjS)Y4Kem0ZXF3)Vf4$`220&mmHl`@aNqZA2-*dBk(Y"Z +6pf"XNRFD$hDiaicdi*!!l-&pcJFR!L"Tq,AQa@NLG0-XQUDFJ1fVmpN#bKMC,C( +`5TLkB6j-HiiiLbX0J8ML$`JmVBK,iCD'9ULd$m!MU)3F1E&(4ITfkNiL2NV&0Jm +##5H4"5FaR!r'AdX,#(NlZRE+*MZ3!&9!d84$PhX-drS`d)GT,f0D*EVEDF!*FVb +LjQ!l$9TX"e12"qiDBBENX+31&0mPeijj0@9#DJSCe#BGhmJVV)fm`QVi9!CX&K1 +`DDL-**CINi"03b9qhT!!!C[&6Q$$1hSjX%%493hd15*,hehCd2VZ9bafr9984TQ +b`hNM5bGG2pTd5$`c+1j`%f6Ra'"N+8*AC#SM(mB823@&,,*"E"(2'Q`[$U%`SCY +"l!h%1)kh+C*iG$Tp%&Z-*0LKDIK$#J'[[NrCbLl!ie#MCUY'Sq#CAK3cmd$!L)l +809p@V@lMkYS@5Dbrc05e$6mIbkV9(6*eSH0ARZEUiZc`d#Q'S-aqM#f)A9D`"GM +01j-Y`)S2"LQ-$REP*PrC@FRD@E9+e"5`%Fe!M$)eHMChEm"MhrJq,IeL02f$P!1 +j@Qj15ZlCj25,[b8k2`R9EXECj,0D6SV'+Qmr5$J3bQXBkIh[B8R[-Mp*ljKIT2G +m!-"+kj!!NBVi2*!!6N6iP3XJ)3Z)&1jZiD6f2Z&Jj,-p91XH-a1*YUS'DB4UmqR +h6,N0,BcdJh(rPlDb6&aR5rSpED4-"!%@NmJZ4RD$N!$JC&HPl2,G#[RhG)H-r![ +)''52,IRhjHf8Z%!KZh(S)!q[Q&km#%YK$bdN)q%6dG3X,5X9T*MZE(*1@P5lI-" +XMUCbUSSST3kqMQCFbNCf6R+1N!$(EU[-d%YMmYbY3B69FhGIAcfMTd2fkbR6$#d +3$-VU&SQi2riT)qjlkb2ZZ6N`*qj486MZYk"+#'jdA4lZ2SbK`e$@d+FMF`q6f[4 +!8DGVc9B"P*d(ca"'CS,Z)%&2DZ)LlY&CrRDa##T"(HFK3aJf$h1$[jZd)2GB8P- +m1)N&2BF+bq0`5#E5mL0fDLa)ikJ6XNXkC*GN)!&5-&'EBG5'VYfc8MM0`i[i0NI +8L`F`KBl)3femJkPDmGfSjG14q%a8S,hGaiIA6VV-mlS(X!A22k2lfPTkV('$CXN +%d@9aQRrR&JY*9)Zr&%j8LfIk*kV&lAk*kSlk40Aqb-$b&DBR)kSlBlDLHMbCLG- +'@e(GHG4[8Ae-%G@Gdm+)DUQYU1l8j+)U&e&X*(MkSMV')@mpX[Vj%&Ejl8jTP3q +ITVLZ-&8AekjErSNVa0("KE9CTpFXefUYa1Tf@hD(i$U3!05)Lkmmb-U2`CQRD3Q +T'%PR,-i+["k4YA0aHa9(8B38$L%5fTS()qE8mi1PDhaD$hI-H'b24N4Er!Lj+(N +R"'6LSpf(HFEl)C,bM8"iM%`-Iaj@$1ri+BD$ISPK"F5`K"*r'&RJf&KE*`aA1f# +f(@V@RGFXX$!&4Be!EdQ5$b(H%L*i)%K&X9CHQ1XPJj(l,DqliPh5*cP1Z$J8a4l +RA5b[5bEJ*IGGcQ[-#53DQbdXQEI'Qch0p%6ZG8kQJHb&fIG9FNTj[(*h`L+Sdf* +4-j5l%`akLd9V+ff"kE[RdQrdEE1DfjS*h1SRHL`,QaFGXPMd#p3T50DQCfi*FJX +CTL`@E,&EkmPXFIcKdUEZYS9hfql5G,UbHk*6c()Ca'5cqIj$(A54rSb-h4LiqN) +a(F0dNBMrf0-3!8CNd#I-(!`-Z($4lp",iEmD$Ud,e0fJ6N,!*SJ#QeI('AAikF` +a*&d+m8F53dXN`IT#+K1XqPeJMGBK#L8M'jUNJcle)DScRe+GSB,TT33$8Y9N9&8 +8JL$S1[((JD#k$9KqLT[k8()N'D[f-&Epml#XHYj29MAl`kS0QUhbCpk4+EpLB2N +,JiVbAaMd@rNpe0fJ6P+92j-A,"J3N@G"Ejk8"9qUU#S,K&042#084Dk@-a%&mhN +BAeS8FPF&lcLm8YC4PK($'f3CN!$+-Z#2`fD!bmm-Z1jA"Y3j9FFG%@$i&hBC@ZC +bGkd@bKacEPp9m&DTNk3d`C9fDUaqP98$hKiCm'C+U0E&84fmmf1"&GB&phiXkL3 +GbpjFeE%@e(ci54a0FPZ['`c[YZD%)3I#Q1!CjF3KTNdKkEFH!BYlU)"NS4!pL&0 +b9HTkRfNq)XCV0pk,PZU(0)Xck3pRN@Q-4Iia,)ZmjLH,&2M&)MYNQF%FY,(cf(J +"1A,GiE+LJ'9&8HcFhKL%%lT,&q8)Ll#Jf'r4MZ[DaTFUB!m'+if5S2J84r0pZ(Q +(*1B!1*`A+5ShmQ5a$H6d+QrR!4H2,LP0J#!XP!DPlC8r-Ji&QbmJ10A"hHq%$$, +N6(8)C#-5@4D9Yi8%N6QkQ8kh(9f04qpc%kBKR8HC&*YpLKNVm30T@ZM8Q('"6$P +9Q,U8(r((e%A3NDDFM1AJM'A+I4e"KI+E4Zl!,'F',Z8R0VVFBaPHbBbJ2*N0CaZ +3!"!Cj2Ba!,#CXU!iIl$m)VVemJQAqB5%k+jj!C&&j%6df'9(19,28I,S#&'Be@K +$ibkV01KQ,PaDK!`Q-Tk!UeFMpflj)6+5`@''Z5QC)KEFN!"-!UAPa``YQEC',6! +*SFTI3fEc5r,d!Q)&phlk56+YiFr`,HXd[X8U(KNRFi$YP)9D$bS&")h@M0+5Ah0 +G9Lei@0Ed1*1-%ZY,$'PN!P*qLV[RpH4SP`DkKkC6jR$(GrPlQC*C4%*Xi'6QP(0 +5KQE6TDKm'VP`q`A[2T-1)@FV8VkHJ4F+#F2!"1!a(Z((IQrT`jVp[UZdKIjIha* +SDA8CLA4EMH0ke%H)000c`mHV5lGARl$d$3+hFU9E19JNa`V%eV'`%X6[YFb@c$p +C@'NZe#lTce3h!YBc`)IM"3(fK#r'Ye9X&!Ni'#lh8P'i''CE'Fc!`,H(&mpDR3B +'[Teb!i2baG6daiTl5"`iZ`!+Zj`R+@aTCEfEe4!1X(bZKB)"bcETlGSK8p)TN!# +C&"6d28DAFM$FUhpq[$Ec1J"Zi5paQ,M`4@jM5P--`@ilQ3E$f9ma0Dce))P$6'q +rheakRIjIIheY5fYc#+E"jVDM[QdJL$1kpYcFH22b2*MiG2'$I8`0Dc#(IC!!LMr +DZkDN(Q&p%mAe![8!5'DKhILQ5cqBC%qiX,bT@3+eG1K&chX%#9#JfENmCl2-XeP +QfLc2fba2f5bIP5hGY4Z[4kr(CmUIjGA25K6I,2Qe'3B05L3bAe)N+C%fdLp-5AB +BJmmTipA+pd&J$9[Ij"ZIcN2M[$"JZ+Q%hG1Lh*J3EMbB8#EEfJ)m%9-!UiH$!5G +6GVfSJ5(R14Q59jbE@FAjF0L+Xp,2LR1YAa9R@A95i@Ip9C-+AT98S+)-*R@M+,1 +93&UkGm%MC+iTFjX!B*dDLjE*#e5bcEDbcAiel'Dhq,RC4Vmf@k)Bqb'CVLF9lSM +3UqRYf2+j3('R''G&X0jI#CpG&,mDh9Q0a*2!CU)mE@$jQJ3)KmAFP01"(hYi%S0 +hjF4HH8C9*)BTGf'[T)k&$iC6ad+[IqTBD2"((E1p-M)5&@P&XN*1QLjD-&"Z'&M +q5lG8P,%iD1&ZB8Yl[3@D)p4TVYSCRhDTm%,Aa@C,K&EjaUS,,dkLeq*a-Y)#Y4K +5i9)IPX*h3lE(MZd-eA*!0Xc#*G+dSe+P*&2h"&2hYm1UqjLIkJljTHj-HKLUZH8 +--+)+"d%9LcZh3!'XmQh5SF@jHY9mKbiaY(!L)-5R*0idUdXNM9RKV9V&dP9)m(# +B6hilFfbr`!+9lCD5L38U`X`3-(IEdMLK9ZH0+a8b!NJkrLdNX49XJ@)NM!r3#!D ++q1,6%954D2S%VRB3Qe[@R9a`ENb(-'IM5PQBmlaL5V!-C2kFDIZ(Q$%"R+%[HVN +j()8kcpQD%bbMC$eEpimdcT-1fl@G"lr)j,4A)6c5cfD64bS,KUDD1HFJ$feH`!G +-`$"f'N(-lja0Y`eU3JQ2Rki5S)!YD+U(,kcpqr'Ip!H)p5FAF,@8bY55VkJPm+' +0@T!!K,ql69A,4PZe",J"%#9NB@S[P061Vhqma[8)'3H1UGHAF)1)a++2eHYIPPf +2cVrBaC4H+#Rp"T%dL6R&p5Jp(I(Ej'JeY8ZM6d6aiE2dL9p1KJZb6-8',5Gj!$& +C%3K,(JN%9,VQj!)fT!rYbq3X6FEFURTl&+I!UP*&[6`SLB34fJ99[4&Eam#U$&) +[Udime49k-#Z&YNYqd'Sl*p36h2KkCH0)aZP!X(48H+lK)%C"cAXFj-Pa36c1cNT +69$(8`d%$ZFTjN@G,+CM-lGRAp'pF'HYPbR!V6ScIV9193@k-PC(%JMj9'BGX(4Q +rbb4P8%"h'3j#(iT#N!$2'4)PjY3"$Akq9-#$N!!`QqGKb+153T4YYq99frC15E4 +X0MbZE,LbYIU'YiE#EEMbSRc$h0@JXX#28h-J5Y+HT3hcS5Hfi5eUCC2`ZEP4qJA +1S28BCeCfbKaE-&CCq5&c2KfcCH#(2qDEN!!D5[,)6I0X1AE[jRR9MmXVkca@@DH +(VD`cr+bXNrbUV1Z8S)qf4+UDDe6$-m16b"T[2UVi@Kk-5Q3%4`ZUp'&L)PDpVjC +23,0HEFV!"*RkE1,2Zf3A($APcSk6Qd+kV1PC0cXq"Ui6%LC8Z3[4G&h6)4RU3fN +D!X'j#emK"j%-q3C$YQ'"aLHD2!S5UTKJUQKaETYI8qHMX(+E3Jb,632,pdbaT", +"qNPJkX##X)rYK36HaM,kVm0Qp(Br-hU$AaNpcBDmpr*N6caj"SL+!)iqR39c[EC +*3DTYF,Ub`6HEpl,"qfb$MiEGB)@I'jcYe`CI83p,"UCf-X['"i*mc'RC*KYZJpY +"!JbG+2DAm54T%XULSSi!Y8U'XUZSFd#p,%-j9&358$rJE#DK0"9e(5LA$$@SSX# +UM@D*i6M+TD+3!)LdXBH,Q!m0XjBbph`VFl58d3F8-,qHV%*V05UC60IdU8YkENT +GdV'fUNXk[N0GdMEEe#A8-5HQ,U'f16Yj-)i)Scf-#*qSedQfKEQ%4d@CfB)U[e9 +eqAM*jH-KjeM[CH%c6[bfV5[5J#5i'PScb"5Aa9(aJ#J@P@)R8[1Z6QT#JjDP#!3 +GQNY0-D,49AkPm0hKLF1fN`'[6mq4E5V5bj&,10+6j'0AY+'Dkh3HiTb,%0`!Z!b +S)l,M19'VJ$VR4,QGU*H"5R+L8Kf"ZbTb'T!!ef9)688H"HS9'@T349d'DVF6e88 ++8TkVARNG8bU[[ir,$1GPaXR#E9YjlDE!d&BTFj4U+q8RZCHc$SDam2l1Z3[IbFU +)(ZcVddAp-24f"Pij%03iBHP"d+U9XPiE3Z+d89%U$jJ5'iI!eXr+Ua"Q&X!c[6A +0p``e59`'!i&5lX,fQE[Je'q01rLbc@cAKJ)Z%"5Y'lM4cCcVcUjiISI86EHT!d` +"-i4@@`-M4Ji"BDDUE,%S9CTAY!RVjKEB*B"@m%`iJ&D`fMq!9Y$Y&d$E9#0TVTm +9-LTbab,ZPMZGUDT"er#N+pAh,fr0(C!!3Mi`B"l@,*20-+VSP*PM)&!4U0hJNP! +JUeVR`S")VPUCkNDBkRiE9RApIUV1j*IUbRLL),jT9&Pl&#FPrJ5T)9dbEk'%2'M +Hc[1j&UYJL6F8`k3e0BKF#-iZ%5EK6Ya@`(l6SL6F8F%F919dMpB`%MS2#k@ae)a +S+K-cfi(6-3cD+Qf@'3C0Skc1V-,&4iempZJ"A"bSA$a`mYQlbE(UQlb,V2CdPk% +i`KIQQ00K4Z%Fl5(K#E`P(#pLQJCA$DPaS!)"l)H%BpNe3KHr*B,T)ae[JE4(Kqk +(e'[EYDI3('D,dF8[q9GqKI6)6UG,MBHk2+(DA&i0ERa&@(*9JC3ae6R'9'I$-Y9 +P2jNUfaqQQQ153PUrlR@'Y1Tc2IqkYkU!XZSq6h603qFH)LE$1Fi*cBbl@UXLY6K +j8e5qMK%0j%ED)6pHZ)A6qDP@kc4j&k[@LmTA9@Rk8N,'&P5SB`IBkDC'R%YBSC' +'eUMCTCKP&*8hUNd%F%+0KU@3!%*K(f[DQaBMlM'fK2P6SCi+RK++RQ&,3PQi-pL +V-h'R-`ee)J-G6X(M#5h+'0+aPiXkcIPUiJ4Xrj5D-FTa&4@cBciV1h+QcC((C8q +9f$`e@12)298FqF*H,V)pmLlCNGH6FeYaAI#N'q6JAFm[UC!!M-E+U4(epB3S[+0 +H(Q1)%QP4f-X1,-4L0Y5YZ4HZ!-!r`4+ac@C6k&LVfG6CkY5JESS0+"-l`hEfQ0I +aa!G5iqJaFS1f25Bl6)Cd'20@0V#kaN%p5'abAYjNKk+'d20%%V0V&8A%C)USN!! +TSN+f,GXMHRA8E0TXG3XmdE6T!`U&&KkZfGfmSZ0j`pA-@h0$F,RGUZpJr0QMNf5 +Z*ahK935L+Ta*Zd9QM@6fFFAe+LADCXqR`@`!eGYF0i%AAZ4"+,X`DIaj[L$"TJB +H0H83"j%@m22Yp+2QC)AUB$EPrMSZ0F"3Q'mk5#jVb3&3@'!-CIldI66dBI`T9DA +NpLjmJbYqMj3KKDm4Dj2C-*NAm`lcHBHe6,f[)9(,9VEiJH+8,jc"KRl)c%'8c'L +K"1rQ3*`A"HDXYdRX,4N3Kf6r6%+MNMAB`#PHm+GXbAFfRb"i8%'lbVDcfCR"fP8 +T,'!m8bqiCFBQe-3&6qV2'CSD)+%KPNQPf&UF-Y,UB&Qi@cC"BLZ(MPb5$MBS-H% +9+4aIH(KbHSd*AR2!pJRj%9(pR@!9kII$9U3YIPDN-rbU5*0B4CUfPiSdcEq+G&I +E`2,(KbR*-SM9[$$9kDM5#F44RM2jmNGG94P00ke4%K$`*M!XI-U889$LB#3$2UT +F4XBY@GNRI&mZiN6P$4P*Q8I,$Djk#-Z3!%*B[[j+'-)bdjD`I(e#)5cTRh4!iMZ +@T#"F)Yd,Ce15Rda#ADNa30Tf'LAAQ1SSlPFq,1c$cMiml-2"2S,X`mXq1YfeRPT +ZF,`aMCZm`SbLNXM&ElTimqhfiLA8p,)S`!3pA%K)lNT6aiXp3Khbe4KUUc%d9'2 +)8Q2S4SfKVKT$EbT$-,j!mfp4dA3a(Uaj1,MjFI$S6Ja-G&a,me(6`++ND6e-b#D +SNrEcrYQ"i[lClk2TEldbH+GIB&!mj1UhS($+"lX2DErUY`4)XBF@ZIVYS`VL%b$ +X!9,d*d"iTK6%"5!m!9,m"5!F)`VLA5!F!FU)Gi%)`NaQ!Ui03S&eJ!`'+(-Z!HR +Pb"+',!(5'k!-)f3RhrEkA$4('pr+1mCBaaJkmLhaMP!!bpBe,&ZRR%V5NjSQB*+ +IechK%5r@G[+"mH)H4@hV-*!!Tj(a%6UF3&0hr!Sh$#ST-@N(%T0f5iP$Bp19"+I +P+ja*4Q0Na$*-$fShaZrK)F06a8H3!%k"VM91i($0qI4--5@D9j+9FM!hRi'jSV" +JESQIB#lK&jLlCJZQ[RF+)'LA(f"U9dd`Y6PqZQ"UmmfpJkQ!5`kQ!UkU`G5X0[r +!9-'Yd`06N`HcI[aN`&4$krmD-0A3qKmhQ'TS26d`e9$fT`&-0C5G(TK#FZJ+8S4 +4BT1*pj2`lm&Bf+HG*eLN6`p2fNHI$Z&JRd'H`*!!2Vh#bcil4HHlAi&i+8pmc"M +R%FS'DV5"NRVVdB4$3i89B)ih(eD%IhF(!dj35-!LZSShQQEK(3*'N!#$V(0JP!` +Lf86pN!$a"X#DJmK,mq-dj5JPM)Cja+2CdY-`Dc@aj2J%3LRTr(S#""A6F#8bJ$f +aR9r,(`#JlKUrL3-EU&N*p8M"+#Y3mZZ0@THcZ3J'5"pMJ25&X)"dRCq!Y03[3*T +Idb4Y@GI!mRp+0V6mAQUf,U`a'R@53'LJT-S!#L20CFf@V6D1Fb0b0"6('jZ509a +@Z%GUq'hC5Z'a*DDPDp"F($YS`EB&5T)5H90a5fcGKl`4258*R%Gh3QNk%QDdlDc +TVeTH21308ZfeH&KRfr#AAY"'b)M8bXf9#r3,*$-bGL6@I"9[RT-+3TE`cGF"3Km +iQ%aTdMA@'+@XpFNReQK8`AV'9Lq&CDYjrV(9V+kUf5TdHpD$CJFk8PEH*m5X"c2 +(',-&!#)Ih(GSAmiRha[ifF"(!pmDh$6`YAdI$UB0IRr`pAdE"Zm0CJdQG9`Fr,Z +"dAdIGk4dI$a`8V$r!*!$+aY"4%05!`"TZa"9#f5C!&PYNqr@ET4DPQB-deZ'[)a +DkTcEN!$&')l!fdfPeV'9EXK#5&UhYGedep1cke-)Ke9h23b[Mmej$"J1-BD)'03 +&G8iLdSJh%I%(`aJ3BN!%3BKkHh*c2$YLl22prqrEkpZQQd$1ZArh04e@0L32%4! +3!"!3!"!3)HlIe5Y4M`Gr&088FU5%&GQP)Yq%Lpa5T@cDaeaN%2ice%ZZ'4-CTXf +5B#)f+F5%8G(bk(!3cX'Ep2@(&'GpE2"1-5'Pc6d+"-3dmh3eF-)FFrHTG,GFmRM +UE5NV2*klTV'EraLQ3Bi@-QEjKr+N1-I#qKV&Pl*#86kM@krTeXPZh4!0K0Ud'-) +ZcL3T6R3$-$`!rShGATCMYhpeqZVdR,*pT@RTp[`MkGUpf9bmV+qI@aqMSq`#%b8 +b@+0FlCkJf'3ReUf#F[T2chZ(i,!GTe5'mq#feZ&@2"MRDBdH9Xam19F`+TU6iP3 +#3S@YdFb9*q[*a8D(DS03hHT'Tk@*%+RUKI9QpK++26X3aiqjhRV-A6X9d4'ME36 +qmE!E5fRbEU8YVp0BeSNI-hjXq2(LTamr2[`d4Ha"1ahejG+-dJU1'X"CCFHQb9d +MKRlb0pA01L"*Y!&P*c401MMFP8B*(38-[$*#)Xfl$LK1a8P)&HHUKN,0(-"F)9` +Vl2BMkDCe'q`KVDBR,6FM4eX@b%Q9[Mrd*lZp1+h`5,(@ATSCYMmNMlrkY$fK0%1 +&led0Y1m0p6aH[#A!e-IU,Hk$8jr9T)3YKi5Tjm+0q(-jH($UZ4"8ZGF&aca(G#4 +kb$heT1KZQ(l0q-(T8lX[,TRD(FeFlSXqTbK(MNR+Ph8h%$D94)dA6*GVh*cTH-j +d(*L1$ih@@i`B6K$GhZRA2!Q'Nm"`%KK'L1%[9[XaA%i-JlG(#0(r"YpR!d1SYm& +pF1ecQXTSjYTLQ[EFF$6c-ATmJC4-0bf!65iVQlA286A"P,rb+9qDTMb2abd96[N +VQe*b+ddT-CZQV-IMfBUQP0`U65RN8il6P-1V'&NPC66PcfmC6#Q8TRc$TcaVQJ+ +b5[396[Q'69Pj0deCf@+D!V*@0P8dCHAGI$2Zi2+'d26P$@iAYR`l,bjCANHJiQS +ISfR[EX((T`JBeSpR+bmZ@41MirTrA,lCm+-DNcXcPpIG%9AUf-1D'$f)Z&(2aTC +#G$X*F3YLG898JZikPc4P-`h$-J%#NC9Prf*m(%0!X(im-rlLNV9"1UEracAc$$q +U-4NN""Jjp,!fb-KC'qb+($jP(Jd$Z!,NE)F6d8b9r%fl[C!!4-[9IU+PEJF%cYj +X8c8bG3Q,%`"QK%+cS-j2FB%b*3S`b,I,0l0E%[piV"1rl5aAc*fP%+JGdXHRq%H +RmFFeXD)IPfmfrSK"BqMih`FSe`EPfcAcf+h%*P"dZ69MLV*H'kb!K(R'(`'N+(8 +prYd1Vk)%X,+U!3a#2U*aGQaaE(IA+#1UX`b"0A9Z*5Q1[cL&6QN%iTKh)Bj(h0J +J90',2)MqL,bJDepKF9UkeL6lrS$e5J[YQY*LEAkZaVjIPS&eKH9(8ZdjU8G+Fp, +afFkk35B##H'4FL@b"ZiP93XMj%Jq@c$XBCY3dR*r6RmZSh#X9Z[Uk0I,4lplJpr +4Vhq&4bqXN!#D`XIRk*0GM3FcpE4&K1@Lj8U6RaPJC1c`KD+PQIQjTQ292F4@5Xp +*e4l*R$b8jHjb1q[X8,h6d*ARZUj0eqE3e,(J'GKIV($c,pIe"f-!e)C*YXcLq[6 +bY2fC4c+H'eXq5"la%+2FM$*YUUBiEIpB-J*#&P)A5SlJqVQSfJ&8E&e+"`+PK6E +"ii%DjQh(BSjBj)"LM[mT0RAD'bbb5(6GR2X+&TF2%Fir8RK!Fk5dH'`Bl6FaZMB +YHqaKXIr99XkZkm&B+fIA2!1&aE94VFR@dA"9&@XLBS8fh)SU&Y[bSUdk%R$C(SH +0&#X%aF,f9,YBGG@U`L'US&KGXbQ9$m'#2,kPIP6aG6b#6C)SY[(-@A!5&1HTPhU +f1TcUTGMfpDC9)M6Slp`TMSM19$&VYpBjUGV4JSh#@1H,l3X5A*V&RHSE%E,FZ2N +P6%D)j8hEHlB*E2YrmSML+fZRfa!'"+2H8B$MAFIC&j3cP[V%qTJ%`(dT(8%P%"I +fP,K8YJ3`#284Qi`[4DFFk,QZ2j`HcXh*'#XekL%pBXIf'4rEKQ1E*hYXFqF)dR# +k2[CQ(0aX1VB!TQBFfPE@3T0aD$-rX0Gde%SkDK)lDRY`*(6Kl+M4JIAm`$ce`(A +YiA59GL`2c+X0UKr5+j!!JML09d1B+0S$iE6dXH()A[aC3r0,$3fII@PKE8CQ@TQ +fk+)(D0%dc9M9r@+$GIj-c-T+8bHcI&H+,CVR$G1rTF1p`l0F9&8V3(H%P"a*F6C +XAd*!UU$X[DkJmMBTpJH%BKk@%*S(YeZ9fdZhm9bj'dDh[q[S[pPbLjpLEeFqMl2 +eH$aqLVfk0SSpQDklCrpN&,[+acEMf(2*0@!ppShkQb6&0KhlHT0bffJ5$QhHEU$ +Dfk(Dr,"3lIJ,fie9He0Y9(YLaNUY9EYVMSqIDRHpk0LTGLYh#!$"UNlUb!2$5F1 +8H0Xj6)J2R%XkaaaekLAcb[QI!,e'Z'HQ"p2`VcU(Z8(-2h9X3+,[cI5"MX9H`&# +3!)aNC5Y-m6UB#+hX3mB#HZ$"hF["+2)V49-(f*65F9EKB43IJX&MEZe4pK&,fP` +`GAlP8U6TCf#A-U"06U$9@Rc8$Q6hAHCrXUdJZbrle35CS[bKaJ"N[,ViJqa2Y3E +CC#T+VGA5!'5R'-L-!@DJB*XNF$RTS5*`@B(eIk&@DBqA@[f50M4dT!*)6i-`A43 +DeTN([A3E2`aRm3@iMpH,#8%[8Y*dbQP0qF&bTFlc&2pc`SfY1P8l0JbH3P)#*5Y +`j`9F#`Q9AR%[Ra$M+Ef,()TbeF'pRJRLhR[,PG1H(i548YCHlIR"(YHpDXmE520 +m!``Q%)1M@cq2`r!XE"f0%h[im%R5m%Pmq'8-[icKiib'la%6a!"F4DHVcIF'2&I +ZcI"Fm6b*G*XR+FRCV@M1LKrMaBr#MCc4MrDi$RlXbI$Z&K-1"V#P'q$,A-#d#jj +Ri!DIJ`pAHkCK1k6Dm`bI-Qf6#aX4hX&Rk"m2-F,8P3#9"FcpMHfG98UM'!r!4$` +[m$r$!-m`dZCr#G$q0m"i2`$eJQF0T@CB93)G@4mhY2YJD-GcB2fhBd5-Tm28Q-@ +,)(Zm42CiN!"pdC-+XZ-jJFY"hR*+`8-+GN@Np8U1H5`20pH#52bp4h(-+4+l+AY +FYkU9dpbaFBDrHTQrH(Q25h66mM!NIqRGM9GAHplL!hl-!I)@(rCM$K!!(SU56bD +RHXQlHl!C[,86P@RG8RC,'`T*`l5"(Xfm2ir3pI2H%"`9NSZk$EFm2CdH&hYT%([ +%`%e*h#@+fh%!feE2'(+E(RJ,!q"N[&md(E6TB))RQk0aYS6'Pd$N5kQ*qYe)i4R +&i8Fe05"NpVAP5S2RG@ca[6l%RBMBe'SAMf%VM9*TXNf+1b*[8,RfDBTcdmZlUSF +6#pDV*(SN3Eh8+RVZ@rV+4FqV,Cl6(NIac0+JXaYY&U84,YLq(8XpV8NAS&5YT&3 +)15YCi3iL2(T!dCR-Xrk8$Kr5*+'5&KbK(f&-Hi*,eB+I[!5Hm)NYXHdA`3M*kc! +3bcUaY4IaRSQkSRT52lMS6S4Ff1ULVE-@T(pXe9j&4+Mk+$9H-ZaZcXe),br9j)b +PZmk648T!+#GR4I5SJD-LbqUSX#)aHCi*L6P!HU89DE6TL+1fmmRcV*0K[&EkGc& +*E)%YeN(SCQia)AQ[Rd1NkSFUiJjK@kZR1!Ta6"ZP*ETrUN48hV#2K)6L#cD5Q0$ +B`Tk)LlB%)DM(ki"8&(jJ"2Y51R3b`8D1Ql"A2`UKeZNq"&GVNlZ[f-H#'-RG'M- +a2)k85)JqK0k(Q11ec1YfNIK6@3HG$TXjZe2L6YT+Z"-9cA4V0YhD"V&B"+EpVVf ++Na@#!E$X"UCieF&9C80F6KSa!U2A%%M"#S"8Bq(!0VZl99lhD)BaN!$[Ye@MF%L +raSQA%3l%8ql4iM0q3$5HX)B%Zp+2LK1MRkpG+Y(4H4K&-JihiXAC9$2[BXk)"a# +)r9%a[cRXD$Nmj,##1"AXKej3kTeLBLFAmmk0pFTN8$*Sa,B+D*&CjDqT9L*2%iZ +N1*1B,M8)A+U1SV%,@bE*k4pmSr[kJdI4d@r@j-(aVJ`p44fjBY2d5cFNA*a)r,E +KC6kf$@j4kG$CE#Ca`%331[m&[20I`%@4ac5m$S`V2C33mT&9$6"mSk3)Ni`U5b- +BE+4%[RXcP1pij[1T'c")MjqVm20hr+b5EZC$$"%4'b5fYT31G*2[iHFQhVRI40f +"T!JN5-dSI)'M0Ei1dfLqjqqd[8%Tc%A%+!G!ie1-r-EX3EJ0XGbAJhFLlF"#)T` +'hqcM*0l&MCa(SD6i3qQT)(i"42jG)6)9CT(4%#aAE*dlrpCEq5,50+J,@&5I9cq +A$J6LCq(Q,Rk3!%5rBrbA$ij9Vj11J1lJ%XL2PilKFa4,JT3R1[aEDpM$MFD2B%M +H"4)Ej9IIRFE61Di(%BXk2UNf$pjCrkP-rU90r'8R%BMdAeH)A"#r`a!U41BhL"d +0+H(Eb6A"#dpLJ!k(FP4c%2BA!@"r"34@KbM0EcBChM!RE8L(JQ(kYpi9lfQqp"p +1B2rF@LAqeG#pA[8k!9mUhf++T#'eU4j13"L(UTMN+((Q`f(!YjCb%mD4m`!Z[ca +kk4fP"eCB8V5`)Dj,4CbkYD)$9HfiA09SBieAY$DQD*D0*YG01lNNk4'SehRSC3Q +[D1KSj($%6QP-(r&UpP'5T+U@0M"dHMC,VL8RN!"d!6mhK&X`l)+Q%S$Ic!hACf& +mE[D8!23Pq2KX1)CL`8Mk6l83kd3R@0r!MH@'A56!h'm[pGb!aiF`GCL+(+1)kE" +L3q9jfr-HNIRl$-pl(Jq[DZq"M"L[V"-Sm2'VjPG*e6c*50aAHkj#94p!+X#3!,c +*b)qfJ4pYJhbdS4)XprmpXcMVF@!5PSVj2S#I(1PQPL3'aNR,HRN&HJNr2q2%rDa +L-6$d'CM2mMc!JDFh!PiIIUlM`1[M`00ci%d#m25Hm3$HH(bF*!([1L2JA@F![1X +Ni,NNi,Qimir!pS!%YJFJAYEK#-GPp9qmM`[!U`*aaAZYJ!NUT*)!bYQ++RlMbGX +YIY8q+f%Jh2JPG91aM#qjH&V'+r%bL+D0*Y%dalU!$JX8G,h!k5ERlARq5mKL6EH +6"0["(ClIF43YNJT"c1&#M4HmmIbZhLBKD*%IJ[lV&!Qi6d&QcGHbB009+0LHjF9 +3fG*6%%$H&BKM"i*3ZX64YmS)IFrMCb0(hr-FIDXiqXB!IDZ3!%*0DFG)cTA3Yp% +)I4X0d,G43YpK#Af(6HLl5d,IACKf`P"iH8iB#DppZ@-RZE,PP$&QF*2)B"[f8&b +qlE'5a!8+jARIG66jEei`99%j5DJCE@YG+V+a9P[cr`QC(2@5@B1GEL3TGj%8a`( +C4!&2VG2aRV#+##bcQ3@C&0EGaK-%*FHHMYrSN!$9613!DA,!DI$"E2#"`LiNT#T +Q8fKb$`Y0T!&bH(+23AJbhdS@XB6L9abLE2BIq(Z%+FCT2+kHLX,4LF0I#NIrC0q +lBq5Lm[p%U$NaGm0BK*UZikC3mjeA0G4m[iUKCLf53ViRSHD)FDJTT63pAU(Q5+e +$c9GKbqGa#$9rCa"UMKL(QK)3M5GX+K*U9MXD%'TZp`XeGA+SkErPpkEVHaTiMVb +L`229hLkEiKGiMR#$H*2'6#Ne--e1fM)m(S5FCk3EXiJA%$e8$*f&P'%BaZqVUY' +&E')ICH&%KKJh)UqM3)icG%U6,R%MC6dQVIFc8(XP*CPL%)Ef3V#fA3[9mYc!Tfl +"S09'BHLA2!4&J9R*`0RL&m$p&6rrj)E#2`d-8#6BXi-fMS-*qSr*"+)53"VhX#- +d[L#&SJ@'S5JRFh%&SHJ0k")@aeFp&&dmd9$dHKcKZ(58-ii-I`1)#1C'@qrM()c +@&3P''lS)4Xp@5',Ai@L"`B4DKU166r@5`p(Y4F24'*('`Xf[B9EaMASHN!!fM0+ +$U4*3i`&9$dXR5ip"@$SLKD@5fMNE6)'T0ei+6"YdRS9iGCCA2`K![l"d2Dpikj0 +-LQYCbXhc6E*jAL6Pi3*h'E%`G6X3JSe+)$8,a[SQcaUS6``,C2'L[j6m3%@-&KL +Cl!Yi@VR9E-IVAQcf[+fAYRZ-JPB8IIV)m`iGiD%-ccZHKGJiH3F%T[#+r35@H-* +2*-b[-'5G,i@X%Eq3!(8,2rB@kl'(@P'Y2r(FajP2-`TDCdP"+phF*`Q0DAj"d@r +`Xi),M49&K%Dla(i-AYmAG5&4FKB(lqSZ`GZ(Rh95)%[JAFh"1`AJAHejA3,[&#V +FD3,[1L2`VLX#hR9qi$8)DaqLB*S!1`Z#DP%&3Hem",A4#S*DAm8LT2(CbB5e"3C +KV9A-946@GV9%B+`#fm@e$Qc21+Ul%*-I'BHfALp(kf+Mm,D1SrM,,P(m2(9I8V" +,+2k5SrKPS2K,cjX5LPr'cjXQ&2FDSELh#)Tlr9"X%2S#aBXp#kqP2bF-K@3Y`Yk +*TX-EKEdM21aPhAL0+I"e0KL%[GX9%T%8pT,SE+K0f$Za8-3Sl(hJHa,f2V"K)Q( +[b#X*HhQBa-,HGakhX2IpUSHp%pf%03jl&m+S@#JIjGTLcViK&m820%F+Y6Pb%EM +#R1I#@Z*KYp1(#X-[2eEA2mX+&aLb!P'`9`ZcFa#')kQRDij&@0kbG@)XpdqFT8X +1EY!dS`eT&mI##dYF+*9p'F,Z(NT#S"3&+YL[A[*K2M8qb"-8PR&heaceN[Yr'ID +%A'kICM'UqXXKPd'5`Kb@T-"Z+8%"dhK$'MfB+TUp0fU3!!,ai45q!"DXiBA22Nq +Y6d5kJXZ8VZ#$N!$aXZ*d9&JqL%)i5!bCM53'Pbi"k5)ZeHQ`46rDD6Qqqk4VQeT +"FfVE"+KSTH,N4Pi"Eqj$CY#f$HV+Nfh3m"i2VDMaU3[ee%62KASH%T9Y4f,-+*U +dK*!!IRIkr6[h+56%)-aMeHr@ImS+!KQRMN""el'd%BME"ph6Tij6YB6`4ih#IMS +c'DV@)d5LR2aHASLU")dIC%93,"!(`*r1Je-Rd5(3b"%+i%dG,lU4U-m,`0UAF4- +$4pY&4kZ4MMD01RI6dISJ5QeL1hrejX(-U423$81SHelRM5iJp)$`IE1V*'Cqa!J +)@X0-S3S1ZBSG8KF,pTR%F+&aHG3rrF'8bi"5Q9elQk6[Tim8NblQT+9b&p6AaB@ +bM[Ur-a9YCFeZm5EB3N'[cR)l&BC,C%@c&JXP!p4YPh8'3d'%`MGpJ+4V)&G-E1Y +$J'YKiA8C,k)Z0j[PLN0E"+8[D&qe!jK)4A)BUUPlqXSX65`dIH@H3jNVpkc-#Kj +FQ58H#`BL1d9,&N3mNZ)Y-iF4Z*XMB6-DUU%QC+e&ML1Xb,&A[H5ICb+m5e![QGN +8'4D2eAL$&h8A$GRAJ(ePSTLBp92&U6eER4Kk'Xb8qNqPiVjkhK(RX3AIePHEN5M +eX5k!SX("K#F8TmBTMML'1VB%SlUG+2lEcJS+5k)B4H%qMm1f%4Uk&FpaSSq*!5T +L&rNA%1ifUF0HZlffSP)'*J4iH4T+HD@Le'i4-"BB(E3!B#bB#"LcLS$4"MF8Gq' +0G+*j%5X)r9J$K!Arab"m[bJ)UpK&9!a*3e#Z-MV`+S"beGL$FZF0IU$dB`e3V[U +I$-VpB`R+fKFMRjPN,8DqmZJV,dBqmaI@BZ3VXkY3M$b,'PqQ*K"3Q2SCc9(CJ6h +ieX8P+kI*VQdb)S0ZhJNB1,#a$%mMc"K$)T5@kF,TEH63jX@aRe&M!91c"BA&4p* +*YYVp3#dAQQ`P`"ThN[kUPU*(8HqB62Vl363Ge-T5YfIQb`C)%%)qQMNcAjTbKVS ++iq-9)EY6,[$jljP($QMYA9-S0ce+95JS05B(NkNrdP0bS8ah5hXplk,h*SRZMJm +kcI0HShp,ApXi2'[hpedq*IlFf[@IafNAm#4*YR'a[5`0fGYf3`RC3d8jk(rQe(b +SJEhKTBScMk3I-#+&0I$3MN1fV0a3'$QXq%!B5,%a8Xj5F'M4plP4l%56"a)qdFl +L982D1!%"kB9(-LUQSS[P'A&M4i5U+"(r+K14NCC6HbTi%lCIam(*G5DBTTaDqdP +CF&rlGUIY@+1LG6CB(,cBHbq+ZbmV[Ml,V$4m[ml&5EK"h"NIaaZXcA9eJS5FY0a +`'"@m!Pb`PDUkd0+*,B6SF(),3Ec"BDG,8lbGD5K8Y,iXj[9&ADIe2eQ[A551k-J +0G`FBl5mYdfC8U$Q&p2pqa9pGDF1#e"@'8$q3!(9flISbhqf@@ml!qFq%D4e#,2h +DpB%il@`M"Gf&T6+1T+CD!pSL5PSB+14SZ&f"Nl(*eY1SP2A,`*K6h0"J9QM,J)T +9`m`dKa'S+@K'[X+"&RRJFIdaaDG81#M2HFNEajRf,@h,$YMZMZk0rUFC@&M9 +ecaEb*Y+V5N@2CMc$3p*(Tca&hih2cXQ3!#5D52qX`J&HSk-e6)D4B$63)C&a5CP +5a5Q#dF#crJ0j8m`ZD@J-6&eX-'rQ'6G[-QQQHDi#"*+53-QFC&Cf$Yq4TV63`qb +6r-'XQ0q&)U+`ej1+'3f[,jPC4X(qi$CdecZJ'UH0`fb*Db%93HZL`ZCrA@c3F-4 +T@L`b$0HZ6@@$'idC&bmM))ZTmTLTfe@$#rk0r*K@cjDF1DJiU+3q9&,GfIESD23 +$+F(+3pA8De%[q@-aYMdEN!$'hYM[#P%eA5$Zj!k%b3Q$3Y*jUPe9AHD4L5e6N5M +`@qE6"LbK`e*e%!U4$VKSrEX9I'l!jdSbQb+0cbZVGjFjRfq-*!DR+Q*NUP+CUVM +hJ&0hcG"A!f(c'PFK8[hMQcY$SC2Yde$BiR&i#1aqGN!laY&Lr$'dqpNpfUAH2"a +q(Jjr03kIPQ[#Rk%TeV-h9-T%5iMq3Vk%*"(cU4IJL%"P'h"`%3G[kM6MYK+hZKV +c[#[dEqQ9'iCR$93R'S#MUA1UST2!-FB%$N8j*bD%QXN4+Ri9hi&Qd"lh4`kJF`k +[rfF1SMN%)M1"k$5C"4Q6Ka$T5)L,qJ!JYGqiFP%5Ja6LM%%P1iT!d4f)BeARamE +eeT!!p9lr5QV%D*jkbD1AUm#Sd-U)#[X$@@EapePYaAP8A",TZE`"J1C-R+l8DR+ +AiRm$8@5QKdHT#!`*'jhaDUH[YRqXcG#Q`N+VJ2`+f%5Ub+E3'!M86"eV2JZT"Z4 +iGF*9Xa@AI`L&UA(Zqf'L1[Nfbf'Ti5aANY`%N8-Aa@8ZR-b0%Q60E-ePc@`CZ&& +Q5d@IV)eVlIF6UkpqieU",Yl*33f#!h)"dPBS'[@Ebp`TBN+%YR(G)K8QaSZZ(%I +L6YjiQ'6SZlkLRNH9mHUi9+$UK"RZqT5k%2GJQq`FKlRrZ99GikS"A)3V-ae5!aF +me&bX5-9eI&,M,U+I$KZ#4&D%1E+*Uf20&ATYIEFJPS,`'+kDBh6f)QYJ)PSQlKK +&b12Z`64rTbJ5T1k4A+*SRQVfDUY,&!hV9HVkYKe$'1bF1@`01lHjBCBl)m8)pP% +d6Q@10#HG5aM9Y*U-Zhh'$VZVkl+eK36Y3%qf#69@(0"RJNQS"lI@!"ME5GKmN!" +#X5JHZU22mFEpT$!8J5CYQ[CVmRJJZ!!IET3HEX6$$G,$$AMiKr6`$cc-PalQiq( +[dX2ImA#9p(!9(Uk4(Ul"`ccTB4iHlT-HlX2$,1PK&KiHN!!H(UKGd2kBcbKSelr +bS2faZif#p[86#GTcDE13!-#V[84X9pi[IrKUA5!Z*AIJ5(jDDSkL`19b[fDlHhV +"l,3c#IJM(LbB24-&ieE1&Z'm381-q*Ma)%r`QH#H[Q)CNJ!b9ba,D4[%3hdpFbZ +(JNPJfDFpA!U1B,PL$M&E-8FmZ')1-5ZB)c0E-5F$MZd9ph!fph!fpcaj6dTZYpd +Z6CI-)bp5i2[$&YFS(0@fAGLqfYFDG!I1"mk6%+b2K@IhMX)Gbjfam@&k*)GfZ&9 +2'eh2QVH5-++A#4P86*%C6Qm-3L-23'4R3)cN&ZE3BUIf)9J5+qZ9##BrSGJL1HD +Y36GF9ZD1,6`p,$Hb-l[eRHBDLbkaT,XX%S%M("p1ePJ+F-%BR@AY*aSEUSpTH%Q +hGVjSDHY1$8$-fC!!VX,*L&q&jNMi!YY!)-L,XI!f2NDG)TYkQC'ART[2laJSEJC +j2KJZ684%q,YrD4Ch[[e"*"UqkbpYZp$JXN6db$re[cTAkAE281d63hH@NrP0$V( +EGLUf1d2Nj-DY1A)HblE6XPr(4iC0$`q5bU$CS[0hBK"qE1&@-D4[#bTC6bMQ3ZH +f(YSFqacJ1mF),#l0B-3TCq3`-l9e8dGiD(G(f,Rl*dLqi83&4fl5rqTmjFlPefQ +F`5F9fr+rDFb$cB0JLXD$NDTc@bNR%hp`Db0AHK+DjER!&XR0N!#@i@C!24$Ek*U ++5EMJQVME29AaSUNYjqifh2DVE&Lk$BpC2L5Eh,EEYc8Ppf5#"%4MA(2R*CQ!eI@ ++lS9@hEXEqX*$qMijQ!XUcc[A0dGfr[1[iB9k1"Yaf5+,r&+R30Abd*6(Tl,#SBN +,01f",B'RmBUK1-`E,0@TcU,a5aYV0Z-f#0&G"&BhE9acKf,ZC40akH&L5H&EcJ# +-69"#-Hc8GfMbDlBK*6B4j0%Ph(B!01'8h1#1hf`+IrUAjR!VJA[MRNfZd@B-DGE +%$VGZk9L`jmkqk&CaEfAJLrIJp)64B3@b$VFL"2PY)h5a'mC1CYYX)LG6QkV5fY' +NFMC$,N$P"B,lJFlQL),d!RhP$L`i3a0L"$"Lp,Yh-c+FG`,dr0B-j9cZSq3hjfl +F"10AJL6G6k%#kc4$JbHk4ViK-4RD`cR-*)2!D%A+B1D+eXifmD[EGLM11r!!CF! +ImE9$1eDd1Q,dTr1e1hD3!)RB*kN20Ei5*(F)QL2Y(&RaL@DSqEf95eDdDT`dA(a +4CHjXCJ`(JI,"CR&(d%iZNQk6!P)h"8&NbaY9&1rhKdBpRQ@+E43TJ%TC(Llad%J +AB5,dDeDKiie48JfFc6cC#4Y&A$&#CHcQH+V)hD,Xp@9D!%IFEmqh9[B'+[3$"(p +RiqJQ9l!a(#KaP3eP"rMamqL`MKKEl[LbT,KJ&-lfZ8a-NA!VJ5'6lc-YfiZQ!qB +'i$!lj-E%"SJYjeSkqJ+CKC9JaX"i+Yca1`2$l-9[T'iF$[$8Y%al0UbYF&TDF6S +RQ5T8reIR@CA"K40-3TH*DYe1U-3**"1d-m&-&iq$qM3rkj+Ec+9dEJP!%pL0CL- +AL&MkT6,YC"Br4BZ,#-iLGb,)K6,8+jA8e6c@p,Bq%Vdc!21P2@P8Cm',ZNiR5b+ +T9'S8+$95AN8NZX!)Fchr(r-(a-3%&bk8XlZ`(),d!pejQ$j1RI[9Z3hd&A4VTcP +DM&Q(qQM*!TIf%Gej)M[9aT*Re8Y@E(dEKAGJI!8!cUP+!qXB6ZiY29b4122GV)2 +,,&ZjL%-lR%N`3JT1jVH+&Rq'`@M5X#lUEY-FMalqcK4kpHeRaXMr(+j&A',2rD[ +KbUJHbA6LF9`bbqcJADQRp5XAdT,ZkFA'*j+(EGf9AHY*`m"`hKq0e-+1TB6, +4R66-',lNMcK0k@&YQ49eR($4N!"`G2P0[cTR5,i1j&G'G`%JPHH`S@2@L-&i8Ra +92c8Z,*&LSdmid*c"%i-c'!Qr0P3H2b*iT6CVmULbi[M(5Pcj0PBaIR81f`j50I[ +f-e3c$1M1j,`NCc%jEZ"LZTi",FL!PZ!2Y+#LXh#f,I85NCm0"SLa4(#5j0,Ydk4 +U+Af#+Jl!8GP`U9'[am(Q4&A5B-FM)-+0kMZ#p1i@PG5Be'F,3HDCS3-,Ed%cb`F +JKC`J+3CA@)Z+40N)c*Fe2*!!bMf2+)@hH)Nc-(('!@qmP0H[#FZKE!mY"aEcjF+ +%B-,DBZ"-5#"61"laLN-*He#"1pYrEfY8(YENYDp#8Q`-$c'0%`m2KejM3c4AFCF +EY"HjU$N-(a"p%)(Dp#iCaMM$KcR$KcR$Q$($rl3bc%NcBNF'`feSNP#*i)q)*#5 +GiY02Jj-(#8Rij)1M1[H+RIUjX"d*24TYUT("#G3bB(b14MUbi2DKBRflMK)M1"L +M2(fZ4QQUT`ES,UA!4!S2P9##(jU$4aLTJeSkJlKaMkVNSNbj5,$3SFN[(bi@De% +509kC#9mQ"+03B31[82aiT-b)+*r*4BMP)NLRDp+CJ`M'9+&G2BUZ3SC$f0`b*&3 +J3X@j4+B"H6iVHDCM+l*UATD4,P0%*)N%*MSU91eKMFfU41Md2EJB&bBL93+Zf%I +QSJ)d&U#B6RLI(LNQ$jUTQ4401dqHIjKBb"2#PK*AjRB[66)R+(mdijU+miCUP0X +9mfjmT0FF"3d!Vq9E&abLTmfr&a[CC$C3SF[`QPP3`)qa,XL6E$4j5-E6D@T`'6Z +AaQCGfZ&P%rNRQc%a#B4%!"YE`K'iB,hXmcQl(Df,fFR0`!d#!-%F2Bb'k&Ph0GZ +0T1e-FYY'#*c%"%VFBXa)V[JrAja%lUrF!3di&M+3!%)8HMQLkH)&qRF)R$Y0)(D +k4kfJ*@A6m+3Ll5N'-)5-3kRl0K'!Ak3#1+UEB6k1UNiKc"Z5`@%UKX%[eqX(0K% +Z1JRa5A%b#P39)5Q2N!!ibrbe`Jj'bSJdDe(6+5rcmh)#3d@6MB(UlC0CR9A!V-& +Y8H@&B`@ZUM$L$dMU0b%&EGcj)F9@)9+UMC!!dQmLC+Sb&mcUPEN101@#%*Ch1ID +4J)3Hm#kd+Mb&JM)CILS[!93@RpJfTJTh,+80eldm5U*jm#5UU4-0cX6a$BSQ@A3 +$V8j8C+QaB-DQ@m2PY&(+24EQK2eL042$&98kpNUZC!N+NF8q-S6DF%eAVFfiSV! +AAbY-C*R3hX)'bG2jT65NKH#FNaUmb9r$LbF0C5Z63aKM`4K#92NBkYMREJfA+R6 +-4(,ZRXCa0T9LQ4eeMEBK&-V,JlJI3YAGTMb-`1k13m)AP@&2$6VKrQdJ&DJ3YbN +qqS$J)G,a'"ccfj5kMF1BE0(L-RYRKViH1$NJ0Y+3!'kl*NG,2CBL1bRbSq5N'*! +![TY%,)`S+eJ"a$`#085AY$`6L$+S0$U$`rZ-$ZmhK3XHA%T3!Pj8Tpc)Za5Ub+S +b'@RI+USNaYa(P5,2jP3XQVd`#he)Sr'9aA$aLlU#UBU[d-a!kQLJPfep8$8BZNM +6)l(MDm-3ZYL%-DSGHHa4%KE(B$$Y3aG&65"%NH!!iaN1J'BZ(VaG(`0*cECGk)4 +N4,,2!#k9QP)N8mS'%(YK(0DcLfhNEf#"$J'EMDYRJfabC5[l("deE`U5c#YY*KV +dj9h-+6)(qTPCHlCHZ6XX`Nb'Uc4XUARaf-!'9f@Lb[EbJ,JMp*Th0'&!X`LGf9R +4%K8'K8j,MQrQNfJkbh,IX'YhYk['qFJ9$+m6Gb5pKJ6-+[m"fr8[h,kKlhkD(M0 +pA"5fE('KdXDNaIXdLl""HTL,)Z3'&b0NcF34e*3QXq"3&1iakN,K"5e0Xm-'06Q +fpR'R&P3M-bqF9q*+ik+&JKe+2e)[qD,KE6dCPET!C#6FZ%+['KTX$MHZe@2KQ+D +&Ua3A2(a+6"1Mc3"bjm%CE%NjbET[HMN!GcK*%c,hB-T-rb++jJND#59ZHUKQh3J +ZFN20@0RF3R`FE@m$m9&(1ahLZhSFiKjb'Ri4c@iN3a!Q5Q'j9ST"dLMRPiYGMR$ +Y""KP@)#U1&f)J3R%qRDJZjm[SBZi81MN*1q@T3X8mb$BENG$9@9@RPd`jDciCq8 +8Bm@,mjSB[@'hldmYKD9[iN302,mKQlkQckJkcKqGiJCYqR2TGXQU*j0abZdFPI4 +C-XRTF`4"!KF0j9cJ1SPYZ!(HS-6CCPl3T3%r1NHPHdpDbj!!6[P3583J+LU*$Up +l6l(0p-QV*(B11I*53A#U4fbNDN(C&eE6&i6CHPeGESYJmqRTr9#``["cKT23+!" +H$p2V6"6d8[Kr&i5Hm9F0#epGqFpcU`H%6fBYq0N#BFZMp*rDIGGG3UVk0RA+XHq +V$kQcNLmN,aILm62QDI92PmkD)D3+*p91YH@aj+`VDVI`KR"0mM2khLmq&$+%[`X +jFj,A#MeU44lBV[jdG[,8bqUI#e1%CFN[*hrci6FI#@(KMp*)BGR6`UcNbmN6K"2 +VNVqC*ka-[Lcm,hj@#qA6K0q1&j,(#b@FYSprm1$jTmH0HhT`bjA"Z)%Vh30#3#J +62RlkeeHq%Akp),P$k&Z``b2J8R(+3qSI6"2HIr44iAmIII6MHfB)Sc1%jfF)Nai +6PTiBk"EHQ#'X9aIf,%Zq,6PrF,m`@hhdf-(Nlb4r0ILQfYBXR"YmF0Vb[42DK,p +-+qQa#h(6"0Ud'Lmi!"*lYlU-X4AHIf[4SLr`)r`lAKbj8,$L3X&bGFTJQr"EGCl +`dK9K3$hcUGI9Dki)*eHG%-je#"d&2e3I6ABN[b8F&[jPk@"LEh*1F[0J@IFh`X[ +5L'pqU-j*rQAbQm*[KG5PJc8I*KFQ$kJhFXVb-Fla`bH&kF)5GD2`3q%DiIM6*eF +)&iA"RY@[Ulm9[K5Q$Mrjc@@Kjm,2ZSAA&kPI[0)RI(c0K!Hq'G-Rr13(`XAahH1 +lCj`I*h3[RcC&+&`jir8C*i@,mi@2IrhM%bm*&em6[RhQ0d*fKr$-VrYqG+jlc(N +!N!-B!!!NL!!!9lJ!N!-)!*!$)!!!2c`!"kR`!*!$#PM!!&h!!!"G`!#3"#j"9A- +b!*!&!e0PCc)(Ff9RE@9ZG&0PCc-(Ff9RE@9ZG&0PCc3(Ff9RE@9ZG!!!'Qi!N!- +"GJ"1F8U$CL*"l3!J)$`r2!!!)MbTm!!"5N&Q"%T!C`T)3%K"))!K33!%3UG"q[r +1d2`"!#m),c`!!"PZ,`0K!!+X9)pR3%)i#Pj#Tbmm4%&836mm"0@S(h!"%F!+ANU +ICaK1F6!mUA#R4N2k!#SLL%(k!#!`2+P`TNG+JfF%F!&1G8lY!#*1F8U$CJ+Tp(! +!6R9J"J#3"3&1F4mkrrC+(fB551IJi%(krqT3d%kk"Dj-h`F(,cVrhNjeB(*"6%& +%4%008!!$!*!d8(*"E8MRB2"d8*r#,dJ!)#"2)P3aD3!8!"JK3!!N-A`!!3!XdT% +K33!ZS!,I`NcI$`C1G8Si#PjR$#!U!!KR$#"!)""R"Lmkri41G8MR(`C"q[qHF!` +L+J!%`VJ$'Q'NCJ!"2NKkrij1ZJGZ@%q`H[pDCJ!"$U%D,JJ)+J"!!!4R"L"i!UD +J'b`U!!3U+J!)'#S!"*I8PG3J1[p@S4ir1!)JCJ!!l&42,%JJ1[p%)JE#Z!-D@%& +K!2p-)$Vr2-#i!aT"q[mi))"+K@B%S5*J"#"&S#GQ!!#d+NJJ$P#!3IVr###!)$V +r#P'!3IVr!##!3QG)HJ#m,a9)H[m#,cVqiLmkrZ)[1[l+,cVqbLmkrXTK!!e1-"p +R)$m!5S9R##"0S#UJ+f!%)%fJ)b"1S"mJ4k!E-Gm#)'"J)%kJ(b"(S"Yb!")%j`R +M'H34!!%!)!)"!1!J6D"T!J!!(i!")%fJDYA8ep4"q[jf5T!!C`K`!D#BF!1JQ#" +0*8J!#(!!60pJq%je60pJq'!!rVir!#"1S"mJ4k!E-Gm#)0A8ep3`1!)J-F!+B*( +)*8J!#%cIB2K1G8j@!!")j`!i+'i!$%IkrLT&q[iU)"5`NQd%)")SJ%U!Ea)J8b* +Z!!LL,L!8dC14NR!!B!3`22rC60mF!%jH6R919[r)51FH1#BZ!!JS,J!-+'i!%%( +krESY52r83Llrb+%D,8Mrc&92U"``(cS!$%8!!'pF5'lrl$!&8d8r!+J298m[,[r +XU!d`(c`!$%B!!'rF3LHTQeP2,blrl$!'8dBr!+J1)"mY32r`FJ%I!DQE)'lrm%U +3!'F398m[#+QQ-"p)`()%`)&Ra#mZrr#TSf#m%#i!&'F+@8mZZ!+Q)&qJ'cmmS2a +1ZJ5'9%mY32r35S"R!!'H,`"1ZJ2@@%p+!'F+F!%G3!!@6[S#'%KZrq4)E[rJ5'l +rf%kk"@T2l`!-)#lri+%H,8Mrh#!)C`!"C#!Zrq5K(Le)rqJJ#'F!!93[,[rN,`K +1ZJ@i8%mJ!fB!!+CC6bmm3dp%48*RU"mJ(be!rr"+J'F!!)iJ3#*3FKM6`5m*6VS +%Y&K2FJ1`3@Cf)!dJ3(!SdF!Y52rd)Qlrm#44F"M9`#e+rrJ[#Nkk",TB6be!rr` +JE[r`S#P35LCZrp3R5J!S@8m[,[r`6VS9c#!IFZM3J9'!*d!!,&925(Vq-LmZrr4 +)E[rm,``["#mZrp`[,[rJ,blrk%kk#XC86bmZrr#TSb4Zrp3PE[r3!!`PE[rF!"! +PE[rJ!"3PE[rS!"Jr2+'B6VS$9P42*N!r2+LI6VS$5P42)J!J#l#"CJ4`!'!#F!% +J!#9!!"`P4!!J*8`!*%Kkqm`r2+$m2cbJr%kk![K86am!6VS98MmmSCK1ZJ--9%p ++J'F%F!'JQ#"m!!!"@M!35-$JJ()'X)&Q$%(k!+iLI!!!!c`LL"em!!(rb#"Zrmb +J'e92U"``(cS!$%8!!'pd5'lrl$!&8d8r!+J298m[,[rXU!d`(c`!$%B!!'rF3LH +TQeP2,blrl$!'8dBr!+J1)"mY32r`FJ%I!DQE98m[,[r`UDB`(dM!FJ6!J@F),bl +rm+QLB-)NE[r`5T*R%&92,`UTTM!I5-"b"-#"CkS[#UQMB+33,[r)(8!!&NcI((K +1AL"I6qm!$Nl36PErr%MR!$"#,[rm2cbJr%kk!La86b4!5S"RA#m!6VS"J&K25J" +R8#!+*N!J3#mS!!`r2+$m2cbJr%kk!Gj86am!6VS81#",)'J!%+!I)%XJD!!BS"m +JI!!!!9S`%%M!i)"b"V#"CJT`!#"m!!!$2##!(A`!!Irm%#lrr%cI$!"1ANje6PE +rk%MR(cKC6kPe)"mU!%KZrqLSG#!0)%!J%(+'d)%Y32rm)%"F5%2Zrq`Lf#,B@8m +[2%4"9%%r2!69UD!J(bK!)%!N8$)U!!L5DJ!%2!%d+J!'P'S!!Mi#0LlrmNM$1#l +rlNM%PS3i!8M%PS4U!P+$iS-p3rrf0Llrm%M$1#lrl%M%PS3i!NM%PS4U!P+$iS- +p3rrd0LlrpYC"282rqM)Zrr653Me"rrKC6d+R5'lrp%Kk!'Cb!4m"FJ%r!A,r,`& +#*d+RU4-J(bC!,`#SF`D&!*!$H#m-)%Y`%0(!,`LSpPP2UA8J(l#&C!*Jp&92UA3 +3(fB#B2C`rcm!3QFJ(k!b,`ZT&#m-UD-[,[rSU(0-haci6Pj1G3!#!!"19J!!51F +!-#4Z!!JJ#LC!)%!L+!!#$)&"6%&%CKBL+!!'$)&%3de3CJS`+!!+FJ1`3@F%F!" +J!R!"60m-!%jH6R8[#PP22cbSER!"(`"1ZK*i)&mN5&P22cbUER!"(`"1ZK*Q)Pm +J5V(*CJB`2!)!B!3`2!3!*&p1G8j@!!![!cBZ!!J`!dM!!S!!!!J!5S"["(!"B!* +`!#BI6Pj1G8j@rra)ja`!0Li!#$m$6VVrc&42(8$rr()"X!&Q%!*$"rp1Z[q!X%0 +Z"(!!B#KC6cmmU*p`!4m!6VS4m#!I+J"C6cm$(blrr%kk%H!J(bJ!X)9Q!R!!60m +!1%jH6R919J!!51FB-$JZ!!JNEJ!+)%SJ%#C!)%!b%!a"384Q+$)S!!)-3805CKi +f"(,rYN&R'L!S!!4b'1+S!S!!N!2r-J0)`E#"C`4`!'!#F!%G3!!160m-'%jH)&p +F6dl36PB!!&925'i!#($r2`"1Z[q5%"pR%L"Z!!JJ+!!%FKMLU!*!!2pJ!R$r6Pj +1G8j@!!"96dKZ!!K`rcm!6VVrC"!ICa!JEJ!))#J!"!+!!2q3!f!#F2p1ANje6PB +!!%MR'$JQEJ!)+'i!$#",-,`$!A!!*%`NJ#Bm!!!"*0H5"T)!!!*)"T)!N!-J+$` +!N!1!fC,CNLJm!!!%N!$CNYH5fC)'NJ#3!h`'NJ!!J!"`!#4Z!"!NJ!D5!*!$*!D +5!*!$)!D5!*!$5!D5!*!$2N*!60mF'%jH6R919[rN51FI1#CZ!!JU,J!-)!XS3#e +!rqK`*0R!,8crl(!JfF!Y62r`F%MC`#e-rr4`2YR!)!b3!)Z`K@-'F'91qJ#b3N! +q!%*!28$rj$B(F#5f3'4)F!5f3'3%F!"J$(!!-!0CJ'S#9S$NJ(J!1!-Y42rif+l +rk#4%&)!J,[rid)$3V[r`)%!`V[rNF!%8%R)!%J,MB0&Zrq454f#`3N!q!(!"2!! +f"h!IYN"N4(!"YN"N"(!!B!a`!$!$8i"U!P+!iS"i!$J$,86rr0LZrq`N4"5!)#l +rr0#!d+lrp#"!-)C`!435FJ!5!Z0Jh%"54f#d3N"-haci6Pj1G8j@rr")jami*'i +!##CZ!!`k,J!3+'i!%N*!2!!b"A!!-!(3J$3'FJ!b!V#"Ea4#3$3'FJ!b!Y+"dS` +J36#!8NCJfN*!2!"`!Me!rr)f"VC&C!!!Z%*!2J"#3$e!rr"`!$!$jB$3LL"!)"! +Y32rd-JC`!$!"d)XJ3"J3GJ!@",C(B`!!JM!ZrrCb!F""d@lrm(!!-!06J$3(FJ! +b!V#"Ecii,[r`GJ!f"#e$rrc@JpD-)%0+8'B5)#lrr0#!d)`J3$#Zrr*8E[rb-Ll +rm(!!-!(3J0#-)%!`%$e!rr"J&M!&d%$34M3Zrr"b!$)#dS(5M#""-)"54b!Zrr6 +LL#e!rr4J!2pX8NCJ!2p%60mFq%jH6R919[rm51FF-#4Z!!Jf,J!-*Qi!$M)$F!! +`!HD!1!!`!h)(`%%k!(!!,8$rr$3%FJ!b!Y++)%%5%(!!%!%d"A)!-J,LS()"`)( +4V[rm)Llrr11*dSXJ36)3F!!`!5e!rra546!&FJL`3@B'3N!k!&*%-Li!%R!!-!( +3J,#ZrraM!Q#U%#lrra)Z!"25!C!!!8cI$$K1ANje6PErr%MR(b!NEJ!)1#i!$$S +Z!!ib"(!!-!(QJ$`!-J4d"m*#2J&f!$B!eSSJ3a!3G!!8!#e#rra`!$!"0!9b!$) +#d)(QJ()#X)&R$()"X)&R)%U!Cc4J-M3'FJ!b!P5"dSSJ34)3F!!3!A)3ikL"V[r +m0!Cb!$)#8S(5LL""%K"`!"!"iBL"V[rm)#lrr$3(FJ!b!Z+S,8$rr($rFL!f"A3 +!0!15JZ+S`'lrrNcI"2K1ANje6PErf%MR(cJQEJ!)+'i!$L!m!!!"*0'Z!")J2!! +!!NM4VJ!5)#i!%Le!rqab)01Z!")L,J!5,8(rm#3m!*!$J0@Z!")N,J!5,8,rp#4 +,'"*f!"B%,82rq1D$HJI'49*$282rh#BZrrMLJhS$aN983ce$rqCf!6SZrqEVBce +$rqKq3-J(I!!F"$e'rq*i!HYN8d3p42rJ+Llrq(i"bSGR#(S!1J46K@!#H[mp4Ir +HH!Jp42rN5NCR4LmZ!")[!$m$8NS[#NkkrcT2l`!1jd$4E[rN,bi!%LmZrr!r!bm +Zrqa1ZJX)6qm!$LmZrr3r!bmZrq`[,[r`6VVmV%r[!!j#3$e!rpJ`,[rBX'i!$'3 +!!6S`,[rLCcSN3$mZrqJ[,[rd2blrj#m,6VVpMNr[!!`5!#!+F!!3!6e!rpTd!$3 +!e+lrl#"#%""b!")!dflrj'!F2blrjMmZrq3[#dkkrI"36ce!rpS`,[rQd@lrj$! +ZrpU`E[rHCKBb,[rB8Qlrf(!!-!(3M#"!3K"J!2pk-#lrfV"Zrq"Q!!#8-#lriQF +k*%!r,[rS,blrp$mZrq3[#dkkr3C2l`!-%J!J#R!!%!%p32rDG!!d!05Zrq`J3K! +3FJ!5!00Zrq4J($mZrqBr,[rN,`Y1Z[eS8%mp32rD-#lrjY&Zrq4@E[rD-#lrfP0 +ZrpT+3'F!r`!i,[rBGJ!f"#e$rra6JpD-)%-3%#)Zrrc5M#""%)"5E[rBB-i3,[r +Gd#lrfc3ZrpK5E[rBFJ!b!Y+-)%%3J'!!rVib,[rNF!!`!9k!jS"-haci6Pj1G8j +@ria)jami*Qi!##SZ!!`SEJ!3,#i!&#e,rmK`*0I!,8[ri(!Jem!Y5rr-F%MA`#e +,rq3Y62q8*M`!!!%NeklrP#!m!!!#50'Zrj4`)0'Zrj3S2!#3!i$CV[q8fDlrP#e +Zrj6rY#Jm!!!%N!$CV[q8,@lrP2qieklrP#eZrj6r[0QZrj3YE[q8rp4`I0'Zrj3 +YE[q8rk3J2!!!J!$4V[q8)#lrP*!!M,#&B`T`C6e!!#K1qJCkF!!Z!%*!28$rM#4 +Zrk69r!!!J!!Y5[qS,@lrT2q3!#em!!#!!2rS5'lrk#mZrk3JEJ!N6T!!8%mJ,[r +SCJT`Cce!!#K1qJBd*'lrN!"55VAZrkKMD#"Zrj!!8NL4l[qS,8Mrp#"Zrj!!NHl +rT#e)rr!JE[qSNHlrN!!Y52rX)!KR$L"Zrj!!)QlrT#!ZrqbL,L4Zrk69l[rX,8V +rN!")E[r`,blrT#"Z!#41N!"36b!Zrr#`V[rdC!T`Cce!!#K1qJA!)'lrN!"5V[q +3!"!3(8$rS()!%J$5390"28(rd$!Zrp$33$e!rp)JEJ!F)"$3VJ!J,8$rX#4!,`` +[,[qi2c`"*#mZrj!!6VVlmNr[!!ib!#!+F!!`!G'Zrj!!,``[,[qd2c`"*#mZrlK +1ZJHk6qm!$LmZrl`r2!%N,blrZ#mZrl41Z[PF6qm!$L4!,``[,[qi2blrd#mZrj! +!6VVlS%r[!!ib!#!+F!!`!G'Zrj!!,``[,[qd2blrd#mZrlK1ZJGS6qm!$LmZrp3 +r,[r3,blrZ#mZrl41Z[N+6qm!$R!!,J"#3$e!ri`YEJ!Jrk`JE[qXXHlrX'3!"+K +#3$e!rjJ-EJ*)rjKN!!$#-#lrM'B!!)`NE[q3!&*+YHlrU'0S)'lrN!"55*(ZrkJ +Y52rd)'lrN!#4l[qN,8Mrm#"ZrkL4l[q3!#e)rq`J#'F1)'lrN!!LE[qN)#lrl+) +Z*'lrT0AZrq`Y5[q3!%KZrr![,[qN)'i!*%k3!&"2)#lrm,#Zrr4N#R"R28!!+%l +k"%)JE[q3!&+Zrj!!%K"`!"!",J"`#$e!ri``"h)"`%(4E[qB-LlrQ(!!-!(3J0# +Zrl`J3$!328$rQ#!(iSJZ!&0ZriaJ!2mi"'i#52qB$'i"!2qBC"!JE[qX8UlrV"# +ZrjPJ!2m)"'i"!2qB1#lrQ(B!0J3Y3rrieS2@V[r-)%-`%$e!rjSL,[ridUlrb#" +"%K"`!"!"28$rR%T!C`!!`JaZ!"MrM')!!*JNE[q3!&*+YHlrU'0S)'lrN!"55*( +ZrkJY52rd)'lrN!#4l[qN,8Mrm#"ZrkL4l[q3!#e)rq`J#'F1)'lrN!!LE[qN)#l +rl+)Z*'lrT0AZrq`Y5[q3!%KZrr![,[qN)'i!*%k3!&"2)#lrm,#Zrr4N#R"R28! +!+%lk!bJJE[q3!&+Zrj!!%K"`!"!"0#lrM()!-J,MU)k!8'lrM'!!rf*`rh)J1#l +rR(B!0J55Jq+S`%I4E[qD)!IQU#i!Q@lrM%*!28$rQ$!ZrjL`E[r5C!!!`M!Zria +Q!!#-*'lrN!"55VAZrkKMD#"Zrj!!8NL4l[qS,8Mrp#"Zrj!!NHlrT#e)rr!JE[q +SNHlrN!!Y52rX)!KR$L"Zrj!!)QlrT#!ZrqbL,L4Zrk69l[rX,8VrN!")E[r`,bl +rT#"Z!#41N!"36b!Zrr#`V[rdC!T`Cce!!#K1qJ*B)'lrN!"5V[q3!")3F!!3!5i +!F!Jp32q--!Gb!F""d@lrQ$)ZrjK`!$!"d)$3V[r8)%!`%$e!rjJJ"q+),J"6E[q +-B!$r0M!Zrp+4E[qB1#lrQ(B!0J3Y3rrmeS2@V[rN)%-`%$e!rjiL,[rmdUlri#" +"%K"`!"!"28$rR%T!C`!!`JaZ!"MrM')!!*JNE[q3!&*+YHlrU'0S)'lrN!"55*( +ZrkJY52rd)'lrN!#4l[qN,8Mrm#"ZrkL4l[q3!#e)rq`J#'F1)'lrN!!LE[qN)#l +rl+)Z*'lrT0AZrq`Y5[q3!%KZrr![,[qN)'i!*%k3!&"2)#lrm,#Zrr4N#R"R28! +!+%lk!9SJE[q3!&+Zrj!!%K"`!"!"0#lrM()!-J,MU)k!8'lrM'!!rf*`rh)J1#l +rR(B!0J55Jq+S`%I4E[qH)!IQU#i!Q@lrM#"Zrk`b,[qHF!!`!C(!,8MrP,(Z!#" +PB#"Zrj45V[q8%"!JE[qX8UlrV"#!)'lrP&+Zrj33%#"Zrka5V[qX%)!JE[q88Ul +rP"!3)'lrV&+Zrk`3J$!ZrjT6E[qD5N"R!2[H)'lrP&+Zrj33%#"Zrka5V[qX%)" +Jh&CZrjSJEJ!BdFBb,[qHF!!`!5*Zrkb6lJ!JN!#*NF!Y52q8-#lrQQFQ)'i!'0( +'XHlrP'-D)'lrP&+Zrj33%#"Zrka5V[qX%)"6E[qDB03YEJ!Jrj3`,[qD8flrQNT +!C`$lCL"Zrj45V[q8%"!JE[qX8UlrV"#!B0`JE[qXXHlrX'F)F'Fp3!!SB"3JE[q +XNHi!)#*Z!"`LL%*!28!!+%cI(2K1AL"I6qm!)%l3!(!m!$iJ!!"i)$i`)#BQ)(J +J2$dc-J!!1N0[EA"bCA0cD@pZ1N4PBfpYF(*PFh0TEfi`-c!a,Q-!!$`!2L!!!(J +J2M!J*LBJH#!m26-b!!!k3fpYF(*PFh0TEfik4'9MEfe`FQ9cFfP[EM!c-$%ZB`! +!6PErk%MR(cJq,J!)+'i!$$BZ!!T`!$!$1!Gb!$)%N!#"FJ'`J@m!!E3p42rS282 +rkP*ZrqJ`,[rSX'i!#Q3FFJ!b!0+-)%%3%$3(FJ!b!Y+-)%%5%,!"C!*JeP0ZrqS +`,[rUX%GM(()!-J$5M#""%"!d"h)!-J,5M#""%K#`!@-#B0J`,[rSX'lrkQ8#B() +i,[rSGJ!f"#e$rr$@M#4$%K*`!"!"28$rl$SZrqTi!$J&,86rp0L-*N33%a5!&Ul +rl5!Zrr$3J0#Z!"!J3$!328$rl#)Zrr65JG+Z!"!J36)3*#lrm05#e+i!%#"#-)% +L,[rddS(5VJ!3)%%`J'!!rc)`,[rUX%GQ"P*(B!$r"$J(GJ!f"#e$rrM@M#4$%K* +`!"!"28$rl$`ZrqTk!$S',8Arr0U-*N83%a5!&Ulrl5!ZrrM3J0#Z!"!J3$!328$ +rl#)Zrrc5JG+Z!"!J36)3*#lrq05#e+i!%#"#-)%L,[rmdS(5VJ!3)%%`J#!Zrr` +L,[riN!#"0#i!#R)!-J)N,[rm8S+5JV#"E"i[,J!3,``r"Mm%6VVqA%r[!!``,[r +U8N!q!'!!rP`[,J!3,``r,J!+-#lrkP*!2`"1Z[if6qm!$$eZrqS!#Q!!rMK-hac +i6Pj1G8j@rq4)jami*'i!#$SZ!!`QEJ!1+'i!%Le-rr!J2!!!!56C`#e-rr4#3$` +!0JDf4@3XH!!i!be%rrMBLL"%%"!L,[ridUlrm#""%)!J,[rid)$3V[rd)%!`Je* +'B-i[,[rd,blrm$m&3QG1Z[fb6qm!$%*!2!!f"VC&C"*`!$!$d+lrm#"!5K"Q"&* +'B1K`!#e!rq3f"VC&C!!!U%T$Cc)J,[rNH!!i!be%rrcBV[r`)%38%()!%J)Q,[r +m8i2@V[r`)%-@%(3!&!15JZ1S,8$rj$3'FJ!b!Y+Zrr!J34)3F!!3!6i!,@lrj2r +XF!!Y32rS-!G64dT!Cb!J,[rSiiJL,[rXG!(#JS#",8$rk#!ZrqcLL#e!rqaJf$3 +'FJ!b!Y+"dUlrp#""-K"`!$!"jB$3Lb"!)+lrk&*'8Ulrj'!!re4-haci6Pj1G5* +I)&qJ*5k!DJ*#Pdl4)Pm5(c!I5J&R"+G'B!+M4Lk)6Y%LAa)I-"mJAdS"C`5Q4f! +#SNG1d3#3!`S!1+!"!!8!N!B"!!!"MdN!!Bj*!!!%E&028P3&PJ#!!"`$dJ!838a +59!!+!+T"9A-b!!!",N*14%`!!3%k3dp%43!(!9*%394"!!!"XN4*9%`!$3'q4%a +24`!#!QC'8N9'!!3#LNCPBA3!!!,'5801)`!%!Y**3dp1!!!$$P"*3e3!!!-D8(0 +PG!!!!bC659T&!!!$-P088L!!!3-q8e45)`!!!eCKGA0d!!%$BQ0TBfi!!!0kD@0 +X1!!!!iCVD@jN!!!$NRCPFR-!!31H!)$rrb!!",-!N!@"rrmJ!!6$!*!&J[rr)!! +%F`#3"BArrb3!")--l8hS!)Errb3!"+--mjFi!)Irrb!!"*-!N!@)rrmJ!!66!*! +%!J$rrb!!"18!N!3#!Irr)!!%p3#3"!3"rrmJ!!4M!*!%"+rrr`!!&"`!N!G!!!! +Cc`#3"B$rr`!!'CF!N!3"!2rr!!!CG`#3"[rr+!&cE3#3"3%!AK`!(PB-mjFX!!) +!D"`!N!!I$21A*!!$!()F!+`d$21A"!!%!(`F!21L$21A4!!&!)BF!58[$1raK!! +'!*!!(!&)6JcaVlJ!"rrr!!&cb3#3"[rr+!"J'!#3"B$rr`!!!DF!N!@#rrm!!!* +h!*!&KIrr*!!!J!cY6NJ!K[rr*!!"*JcY6H3!Krrr!*!$eJ#3"BMrr`!!!`%!N!@ +errmJ!!)&!*!%!3F!0#!!%fi!N!3#!2rr!!!$f3#3"!)"rrm!!!3A!*!%!qMrrb! +!!Y8!N!3%!Irr)!#3"`4,!#J%!",J$21A3!5[rrm!!"-`!*!%!3F!(#!!%5-!N!3 +$k2rr)!!*@!#3"!4,!"!%!"%+$21A!!#!rrm!!"P!!*!&JIrr!!!C5`#3"B,rr`! +!'9B!N!@$rrm!!"PK!*!&K2rr!!!CE!#3"[rr!!'11`#3"B$rr`!!&#`!N!@"rrm +!!"8`!*!&J[rr!!!@0!#3"B2rr`!!&cJ!N!@%rrm!!"Jm!*!%"%[rr`3!%Q8-mjE +S!qMrr`!!#E3!N!@!rrm!!!8K!*!%rj!%!!&cL3#3"!)!N!-J!!8&!*!%!J%!"b! +!"48!N!@!rrm!!!Pd!*!(6`!!'IF!N!@%rrm!!"Rc!*!%"%[rr`3!%6m-l8hX!)6 +rr`!!'P)!N!@!rrm!!A1A!*!&!Irr)!!3q!#3"3,rrb!!%0S!N!3'F(*[EA"d#-3 +JFh9QCQPi#dPZFf9bG#"%DA0V#d9iDA0dD@jR)&"A#dPZFf9bG#"%DA0V#d9iDA0 +dD@jR)&"A$NphEQ9b)(*PFfpeFQ0P$NphEQ9b)(*PFfpeFQ0P#90PCfePER3J-3P +6C@GYC@jd)$)*8f9RE@9ZG#!c#90PCfePER3J03P6C@GYC@jd)$B*8f9RE@9ZG#! +fS33: diff --git a/mac/tclMacResource.c b/mac/tclMacResource.c new file mode 100644 index 0000000..3d228d2 --- /dev/null +++ b/mac/tclMacResource.c @@ -0,0 +1,2258 @@ +/* + * tclMacResource.c -- + * + * This file contains several commands that manipulate or use + * Macintosh resources. Included are extensions to the "source" + * command, the mac specific "beep" and "resource" commands, and + * administration for open resource file references. + * + * Copyright (c) 1996-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacResource.c,v 1.20 2003/12/24 04:18:21 davygrvy Exp $ + */ + +#include <Errors.h> +#include <FSpCompat.h> +#include <Processes.h> +#include <Resources.h> +#include <Sound.h> +#include <Strings.h> +#include <Traps.h> +#include <LowMem.h> + +#include "FullPath.h" +#include "tcl.h" +#include "tclInt.h" +#include "tclMac.h" +#include "tclMacInt.h" +#include "tclMacPort.h" + +/* + * This flag tells the RegisterResource function to insert the + * resource into the tail of the resource fork list. Needed only + * Resource_Init. + */ + +#define TCL_RESOURCE_INSERT_TAIL 1 +/* + * 2 is taken by TCL_RESOURCE_DONT_CLOSE + * which is the only public flag to TclMacRegisterResourceFork. + */ + +#define TCL_RESOURCE_CHECK_IF_OPEN 4 + +/* + * Pass this in the mode parameter of SetSoundVolume to determine + * which volume to set. + */ + +enum WhichVolume { + SYS_BEEP_VOLUME, /* This sets the volume for SysBeep calls */ + DEFAULT_SND_VOLUME, /* This one for SndPlay calls */ + RESET_VOLUME /* And this undoes the last call to SetSoundVolume */ +}; + +/* + * Hash table to track open resource files. + */ + +typedef struct OpenResourceFork { + short fileRef; + int flags; +} OpenResourceFork; + + + +static Tcl_HashTable nameTable; /* Id to process number mapping. */ +static Tcl_HashTable resourceTable; /* Process number to id mapping. */ +static Tcl_Obj *resourceForkList; /* Ordered list of resource forks */ +static int appResourceIndex; /* This is the index of the application* + * in the list of resource forks */ +static int newId = 0; /* Id source. */ +static int initialized = 0; /* 0 means static structures haven't + * been initialized yet. */ +static int osTypeInit = 0; /* 0 means Tcl object of osType hasn't + * been initialized yet. */ +/* + * Prototypes for procedures defined later in this file: + */ + +static void DupOSTypeInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr, + Tcl_Obj *copyPtr)); +static void ResourceInit _ANSI_ARGS_((void)); +static void BuildResourceForkList _ANSI_ARGS_((void)); +static int SetOSTypeFromAny _ANSI_ARGS_((Tcl_Interp *interp, + Tcl_Obj *objPtr)); +static void UpdateStringOfOSType _ANSI_ARGS_((Tcl_Obj *objPtr)); +static OpenResourceFork* GetRsrcRefFromObj _ANSI_ARGS_((Tcl_Obj *objPtr, + int okayOnReadOnly, const char *operation, + Tcl_Obj *resultPtr)); + +static void SetSoundVolume(int volume, enum WhichVolume mode); + +/* + * The structures below defines the Tcl object type defined in this file by + * means of procedures that can be invoked by generic object code. + */ + +static Tcl_ObjType osType = { + "ostype", /* name */ + (Tcl_FreeInternalRepProc *) NULL, /* freeIntRepProc */ + DupOSTypeInternalRep, /* dupIntRepProc */ + UpdateStringOfOSType, /* updateStringProc */ + SetOSTypeFromAny /* setFromAnyProc */ +}; + +/* + *---------------------------------------------------------------------- + * + * Tcl_ResourceObjCmd -- + * + * This procedure is invoked to process the "resource" Tcl command. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_ResourceObjCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *CONST objv[]) /* Argument values. */ +{ + Tcl_Obj *resultPtr, *objPtr; + int index, result; + long fileRef, rsrcId; + FSSpec fileSpec; + char *stringPtr; + char errbuf[16]; + OpenResourceFork *resourceRef; + Handle resource = NULL; + OSErr err; + int count, i, limitSearch = false, length; + short id, saveRef, resInfo; + Str255 theName; + OSType rezType; + int gotInt, releaseIt = 0, force; + char *resourceId = NULL; + long size; + char macPermision; + int mode; + + static CONST char *switches[] = {"close", "delete" ,"files", "list", + "open", "read", "types", "write", (char *) NULL + }; + + enum { + RESOURCE_CLOSE, RESOURCE_DELETE, RESOURCE_FILES, RESOURCE_LIST, + RESOURCE_OPEN, RESOURCE_READ, RESOURCE_TYPES, RESOURCE_WRITE + }; + + static CONST char *writeSwitches[] = { + "-id", "-name", "-file", "-force", (char *) NULL + }; + + enum { + RESOURCE_WRITE_ID, RESOURCE_WRITE_NAME, + RESOURCE_WRITE_FILE, RESOURCE_FORCE + }; + + static CONST char *deleteSwitches[] = {"-id", "-name", "-file", (char *) NULL}; + + enum {RESOURCE_DELETE_ID, RESOURCE_DELETE_NAME, RESOURCE_DELETE_FILE}; + + resultPtr = Tcl_GetObjResult(interp); + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); + return TCL_ERROR; + } + + if (Tcl_GetIndexFromObj(interp, objv[1], switches, "option", 0, &index) + != TCL_OK) { + return TCL_ERROR; + } + if (!initialized) { + ResourceInit(); + } + result = TCL_OK; + + switch (index) { + case RESOURCE_CLOSE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "resourceRef"); + return TCL_ERROR; + } + stringPtr = Tcl_GetStringFromObj(objv[2], &length); + fileRef = TclMacUnRegisterResourceFork(stringPtr, resultPtr); + + if (fileRef >= 0) { + CloseResFile((short) fileRef); + return TCL_OK; + } else { + return TCL_ERROR; + } + case RESOURCE_DELETE: + if (!((objc >= 3) && (objc <= 9) && ((objc % 2) == 1))) { + Tcl_WrongNumArgs(interp, 2, objv, + "?-id resourceId? ?-name resourceName? ?-file \ +resourceRef? resourceType"); + return TCL_ERROR; + } + + i = 2; + fileRef = -1; + gotInt = false; + resourceId = NULL; + limitSearch = false; + + while (i < (objc - 2)) { + if (Tcl_GetIndexFromObj(interp, objv[i], deleteSwitches, + "option", 0, &index) != TCL_OK) { + return TCL_ERROR; + } + + switch (index) { + case RESOURCE_DELETE_ID: + if (Tcl_GetLongFromObj(interp, objv[i+1], &rsrcId) + != TCL_OK) { + return TCL_ERROR; + } + gotInt = true; + break; + case RESOURCE_DELETE_NAME: + resourceId = Tcl_GetStringFromObj(objv[i+1], &length); + if (length > 255) { + Tcl_AppendStringsToObj(resultPtr,"-name argument ", + "too long, must be < 255 characters", + (char *) NULL); + return TCL_ERROR; + } + strcpy((char *) theName, resourceId); + resourceId = (char *) theName; + c2pstr(resourceId); + break; + case RESOURCE_DELETE_FILE: + resourceRef = GetRsrcRefFromObj(objv[i+1], 0, + "delete from", resultPtr); + if (resourceRef == NULL) { + return TCL_ERROR; + } + limitSearch = true; + break; + } + i += 2; + } + + if ((resourceId == NULL) && !gotInt) { + Tcl_AppendStringsToObj(resultPtr,"you must specify either ", + "\"-id\" or \"-name\" or both ", + "to \"resource delete\"", + (char *) NULL); + return TCL_ERROR; + } + + if (Tcl_GetOSTypeFromObj(interp, objv[i], &rezType) != TCL_OK) { + return TCL_ERROR; + } + + if (limitSearch) { + saveRef = CurResFile(); + UseResFile((short) resourceRef->fileRef); + } + + SetResLoad(false); + + if (gotInt == true) { + if (limitSearch) { + resource = Get1Resource(rezType, rsrcId); + } else { + resource = GetResource(rezType, rsrcId); + } + err = ResError(); + + if (err == resNotFound || resource == NULL) { + Tcl_AppendStringsToObj(resultPtr, "resource not found", + (char *) NULL); + result = TCL_ERROR; + goto deleteDone; + } else if (err != noErr) { + char buffer[16]; + + sprintf(buffer, "%12d", err); + Tcl_AppendStringsToObj(resultPtr, "resource error #", + buffer, "occured while trying to find resource", + (char *) NULL); + result = TCL_ERROR; + goto deleteDone; + } + } + + if (resourceId != NULL) { + Handle tmpResource; + if (limitSearch) { + tmpResource = Get1NamedResource(rezType, + (StringPtr) resourceId); + } else { + tmpResource = GetNamedResource(rezType, + (StringPtr) resourceId); + } + err = ResError(); + + if (err == resNotFound || tmpResource == NULL) { + Tcl_AppendStringsToObj(resultPtr, "resource not found", + (char *) NULL); + result = TCL_ERROR; + goto deleteDone; + } else if (err != noErr) { + char buffer[16]; + + sprintf(buffer, "%12d", err); + Tcl_AppendStringsToObj(resultPtr, "resource error #", + buffer, "occured while trying to find resource", + (char *) NULL); + result = TCL_ERROR; + goto deleteDone; + } + + if (gotInt) { + if (resource != tmpResource) { + Tcl_AppendStringsToObj(resultPtr, + "\"-id\" and \"-name\" ", + "values do not point to the same resource", + (char *) NULL); + result = TCL_ERROR; + goto deleteDone; + } + } else { + resource = tmpResource; + } + } + + resInfo = GetResAttrs(resource); + + if ((resInfo & resProtected) == resProtected) { + Tcl_AppendStringsToObj(resultPtr, "resource ", + "cannot be deleted: it is protected.", + (char *) NULL); + result = TCL_ERROR; + goto deleteDone; + } else if ((resInfo & resSysHeap) == resSysHeap) { + Tcl_AppendStringsToObj(resultPtr, "resource", + "cannot be deleted: it is in the system heap.", + (char *) NULL); + result = TCL_ERROR; + goto deleteDone; + } + + /* + * Find the resource file, if it was not specified, + * so we can flush the changes now. Perhaps this is + * a little paranoid, but better safe than sorry. + */ + + RemoveResource(resource); + + if (!limitSearch) { + UpdateResFile(HomeResFile(resource)); + } else { + UpdateResFile(resourceRef->fileRef); + } + + + deleteDone: + + SetResLoad(true); + if (limitSearch) { + UseResFile(saveRef); + } + return result; + + case RESOURCE_FILES: + if ((objc < 2) || (objc > 3)) { + Tcl_SetStringObj(resultPtr, + "wrong # args: should be \"resource files \ +?resourceId?\"", -1); + return TCL_ERROR; + } + + if (objc == 2) { + stringPtr = Tcl_GetStringFromObj(resourceForkList, &length); + Tcl_SetStringObj(resultPtr, stringPtr, length); + } else { + FCBPBRec fileRec; + Handle pathHandle; + short pathLength; + Str255 fileName; + Tcl_DString dstr; + + if (strcmp(Tcl_GetString(objv[2]), "ROM Map") == 0) { + Tcl_SetStringObj(resultPtr,"no file path for ROM Map", -1); + return TCL_ERROR; + } + + resourceRef = GetRsrcRefFromObj(objv[2], 1, "files", resultPtr); + if (resourceRef == NULL) { + return TCL_ERROR; + } + + fileRec.ioCompletion = NULL; + fileRec.ioFCBIndx = 0; + fileRec.ioNamePtr = fileName; + fileRec.ioVRefNum = 0; + fileRec.ioRefNum = resourceRef->fileRef; + err = PBGetFCBInfo(&fileRec, false); + if (err != noErr) { + Tcl_SetStringObj(resultPtr, + "could not get FCB for resource file", -1); + return TCL_ERROR; + } + + err = GetFullPath(fileRec.ioFCBVRefNum, fileRec.ioFCBParID, + fileRec.ioNamePtr, &pathLength, &pathHandle); + if ( err != noErr) { + Tcl_SetStringObj(resultPtr, + "could not get file path from token", -1); + return TCL_ERROR; + } + + HLock(pathHandle); + Tcl_ExternalToUtfDString(NULL, *pathHandle, pathLength, &dstr); + + Tcl_SetStringObj(resultPtr, Tcl_DStringValue(&dstr), Tcl_DStringLength(&dstr)); + HUnlock(pathHandle); + DisposeHandle(pathHandle); + Tcl_DStringFree(&dstr); + } + return TCL_OK; + case RESOURCE_LIST: + if (!((objc == 3) || (objc == 4))) { + Tcl_WrongNumArgs(interp, 2, objv, "resourceType ?resourceRef?"); + return TCL_ERROR; + } + if (Tcl_GetOSTypeFromObj(interp, objv[2], &rezType) != TCL_OK) { + return TCL_ERROR; + } + + if (objc == 4) { + resourceRef = GetRsrcRefFromObj(objv[3], 1, + "list", resultPtr); + if (resourceRef == NULL) { + return TCL_ERROR; + } + + saveRef = CurResFile(); + UseResFile((short) resourceRef->fileRef); + limitSearch = true; + } + + Tcl_ResetResult(interp); + if (limitSearch) { + count = Count1Resources(rezType); + } else { + count = CountResources(rezType); + } + SetResLoad(false); + for (i = 1; i <= count; i++) { + if (limitSearch) { + resource = Get1IndResource(rezType, i); + } else { + resource = GetIndResource(rezType, i); + } + if (resource != NULL) { + GetResInfo(resource, &id, (ResType *) &rezType, theName); + if (theName[0] != 0) { + + objPtr = Tcl_NewStringObj((char *) theName + 1, + theName[0]); + } else { + objPtr = Tcl_NewIntObj(id); + } + /* + * If the Master Pointer of the returned handle is + * null, then resource was not in memory, and it is + * safe to release it. Otherwise, it is not. + */ + if (*resource == NULL) { + ReleaseResource(resource); + } + result = Tcl_ListObjAppendElement(interp, resultPtr, + objPtr); + if (result != TCL_OK) { + Tcl_DecrRefCount(objPtr); + break; + } + } + } + SetResLoad(true); + + if (limitSearch) { + UseResFile(saveRef); + } + + return TCL_OK; + case RESOURCE_OPEN: { + Tcl_DString ds, buffer; + CONST char *str, *native; + int length; + + if (!((objc == 3) || (objc == 4))) { + Tcl_WrongNumArgs(interp, 2, objv, "fileName ?permissions?"); + return TCL_ERROR; + } + str = Tcl_GetStringFromObj(objv[2], &length); + if (Tcl_TranslateFileName(interp, str, &buffer) == NULL) { + return TCL_ERROR; + } + native = Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&buffer), + Tcl_DStringLength(&buffer), &ds); + err = FSpLocationFromPath(Tcl_DStringLength(&ds), native, &fileSpec); + Tcl_DStringFree(&ds); + Tcl_DStringFree(&buffer); + + if (!((err == noErr) || (err == fnfErr))) { + Tcl_AppendStringsToObj(resultPtr, "invalid path", (char *) NULL); + return TCL_ERROR; + } + + /* + * Get permissions for the file. We really only understand + * read-only and shared-read-write. If no permissions are + * given we default to read only. + */ + + if (objc == 4) { + stringPtr = Tcl_GetStringFromObj(objv[3], &length); + mode = TclGetOpenMode(interp, stringPtr, &index); + if (mode == -1) { + /* TODO: TclGetOpenMode doesn't work with Obj commands. */ + return TCL_ERROR; + } + switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) { + case O_RDONLY: + macPermision = fsRdPerm; + break; + case O_WRONLY: + case O_RDWR: + macPermision = fsRdWrShPerm; + break; + default: + Tcl_Panic("Tcl_ResourceObjCmd: invalid mode value"); + break; + } + } else { + macPermision = fsRdPerm; + } + + /* + * Don't load in any of the resources in the file, this could + * cause problems if you open a file that has CODE resources... + */ + + SetResLoad(false); + fileRef = (long) FSpOpenResFileCompat(&fileSpec, macPermision); + SetResLoad(true); + + if (fileRef == -1) { + err = ResError(); + if (((err == fnfErr) || (err == eofErr)) && + (macPermision == fsRdWrShPerm)) { + /* + * No resource fork existed for this file. Since we are + * opening it for writing we will create the resource fork + * now. + */ + + HCreateResFile(fileSpec.vRefNum, fileSpec.parID, + fileSpec.name); + fileRef = (long) FSpOpenResFileCompat(&fileSpec, + macPermision); + if (fileRef == -1) { + goto openError; + } + } else if (err == fnfErr) { + Tcl_AppendStringsToObj(resultPtr, + "file does not exist", (char *) NULL); + return TCL_ERROR; + } else if (err == eofErr) { + Tcl_AppendStringsToObj(resultPtr, + "file does not contain resource fork", (char *) NULL); + return TCL_ERROR; + } else { + openError: + Tcl_AppendStringsToObj(resultPtr, + "error opening resource file", (char *) NULL); + return TCL_ERROR; + } + } + + /* + * The FspOpenResFile function does not set the ResFileAttrs. + * Even if you open the file read only, the mapReadOnly + * attribute is not set. This means we can't detect writes to a + * read only resource fork until the write fails, which is bogus. + * So set it here... + */ + + if (macPermision == fsRdPerm) { + SetResFileAttrs(fileRef, mapReadOnly); + } + + Tcl_SetStringObj(resultPtr, "", 0); + if (TclMacRegisterResourceFork(fileRef, resultPtr, + TCL_RESOURCE_CHECK_IF_OPEN) != TCL_OK) { + CloseResFile(fileRef); + return TCL_ERROR; + } + return TCL_OK; + } + case RESOURCE_READ: + if (!((objc == 4) || (objc == 5))) { + Tcl_WrongNumArgs(interp, 2, objv, + "resourceType resourceId ?resourceRef?"); + return TCL_ERROR; + } + + if (Tcl_GetOSTypeFromObj(interp, objv[2], &rezType) != TCL_OK) { + return TCL_ERROR; + } + + if (Tcl_GetLongFromObj((Tcl_Interp *) NULL, objv[3], &rsrcId) + != TCL_OK) { + resourceId = Tcl_GetStringFromObj(objv[3], &length); + } + + if (objc == 5) { + stringPtr = Tcl_GetStringFromObj(objv[4], &length); + } else { + stringPtr = NULL; + } + + resource = Tcl_MacFindResource(interp, rezType, resourceId, + rsrcId, stringPtr, &releaseIt); + + if (resource != NULL) { + size = GetResourceSizeOnDisk(resource); + Tcl_SetByteArrayObj(resultPtr, (unsigned char *) *resource, size); + + /* + * Don't release the resource unless WE loaded it... + */ + + if (releaseIt) { + ReleaseResource(resource); + } + return TCL_OK; + } else { + Tcl_AppendStringsToObj(resultPtr, "could not load resource", + (char *) NULL); + return TCL_ERROR; + } + case RESOURCE_TYPES: + if (!((objc == 2) || (objc == 3))) { + Tcl_WrongNumArgs(interp, 2, objv, "?resourceRef?"); + return TCL_ERROR; + } + + if (objc == 3) { + resourceRef = GetRsrcRefFromObj(objv[2], 1, + "get types of", resultPtr); + if (resourceRef == NULL) { + return TCL_ERROR; + } + + saveRef = CurResFile(); + UseResFile((short) resourceRef->fileRef); + limitSearch = true; + } + + if (limitSearch) { + count = Count1Types(); + } else { + count = CountTypes(); + } + for (i = 1; i <= count; i++) { + if (limitSearch) { + Get1IndType((ResType *) &rezType, i); + } else { + GetIndType((ResType *) &rezType, i); + } + objPtr = Tcl_NewOSTypeObj(rezType); + result = Tcl_ListObjAppendElement(interp, resultPtr, objPtr); + if (result != TCL_OK) { + Tcl_DecrRefCount(objPtr); + break; + } + } + + if (limitSearch) { + UseResFile(saveRef); + } + + return result; + case RESOURCE_WRITE: + if ((objc < 4) || (objc > 11)) { + Tcl_WrongNumArgs(interp, 2, objv, + "?-id resourceId? ?-name resourceName? ?-file resourceRef?\ + ?-force? resourceType data"); + return TCL_ERROR; + } + + i = 2; + gotInt = false; + resourceId = NULL; + limitSearch = false; + force = 0; + + while (i < (objc - 2)) { + if (Tcl_GetIndexFromObj(interp, objv[i], writeSwitches, + "switch", 0, &index) != TCL_OK) { + return TCL_ERROR; + } + + switch (index) { + case RESOURCE_WRITE_ID: + if (Tcl_GetLongFromObj(interp, objv[i+1], &rsrcId) + != TCL_OK) { + return TCL_ERROR; + } + gotInt = true; + i += 2; + break; + case RESOURCE_WRITE_NAME: + resourceId = Tcl_GetStringFromObj(objv[i+1], &length); + strcpy((char *) theName, resourceId); + resourceId = (char *) theName; + c2pstr(resourceId); + i += 2; + break; + case RESOURCE_WRITE_FILE: + resourceRef = GetRsrcRefFromObj(objv[i+1], 0, + "write to", resultPtr); + if (resourceRef == NULL) { + return TCL_ERROR; + } + limitSearch = true; + i += 2; + break; + case RESOURCE_FORCE: + force = 1; + i += 1; + break; + } + } + if (Tcl_GetOSTypeFromObj(interp, objv[i], &rezType) != TCL_OK) { + return TCL_ERROR; + } + stringPtr = (char *) Tcl_GetByteArrayFromObj(objv[i+1], &length); + + if (gotInt == false) { + rsrcId = UniqueID(rezType); + } + if (resourceId == NULL) { + resourceId = (char *) "\p"; + } + if (limitSearch) { + saveRef = CurResFile(); + UseResFile((short) resourceRef->fileRef); + } + + /* + * If we are adding the resource by number, then we must make sure + * there is not already a resource of that number. We are not going + * load it here, since we want to detect whether we loaded it or + * not. Remember that releasing some resources in particular menu + * related ones, can be fatal. + */ + + if (gotInt == true) { + SetResLoad(false); + resource = Get1Resource(rezType,rsrcId); + SetResLoad(true); + } + + if (resource == NULL) { + /* + * We get into this branch either if there was not already a + * resource of this type & id, or the id was not specified. + */ + + resource = NewHandle(length); + if (resource == NULL) { + resource = NewHandleSys(length); + if (resource == NULL) { + Tcl_Panic("could not allocate memory to write resource"); + } + } + HLock(resource); + memcpy(*resource, stringPtr, length); + HUnlock(resource); + AddResource(resource, rezType, (short) rsrcId, + (StringPtr) resourceId); + releaseIt = 1; + } else { + /* + * We got here because there was a resource of this type + * & ID in the file. + */ + + if (*resource == NULL) { + releaseIt = 1; + } else { + releaseIt = 0; + } + + if (!force) { + /* + *We only overwrite extant resources + * when the -force flag has been set. + */ + + sprintf(errbuf,"%d", rsrcId); + + Tcl_AppendStringsToObj(resultPtr, "the resource ", + errbuf, " already exists, use \"-force\"", + " to overwrite it.", (char *) NULL); + + result = TCL_ERROR; + goto writeDone; + } else if (GetResAttrs(resource) & resProtected) { + /* + * + * Next, check to see if it is protected... + */ + + sprintf(errbuf,"%d", rsrcId); + Tcl_AppendStringsToObj(resultPtr, + "could not write resource id ", + errbuf, " of type ", + Tcl_GetStringFromObj(objv[i],&length), + ", it was protected.",(char *) NULL); + result = TCL_ERROR; + goto writeDone; + } else { + /* + * Be careful, the resource might already be in memory + * if something else loaded it. + */ + + if (*resource == 0) { + LoadResource(resource); + err = ResError(); + if (err != noErr) { + sprintf(errbuf,"%d", rsrcId); + Tcl_AppendStringsToObj(resultPtr, + "error loading resource ", + errbuf, " of type ", + Tcl_GetStringFromObj(objv[i],&length), + " to overwrite it", (char *) NULL); + goto writeDone; + } + } + + SetHandleSize(resource, length); + if ( MemError() != noErr ) { + Tcl_Panic("could not allocate memory to write resource"); + } + + HLock(resource); + memcpy(*resource, stringPtr, length); + HUnlock(resource); + + ChangedResource(resource); + + /* + * We also may have changed the name... + */ + + SetResInfo(resource, rsrcId, (StringPtr) resourceId); + } + } + + err = ResError(); + if (err != noErr) { + Tcl_AppendStringsToObj(resultPtr, + "error adding resource to resource map", + (char *) NULL); + result = TCL_ERROR; + goto writeDone; + } + + WriteResource(resource); + err = ResError(); + if (err != noErr) { + Tcl_AppendStringsToObj(resultPtr, + "error writing resource to disk", + (char *) NULL); + result = TCL_ERROR; + } + + writeDone: + + if (releaseIt) { + ReleaseResource(resource); + err = ResError(); + if (err != noErr) { + Tcl_AppendStringsToObj(resultPtr, + "error releasing resource", + (char *) NULL); + result = TCL_ERROR; + } + } + + if (limitSearch) { + UseResFile(saveRef); + } + + return result; + default: + Tcl_Panic("Tcl_GetIndexFromObj returned unrecognized option"); + return TCL_ERROR; /* Should never be reached. */ + } +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_MacSourceObjCmd -- + * + * This procedure is invoked to process the "source" Tcl command. + * See the user documentation for details on what it does. In + * addition, it supports sourceing from the resource fork of + * type 'TEXT'. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_MacSourceObjCmd( + ClientData dummy, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *CONST objv[]) /* Argument objects. */ +{ + char *errNum = "wrong # args: "; + char *errBad = "bad argument: "; + char *errStr; + char *fileName = NULL, *rsrcName = NULL; + long rsrcID = -1; + char *string; + char *encodingName = NULL; + int length; + + if (objc < 2 || objc > 4) { + errStr = errNum; + goto sourceFmtErr; + } + + if (objc == 2) { + return Tcl_FSEvalFile(interp, objv[1]); + } + + /* + * The following code supports a few older forms of this command + * for backward compatability. + */ + string = Tcl_GetStringFromObj(objv[1], &length); + if (!strcmp(string, "-rsrc") || !strcmp(string, "-rsrcname")) { + rsrcName = Tcl_GetStringFromObj(objv[2], &length); + } else if (!strcmp(string, "-rsrcid")) { + if (Tcl_GetLongFromObj(interp, objv[2], &rsrcID) != TCL_OK) { + return TCL_ERROR; + } + } else if (!strcmp(string, "-encoding")) { + if (objc != 4) + goto sourceFmtErr; + encodingName = Tcl_GetString(objv[2]); + } else { + errStr = errBad; + goto sourceFmtErr; + } + + if (objc == 4) { + fileName = Tcl_GetStringFromObj(objv[3], &length); + } + + if (encodingName) { + return Tcl_FSEvalFileEx(interp, fileName, encodingName); + } + + return Tcl_MacEvalResource(interp, rsrcName, rsrcID, fileName); + + sourceFmtErr: + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), errStr, "should be \"", + Tcl_GetString(objv[0]), " fileName\" or \"", + Tcl_GetString(objv[0]), " -rsrc name ?fileName?\" or \"", + Tcl_GetString(objv[0]), " -rsrcid id ?fileName?\" or \"", + Tcl_GetString(objv[0]), " -encoding name fileName\"", + (char *) NULL); + return TCL_ERROR; +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_BeepObjCmd -- + * + * This procedure makes the beep sound. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * Makes a beep. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_BeepObjCmd( + ClientData dummy, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *CONST objv[]) /* Argument values. */ +{ + Tcl_Obj *resultPtr, *objPtr; + Handle sound; + Str255 sndName; + int volume = -1, length; + char * sndArg = NULL; + + resultPtr = Tcl_GetObjResult(interp); + if (objc == 1) { + SysBeep(1); + return TCL_OK; + } else if (objc == 2) { + if (!strcmp(Tcl_GetStringFromObj(objv[1], &length), "-list")) { + int count, i; + short id; + Str255 theName; + ResType rezType; + + count = CountResources('snd '); + for (i = 1; i <= count; i++) { + sound = GetIndResource('snd ', i); + if (sound != NULL) { + GetResInfo(sound, &id, &rezType, theName); + if (theName[0] == 0) { + continue; + } + objPtr = Tcl_NewStringObj((char *) theName + 1, + theName[0]); + Tcl_ListObjAppendElement(interp, resultPtr, objPtr); + } + } + return TCL_OK; + } else { + sndArg = Tcl_GetStringFromObj(objv[1], &length); + } + } else if (objc == 3) { + if (!strcmp(Tcl_GetStringFromObj(objv[1], &length), "-volume")) { + Tcl_GetIntFromObj(interp, objv[2], &volume); + } else { + goto beepUsage; + } + } else if (objc == 4) { + if (!strcmp(Tcl_GetStringFromObj(objv[1], &length), "-volume")) { + Tcl_GetIntFromObj(interp, objv[2], &volume); + sndArg = Tcl_GetStringFromObj(objv[3], &length); + } else { + goto beepUsage; + } + } else { + goto beepUsage; + } + + /* + * Play the sound + */ + if (sndArg == NULL) { + /* + * Set Volume for SysBeep + */ + + if (volume >= 0) { + SetSoundVolume(volume, SYS_BEEP_VOLUME); + } + SysBeep(1); + + /* + * Reset Volume + */ + + if (volume >= 0) { + SetSoundVolume(0, RESET_VOLUME); + } + } else { + strcpy((char *) sndName + 1, sndArg); + sndName[0] = length; + sound = GetNamedResource('snd ', sndName); + if (sound != NULL) { + /* + * Set Volume for Default Output device + */ + + if (volume >= 0) { + SetSoundVolume(volume, DEFAULT_SND_VOLUME); + } + + SndPlay(NULL, (SndListHandle) sound, false); + + /* + * Reset Volume + */ + + if (volume >= 0) { + SetSoundVolume(0, RESET_VOLUME); + } + } else { + Tcl_AppendStringsToObj(resultPtr, " \"", sndArg, + "\" is not a valid sound. (Try ", + Tcl_GetString(objv[0]), " -list)", NULL); + return TCL_ERROR; + } + } + + return TCL_OK; + + beepUsage: + Tcl_WrongNumArgs(interp, 1, objv, "[-volume num] [-list | sndName]?"); + return TCL_ERROR; +} + +/* + *----------------------------------------------------------------------------- + * + * SetSoundVolume -- + * + * Set the volume for either the SysBeep or the SndPlay call depending + * on the value of mode (SYS_BEEP_VOLUME or DEFAULT_SND_VOLUME + * respectively. + * + * It also stores the last channel set, and the old value of its + * VOLUME. If you call SetSoundVolume with a mode of RESET_VOLUME, + * it will undo the last setting. The volume parameter is + * ignored in this case. + * + * Side Effects: + * Sets the System Volume + * + * Results: + * None + * + *----------------------------------------------------------------------------- + */ + +void +SetSoundVolume( + int volume, /* This is the new volume */ + enum WhichVolume mode) /* This flag says which volume to + * set: SysBeep, SndPlay, or instructs us + * to reset the volume */ +{ + static int hasSM3 = -1; + static enum WhichVolume oldMode; + static long oldVolume = -1; + + /* + * The volume setting calls only work if we have SoundManager + * 3.0 or higher. So we check that here. + */ + + if (hasSM3 == -1) { + if (GetToolboxTrapAddress(_SoundDispatch) + != GetToolboxTrapAddress(_Unimplemented)) { + NumVersion SMVers = SndSoundManagerVersion(); + if (SMVers.majorRev > 2) { + hasSM3 = 1; + } else { + hasSM3 = 0; + } + } else { + /* + * If the SoundDispatch trap is not present, then + * we don't have the SoundManager at all. + */ + + hasSM3 = 0; + } + } + + /* + * If we don't have Sound Manager 3.0, we can't set the sound volume. + * We will just ignore the request rather than raising an error. + */ + + if (!hasSM3) { + return; + } + + switch (mode) { + case SYS_BEEP_VOLUME: + GetSysBeepVolume(&oldVolume); + SetSysBeepVolume(volume); + oldMode = SYS_BEEP_VOLUME; + break; + case DEFAULT_SND_VOLUME: + GetDefaultOutputVolume(&oldVolume); + SetDefaultOutputVolume(volume); + oldMode = DEFAULT_SND_VOLUME; + break; + case RESET_VOLUME: + /* + * If oldVolume is -1 someone has made a programming error + * and called reset before setting the volume. This is benign + * however, so we will just exit. + */ + + if (oldVolume != -1) { + if (oldMode == SYS_BEEP_VOLUME) { + SetSysBeepVolume(oldVolume); + } else if (oldMode == DEFAULT_SND_VOLUME) { + SetDefaultOutputVolume(oldVolume); + } + } + oldVolume = -1; + } +} + +/* + *----------------------------------------------------------------------------- + * + * Tcl_MacEvalResource -- + * + * Used to extend the source command. Sources Tcl code from a Text + * resource. Currently only sources the resouce by name file ID may be + * supported at a later date. + * + * Side Effects: + * Depends on the Tcl code in the resource. + * + * Results: + * Returns a Tcl result. + * + *----------------------------------------------------------------------------- + */ + +int +Tcl_MacEvalResource( + Tcl_Interp *interp, /* Interpreter in which to process file. */ + CONST char *resourceName, /* Name of TEXT resource to source, + NULL if number should be used. */ + int resourceNumber, /* Resource id of source. */ + CONST char *fileName) /* Name of file to process. + NULL if application resource. */ +{ + Handle sourceText; + Str255 rezName; + int result, iOpenedResFile = false; + short saveRef, fileRef = -1; + char idStr[64]; + FSSpec fileSpec; + Tcl_DString ds, buffer; + CONST char *nativeName; + + saveRef = CurResFile(); + + if (fileName != NULL) { + OSErr err; + + if (Tcl_TranslateFileName(interp, fileName, &buffer) == NULL) { + return TCL_ERROR; + } + nativeName = Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&buffer), + Tcl_DStringLength(&buffer), &ds); + err = FSpLocationFromPath(strlen(nativeName), nativeName, + &fileSpec); + Tcl_DStringFree(&ds); + Tcl_DStringFree(&buffer); + if (err != noErr) { + Tcl_AppendResult(interp, "Error finding the file: \"", + fileName, "\".", NULL); + return TCL_ERROR; + } + + fileRef = FSpOpenResFileCompat(&fileSpec, fsRdPerm); + if (fileRef == -1) { + Tcl_AppendResult(interp, "Error reading the file: \"", + fileName, "\".", NULL); + return TCL_ERROR; + } + + UseResFile(fileRef); + iOpenedResFile = true; + } else { + /* + * The default behavior will search through all open resource files. + * This may not be the behavior you desire. If you want the behavior + * of this call to *only* search the application resource fork, you + * must call UseResFile at this point to set it to the application + * file. This means you must have already obtained the application's + * fileRef when the application started up. + */ + } + + /* + * Load the resource by name or ID + */ + if (resourceName != NULL) { + Tcl_DString ds; + Tcl_UtfToExternalDString(NULL, resourceName, -1, &ds); + strcpy((char *) rezName + 1, Tcl_DStringValue(&ds)); + rezName[0] = (unsigned) Tcl_DStringLength(&ds); + sourceText = GetNamedResource('TEXT', rezName); + Tcl_DStringFree(&ds); + } else { + sourceText = GetResource('TEXT', (short) resourceNumber); + } + + if (sourceText == NULL) { + result = TCL_ERROR; + } else { + char *sourceStr = NULL; + + HLock(sourceText); + sourceStr = Tcl_MacConvertTextResource(sourceText); + HUnlock(sourceText); + ReleaseResource(sourceText); + + /* + * We now evaluate the Tcl source + */ + result = Tcl_Eval(interp, sourceStr); + ckfree(sourceStr); + if (result == TCL_RETURN) { + result = TCL_OK; + } else if (result == TCL_ERROR) { + Tcl_Obj *errorLine = Tcl_NewIntObj(interp->errorLine); + Tcl_Obj *msg = Tcl_NewStringObj("\n (rsrc \"", -1); + Tcl_IncrRefCount(errorLine); + Tcl_IncrRefCount(msg); + TclAppendLimitedToObj(msg, resourceName, -1, 150, ""); + Tcl_AppendToObj(msg, "\" line ", -1); + Tcl_AppendObjToObj(msg, errorLine); + Tcl_DecrRefCount(errorLine); + Tcl_AppendToObj(msg, ")", -1); + TclAppendObjToErrorInfo(interp, msg); + Tcl_DecrRefCount(msg); + } + + goto rezEvalCleanUp; + } + + rezEvalError: + sprintf(idStr, "ID=%d", resourceNumber); + Tcl_AppendResult(interp, "The resource \"", + (resourceName != NULL ? resourceName : idStr), + "\" could not be loaded from ", + (fileName != NULL ? fileName : "application"), + ".", NULL); + + rezEvalCleanUp: + + /* + * TRICKY POINT: The code that you are sourcing here could load a + * shared library. This will go AHEAD of the resource we stored away + * in saveRef on the resource path. + * If you restore the saveRef in this case, you will never be able + * to get to the resources in the shared library, since you are now + * pointing too far down on the resource list. + * So, we only reset the current resource file if WE opened a resource + * explicitly, and then only if the CurResFile is still the + * one we opened... + */ + + if (iOpenedResFile && (CurResFile() == fileRef)) { + UseResFile(saveRef); + } + + if (fileRef != -1) { + CloseResFile(fileRef); + } + + return result; +} + +/* + *----------------------------------------------------------------------------- + * + * Tcl_MacConvertTextResource -- + * + * Converts a TEXT resource into a Tcl suitable string. + * + * Side Effects: + * Mallocs the returned memory, converts '\r' to '\n', and appends a NULL. + * + * Results: + * A new malloced string. + * + *----------------------------------------------------------------------------- + */ + +char * +Tcl_MacConvertTextResource( + Handle resource) /* Handle to TEXT resource. */ +{ + int i, size; + char *resultStr; + Tcl_DString dstr; + + size = GetResourceSizeOnDisk(resource); + + Tcl_ExternalToUtfDString(NULL, *resource, size, &dstr); + + size = Tcl_DStringLength(&dstr) + 1; + resultStr = (char *) ckalloc((unsigned) size); + + memcpy((VOID *) resultStr, (VOID *) Tcl_DStringValue(&dstr), (size_t) size); + + Tcl_DStringFree(&dstr); + + for (i=0; i<size; i++) { + if (resultStr[i] == '\r') { + resultStr[i] = '\n'; + } + } + + return resultStr; +} + +/* + *----------------------------------------------------------------------------- + * + * Tcl_MacFindResource -- + * + * Higher level interface for loading resources. + * + * Side Effects: + * Attempts to load a resource. + * + * Results: + * A handle on success. + * + *----------------------------------------------------------------------------- + */ + +Handle +Tcl_MacFindResource( + Tcl_Interp *interp, /* Interpreter in which to process file. */ + long resourceType, /* Type of resource to load. */ + CONST char *resourceName, /* Name of resource to find, + * NULL if number should be used. */ + int resourceNumber, /* Resource id of source. */ + CONST char *resFileRef, /* Registered resource file reference, + * NULL if searching all open resource files. */ + int *releaseIt) /* Should we release this resource when done. */ +{ + Tcl_HashEntry *nameHashPtr; + OpenResourceFork *resourceRef; + int limitSearch = false; + short saveRef; + Handle resource; + + if (resFileRef != NULL) { + nameHashPtr = Tcl_FindHashEntry(&nameTable, resFileRef); + if (nameHashPtr == NULL) { + Tcl_AppendResult(interp, "invalid resource file reference \"", + resFileRef, "\"", (char *) NULL); + return NULL; + } + resourceRef = (OpenResourceFork *) Tcl_GetHashValue(nameHashPtr); + saveRef = CurResFile(); + UseResFile((short) resourceRef->fileRef); + limitSearch = true; + } + + /* + * Some system resources (for example system resources) should not + * be released. So we set autoload to false, and try to get the resource. + * If the Master Pointer of the returned handle is null, then resource was + * not in memory, and it is safe to release it. Otherwise, it is not. + */ + + SetResLoad(false); + + if (resourceName == NULL) { + if (limitSearch) { + resource = Get1Resource(resourceType, resourceNumber); + } else { + resource = GetResource(resourceType, resourceNumber); + } + } else { + Str255 rezName; + Tcl_DString ds; + Tcl_UtfToExternalDString(NULL, resourceName, -1, &ds); + strcpy((char *) rezName + 1, Tcl_DStringValue(&ds)); + rezName[0] = (unsigned) Tcl_DStringLength(&ds); + if (limitSearch) { + resource = Get1NamedResource(resourceType, + rezName); + } else { + resource = GetNamedResource(resourceType, + rezName); + } + Tcl_DStringFree(&ds); + } + + if (resource != NULL && *resource == NULL) { + *releaseIt = 1; + LoadResource(resource); + } else { + *releaseIt = 0; + } + + SetResLoad(true); + + + if (limitSearch) { + UseResFile(saveRef); + } + + return resource; +} + +/* + *---------------------------------------------------------------------- + * + * ResourceInit -- + * + * Initialize the structures used for resource management. + * + * Results: + * None. + * + * Side effects: + * Read the code. + * + *---------------------------------------------------------------------- + */ + +static void +ResourceInit() +{ + + initialized = 1; + Tcl_InitHashTable(&nameTable, TCL_STRING_KEYS); + Tcl_InitHashTable(&resourceTable, TCL_ONE_WORD_KEYS); + resourceForkList = Tcl_NewObj(); + Tcl_IncrRefCount(resourceForkList); + + BuildResourceForkList(); + +} +/***/ + +/*Tcl_RegisterObjType(typePtr) */ + +/* + *---------------------------------------------------------------------- + * + * Tcl_NewOSTypeObj -- + * + * This procedure is used to create a new resource name type object. + * + * Results: + * The newly created object is returned. This object will have a NULL + * string representation. The returned object has ref count 0. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_Obj * +Tcl_NewOSTypeObj( + OSType newOSType) /* Int used to initialize the new object. */ +{ + register Tcl_Obj *objPtr; + + if (!osTypeInit) { + osTypeInit = 1; + Tcl_RegisterObjType(&osType); + } + + objPtr = Tcl_NewObj(); + objPtr->bytes = NULL; + objPtr->internalRep.longValue = newOSType; + objPtr->typePtr = &osType; + return objPtr; +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_SetOSTypeObj -- + * + * Modify an object to be a resource type and to have the + * specified long value. + * + * Results: + * None. + * + * Side effects: + * The object's old string rep, if any, is freed. Also, any old + * internal rep is freed. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_SetOSTypeObj( + Tcl_Obj *objPtr, /* Object whose internal rep to init. */ + OSType newOSType) /* Integer used to set object's value. */ +{ + register Tcl_ObjType *oldTypePtr = objPtr->typePtr; + + if (!osTypeInit) { + osTypeInit = 1; + Tcl_RegisterObjType(&osType); + } + + if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) { + oldTypePtr->freeIntRepProc(objPtr); + } + + objPtr->internalRep.longValue = newOSType; + objPtr->typePtr = &osType; + + Tcl_InvalidateStringRep(objPtr); +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_GetOSTypeFromObj -- + * + * Attempt to return an int from the Tcl object "objPtr". If the object + * is not already an int, an attempt will be made to convert it to one. + * + * Results: + * The return value is a standard Tcl object result. If an error occurs + * during conversion, an error message is left in interp->objResult + * unless "interp" is NULL. + * + * Side effects: + * If the object is not already an int, the conversion will free + * any old internal representation. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_GetOSTypeFromObj( + Tcl_Interp *interp, /* Used for error reporting if not NULL. */ + Tcl_Obj *objPtr, /* The object from which to get a int. */ + OSType *osTypePtr) /* Place to store resulting int. */ +{ + register int result; + + if (!osTypeInit) { + osTypeInit = 1; + Tcl_RegisterObjType(&osType); + } + + if (objPtr->typePtr == &osType) { + *osTypePtr = objPtr->internalRep.longValue; + return TCL_OK; + } + + result = SetOSTypeFromAny(interp, objPtr); + if (result == TCL_OK) { + *osTypePtr = objPtr->internalRep.longValue; + } + return result; +} + +/* + *---------------------------------------------------------------------- + * + * DupOSTypeInternalRep -- + * + * Initialize the internal representation of an int Tcl_Obj to a + * copy of the internal representation of an existing int object. + * + * Results: + * None. + * + * Side effects: + * "copyPtr"s internal rep is set to the integer corresponding to + * "srcPtr"s internal rep. + * + *---------------------------------------------------------------------- + */ + +static void +DupOSTypeInternalRep( + Tcl_Obj *srcPtr, /* Object with internal rep to copy. */ + Tcl_Obj *copyPtr) /* Object with internal rep to set. */ +{ + copyPtr->internalRep.longValue = srcPtr->internalRep.longValue; + copyPtr->typePtr = &osType; +} + +/* + *---------------------------------------------------------------------- + * + * SetOSTypeFromAny -- + * + * Attempt to generate an integer internal form for the Tcl object + * "objPtr". + * + * Results: + * The return value is a standard object Tcl result. If an error occurs + * during conversion, an error message is left in interp->objResult + * unless "interp" is NULL. + * + * Side effects: + * If no error occurs, an int is stored as "objPtr"s internal + * representation. + * + *---------------------------------------------------------------------- + */ + +static int +SetOSTypeFromAny( + Tcl_Interp *interp, /* Used for error reporting if not NULL. */ + Tcl_Obj *objPtr) /* The object to convert. */ +{ + Tcl_ObjType *oldTypePtr = objPtr->typePtr; + char *string; + int length; + OSType newOSType = 0UL; + Tcl_DString ds; + + /* + * Get the string representation. Make it up-to-date if necessary. + */ + + string = Tcl_GetStringFromObj(objPtr, &length); + Tcl_UtfToExternalDString(NULL, string, length, &ds); + + if (Tcl_DStringLength(&ds) > sizeof(OSType)) { + if (interp != NULL) { + Tcl_ResetResult(interp); + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "expected Macintosh OS type but got \"", string, "\"", + (char *) NULL); + } + Tcl_DStringFree(&ds); + return TCL_ERROR; + } + memcpy(&newOSType, Tcl_DStringValue(&ds), + (size_t) Tcl_DStringLength(&ds)); + Tcl_DStringFree(&ds); + + /* + * The conversion to resource type succeeded. Free the old internalRep + * before setting the new one. + */ + + if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) { + oldTypePtr->freeIntRepProc(objPtr); + } + + objPtr->internalRep.longValue = newOSType; + objPtr->typePtr = &osType; + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * UpdateStringOfOSType -- + * + * Update the string representation for an resource type object. + * Note: This procedure does not free an existing old string rep + * so storage will be lost if this has not already been done. + * + * Results: + * None. + * + * Side effects: + * The object's string is set to a valid string that results from + * the int-to-string conversion. + * + *---------------------------------------------------------------------- + */ + +static void +UpdateStringOfOSType( + register Tcl_Obj *objPtr) /* Int object whose string rep to update. */ +{ + char string[sizeof(OSType)+1]; + Tcl_DString ds; + + memcpy(string, &(objPtr->internalRep.longValue), sizeof(OSType)); + string[sizeof(OSType)] = '\0'; + Tcl_ExternalToUtfDString(NULL, string, -1, &ds); + objPtr->bytes = ckalloc(Tcl_DStringLength(&ds) + 1); + memcpy(objPtr->bytes, Tcl_DStringValue(&ds), Tcl_DStringLength(&ds) + 1); + objPtr->length = Tcl_DStringLength(&ds); + Tcl_DStringFree(&ds); +} + +/* + *---------------------------------------------------------------------- + * + * GetRsrcRefFromObj -- + * + * Given a String object containing a resource file token, return + * the OpenResourceFork structure that it represents, or NULL if + * the token cannot be found. If okayOnReadOnly is false, it will + * also check whether the token corresponds to a read-only file, + * and return NULL if it is. + * + * Results: + * A pointer to an OpenResourceFork structure, or NULL. + * + * Side effects: + * An error message may be left in resultPtr. + * + *---------------------------------------------------------------------- + */ + +static OpenResourceFork * +GetRsrcRefFromObj( + register Tcl_Obj *objPtr, /* String obj containing file token */ + int okayOnReadOnly, /* Whether this operation is okay for a * + * read only file. */ + const char *operation, /* String containing the operation we * + * were trying to perform, used for errors */ + Tcl_Obj *resultPtr) /* Tcl_Obj to contain error message */ +{ + char *stringPtr; + Tcl_HashEntry *nameHashPtr; + OpenResourceFork *resourceRef; + int length; + OSErr err; + + stringPtr = Tcl_GetStringFromObj(objPtr, &length); + nameHashPtr = Tcl_FindHashEntry(&nameTable, stringPtr); + if (nameHashPtr == NULL) { + Tcl_AppendStringsToObj(resultPtr, + "invalid resource file reference \"", + stringPtr, "\"", (char *) NULL); + return NULL; + } + + resourceRef = (OpenResourceFork *) Tcl_GetHashValue(nameHashPtr); + + if (!okayOnReadOnly) { + err = GetResFileAttrs((short) resourceRef->fileRef); + if (err & mapReadOnly) { + Tcl_AppendStringsToObj(resultPtr, "cannot ", operation, + " resource file \"", + stringPtr, "\", it was opened read only", + (char *) NULL); + return NULL; + } + } + return resourceRef; +} + +/* + *---------------------------------------------------------------------- + * + * TclMacRegisterResourceFork -- + * + * Register an open resource fork in the table of open resources + * managed by the procedures in this file. If the resource file + * is already registered with the table, then no new token is made. + * + * The behavior is controlled by the value of tokenPtr, and of the + * flags variable. For tokenPtr, the possibilities are: + * - NULL: The new token is auto-generated, but not returned. + * - The string value of tokenPtr is the empty string: Then + * the new token is auto-generated, and returned in tokenPtr + * - tokenPtr has a value: The string value will be used for the token, + * unless it is already in use, in which case a new token will + * be generated, and returned in tokenPtr. + * + * For the flags variable: it can be one of: + * - TCL_RESOURCE__INSERT_TAIL: The element is inserted at the + * end of the list of open resources. Used only in Resource_Init. + * - TCL_RESOURCE_DONT_CLOSE: The resource close command will not close + * this resource. + * - TCL_RESOURCE_CHECK_IF_OPEN: This will check to see if this file's + * resource fork is already opened by this Tcl shell, and return + * an error without registering the resource fork. + * + * Results: + * Standard Tcl Result + * + * Side effects: + * An entry may be added to the resource name table. + * + *---------------------------------------------------------------------- + */ + +int +TclMacRegisterResourceFork( + short fileRef, /* File ref for an open resource fork. */ + Tcl_Obj *tokenPtr, /* A Tcl Object to which to write the * + * new token */ + int flags) /* 1 means insert at the head of the resource + * fork list, 0 means at the tail */ + +{ + Tcl_HashEntry *resourceHashPtr; + Tcl_HashEntry *nameHashPtr; + OpenResourceFork *resourceRef; + int new; + char *resourceId = NULL; + + if (!initialized) { + ResourceInit(); + } + + /* + * If we were asked to, check that this file has not been opened + * already with a different permission. It it has, then return an error. + */ + + new = 1; + + if (flags & TCL_RESOURCE_CHECK_IF_OPEN) { + Tcl_HashSearch search; + short oldFileRef, filePermissionFlag; + FCBPBRec newFileRec, oldFileRec; + OSErr err; + + oldFileRec.ioCompletion = NULL; + oldFileRec.ioFCBIndx = 0; + oldFileRec.ioNamePtr = NULL; + + newFileRec.ioCompletion = NULL; + newFileRec.ioFCBIndx = 0; + newFileRec.ioNamePtr = NULL; + newFileRec.ioVRefNum = 0; + newFileRec.ioRefNum = fileRef; + err = PBGetFCBInfo(&newFileRec, false); + filePermissionFlag = ( newFileRec.ioFCBFlags >> 12 ) & 0x1; + + + resourceHashPtr = Tcl_FirstHashEntry(&resourceTable, &search); + while (resourceHashPtr != NULL) { + oldFileRef = (short) Tcl_GetHashKey(&resourceTable, + resourceHashPtr); + if (oldFileRef == fileRef) { + new = 0; + break; + } + oldFileRec.ioVRefNum = 0; + oldFileRec.ioRefNum = oldFileRef; + err = PBGetFCBInfo(&oldFileRec, false); + + /* + * err might not be noErr either because the file has closed + * out from under us somehow, which is bad but we're not going + * to fix it here, OR because it is the ROM MAP, which has a + * fileRef, but can't be gotten to by PBGetFCBInfo. + */ + if ((err == noErr) + && (newFileRec.ioFCBVRefNum == oldFileRec.ioFCBVRefNum) + && (newFileRec.ioFCBFlNm == oldFileRec.ioFCBFlNm)) { + /* + * In MacOS 8.1 it seems like we get different file refs even + * though we pass the same file & permissions. This is not + * what Inside Mac says should happen, but it does, so if it + * does, then close the new res file and return the original + * one... + */ + + if (filePermissionFlag == ((oldFileRec.ioFCBFlags >> 12) & 0x1)) { + CloseResFile(fileRef); + new = 0; + break; + } else { + if (tokenPtr != NULL) { + Tcl_SetStringObj(tokenPtr, "Resource already open with different permissions.", -1); + } + return TCL_ERROR; + } + } + resourceHashPtr = Tcl_NextHashEntry(&search); + } + } + + + /* + * If the file has already been opened with these same permissions, then it + * will be in our list and we will have set new to 0 above. + * So we will just return the token (if tokenPtr is non-null) + */ + + if (new) { + resourceHashPtr = Tcl_CreateHashEntry(&resourceTable, + (char *) fileRef, &new); + } + + if (!new) { + if (tokenPtr != NULL) { + resourceId = (char *) Tcl_GetHashValue(resourceHashPtr); + Tcl_SetStringObj(tokenPtr, resourceId, -1); + } + return TCL_OK; + } + + /* + * If we were passed in a result pointer which is not an empty + * string, attempt to use that as the key. If the key already + * exists, silently fall back on resource%d... + */ + + if (tokenPtr != NULL) { + char *tokenVal; + int length; + tokenVal = Tcl_GetStringFromObj(tokenPtr, &length); + if (length > 0) { + nameHashPtr = Tcl_FindHashEntry(&nameTable, tokenVal); + if (nameHashPtr == NULL) { + resourceId = ckalloc(length + 1); + memcpy(resourceId, tokenVal, length); + resourceId[length] = '\0'; + } + } + } + + if (resourceId == NULL) { + resourceId = (char *) ckalloc(15); + sprintf(resourceId, "resource%d", newId); + } + + Tcl_SetHashValue(resourceHashPtr, resourceId); + newId++; + + nameHashPtr = Tcl_CreateHashEntry(&nameTable, resourceId, &new); + if (!new) { + Tcl_Panic("resource id has repeated itself"); + } + + resourceRef = (OpenResourceFork *) ckalloc(sizeof(OpenResourceFork)); + resourceRef->fileRef = fileRef; + resourceRef->flags = flags; + + Tcl_SetHashValue(nameHashPtr, (ClientData) resourceRef); + if (tokenPtr != NULL) { + Tcl_SetStringObj(tokenPtr, resourceId, -1); + } + + if (flags & TCL_RESOURCE_INSERT_TAIL) { + Tcl_ListObjAppendElement(NULL, resourceForkList, tokenPtr); + } else { + Tcl_ListObjReplace(NULL, resourceForkList, 0, 0, 1, &tokenPtr); + } + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclMacUnRegisterResourceFork -- + * + * Removes the entry for an open resource fork from the table of + * open resources managed by the procedures in this file. + * If resultPtr is not NULL, it will be used for error reporting. + * + * Results: + * The fileRef for this token, or -1 if an error occured. + * + * Side effects: + * An entry is removed from the resource name table. + * + *---------------------------------------------------------------------- + */ + +short +TclMacUnRegisterResourceFork( + char *tokenPtr, + Tcl_Obj *resultPtr) + +{ + Tcl_HashEntry *resourceHashPtr; + Tcl_HashEntry *nameHashPtr; + OpenResourceFork *resourceRef; + char *resourceId = NULL; + short fileRef; + char *bytes; + int i, match, index, listLen, length, elemLen; + Tcl_Obj **elemPtrs; + + + nameHashPtr = Tcl_FindHashEntry(&nameTable, tokenPtr); + if (nameHashPtr == NULL) { + if (resultPtr != NULL) { + Tcl_AppendStringsToObj(resultPtr, + "invalid resource file reference \"", + tokenPtr, "\"", (char *) NULL); + } + return -1; + } + + resourceRef = (OpenResourceFork *) Tcl_GetHashValue(nameHashPtr); + fileRef = resourceRef->fileRef; + + if ( resourceRef->flags & TCL_RESOURCE_DONT_CLOSE ) { + if (resultPtr != NULL) { + Tcl_AppendStringsToObj(resultPtr, + "can't close \"", tokenPtr, "\" resource file", + (char *) NULL); + } + return -1; + } + + Tcl_DeleteHashEntry(nameHashPtr); + ckfree((char *) resourceRef); + + + /* + * Now remove the resource from the resourceForkList object + */ + + Tcl_ListObjGetElements(NULL, resourceForkList, &listLen, &elemPtrs); + + + index = -1; + length = strlen(tokenPtr); + + for (i = 0; i < listLen; i++) { + match = 0; + bytes = Tcl_GetStringFromObj(elemPtrs[i], &elemLen); + if (length == elemLen) { + match = (memcmp(bytes, tokenPtr, + (size_t) length) == 0); + } + if (match) { + index = i; + break; + } + } + if (!match) { + Tcl_Panic("the resource Fork List is out of synch!"); + } + + Tcl_ListObjReplace(NULL, resourceForkList, index, 1, 0, NULL); + + resourceHashPtr = Tcl_FindHashEntry(&resourceTable, (char *) fileRef); + + if (resourceHashPtr == NULL) { + Tcl_Panic("Resource & Name tables are out of synch in resource command."); + } + ckfree(Tcl_GetHashValue(resourceHashPtr)); + Tcl_DeleteHashEntry(resourceHashPtr); + + return fileRef; + +} + + +/* + *---------------------------------------------------------------------- + * + * BuildResourceForkList -- + * + * Traverses the list of open resource forks, and builds the + * list of resources forks. Also creates a resource token for any that + * are opened but not registered with our resource system. + * This is based on code from Apple DTS. + * + * Results: + * None. + * + * Side effects: + * The list of resource forks is updated. + * The resource name table may be augmented. + * + *---------------------------------------------------------------------- + */ + +void +BuildResourceForkList() +{ + Handle currentMapHandle, mSysMapHandle; + Ptr tempPtr; + FCBPBRec fileRec; + char fileName[256]; + char appName[62]; + Tcl_Obj *nameObj; + OSErr err; + ProcessSerialNumber psn; + ProcessInfoRec info; + FSSpec fileSpec; + + /* + * Get the application name, so we can substitute + * the token "application" for the application's resource. + */ + + GetCurrentProcess(&psn); + info.processInfoLength = sizeof(ProcessInfoRec); + info.processName = (StringPtr) &appName; + info.processAppSpec = &fileSpec; + GetProcessInformation(&psn, &info); + p2cstr((StringPtr) appName); + + + fileRec.ioCompletion = NULL; + fileRec.ioVRefNum = 0; + fileRec.ioFCBIndx = 0; + fileRec.ioNamePtr = (StringPtr) &fileName; + + + currentMapHandle = LMGetTopMapHndl(); + mSysMapHandle = LMGetSysMapHndl(); + + while (1) { + /* + * Now do the ones opened after the application. + */ + + nameObj = Tcl_NewObj(); + + tempPtr = *currentMapHandle; + + fileRec.ioRefNum = *((short *) (tempPtr + 20)); + err = PBGetFCBInfo(&fileRec, false); + + if (err != noErr) { + /* + * The ROM resource map does not correspond to an opened file... + */ + Tcl_SetStringObj(nameObj, "ROM Map", -1); + } else { + p2cstr((StringPtr) fileName); + if (strcmp(fileName,appName) == 0) { + Tcl_SetStringObj(nameObj, "application", -1); + } else { + Tcl_SetStringObj(nameObj, fileName, -1); + } + c2pstr(fileName); + } + + TclMacRegisterResourceFork(fileRec.ioRefNum, nameObj, + TCL_RESOURCE_DONT_CLOSE | TCL_RESOURCE_INSERT_TAIL); + + if (currentMapHandle == mSysMapHandle) { + break; + } + + currentMapHandle = *((Handle *) (tempPtr + 16)); + } +} diff --git a/mac/tclMacResource.r b/mac/tclMacResource.r new file mode 100644 index 0000000..664b715 --- /dev/null +++ b/mac/tclMacResource.r @@ -0,0 +1,44 @@ +/* + * tclMacResource.r -- + * + * This file creates resources for use in a simple shell. + * This is designed to be an example of using the Tcl libraries + * statically in a Macintosh Application. For an example of + * of using the dynamic libraries look at tclMacApplication.r. + * + * Copyright (c) 1993-94 Lockheed Missle & Space Company + * Copyright (c) 1994-97 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacResource.r,v 1.8 2002/09/12 17:33:20 das Exp $ + */ + +#include <Types.r> +#include <SysTypes.r> + +/* + * The folowing include and defines help construct + * the version string for Tcl. + */ + +#define RC_INVOKED +#include "tcl.h" + +/* + * The mechanisim below loads Tcl source into the resource fork of the + * application. The example below creates a TEXT resource named + * "Init" from the file "init.tcl". This allows applications to use + * Tcl to define the behavior of the application without having to + * require some predetermined file structure - all needed Tcl "files" + * are located within the application. To source a file for the + * resource fork the source command has been modified to support + * sourcing from resources. In the below case "source -rsrc {Init}" + * will load the TEXT resource named "Init". + */ + +#ifndef TCLTK_NO_LIBRARY_TEXT_RESOURCES +#include "tclMacTclCode.r" +#endif + diff --git a/mac/tclMacSock.c b/mac/tclMacSock.c new file mode 100644 index 0000000..4321ea3 --- /dev/null +++ b/mac/tclMacSock.c @@ -0,0 +1,2881 @@ +/* + * tclMacSock.c + * + * Channel drivers for Macintosh sockets. + * + * Copyright (c) 1996-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacSock.c,v 1.16 2003/12/24 04:18:21 davygrvy Exp $ + */ + +#include "tclInt.h" +#include "tclPort.h" +#include "tclMacInt.h" +#include <AddressXlation.h> +#include <Aliases.h> +#undef Status +#include <Devices.h> +#include <Errors.h> +#include <Events.h> +#include <Files.h> +#include <Gestalt.h> +#include <MacTCP.h> +#include <Processes.h> +#include <Strings.h> + +/* + * The following variable is used to tell whether this module has been + * initialized. + */ + +static int initialized = 0; + +/* + * If debugging is on we may drop into the debugger to handle certain cases + * that are not supposed to happen. Otherwise, we change ignore the error + * and most code should handle such errors ok. + */ + +#ifndef TCL_DEBUG + #define Debugger() +#endif + +/* + * The preferred buffer size for Macintosh channels. + */ + +#define CHANNEL_BUF_SIZE 8192 + +/* + * Port information structure. Used to match service names + * to a Tcp/Ip port number. + */ + +typedef struct { + char *name; /* Name of service. */ + int port; /* Port number. */ +} PortInfo; + +/* + * This structure describes per-instance state of a tcp based channel. + */ + +typedef struct TcpState { + TCPiopb pb; /* Parameter block used by this stream. + * This must be in the first position. */ + ProcessSerialNumber psn; /* PSN used to wake up process. */ + StreamPtr tcpStream; /* Macintosh tcp stream pointer. */ + int port; /* The port we are connected to. */ + int flags; /* Bit field comprised of the flags + * described below. */ + int checkMask; /* OR'ed combination of TCL_READABLE and + * TCL_WRITABLE as set by an asynchronous + * event handler. */ + int watchMask; /* OR'ed combination of TCL_READABLE and + * TCL_WRITABLE as set by TcpWatch. */ + Tcl_TcpAcceptProc *acceptProc; /* Proc to call on accept. */ + ClientData acceptProcData; /* The data for the accept proc. */ + wdsEntry dataSegment[2]; /* List of buffers to be written async. */ + rdsEntry rdsarray[5+1]; /* Array used when cleaning out recieve + * buffers on a closing socket. */ + Tcl_Channel channel; /* Channel associated with this socket. */ + int writeBufferSize; /* Size of buffer to hold data for + * asynchronous writes. */ + void *writeBuffer; /* Buffer for async write data. */ + struct TcpState *nextPtr; /* The next socket on the global socket + * list. */ +} TcpState; + +/* + * This structure is used by domain name resolver callback. + */ + +typedef struct DNRState { + struct hostInfo hostInfo; /* Data structure used by DNR functions. */ + int done; /* Flag to determine when we are done. */ + ProcessSerialNumber psn; /* Process to wake up when we are done. */ +} DNRState; + +/* + * The following macros may be used to set the flags field of + * a TcpState structure. + */ + +#define TCP_ASYNC_SOCKET (1<<0) /* The socket is in async mode. */ +#define TCP_ASYNC_CONNECT (1<<1) /* The socket is trying to connect. */ +#define TCP_CONNECTED (1<<2) /* The socket is connected. */ +#define TCP_PENDING (1<<3) /* A SocketEvent is on the queue. */ +#define TCP_LISTENING (1<<4) /* This socket is listening for + * a connection. */ +#define TCP_LISTEN_CONNECT (1<<5) /* Someone has connect to the + * listening port. */ +#define TCP_REMOTE_CLOSED (1<<6) /* The remote side has closed + * the connection. */ +#define TCP_RELEASE (1<<7) /* The socket may now be released. */ +#define TCP_WRITING (1<<8) /* A background write is in progress. */ +#define TCP_SERVER_ZOMBIE (1<<9) /* The server can no longer accept connects. */ + +/* + * The following structure is what is added to the Tcl event queue when + * a socket event occurs. + */ + +typedef struct SocketEvent { + Tcl_Event header; /* Information that is standard for + * all events. */ + TcpState *statePtr; /* Socket descriptor that is ready. */ + StreamPtr tcpStream; /* Low level Macintosh stream. */ +} SocketEvent; + +/* + * Static routines for this file: + */ + +static pascal void CleanUpExitProc _ANSI_ARGS_((void)); +static void ClearZombieSockets _ANSI_ARGS_((void)); +static void CloseCompletionRoutine _ANSI_ARGS_((TCPiopb *pb)); +static TcpState * CreateSocket _ANSI_ARGS_((Tcl_Interp *interp, + int port, CONST char *host, CONST char *myAddr, + int myPort, int server, int async)); +static pascal void DNRCompletionRoutine _ANSI_ARGS_(( + struct hostInfo *hostinfoPtr, + DNRState *dnrStatePtr)); +static void FreeSocketInfo _ANSI_ARGS_((TcpState *statePtr)); +static long GetBufferSize _ANSI_ARGS_((void)); +static OSErr GetHostFromString _ANSI_ARGS_((CONST char *name, + ip_addr *address)); +static OSErr GetLocalAddress _ANSI_ARGS_((unsigned long *addr)); +static void IOCompletionRoutine _ANSI_ARGS_((TCPiopb *pb)); +static void InitMacTCPParamBlock _ANSI_ARGS_((TCPiopb *pBlock, + int csCode)); +static void InitSockets _ANSI_ARGS_((void)); +static TcpState * NewSocketInfo _ANSI_ARGS_((StreamPtr stream)); +static OSErr ResolveAddress _ANSI_ARGS_((ip_addr tcpAddress, + Tcl_DString *dsPtr)); +static void SocketCheckProc _ANSI_ARGS_((ClientData clientData, + int flags)); +static int SocketEventProc _ANSI_ARGS_((Tcl_Event *evPtr, + int flags)); +static void SocketExitHandler _ANSI_ARGS_((ClientData clientData)); +static void SocketFreeProc _ANSI_ARGS_((ClientData clientData)); +static int SocketReady _ANSI_ARGS_((TcpState *statePtr)); +static void SocketSetupProc _ANSI_ARGS_((ClientData clientData, + int flags)); +static void TcpAccept _ANSI_ARGS_((TcpState *statePtr)); +static int TcpBlockMode _ANSI_ARGS_((ClientData instanceData, int mode)); +static int TcpClose _ANSI_ARGS_((ClientData instanceData, + Tcl_Interp *interp)); +static int TcpGetHandle _ANSI_ARGS_((ClientData instanceData, + int direction, ClientData *handlePtr)); +static int TcpGetOptionProc _ANSI_ARGS_((ClientData instanceData, + Tcl_Interp *interp, CONST char *optionName, + Tcl_DString *dsPtr)); +static int TcpInput _ANSI_ARGS_((ClientData instanceData, + char *buf, int toRead, int *errorCodePtr)); +static int TcpOutput _ANSI_ARGS_((ClientData instanceData, + CONST char *buf, int toWrite, int *errorCodePtr)); +static void TcpWatch _ANSI_ARGS_((ClientData instanceData, + int mask)); +static int WaitForSocketEvent _ANSI_ARGS_((TcpState *infoPtr, + int mask, int *errorCodePtr)); + +pascal void NotifyRoutine ( + StreamPtr tcpStream, + unsigned short eventCode, + Ptr userDataPtr, + unsigned short terminReason, + struct ICMPReport *icmpMsg); + +/* + * This structure describes the channel type structure for TCP socket + * based IO: + */ + +static Tcl_ChannelType tcpChannelType = { + "tcp", /* Type name. */ + (Tcl_ChannelTypeVersion)TcpBlockMode, /* Set blocking or + * non-blocking mode.*/ + TcpClose, /* Close proc. */ + TcpInput, /* Input proc. */ + TcpOutput, /* Output proc. */ + NULL, /* Seek proc. */ + NULL, /* Set option proc. */ + TcpGetOptionProc, /* Get option proc. */ + TcpWatch, /* Initialize notifier. */ + TcpGetHandle /* Get handles out of channel. */ +}; + +/* + * Universal Procedure Pointers (UPP) for various callback + * routines used by MacTcp code. + */ + +ResultUPP resultUPP = NULL; +TCPIOCompletionUPP completeUPP = NULL; +TCPIOCompletionUPP closeUPP = NULL; +TCPNotifyUPP notifyUPP = NULL; + +/* + * Built-in commands, and the procedures associated with them: + */ + +static PortInfo portServices[] = { + {"echo", 7}, + {"discard", 9}, + {"systat", 11}, + {"daytime", 13}, + {"netstat", 15}, + {"chargen", 19}, + {"ftp-data", 20}, + {"ftp", 21}, + {"telnet", 23}, + {"telneto", 24}, + {"smtp", 25}, + {"time", 37}, + {"whois", 43}, + {"domain", 53}, + {"gopher", 70}, + {"finger", 79}, + {"hostnames", 101}, + {"sunrpc", 111}, + {"nntp", 119}, + {"exec", 512}, + {"login", 513}, + {"shell", 514}, + {"printer", 515}, + {"courier", 530}, + {"uucp", 540}, + {NULL, 0}, +}; + +typedef struct ThreadSpecificData { + /* + * Every open socket has an entry on the following list. + */ + + TcpState *socketList; +} ThreadSpecificData; + +static Tcl_ThreadDataKey dataKey; + +/* + * Globals for holding information about OS support for sockets. + */ + +static int socketsTestInited = false; +static int hasSockets = false; +static short driverRefNum = 0; +static int socketNumber = 0; +static int socketBufferSize = CHANNEL_BUF_SIZE; +static ProcessSerialNumber applicationPSN; + +/* + *---------------------------------------------------------------------- + * + * InitSockets -- + * + * Load the MacTCP driver and open the name resolver. We also + * create several UPP's used by our code. Lastly, we install + * a patch to ExitToShell to clean up socket connections if + * we are about to exit. + * + * Results: + * 1 if successful, 0 on failure. + * + * Side effects: + * Creates a new event source, loads the MacTCP driver, + * registers an exit to shell callback. + * + *---------------------------------------------------------------------- + */ + +#define gestaltMacTCPVersion 'mtcp' +static void +InitSockets() +{ + ParamBlockRec pb; + OSErr err; + long response; + ThreadSpecificData *tsdPtr; + + if (! initialized) { + /* + * Do process wide initialization. + */ + + initialized = 1; + + if (Gestalt(gestaltMacTCPVersion, &response) == noErr) { + hasSockets = true; + } else { + hasSockets = false; + } + + if (!hasSockets) { + return; + } + + /* + * Load MacTcp driver and name server resolver. + */ + + + pb.ioParam.ioCompletion = 0L; + pb.ioParam.ioNamePtr = "\p.IPP"; + pb.ioParam.ioPermssn = fsCurPerm; + err = PBOpenSync(&pb); + if (err != noErr) { + hasSockets = 0; + return; + } + driverRefNum = pb.ioParam.ioRefNum; + + socketBufferSize = GetBufferSize(); + err = OpenResolver(NULL); + if (err != noErr) { + hasSockets = 0; + return; + } + + GetCurrentProcess(&applicationPSN); + /* + * Create UPP's for various callback routines. + */ + + resultUPP = NewResultProc(DNRCompletionRoutine); + completeUPP = NewTCPIOCompletionProc(IOCompletionRoutine); + closeUPP = NewTCPIOCompletionProc(CloseCompletionRoutine); + notifyUPP = NewTCPNotifyProc(NotifyRoutine); + + /* + * Install an ExitToShell patch. We use this patch instead + * of the Tcl exit mechanism because we need to ensure that + * these routines are cleaned up even if we crash or are forced + * to quit. There are some circumstances when the Tcl exit + * handlers may not fire. + */ + + TclMacInstallExitToShellPatch(CleanUpExitProc); + } + + /* + * Do per-thread initialization. + */ + + tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey); + if (tsdPtr == NULL) { + tsdPtr->socketList = NULL; + Tcl_CreateEventSource(SocketSetupProc, SocketCheckProc, NULL); + Tcl_CreateThreadExitHandler(SocketExitHandler, (ClientData) NULL); + } +} + +/* + *---------------------------------------------------------------------- + * + * SocketExitHandler -- + * + * Callback invoked during exit clean up to deinitialize the + * socket module. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static void +SocketExitHandler( + ClientData clientData) /* Not used. */ +{ + if (hasSockets) { + Tcl_DeleteEventSource(SocketSetupProc, SocketCheckProc, NULL); + /* CleanUpExitProc(); + TclMacDeleteExitToShellPatch(CleanUpExitProc); */ + } +} + +/* + *---------------------------------------------------------------------- + * + * TclpHasSockets -- + * + * This function determines whether sockets are available on the + * current system and returns an error in interp if they are not. + * Note that interp may be NULL. + * + * Results: + * Returns TCL_OK if the system supports sockets, or TCL_ERROR with + * an error in interp. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TclpHasSockets( + Tcl_Interp *interp) /* Interp for error messages. */ +{ + InitSockets(); + + if (hasSockets) { + return TCL_OK; + } + if (interp != NULL) { + Tcl_AppendResult(interp, "sockets are not available on this system", + NULL); + } + return TCL_ERROR; +} + +/* + *---------------------------------------------------------------------- + * + * SocketSetupProc -- + * + * This procedure is invoked before Tcl_DoOneEvent blocks waiting + * for an event. + * + * Results: + * None. + * + * Side effects: + * Adjusts the block time if needed. + * + *---------------------------------------------------------------------- + */ + +static void +SocketSetupProc( + ClientData data, /* Not used. */ + int flags) /* Event flags as passed to Tcl_DoOneEvent. */ +{ + TcpState *statePtr; + Tcl_Time blockTime = { 0, 0 }; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + if (!(flags & TCL_FILE_EVENTS)) { + return; + } + + /* + * Check to see if there is a ready socket. If so, poll. + */ + + for (statePtr = tsdPtr->socketList; statePtr != NULL; + statePtr = statePtr->nextPtr) { + if (statePtr->flags & TCP_RELEASE) { + continue; + } + if (SocketReady(statePtr)) { + Tcl_SetMaxBlockTime(&blockTime); + break; + } + } +} + +/* + *---------------------------------------------------------------------- + * + * SocketCheckProc -- + * + * This procedure is called by Tcl_DoOneEvent to check the socket + * event source for events. + * + * Results: + * None. + * + * Side effects: + * May queue an event. + * + *---------------------------------------------------------------------- + */ + +static void +SocketCheckProc( + ClientData data, /* Not used. */ + int flags) /* Event flags as passed to Tcl_DoOneEvent. */ +{ + TcpState *statePtr; + SocketEvent *evPtr; + TcpState dummyState; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + if (!(flags & TCL_FILE_EVENTS)) { + return; + } + + /* + * Queue events for any ready sockets that don't already have events + * queued (caused by persistent states that won't generate WinSock + * events). + */ + + for (statePtr = tsdPtr->socketList; statePtr != NULL; + statePtr = statePtr->nextPtr) { + /* + * Check to see if this socket is dead and needs to be cleaned + * up. We use a dummy statePtr whose only valid field is the + * nextPtr to allow the loop to continue even if the element + * is deleted. + */ + + if (statePtr->flags & TCP_RELEASE) { + if (!(statePtr->flags & TCP_PENDING)) { + dummyState.nextPtr = statePtr->nextPtr; + SocketFreeProc(statePtr); + statePtr = &dummyState; + } + continue; + } + + if (!(statePtr->flags & TCP_PENDING) && SocketReady(statePtr)) { + statePtr->flags |= TCP_PENDING; + evPtr = (SocketEvent *) ckalloc(sizeof(SocketEvent)); + evPtr->header.proc = SocketEventProc; + evPtr->statePtr = statePtr; + evPtr->tcpStream = statePtr->tcpStream; + Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL); + } + } +} + +/* + *---------------------------------------------------------------------- + * + * SocketReady -- + * + * This function checks the current state of a socket to see + * if any interesting conditions are present. + * + * Results: + * Returns 1 if an event that someone is watching is present, else + * returns 0. + * + * Side effects: + * Updates the checkMask for the socket to reflect any newly + * detected events. + * + *---------------------------------------------------------------------- + */ + +static int +SocketReady( + TcpState *statePtr) +{ + TCPiopb statusPB; + int foundSomething = 0; + int didStatus = 0; + int amount; + OSErr err; + + if (statePtr->flags & TCP_LISTEN_CONNECT) { + foundSomething = 1; + statePtr->checkMask |= TCL_READABLE; + } + if (statePtr->watchMask & TCL_READABLE) { + if (statePtr->checkMask & TCL_READABLE) { + foundSomething = 1; + } else if (statePtr->flags & TCP_CONNECTED) { + statusPB.ioCRefNum = driverRefNum; + statusPB.tcpStream = statePtr->tcpStream; + statusPB.csCode = TCPStatus; + err = PBControlSync((ParmBlkPtr) &statusPB); + didStatus = 1; + + /* + * We make the fchannel readable if 1) we get an error, + * 2) there is more data available, or 3) we detect + * that a close from the remote connection has arrived. + */ + + if ((err != noErr) || + (statusPB.csParam.status.amtUnreadData > 0) || + (statusPB.csParam.status.connectionState == 14)) { + statePtr->checkMask |= TCL_READABLE; + foundSomething = 1; + } + } + } + if (statePtr->watchMask & TCL_WRITABLE) { + if (statePtr->checkMask & TCL_WRITABLE) { + foundSomething = 1; + } else if (statePtr->flags & TCP_CONNECTED) { + if (!didStatus) { + statusPB.ioCRefNum = driverRefNum; + statusPB.tcpStream = statePtr->tcpStream; + statusPB.csCode = TCPStatus; + err = PBControlSync((ParmBlkPtr) &statusPB); + } + + /* + * If there is an error or there if there is room to + * send more data we make the channel writeable. + */ + + amount = statusPB.csParam.status.sendWindow - + statusPB.csParam.status.amtUnackedData; + if ((err != noErr) || (amount > 0)) { + statePtr->checkMask |= TCL_WRITABLE; + foundSomething = 1; + } + } + } + return foundSomething; +} + +/* + *---------------------------------------------------------------------- + * + * InitMacTCPParamBlock-- + * + * Initialize a MacTCP parameter block. + * + * Results: + * None. + * + * Side effects: + * Initializes the parameter block. + * + *---------------------------------------------------------------------- + */ + +static void +InitMacTCPParamBlock( + TCPiopb *pBlock, /* Tcp parmeter block. */ + int csCode) /* Tcp operation code. */ +{ + memset(pBlock, 0, sizeof(TCPiopb)); + pBlock->ioResult = 1; + pBlock->ioCRefNum = driverRefNum; + pBlock->csCode = (short) csCode; +} + +/* + *---------------------------------------------------------------------- + * + * TcpBlockMode -- + * + * Set blocking or non-blocking mode on channel. + * + * Results: + * 0 if successful, errno when failed. + * + * Side effects: + * Sets the device into blocking or non-blocking mode. + * + *---------------------------------------------------------------------- + */ + +static int +TcpBlockMode( + ClientData instanceData, /* Channel state. */ + int mode) /* The mode to set. */ +{ + TcpState *statePtr = (TcpState *) instanceData; + + if (mode == TCL_MODE_BLOCKING) { + statePtr->flags &= ~TCP_ASYNC_SOCKET; + } else { + statePtr->flags |= TCP_ASYNC_SOCKET; + } + return 0; +} + +/* + *---------------------------------------------------------------------- + * + * TcpClose -- + * + * Close the socket. + * + * Results: + * 0 if successful, the value of errno if failed. + * + * Side effects: + * Closes the socket. + * + *---------------------------------------------------------------------- + */ + +static int +TcpClose( + ClientData instanceData, /* The socket to close. */ + Tcl_Interp *interp) /* Interp for error messages. */ +{ + TcpState *statePtr = (TcpState *) instanceData; + StreamPtr tcpStream; + TCPiopb closePB; + OSErr err; + + tcpStream = statePtr->tcpStream; + statePtr->flags &= ~TCP_CONNECTED; + + /* + * If this is a server socket we can't use the statePtr + * param block because it is in use. However, we can + * close syncronously. + */ + + if ((statePtr->flags & TCP_LISTENING) || + (statePtr->flags & TCP_LISTEN_CONNECT)) { + InitMacTCPParamBlock(&closePB, TCPClose); + closePB.tcpStream = tcpStream; + closePB.ioCompletion = NULL; + closePB.csParam.close.ulpTimeoutValue = 60 /* seconds */; + closePB.csParam.close.ulpTimeoutAction = 1 /* 1:abort 0:report */; + closePB.csParam.close.validityFlags = timeoutValue | timeoutAction; + err = PBControlSync((ParmBlkPtr) &closePB); + if (err != noErr) { + Debugger(); + goto afterRelease; + /* Tcl_Panic("error closing server socket"); */ + } + statePtr->flags |= TCP_RELEASE; + + /* + * Server sockets are closed sync. Therefor, we know it is OK to + * release the socket now. + */ + + InitMacTCPParamBlock(&statePtr->pb, TCPRelease); + statePtr->pb.tcpStream = statePtr->tcpStream; + err = PBControlSync((ParmBlkPtr) &statePtr->pb); + if (err != noErr) { + Tcl_Panic("error releasing server socket"); + } + + /* + * Free the buffer space used by the socket and the + * actual socket state data structure. + */ + afterRelease: + + /* + * Have to check whether the pointer is NULL, since we could get here + * on a failed socket open, and then the rcvBuff would never have been + * allocated. + */ + + if (err == noErr) { + ckfree((char *) statePtr->pb.csParam.create.rcvBuff); + } + FreeSocketInfo(statePtr); + return 0; + } + + /* + * If this socket is in the midddle on async connect we can just + * abort the connect and release the stream right now. + */ + + if (statePtr->flags & TCP_ASYNC_CONNECT) { + InitMacTCPParamBlock(&closePB, TCPClose); + closePB.tcpStream = tcpStream; + closePB.ioCompletion = NULL; + err = PBControlSync((ParmBlkPtr) &closePB); + if (err == noErr) { + statePtr->flags |= TCP_RELEASE; + + InitMacTCPParamBlock(&closePB, TCPRelease); + closePB.tcpStream = tcpStream; + closePB.ioCompletion = NULL; + + err = PBControlSync((ParmBlkPtr) &closePB); + } + + /* + * Free the buffer space used by the socket and the + * actual socket state data structure. However, if the + * RELEASE returns an error, then the rcvBuff is usually + * bad, so we can't release it. I think this means we will + * leak the buffer, so in the future, we may want to track the + * buffers separately, and nuke them on our own (or just not + * use MacTCP!). + */ + + if (err == noErr) { + ckfree((char *) closePB.csParam.create.rcvBuff); + } + + FreeSocketInfo(statePtr); + return err; + } + + /* + * Client sockets: + * If a background write is in progress, don't close + * the socket yet. The completion routine for the + * write will take care of it. + */ + + if (!(statePtr->flags & TCP_WRITING)) { + InitMacTCPParamBlock(&statePtr->pb, TCPClose); + statePtr->pb.tcpStream = tcpStream; + statePtr->pb.ioCompletion = closeUPP; + statePtr->pb.csParam.close.userDataPtr = (Ptr) statePtr; + err = PBControlAsync((ParmBlkPtr) &statePtr->pb); + if (err != noErr) { + Debugger(); + statePtr->flags |= TCP_RELEASE; + /* return 0; */ + } + } + + SocketFreeProc(instanceData); + return 0; +} + +/* + *---------------------------------------------------------------------- + * + * CloseCompletionRoutine -- + * + * Handles the close protocol for a Tcp socket. This will do + * a series of calls to release all data currently buffered for + * the socket. This is important to do to as it allows the remote + * connection to recieve and issue it's own close on the socket. + * Note that this function is running at interupt time and can't + * allocate memory or do much else except set state. + * + * Results: + * None. + * + * Side effects: + * The buffers for the socket are flushed. + * + *---------------------------------------------------------------------- + */ + +static void +CloseCompletionRoutine( + TCPiopb *pbPtr) /* Tcp parameter block. */ +{ + TcpState *statePtr; + OSErr err; + + if (pbPtr->csCode == TCPClose) { + statePtr = (TcpState *) (pbPtr->csParam.close.userDataPtr); + } else { + statePtr = (TcpState *) (pbPtr->csParam.receive.userDataPtr); + } + + /* + * It's very bad if the statePtr is nNULL - we should probably panic... + */ + + if (statePtr == NULL) { + Debugger(); + return; + } + + WakeUpProcess(&statePtr->psn); + + /* + * If there is an error we assume the remote side has already + * close. We are done closing as soon as we decide that the + * remote connection has closed. + */ + + if (pbPtr->ioResult != noErr) { + statePtr->flags |= TCP_RELEASE; + return; + } + if (statePtr->flags & TCP_REMOTE_CLOSED) { + statePtr->flags |= TCP_RELEASE; + return; + } + + /* + * If we just did a recieve we need to return the buffers. + * Otherwise, attempt to recieve more data until we recieve an + * error (usually because we have no more data). + */ + + if (statePtr->pb.csCode == TCPNoCopyRcv) { + InitMacTCPParamBlock(&statePtr->pb, TCPRcvBfrReturn); + statePtr->pb.tcpStream = statePtr->tcpStream; + statePtr->pb.ioCompletion = closeUPP; + statePtr->pb.csParam.receive.rdsPtr = (Ptr) statePtr->rdsarray; + statePtr->pb.csParam.receive.userDataPtr = (Ptr) statePtr; + err = PBControlAsync((ParmBlkPtr) &statePtr->pb); + } else { + InitMacTCPParamBlock(&statePtr->pb, TCPNoCopyRcv); + statePtr->pb.tcpStream = statePtr->tcpStream; + statePtr->pb.ioCompletion = closeUPP; + statePtr->pb.csParam.receive.commandTimeoutValue = 1; + statePtr->pb.csParam.receive.rdsPtr = (Ptr) statePtr->rdsarray; + statePtr->pb.csParam.receive.rdsLength = 5; + statePtr->pb.csParam.receive.userDataPtr = (Ptr) statePtr; + err = PBControlAsync((ParmBlkPtr) &statePtr->pb); + } + + if (err != noErr) { + statePtr->flags |= TCP_RELEASE; + } +} +/* + *---------------------------------------------------------------------- + * + * SocketFreeProc -- + * + * This callback is invoked in order to delete + * the notifier data associated with a file handle. + * + * Results: + * None. + * + * Side effects: + * Removes the SocketInfo from the global socket list. + * + *---------------------------------------------------------------------- + */ + +static void +SocketFreeProc( + ClientData clientData) /* Channel state. */ +{ + TcpState *statePtr = (TcpState *) clientData; + OSErr err; + TCPiopb statusPB; + + /* + * Get the status of this connection. We need to do a + * few tests to see if it's OK to release the stream now. + */ + + if (!(statePtr->flags & TCP_RELEASE)) { + return; + } + statusPB.ioCRefNum = driverRefNum; + statusPB.tcpStream = statePtr->tcpStream; + statusPB.csCode = TCPStatus; + err = PBControlSync((ParmBlkPtr) &statusPB); + if ((statusPB.csParam.status.connectionState == 0) || + (statusPB.csParam.status.connectionState == 2)) { + /* + * If the conection state is 0 then this was a client + * connection and it's closed. If it is 2 then this a + * server client and we may release it. If it isn't + * one of those values then we return and we'll try to + * clean up later. + */ + + } else { + return; + } + + /* + * The Close request is made async. We know it's + * OK to release the socket when the TCP_RELEASE flag + * gets set. + */ + + InitMacTCPParamBlock(&statePtr->pb, TCPRelease); + statePtr->pb.tcpStream = statePtr->tcpStream; + err = PBControlSync((ParmBlkPtr) &statePtr->pb); + if (err != noErr) { + Debugger(); /* Ignoreing leaves stranded stream. Is there an + alternative? */ + } + + /* + * Free the buffer space used by the socket and the + * actual socket state data structure. + */ + + ckfree((char *) statePtr->pb.csParam.create.rcvBuff); + FreeSocketInfo(statePtr); +} + +/* + *---------------------------------------------------------------------- + * + * TcpInput -- + * + * Reads input from the IO channel into the buffer given. Returns + * count of how many bytes were actually read, and an error + * indication. + * + * Results: + * A count of how many bytes were read is returned. A value of -1 + * implies an error occured. A value of zero means we have reached + * the end of data (EOF). + * + * Side effects: + * Reads input from the actual channel. + * + *---------------------------------------------------------------------- + */ + +int +TcpInput( + ClientData instanceData, /* Channel state. */ + char *buf, /* Where to store data read. */ + int bufSize, /* How much space is available + * in the buffer? */ + int *errorCodePtr) /* Where to store error code. */ +{ + TcpState *statePtr = (TcpState *) instanceData; + StreamPtr tcpStream; + OSErr err; + TCPiopb statusPB; + int toRead, dataAvail; + + *errorCodePtr = 0; + errno = 0; + tcpStream = statePtr->tcpStream; + + if (bufSize == 0) { + return 0; + } + toRead = bufSize; + + /* + * First check to see if EOF was already detected, to prevent + * calling the socket stack after the first time EOF is detected. + */ + + if (statePtr->flags & TCP_REMOTE_CLOSED) { + return 0; + } + + /* + * If an asynchronous connect is in progress, attempt to wait for it + * to complete before reading. + */ + + if ((statePtr->flags & TCP_ASYNC_CONNECT) + && ! WaitForSocketEvent(statePtr, TCL_READABLE, errorCodePtr)) { + return -1; + } + + /* + * No EOF, and it is connected, so try to read more from the socket. + * If the socket is blocking, we keep trying until there is data + * available or the socket is closed. + */ + + while (1) { + + statusPB.ioCRefNum = driverRefNum; + statusPB.tcpStream = tcpStream; + statusPB.csCode = TCPStatus; + err = PBControlSync((ParmBlkPtr) &statusPB); + if (err != noErr) { + Debugger(); + statePtr->flags |= TCP_REMOTE_CLOSED; + return 0; /* EOF */ + } + dataAvail = statusPB.csParam.status.amtUnreadData; + if (dataAvail < bufSize) { + toRead = dataAvail; + } else { + toRead = bufSize; + } + if (toRead != 0) { + /* + * Try to read the data. + */ + + InitMacTCPParamBlock(&statusPB, TCPRcv); + statusPB.tcpStream = tcpStream; + statusPB.csParam.receive.rcvBuff = buf; + statusPB.csParam.receive.rcvBuffLen = toRead; + err = PBControlSync((ParmBlkPtr) &statusPB); + + statePtr->checkMask &= ~TCL_READABLE; + switch (err) { + case noErr: + /* + * The channel remains readable only if this read succeds + * and we had more data then the size of the buffer we were + * trying to fill. Use the info from the call to status to + * determine this. + */ + + if (dataAvail > bufSize) { + statePtr->checkMask |= TCL_READABLE; + } + return statusPB.csParam.receive.rcvBuffLen; + case connectionClosing: + *errorCodePtr = errno = ESHUTDOWN; + statePtr->flags |= TCP_REMOTE_CLOSED; + return 0; + case connectionDoesntExist: + case connectionTerminated: + *errorCodePtr = errno = ENOTCONN; + statePtr->flags |= TCP_REMOTE_CLOSED; + return 0; + case invalidStreamPtr: + default: + *errorCodePtr = EINVAL; + return -1; + } + } + + /* + * No data is available, so check the connection state to + * see why this is the case. + */ + + if (statusPB.csParam.status.connectionState == 14) { + statePtr->flags |= TCP_REMOTE_CLOSED; + return 0; + } + if (statusPB.csParam.status.connectionState != 8) { + Debugger(); + } + statePtr->checkMask &= ~TCL_READABLE; + if (statePtr->flags & TCP_ASYNC_SOCKET) { + *errorCodePtr = EWOULDBLOCK; + return -1; + } + + /* + * In the blocking case, wait until the file becomes readable + * or closed and try again. + */ + + if (!WaitForSocketEvent(statePtr, TCL_READABLE, errorCodePtr)) { + return -1; + } + } +} + +/* + *---------------------------------------------------------------------- + * + * TcpGetHandle -- + * + * Called from Tcl_GetChannelHandle to retrieve handles from inside + * a file based channel. + * + * Results: + * The appropriate handle or NULL if not present. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +TcpGetHandle( + ClientData instanceData, /* The file state. */ + int direction, /* Which handle to retrieve? */ + ClientData *handlePtr) +{ + TcpState *statePtr = (TcpState *) instanceData; + + *handlePtr = (ClientData) statePtr->tcpStream; + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TcpOutput-- + * + * Writes the given output on the IO channel. Returns count of how + * many characters were actually written, and an error indication. + * + * Results: + * A count of how many characters were written is returned and an + * error indication is returned in an output argument. + * + * Side effects: + * Writes output on the actual channel. + * + *---------------------------------------------------------------------- + */ + +static int +TcpOutput( + ClientData instanceData, /* Channel state. */ + CONST char *buf, /* The data buffer. */ + int toWrite, /* How many bytes to write? */ + int *errorCodePtr) /* Where to store error code. */ +{ + TcpState *statePtr = (TcpState *) instanceData; + StreamPtr tcpStream; + OSErr err; + int amount; + TCPiopb statusPB; + + *errorCodePtr = 0; + tcpStream = statePtr->tcpStream; + + /* + * If an asynchronous connect is in progress, attempt to wait for it + * to complete before writing. + */ + + if ((statePtr->flags & TCP_ASYNC_CONNECT) + && ! WaitForSocketEvent(statePtr, TCL_WRITABLE, errorCodePtr)) { + return -1; + } + + /* + * Loop until we have written some data, or an error occurs. + */ + + while (1) { + statusPB.ioCRefNum = driverRefNum; + statusPB.tcpStream = tcpStream; + statusPB.csCode = TCPStatus; + err = PBControlSync((ParmBlkPtr) &statusPB); + if ((err == connectionDoesntExist) || ((err == noErr) && + (statusPB.csParam.status.connectionState == 14))) { + /* + * The remote connection is gone away. Report an error + * and don't write anything. + */ + + *errorCodePtr = errno = EPIPE; + return -1; + } else if (err != noErr) { + return -1; + } + amount = statusPB.csParam.status.sendWindow + - statusPB.csParam.status.amtUnackedData; + + /* + * Attempt to write the data to the socket if a background + * write isn't in progress and there is room in the output buffers. + */ + + if (!(statePtr->flags & TCP_WRITING) && amount > 0) { + if (toWrite < amount) { + amount = toWrite; + } + + /* We need to copy the data, otherwise the caller may overwrite + * the buffer in the middle of our asynchronous call + */ + + if (amount > statePtr->writeBufferSize) { + /* + * need to grow write buffer + */ + + if (statePtr->writeBuffer != (void *) NULL) { + ckfree(statePtr->writeBuffer); + } + statePtr->writeBuffer = (void *) ckalloc(amount); + statePtr->writeBufferSize = amount; + } + memcpy(statePtr->writeBuffer, buf, amount); + statePtr->dataSegment[0].ptr = statePtr->writeBuffer; + + statePtr->dataSegment[0].length = amount; + statePtr->dataSegment[1].length = 0; + InitMacTCPParamBlock(&statePtr->pb, TCPSend); + statePtr->pb.ioCompletion = completeUPP; + statePtr->pb.tcpStream = tcpStream; + statePtr->pb.csParam.send.wdsPtr = (Ptr) statePtr->dataSegment; + statePtr->pb.csParam.send.pushFlag = 1; + statePtr->pb.csParam.send.userDataPtr = (Ptr) statePtr; + statePtr->flags |= TCP_WRITING; + err = PBControlAsync((ParmBlkPtr) &(statePtr->pb)); + switch (err) { + case noErr: + return amount; + case connectionClosing: + *errorCodePtr = errno = ESHUTDOWN; + statePtr->flags |= TCP_REMOTE_CLOSED; + return -1; + case connectionDoesntExist: + case connectionTerminated: + *errorCodePtr = errno = ENOTCONN; + statePtr->flags |= TCP_REMOTE_CLOSED; + return -1; + case invalidStreamPtr: + default: + return -1; + } + + } + + /* + * The socket wasn't writable. In the non-blocking case, return + * immediately, otherwise wait until the file becomes writable + * or closed and try again. + */ + + if (statePtr->flags & TCP_ASYNC_SOCKET) { + statePtr->checkMask &= ~TCL_WRITABLE; + *errorCodePtr = EWOULDBLOCK; + return -1; + } else if (!WaitForSocketEvent(statePtr, TCL_WRITABLE, errorCodePtr)) { + return -1; + } + } +} + +/* + *---------------------------------------------------------------------- + * + * TcpGetOptionProc -- + * + * Computes an option value for a TCP socket based channel, or a + * list of all options and their values. + * + * Note: This code is based on code contributed by John Haxby. + * + * Results: + * A standard Tcl result. The value of the specified option or a + * list of all options and their values is returned in the + * supplied DString. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +TcpGetOptionProc( + ClientData instanceData, /* Socket state. */ + Tcl_Interp *interp, /* For error reporting - can be NULL.*/ + CONST char *optionName, /* Name of the option to + * retrieve the value for, or + * NULL to get all options and + * their values. */ + Tcl_DString *dsPtr) /* Where to store the computed + * value; initialized by caller. */ +{ + TcpState *statePtr = (TcpState *) instanceData; + int doPeerName = false, doSockName = false, doError = false, doAll = false; + ip_addr tcpAddress; + char buffer[128]; + OSErr err; + Tcl_DString dString; + TCPiopb statusPB; + int errorCode; + size_t len = 0; + + /* + * If an asynchronous connect is in progress, attempt to wait for it + * to complete before accessing the socket state. + */ + + if ((statePtr->flags & TCP_ASYNC_CONNECT) + && ! WaitForSocketEvent(statePtr, TCL_WRITABLE, &errorCode)) { + if (interp) { + /* + * fix the error message. + */ + + Tcl_AppendResult(interp, "connect is in progress and can't wait", + NULL); + } + return TCL_ERROR; + } + + /* + * Determine which options we need to do. Do all of them + * if optionName is NULL. + */ + + if (optionName == (CONST char *) NULL || optionName[0] == '\0') { + doAll = true; + } else { + len = strlen(optionName); + if (!strncmp(optionName, "-peername", len)) { + doPeerName = true; + } else if (!strncmp(optionName, "-sockname", len)) { + doSockName = true; + } else if (!strncmp(optionName, "-error", len)) { + /* SF Bug #483575 */ + doError = true; + } else { + return Tcl_BadChannelOption(interp, optionName, + "error peername sockname"); + } + } + + /* + * SF Bug #483575 + * + * Return error information. Currently we ignore + * this option. IOW, we always return the empty + * string, signaling 'no error'. + * + * FIXME: Get a mac/socket expert to write a correct + * FIXME: implementation. + */ + + if (doAll || doError) { + if (doAll) { + Tcl_DStringAppendElement(dsPtr, "-error"); + Tcl_DStringAppendElement(dsPtr, ""); + } else { + Tcl_DStringAppend (dsPtr, "", -1); + return TCL_OK; + } + } + + /* + * Get status on the stream. Make sure to use a new pb struct because + * the struct in the statePtr may be part of an asyncronous call. + */ + + statusPB.ioCRefNum = driverRefNum; + statusPB.tcpStream = statePtr->tcpStream; + statusPB.csCode = TCPStatus; + err = PBControlSync((ParmBlkPtr) &statusPB); + if ((err == connectionDoesntExist) || + ((err == noErr) && (statusPB.csParam.status.connectionState == 14))) { + /* + * The socket was probably closed on the other side of the connection. + */ + + if (interp) { + Tcl_AppendResult(interp, "can't access socket info: ", + "connection reset by peer", NULL); + } + return TCL_ERROR; + } else if (err != noErr) { + if (interp) { + Tcl_AppendResult(interp, "unknown socket error", NULL); + } + Debugger(); + return TCL_ERROR; + } + + + /* + * Get the sockname for the socket. + */ + + Tcl_DStringInit(&dString); + if (doAll || doSockName) { + if (doAll) { + Tcl_DStringAppendElement(dsPtr, "-sockname"); + Tcl_DStringStartSublist(dsPtr); + } + tcpAddress = statusPB.csParam.status.localHost; + sprintf(buffer, "%d.%d.%d.%d", tcpAddress>>24, + tcpAddress>>16 & 0xff, tcpAddress>>8 & 0xff, + tcpAddress & 0xff); + Tcl_DStringAppendElement(dsPtr, buffer); + if (ResolveAddress(tcpAddress, &dString) == noErr) { + Tcl_DStringAppendElement(dsPtr, dString.string); + } else { + Tcl_DStringAppendElement(dsPtr, "<unknown>"); + } + sprintf(buffer, "%d", statusPB.csParam.status.localPort); + Tcl_DStringAppendElement(dsPtr, buffer); + if (doAll) { + Tcl_DStringEndSublist(dsPtr); + } + } + + /* + * Get the peername for the socket. + */ + + if ((doAll || doPeerName) && (statePtr->flags & TCP_CONNECTED)) { + if (doAll) { + Tcl_DStringAppendElement(dsPtr, "-peername"); + Tcl_DStringStartSublist(dsPtr); + } + tcpAddress = statusPB.csParam.status.remoteHost; + sprintf(buffer, "%d.%d.%d.%d", tcpAddress>>24, + tcpAddress>>16 & 0xff, tcpAddress>>8 & 0xff, + tcpAddress & 0xff); + Tcl_DStringAppendElement(dsPtr, buffer); + Tcl_DStringSetLength(&dString, 0); + if (ResolveAddress(tcpAddress, &dString) == noErr) { + Tcl_DStringAppendElement(dsPtr, dString.string); + } else { + Tcl_DStringAppendElement(dsPtr, "<unknown>"); + } + sprintf(buffer, "%d", statusPB.csParam.status.remotePort); + Tcl_DStringAppendElement(dsPtr, buffer); + if (doAll) { + Tcl_DStringEndSublist(dsPtr); + } + } + + Tcl_DStringFree(&dString); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TcpWatch -- + * + * Initialize the notifier to watch this channel. + * + * Results: + * None. + * + * Side effects: + * Sets the watchMask for the channel. + * + *---------------------------------------------------------------------- + */ + +static void +TcpWatch(instanceData, mask) + ClientData instanceData; /* The file state. */ + int mask; /* Events of interest; an OR-ed + * combination of TCL_READABLE, + * TCL_WRITABLE and TCL_EXCEPTION. */ +{ + TcpState *statePtr = (TcpState *) instanceData; + + statePtr->watchMask = mask; +} + +/* + *---------------------------------------------------------------------- + * + * NewSocketInfo -- + * + * This function allocates and initializes a new SocketInfo + * structure. + * + * Results: + * Returns a newly allocated SocketInfo. + * + * Side effects: + * Adds the socket to the global socket list, allocates memory. + * + *---------------------------------------------------------------------- + */ + +static TcpState * +NewSocketInfo( + StreamPtr tcpStream) +{ + TcpState *statePtr; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + statePtr = (TcpState *) ckalloc((unsigned) sizeof(TcpState)); + statePtr->tcpStream = tcpStream; + statePtr->psn = applicationPSN; + statePtr->flags = 0; + statePtr->checkMask = 0; + statePtr->watchMask = 0; + statePtr->acceptProc = (Tcl_TcpAcceptProc *) NULL; + statePtr->acceptProcData = (ClientData) NULL; + statePtr->writeBuffer = (void *) NULL; + statePtr->writeBufferSize = 0; + statePtr->nextPtr = tsdPtr->socketList; + tsdPtr->socketList = statePtr; + return statePtr; +} + +/* + *---------------------------------------------------------------------- + * + * FreeSocketInfo -- + * + * This function deallocates a SocketInfo structure that is no + * longer needed. + * + * Results: + * None. + * + * Side effects: + * Removes the socket from the global socket list, frees memory. + * + *---------------------------------------------------------------------- + */ + +static void +FreeSocketInfo( + TcpState *statePtr) /* The state pointer to free. */ +{ + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + if (statePtr == tsdPtr->socketList) { + tsdPtr->socketList = statePtr->nextPtr; + } else { + TcpState *p; + for (p = tsdPtr->socketList; p != NULL; p = p->nextPtr) { + if (p->nextPtr == statePtr) { + p->nextPtr = statePtr->nextPtr; + break; + } + } + } + + if (statePtr->writeBuffer != (void *) NULL) { + ckfree(statePtr->writeBuffer); + } + + ckfree((char *) statePtr); +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_MakeTcpClientChannel -- + * + * Creates a Tcl_Channel from an existing client TCP socket. + * + * Results: + * The Tcl_Channel wrapped around the preexisting TCP socket. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_Channel +Tcl_MakeTcpClientChannel( + ClientData sock) /* The socket to wrap up into a channel. */ +{ + TcpState *statePtr; + char channelName[20]; + + if (TclpHasSockets(NULL) != TCL_OK) { + return NULL; + } + + statePtr = NewSocketInfo((StreamPtr) sock); + /* TODO: do we need to set the port??? */ + + sprintf(channelName, "sock%d", socketNumber++); + + statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, + (ClientData) statePtr, (TCL_READABLE | TCL_WRITABLE)); + Tcl_SetChannelBufferSize(statePtr->channel, socketBufferSize); + Tcl_SetChannelOption(NULL, statePtr->channel, "-translation", "auto crlf"); + return statePtr->channel; +} + +/* + *---------------------------------------------------------------------- + * + * CreateSocket -- + * + * This function opens a new socket and initializes the + * SocketInfo structure. + * + * Results: + * Returns a new SocketInfo, or NULL with an error in interp. + * + * Side effects: + * Adds a new socket to the socketList. + * + *---------------------------------------------------------------------- + */ + +static TcpState * +CreateSocket( + Tcl_Interp *interp, /* For error reporting; can be NULL. */ + int port, /* Port number to open. */ + CONST char *host, /* Name of host on which to open port. */ + CONST char *myaddr, /* Optional client-side address */ + int myport, /* Optional client-side port */ + int server, /* 1 if socket should be a server socket, + * else 0 for a client socket. */ + int async) /* 1 create async, 0 do sync. */ +{ + ip_addr macAddr; + OSErr err; + TCPiopb pb; + StreamPtr tcpStream; + TcpState *statePtr; + char * buffer; + + /* + * Figure out the ip address from the host string. + */ + + if (host == NULL) { + err = GetLocalAddress(&macAddr); + } else { + err = GetHostFromString(host, &macAddr); + } + if (err != noErr) { + Tcl_SetErrno(EHOSTUNREACH); + if (interp != (Tcl_Interp *) NULL) { + Tcl_AppendResult(interp, "couldn't open socket: ", + Tcl_PosixError(interp), (char *) NULL); + } + return (TcpState *) NULL; + } + + /* + * Create a MacTCP stream and create the state used for socket + * transactions from here on out. + */ + + ClearZombieSockets(); + buffer = ckalloc(socketBufferSize); + InitMacTCPParamBlock(&pb, TCPCreate); + pb.csParam.create.rcvBuff = buffer; + pb.csParam.create.rcvBuffLen = socketBufferSize; + pb.csParam.create.notifyProc = nil /* notifyUPP */; + err = PBControlSync((ParmBlkPtr) &pb); + if (err != noErr) { + Tcl_SetErrno(0); /* TODO: set to ENOSR - maybe?*/ + if (interp != (Tcl_Interp *) NULL) { + Tcl_AppendResult(interp, "couldn't open socket: ", + Tcl_PosixError(interp), (char *) NULL); + } + return (TcpState *) NULL; + } + + tcpStream = pb.tcpStream; + statePtr = NewSocketInfo(tcpStream); + statePtr->port = port; + + if (server) { + /* + * Set up server connection. + */ + + InitMacTCPParamBlock(&statePtr->pb, TCPPassiveOpen); + statePtr->pb.tcpStream = tcpStream; + statePtr->pb.csParam.open.localPort = statePtr->port; + statePtr->pb.ioCompletion = completeUPP; + statePtr->pb.csParam.open.userDataPtr = (Ptr) statePtr; + statePtr->pb.csParam.open.ulpTimeoutValue = 100; + statePtr->pb.csParam.open.ulpTimeoutAction = 1 /* 1:abort 0:report */; + statePtr->pb.csParam.open.commandTimeoutValue = 0 /* infinity */; + + statePtr->flags |= TCP_LISTENING; + err = PBControlAsync((ParmBlkPtr) &(statePtr->pb)); + + /* + * If this is a server on port 0 then we need to wait until + * the dynamic port allocation is made by the MacTcp driver. + */ + + if (statePtr->port == 0) { + EventRecord dummy; + + while (statePtr->pb.csParam.open.localPort == 0) { + WaitNextEvent(0, &dummy, 1, NULL); + if (statePtr->pb.ioResult != 0) { + break; + } + } + statePtr->port = statePtr->pb.csParam.open.localPort; + } + Tcl_SetErrno(EINPROGRESS); + } else { + /* + * Attempt to connect. The connect may fail at present with an + * EINPROGRESS but at a later time it will complete. The caller + * will set up a file handler on the socket if she is interested in + * being informed when the connect completes. + */ + + InitMacTCPParamBlock(&statePtr->pb, TCPActiveOpen); + + statePtr->pb.tcpStream = tcpStream; + statePtr->pb.csParam.open.remoteHost = macAddr; + statePtr->pb.csParam.open.remotePort = port; + statePtr->pb.csParam.open.localHost = 0; + statePtr->pb.csParam.open.localPort = myport; + statePtr->pb.csParam.open.userDataPtr = (Ptr) statePtr; + statePtr->pb.csParam.open.validityFlags = timeoutValue | timeoutAction; + statePtr->pb.csParam.open.ulpTimeoutValue = 60 /* seconds */; + statePtr->pb.csParam.open.ulpTimeoutAction = 1 /* 1:abort 0:report */; + statePtr->pb.csParam.open.commandTimeoutValue = 0; + + statePtr->pb.ioCompletion = completeUPP; + if (async) { + statePtr->flags |= TCP_ASYNC_CONNECT; + err = PBControlAsync((ParmBlkPtr) &(statePtr->pb)); + Tcl_SetErrno(EINPROGRESS); + } else { + err = PBControlSync((ParmBlkPtr) &(statePtr->pb)); + } + } + + switch (err) { + case noErr: + if (!async) { + statePtr->flags |= TCP_CONNECTED; + } + return statePtr; + case duplicateSocket: + Tcl_SetErrno(EADDRINUSE); + break; + case openFailed: + case connectionTerminated: + Tcl_SetErrno(ECONNREFUSED); + break; + case invalidStreamPtr: + case connectionExists: + default: + /* + * These cases should never occur. However, we will fail + * gracefully and hope Tcl can resume. The alternative is to panic + * which is probably a bit drastic. + */ + + Debugger(); + Tcl_SetErrno(err); + } + + /* + * We had error during the connection. Release the stream + * and file handle. Also report to the interp. + */ + + pb.ioCRefNum = driverRefNum; + pb.csCode = TCPRelease; + pb.tcpStream = tcpStream; + pb.ioCompletion = NULL; + err = PBControlSync((ParmBlkPtr) &pb); + + if (interp != (Tcl_Interp *) NULL) { + Tcl_AppendResult(interp, "couldn't open socket: ", + Tcl_PosixError(interp), (char *) NULL); + } + + ckfree(buffer); + FreeSocketInfo(statePtr); + return (TcpState *) NULL; +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_OpenTcpClient -- + * + * Opens a TCP client socket and creates a channel around it. + * + * Results: + * The channel or NULL if failed. On failure, the routine also + * sets the output argument errorCodePtr to the error code. + * + * Side effects: + * Opens a client socket and creates a new channel. + * + *---------------------------------------------------------------------- + */ + +Tcl_Channel +Tcl_OpenTcpClient( + Tcl_Interp *interp, /* For error reporting; can be NULL. */ + int port, /* Port number to open. */ + CONST char *host, /* Host on which to open port. */ + CONST char *myaddr, /* Client-side address */ + int myport, /* Client-side port */ + int async) /* If nonzero, attempt to do an + * asynchronous connect. Otherwise + * we do a blocking connect. + * - currently ignored */ +{ + TcpState *statePtr; + char channelName[20]; + + if (TclpHasSockets(interp) != TCL_OK) { + return NULL; + } + + /* + * Create a new client socket and wrap it in a channel. + */ + + statePtr = CreateSocket(interp, port, host, myaddr, myport, 0, async); + if (statePtr == NULL) { + return NULL; + } + + sprintf(channelName, "sock%d", socketNumber++); + + statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, + (ClientData) statePtr, (TCL_READABLE | TCL_WRITABLE)); + Tcl_SetChannelBufferSize(statePtr->channel, socketBufferSize); + Tcl_SetChannelOption(NULL, statePtr->channel, "-translation", "auto crlf"); + return statePtr->channel; +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_OpenTcpServer -- + * + * Opens a TCP server socket and creates a channel around it. + * + * Results: + * The channel or NULL if failed. + * + * Side effects: + * Opens a server socket and creates a new channel. + * + *---------------------------------------------------------------------- + */ + +Tcl_Channel +Tcl_OpenTcpServer( + Tcl_Interp *interp, /* For error reporting - may be + * NULL. */ + int port, /* Port number to open. */ + CONST char *host, /* Name of local host. */ + Tcl_TcpAcceptProc *acceptProc, /* Callback for accepting connections + * from new clients. */ + ClientData acceptProcData) /* Data for the callback. */ +{ + TcpState *statePtr; + char channelName[20]; + + if (TclpHasSockets(interp) != TCL_OK) { + return NULL; + } + + /* + * Create a new client socket and wrap it in a channel. + */ + + statePtr = CreateSocket(interp, port, host, NULL, 0, 1, 1); + if (statePtr == NULL) { + return NULL; + } + + statePtr->acceptProc = acceptProc; + statePtr->acceptProcData = acceptProcData; + + sprintf(channelName, "sock%d", socketNumber++); + + statePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, + (ClientData) statePtr, 0); + Tcl_SetChannelBufferSize(statePtr->channel, socketBufferSize); + Tcl_SetChannelOption(NULL, statePtr->channel, "-translation", "auto crlf"); + return statePtr->channel; +} + +/* + *---------------------------------------------------------------------- + * + * SocketEventProc -- + * + * This procedure is called by Tcl_ServiceEvent when a socket event + * reaches the front of the event queue. This procedure is + * responsible for notifying the generic channel code. + * + * Results: + * Returns 1 if the event was handled, meaning it should be removed + * from the queue. Returns 0 if the event was not handled, meaning + * it should stay on the queue. The only time the event isn't + * handled is if the TCL_FILE_EVENTS flag bit isn't set. + * + * Side effects: + * Whatever the channel callback procedures do. + * + *---------------------------------------------------------------------- + */ + +static int +SocketEventProc( + Tcl_Event *evPtr, /* Event to service. */ + int flags) /* Flags that indicate what events to + * handle, such as TCL_FILE_EVENTS. */ +{ + TcpState *statePtr; + SocketEvent *eventPtr = (SocketEvent *) evPtr; + int mask = 0; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + if (!(flags & TCL_FILE_EVENTS)) { + return 0; + } + + /* + * Find the specified socket on the socket list. + */ + + for (statePtr = tsdPtr->socketList; statePtr != NULL; + statePtr = statePtr->nextPtr) { + if ((statePtr == eventPtr->statePtr) && + (statePtr->tcpStream == eventPtr->tcpStream)) { + break; + } + } + + /* + * Discard events that have gone stale. + */ + + if (!statePtr) { + return 1; + } + statePtr->flags &= ~(TCP_PENDING); + if (statePtr->flags & TCP_RELEASE) { + SocketFreeProc(statePtr); + return 1; + } + + + /* + * Handle connection requests directly. + */ + + if (statePtr->flags & TCP_LISTEN_CONNECT) { + if (statePtr->checkMask & TCL_READABLE) { + TcpAccept(statePtr); + } + return 1; + } + + /* + * Mask off unwanted events then notify the channel. + */ + + mask = statePtr->checkMask & statePtr->watchMask; + if (mask) { + Tcl_NotifyChannel(statePtr->channel, mask); + } + return 1; +} + +/* + *---------------------------------------------------------------------- + * + * WaitForSocketEvent -- + * + * Waits until one of the specified events occurs on a socket. + * + * Results: + * Returns 1 on success or 0 on failure, with an error code in + * errorCodePtr. + * + * Side effects: + * Processes socket events off the system queue. + * + *---------------------------------------------------------------------- + */ + +static int +WaitForSocketEvent( + TcpState *statePtr, /* Information about this socket. */ + int mask, /* Events to look for. */ + int *errorCodePtr) /* Where to store errors? */ +{ + OSErr err; + TCPiopb statusPB; + EventRecord dummy; + + /* + * Loop until we get the specified condition, unless the socket is + * asynchronous. + */ + + do { + statusPB.ioCRefNum = driverRefNum; + statusPB.tcpStream = statePtr->tcpStream; + statusPB.csCode = TCPStatus; + err = PBControlSync((ParmBlkPtr) &statusPB); + if (err != noErr) { + /* + * I am not sure why it is right to return 1 - indicating success + * for synchronous sockets when an attempt to get status on the + * driver yeilds an error. But it is CERTAINLY wrong for async + * sockect which have not yet connected. + */ + + if (statePtr->flags & TCP_ASYNC_CONNECT) { + *errorCodePtr = EWOULDBLOCK; + return 0; + } else { + statePtr->checkMask |= (TCL_READABLE | TCL_WRITABLE); + return 1; + } + } + statePtr->checkMask = 0; + + /* + * The "6" below is the "connection being established" flag. I couldn't + * find a define for this in MacTCP.h, but that's what the programmer's + * guide says. + */ + + if ((statusPB.csParam.status.connectionState != 0) + && (statusPB.csParam.status.connectionState != 4) + && (statusPB.csParam.status.connectionState != 6)) { + if (statusPB.csParam.status.amtUnreadData > 0) { + statePtr->checkMask |= TCL_READABLE; + } + if (!(statePtr->flags & TCP_WRITING) + && (statusPB.csParam.status.sendWindow - + statusPB.csParam.status.amtUnackedData) > 0) { + statePtr->flags &= ~(TCP_ASYNC_CONNECT); + statePtr->checkMask |= TCL_WRITABLE; + } + if (mask & statePtr->checkMask) { + return 1; + } + } else { + break; + } + + /* + * Call the system to let other applications run while we + * are waiting for this event to occur. + */ + + WaitNextEvent(0, &dummy, 1, NULL); + } while (!(statePtr->flags & TCP_ASYNC_SOCKET)); + *errorCodePtr = EWOULDBLOCK; + return 0; +} + +/* + *---------------------------------------------------------------------- + * + * TcpAccept -- + * Accept a TCP socket connection. This is called by the event + * loop, and it in turns calls any registered callbacks for this + * channel. + * + * Results: + * None. + * + * Side effects: + * Evals the Tcl script associated with the server socket. + * + *---------------------------------------------------------------------- + */ + +static void +TcpAccept( + TcpState *statePtr) +{ + TcpState *newStatePtr; + StreamPtr tcpStream; + char remoteHostname[255]; + OSErr err; + ip_addr remoteAddress; + long remotePort; + char channelName[20]; + + statePtr->flags &= ~TCP_LISTEN_CONNECT; + statePtr->checkMask &= ~TCL_READABLE; + + /* + * Transfer sever stream to new connection. + */ + + tcpStream = statePtr->tcpStream; + newStatePtr = NewSocketInfo(tcpStream); + newStatePtr->tcpStream = tcpStream; + sprintf(channelName, "sock%d", socketNumber++); + + + newStatePtr->flags |= TCP_CONNECTED; + newStatePtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName, + (ClientData) newStatePtr, (TCL_READABLE | TCL_WRITABLE)); + Tcl_SetChannelBufferSize(newStatePtr->channel, socketBufferSize); + Tcl_SetChannelOption(NULL, newStatePtr->channel, "-translation", + "auto crlf"); + + remoteAddress = statePtr->pb.csParam.open.remoteHost; + remotePort = statePtr->pb.csParam.open.remotePort; + + /* + * Reopen passive connect. Make new tcpStream the server. + */ + + ClearZombieSockets(); + InitMacTCPParamBlock(&statePtr->pb, TCPCreate); + statePtr->pb.csParam.create.rcvBuff = ckalloc(socketBufferSize); + statePtr->pb.csParam.create.rcvBuffLen = socketBufferSize; + err = PBControlSync((ParmBlkPtr) &statePtr->pb); + if (err != noErr) { + /* + * Hmmm... We can't reopen the server. We'll go ahead + * an continue - but we are kind of broken now... + */ + Debugger(); + statePtr->tcpStream = -1; + statePtr->flags |= TCP_SERVER_ZOMBIE; + } + + tcpStream = statePtr->tcpStream = statePtr->pb.tcpStream; + + InitMacTCPParamBlock(&statePtr->pb, TCPPassiveOpen); + statePtr->pb.tcpStream = tcpStream; + statePtr->pb.csParam.open.localHost = 0; + statePtr->pb.csParam.open.localPort = statePtr->port; + statePtr->pb.ioCompletion = completeUPP; + statePtr->pb.csParam.open.userDataPtr = (Ptr) statePtr; + statePtr->flags |= TCP_LISTENING; + err = PBControlAsync((ParmBlkPtr) &(statePtr->pb)); + /* + * TODO: deal with case where we can't recreate server socket... + */ + + /* + * Finally we run the accept procedure. We must do this last to make + * sure we are in a nice clean state. This Tcl code can do anything + * including closing the server or client sockets we've just delt with. + */ + + if (statePtr->acceptProc != NULL) { + sprintf(remoteHostname, "%d.%d.%d.%d", remoteAddress>>24, + remoteAddress>>16 & 0xff, remoteAddress>>8 & 0xff, + remoteAddress & 0xff); + + (statePtr->acceptProc)(statePtr->acceptProcData, newStatePtr->channel, + remoteHostname, remotePort); + } +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_GetHostName -- + * + * Returns the name of the local host. + * + * Results: + * A string containing the network name for this machine, or + * an empty string if we can't figure out the name. The caller + * must not modify or free this string. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +CONST char * +Tcl_GetHostName() +{ + static int hostnameInited = 0; + static char hostname[255]; + ip_addr ourAddress; + Tcl_DString dString; + OSErr err; + + if (hostnameInited) { + return hostname; + } + + if (TclpHasSockets(NULL) == TCL_OK) { + err = GetLocalAddress(&ourAddress); + if (err == noErr) { + /* + * Search for the doman name and return it if found. Otherwise, + * just print the IP number to a string and return that. + */ + + Tcl_DStringInit(&dString); + err = ResolveAddress(ourAddress, &dString); + if (err == noErr) { + strcpy(hostname, dString.string); + } else { + sprintf(hostname, "%d.%d.%d.%d", ourAddress>>24, ourAddress>>16 & 0xff, + ourAddress>>8 & 0xff, ourAddress & 0xff); + } + Tcl_DStringFree(&dString); + + hostnameInited = 1; + return hostname; + } + } + + hostname[0] = '\0'; + hostnameInited = 1; + return hostname; +} + +/* + *---------------------------------------------------------------------- + * + * ResolveAddress -- + * + * This function is used to resolve an ip address to it's full + * domain name address. + * + * Results: + * An os err value. + * + * Side effects: + * Treats client data as int we set to true. + * + *---------------------------------------------------------------------- + */ + +static OSErr +ResolveAddress( + ip_addr tcpAddress, /* Address to resolve. */ + Tcl_DString *dsPtr) /* Returned address in string. */ +{ + int i; + EventRecord dummy; + DNRState dnrState; + OSErr err; + + /* + * Call AddrToName to resolve our ip address to our domain name. + * The call is async, so we must wait for a callback to tell us + * when to continue. + */ + + for (i = 0; i < NUM_ALT_ADDRS; i++) { + dnrState.hostInfo.addr[i] = 0; + } + dnrState.done = 0; + GetCurrentProcess(&(dnrState.psn)); + err = AddrToName(tcpAddress, &dnrState.hostInfo, resultUPP, (Ptr) &dnrState); + if (err == cacheFault) { + while (!dnrState.done) { + WaitNextEvent(0, &dummy, 1, NULL); + } + } + + /* + * If there is no error in finding the domain name we set the + * result into the dynamic string. We also work around a bug in + * MacTcp where an extranious '.' may be found at the end of the name. + */ + + if (dnrState.hostInfo.rtnCode == noErr) { + i = strlen(dnrState.hostInfo.cname) - 1; + if (dnrState.hostInfo.cname[i] == '.') { + dnrState.hostInfo.cname[i] = '\0'; + } + Tcl_DStringAppend(dsPtr, dnrState.hostInfo.cname, -1); + } + + return dnrState.hostInfo.rtnCode; +} + +/* + *---------------------------------------------------------------------- + * + * DNRCompletionRoutine -- + * + * This function is called when the Domain Name Server is done + * seviceing our request. It just sets a flag that we can poll + * in functions like Tcl_GetHostName to let them know to continue. + * + * Results: + * None. + * + * Side effects: + * Treats client data as int we set to true. + * + *---------------------------------------------------------------------- + */ + +static pascal void +DNRCompletionRoutine( + struct hostInfo *hostinfoPtr, /* Host infor struct. */ + DNRState *dnrStatePtr) /* Completetion state. */ +{ + dnrStatePtr->done = true; + WakeUpProcess(&(dnrStatePtr->psn)); +} + +/* + *---------------------------------------------------------------------- + * + * CleanUpExitProc -- + * + * This procedure is invoked as an exit handler when ExitToShell + * is called. It aborts any lingering socket connections. This + * must be called or the Mac OS will more than likely crash. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static pascal void +CleanUpExitProc() +{ + TCPiopb exitPB; + TcpState *statePtr; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + while (tsdPtr->socketList != NULL) { + statePtr = tsdPtr->socketList; + tsdPtr->socketList = statePtr->nextPtr; + + /* + * Close and Release the connection. + */ + + exitPB.ioCRefNum = driverRefNum; + exitPB.csCode = TCPClose; + exitPB.tcpStream = statePtr->tcpStream; + exitPB.csParam.close.ulpTimeoutValue = 60 /* seconds */; + exitPB.csParam.close.ulpTimeoutAction = 1 /* 1:abort 0:report */; + exitPB.csParam.close.validityFlags = timeoutValue | timeoutAction; + exitPB.ioCompletion = NULL; + PBControlSync((ParmBlkPtr) &exitPB); + + exitPB.ioCRefNum = driverRefNum; + exitPB.csCode = TCPRelease; + exitPB.tcpStream = statePtr->tcpStream; + exitPB.ioCompletion = NULL; + PBControlSync((ParmBlkPtr) &exitPB); + } +} + +/* + *---------------------------------------------------------------------- + * + * GetHostFromString -- + * + * Looks up the passed in domain name in the domain resolver. It + * can accept strings of two types: 1) the ip number in string + * format, or 2) the domain name. + * + * Results: + * We return a ip address or 0 if there was an error or the + * domain does not exist. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static OSErr +GetHostFromString( + CONST char *name, /* Host in string form. */ + ip_addr *address) /* Returned IP address. */ +{ + OSErr err; + int i; + EventRecord dummy; + DNRState dnrState; + + if (TclpHasSockets(NULL) != TCL_OK) { + return 0; + } + + /* + * Call StrToAddr to get the ip number for the passed in domain + * name. The call is async, so we must wait for a callback to + * tell us when to continue. + */ + + for (i = 0; i < NUM_ALT_ADDRS; i++) { + dnrState.hostInfo.addr[i] = 0; + } + dnrState.done = 0; + GetCurrentProcess(&(dnrState.psn)); + err = StrToAddr((char*)name, &dnrState.hostInfo, resultUPP, (Ptr) &dnrState); + if (err == cacheFault) { + while (!dnrState.done) { + WaitNextEvent(0, &dummy, 1, NULL); + } + } + + /* + * For some reason MacTcp may return a cachFault a second time via + * the hostinfo block. This seems to be a bug in MacTcp. In this case + * we run StrToAddr again - which seems to then work just fine. + */ + + if (dnrState.hostInfo.rtnCode == cacheFault) { + dnrState.done = 0; + err = StrToAddr((char*)name, &dnrState.hostInfo, resultUPP, (Ptr) &dnrState); + if (err == cacheFault) { + while (!dnrState.done) { + WaitNextEvent(0, &dummy, 1, NULL); + } + } + } + + if (dnrState.hostInfo.rtnCode == noErr) { + *address = dnrState.hostInfo.addr[0]; + } + + return dnrState.hostInfo.rtnCode; +} + +/* + *---------------------------------------------------------------------- + * + * IOCompletionRoutine -- + * + * This function is called when an asynchronous socket operation + * completes. Since this routine runs as an interrupt handler, + * it will simply set state to tell the notifier that this socket + * is now ready for action. Note that this function is running at + * interupt time and can't allocate memory or do much else except + * set state. + * + * Results: + * None. + * + * Side effects: + * Sets some state in the socket state. May also wake the process + * if we are not currently running. + * + *---------------------------------------------------------------------- + */ + +static void +IOCompletionRoutine( + TCPiopb *pbPtr) /* Tcp parameter block. */ +{ + TcpState *statePtr; + + if (pbPtr->csCode == TCPSend) { + statePtr = (TcpState *) pbPtr->csParam.send.userDataPtr; + } else { + statePtr = (TcpState *) pbPtr->csParam.open.userDataPtr; + } + + /* + * Always wake the process in case it's in WaitNextEvent. + * If an error has a occured - just return. We will deal + * with the problem later. + */ + + WakeUpProcess(&statePtr->psn); + if (pbPtr->ioResult != noErr) { + return; + } + + if (statePtr->flags & TCP_ASYNC_CONNECT) { + statePtr->flags &= ~TCP_ASYNC_CONNECT; + statePtr->flags |= TCP_CONNECTED; + statePtr->checkMask |= TCL_READABLE & TCL_WRITABLE; + } else if (statePtr->flags & TCP_LISTENING) { + if (statePtr->port == 0) { + Debugger(); + } + statePtr->flags &= ~TCP_LISTENING; + statePtr->flags |= TCP_LISTEN_CONNECT; + statePtr->checkMask |= TCL_READABLE; + } else if (statePtr->flags & TCP_WRITING) { + statePtr->flags &= ~TCP_WRITING; + statePtr->checkMask |= TCL_WRITABLE; + if (!(statePtr->flags & TCP_CONNECTED)) { + InitMacTCPParamBlock(&statePtr->pb, TCPClose); + statePtr->pb.tcpStream = statePtr->tcpStream; + statePtr->pb.ioCompletion = closeUPP; + statePtr->pb.csParam.close.userDataPtr = (Ptr) statePtr; + if (PBControlAsync((ParmBlkPtr) &statePtr->pb) != noErr) { + statePtr->flags |= TCP_RELEASE; + } + } + } +} + +/* + *---------------------------------------------------------------------- + * + * GetLocalAddress -- + * + * Get the IP address for this machine. The result is cached so + * the result is returned quickly after the first call. + * + * Results: + * Macintosh error code. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static OSErr +GetLocalAddress( + unsigned long *addr) /* Returns host IP address. */ +{ + struct GetAddrParamBlock pBlock; + OSErr err = noErr; + static unsigned long localAddress = 0; + + if (localAddress == 0) { + memset(&pBlock, 0, sizeof(pBlock)); + pBlock.ioResult = 1; + pBlock.csCode = ipctlGetAddr; + pBlock.ioCRefNum = driverRefNum; + err = PBControlSync((ParmBlkPtr) &pBlock); + + if (err != noErr) { + return err; + } + localAddress = pBlock.ourAddress; + } + + *addr = localAddress; + return noErr; +} + +/* + *---------------------------------------------------------------------- + * + * GetBufferSize -- + * + * Get the appropiate buffer size for our machine & network. This + * value will be used by the rest of Tcl & the MacTcp driver for + * the size of its buffers. If out method for determining the + * optimal buffer size fails for any reason - we return a + * reasonable default. + * + * Results: + * Size of optimal buffer in bytes. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static long +GetBufferSize() +{ + UDPiopb iopb; + OSErr err = noErr; + long bufferSize; + + memset(&iopb, 0, sizeof(iopb)); + err = GetLocalAddress(&iopb.csParam.mtu.remoteHost); + if (err != noErr) { + return CHANNEL_BUF_SIZE; + } + iopb.ioCRefNum = driverRefNum; + iopb.csCode = UDPMaxMTUSize; + err = PBControlSync((ParmBlkPtr)&iopb); + if (err != noErr) { + return CHANNEL_BUF_SIZE; + } + bufferSize = (iopb.csParam.mtu.mtuSize * 4) + 1024; + if (bufferSize < CHANNEL_BUF_SIZE) { + bufferSize = CHANNEL_BUF_SIZE; + } + return bufferSize; +} + +/* + *---------------------------------------------------------------------- + * + * TclSockGetPort -- + * + * Maps from a string, which could be a service name, to a port. + * Used by socket creation code to get port numbers and resolve + * registered service names to port numbers. + * + * Results: + * A standard Tcl result. On success, the port number is + * returned in portPtr. On failure, an error message is left in + * the interp's result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TclSockGetPort( + Tcl_Interp *interp, /* Interp for error messages. */ + char *string, /* Integer or service name */ + char *proto, /* "tcp" or "udp", typically - + * ignored on Mac - assumed to be tcp */ + int *portPtr) /* Return port number */ +{ + PortInfo *portInfoPtr = NULL; + + if (Tcl_GetInt(interp, string, portPtr) == TCL_OK) { + if (*portPtr > 0xFFFF) { + Tcl_AppendResult(interp, "couldn't open socket: port number too high", + (char *) NULL); + return TCL_ERROR; + } + if (*portPtr < 0) { + Tcl_AppendResult(interp, "couldn't open socket: negative port number", + (char *) NULL); + return TCL_ERROR; + } + return TCL_OK; + } + for (portInfoPtr = portServices; portInfoPtr->name != NULL; portInfoPtr++) { + if (!strcmp(portInfoPtr->name, string)) { + break; + } + } + if (portInfoPtr != NULL && portInfoPtr->name != NULL) { + *portPtr = portInfoPtr->port; + Tcl_ResetResult(interp); + return TCL_OK; + } + + return TCL_ERROR; +} + +/* + *---------------------------------------------------------------------- + * + * ClearZombieSockets -- + * + * This procedure looks through the socket list and removes the + * first stream it finds that is ready for release. This procedure + * should be called before we ever try to create new Tcp streams + * to ensure we can least allocate one stream. + * + * Results: + * None. + * + * Side effects: + * Tcp streams may be released. + * + *---------------------------------------------------------------------- + */ + +static void +ClearZombieSockets() +{ + TcpState *statePtr; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + for (statePtr = tsdPtr->socketList; statePtr != NULL; + statePtr = statePtr->nextPtr) { + if (statePtr->flags & TCP_RELEASE) { + SocketFreeProc(statePtr); + return; + } + } +} + + +/* + *---------------------------------------------------------------------- + * + * NotifyRoutine -- + * + * This routine does nothing currently, and is not being used. But + * it is useful if you want to experiment with what MacTCP thinks that + * it is doing... + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +pascal void NotifyRoutine ( + StreamPtr tcpStream, + unsigned short eventCode, + Ptr userDataPtr, + unsigned short terminReason, + struct ICMPReport *icmpMsg) +{ + StreamPtr localTcpStream; + unsigned short localEventCode; + unsigned short localTerminReason; + struct ICMPReport localIcmpMsg; + + localTcpStream = tcpStream; + localEventCode = eventCode; + localTerminReason = terminReason; + localIcmpMsg = *icmpMsg; + +} + +/* + *---------------------------------------------------------------------- + * + * TclpCutSockChannel -- + * + * Remove any thread local refs to this channel. See + * Tcl_CutChannel for more info. + * + * Results: + * None. + * + * Side effects: + * Changes thread local list of valid channels. + * + *---------------------------------------------------------------------- + */ + +void +TclpCutSockChannel(chan) + Tcl_Channel chan; +{ + ThreadSpecificData *tsdPtr; + TcpState *infoPtr; + TcpState **nextPtrPtr; + int removed = 0; + + if (Tcl_GetChannelType(chan) != &tcpChannelType) + return; + + tsdPtr = TCL_TSD_INIT(&dataKey); + infoPtr = (TcpState *) Tcl_GetChannelInstanceData (chan); + + for (nextPtrPtr = &(tsdPtr->socketList); (*nextPtrPtr) != NULL; + nextPtrPtr = &((*nextPtrPtr)->nextPtr)) { + if ((*nextPtrPtr) == infoPtr) { + (*nextPtrPtr) = infoPtr->nextPtr; + removed = 1; + break; + } + } + + /* + * This could happen if the channel was created in one thread + * and then moved to another without updating the thread + * local data in each thread. + */ + + if (!removed) + Tcl_Panic("file info ptr not on thread channel list"); + return; +} + +/* + *---------------------------------------------------------------------- + * + * TclpSpliceSockChannel -- + * + * Insert thread local ref for this channel. + * Tcl_SpliceChannel for more info. + * + * Results: + * None. + * + * Side effects: + * Changes thread local list of valid channels. + * + *---------------------------------------------------------------------- + */ + +void +TclpSpliceSockChannel(chan) + Tcl_Channel chan; +{ + ThreadSpecificData *tsdPtr; + TcpState *infoPtr; + + if (Tcl_GetChannelType(chan) != &tcpChannelType) + return; + + InitSockets (); + + tsdPtr = TCL_TSD_INIT(&dataKey); + infoPtr = (TcpState *) Tcl_GetChannelInstanceData (chan); + + infoPtr->nextPtr = tsdPtr->socketList; + tsdPtr->socketList = infoPtr; +} + diff --git a/mac/tclMacTclCode.r b/mac/tclMacTclCode.r new file mode 100644 index 0000000..13b23e2 --- /dev/null +++ b/mac/tclMacTclCode.r @@ -0,0 +1,37 @@ +/* + * tclMacTclCode.r -- + * + * This file creates resources from the Tcl code that is + * usually stored in the TCL_LiBRARY + * + * Copyright (c) 1996-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * SCCS: @(#) tclMacTclCode.r 1.1 98/01/21 22:22:38 + */ + +#include <Types.r> +#include <SysTypes.r> + +#define TCL_LIBRARY_RESOURCES 2000 + +/* + * The mechanisim below loads Tcl source into the resource fork of the + * application. The example below creates a TEXT resource named + * "Init" from the file "init.tcl". This allows applications to use + * Tcl to define the behavior of the application without having to + * require some predetermined file structure - all needed Tcl "files" + * are located within the application. To source a file for the + * resource fork the source command has been modified to support + * sourcing from resources. In the below case "source -rsrc {Init}" + * will load the TEXT resource named "Init". + */ + +read 'TEXT' (TCL_LIBRARY_RESOURCES, "init", purgeable) "::library:init.tcl"; +read 'TEXT' (TCL_LIBRARY_RESOURCES + 1, "auto", purgeable) "::library:auto.tcl"; +read 'TEXT' (TCL_LIBRARY_RESOURCES + 2, "package", purgeable,preload) "::library:package.tcl"; +read 'TEXT' (TCL_LIBRARY_RESOURCES + 3, "history", purgeable) "::library:history.tcl"; +read 'TEXT' (TCL_LIBRARY_RESOURCES + 4, "word", purgeable,preload) "::library:word.tcl"; +read 'TEXT' (TCL_LIBRARY_RESOURCES + 5, "parray", purgeable,preload) "::library:parray.tcl"; diff --git a/mac/tclMacTest.c b/mac/tclMacTest.c new file mode 100644 index 0000000..58154e3 --- /dev/null +++ b/mac/tclMacTest.c @@ -0,0 +1,213 @@ +/* + * tclMacTest.c -- + * + * Contains commands for platform specific tests for + * the Macintosh platform. + * + * Copyright (c) 1996 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacTest.c,v 1.6 2002/10/09 11:54:42 das Exp $ + */ + +#define TCL_TEST +#define USE_COMPAT_CONST +#include "tclInt.h" +#include "tclMacInt.h" +#include "tclMacPort.h" +#include "Files.h" +#include <Errors.h> +#include <Resources.h> +#include <Script.h> +#include <Strings.h> +#include <FSpCompat.h> + +/* + * Forward declarations of procedures defined later in this file: + */ + +int TclplatformtestInit _ANSI_ARGS_((Tcl_Interp *interp)); +static int DebuggerCmd _ANSI_ARGS_((ClientData dummy, + Tcl_Interp *interp, int argc, CONST char **argv)); +static int WriteTextResource _ANSI_ARGS_((ClientData dummy, + Tcl_Interp *interp, int argc, CONST char **argv)); + + +/* + *---------------------------------------------------------------------- + * + * TclplatformtestInit -- + * + * Defines commands that test platform specific functionality for + * Unix platforms. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * Defines new commands. + * + *---------------------------------------------------------------------- + */ + +int +TclplatformtestInit( + Tcl_Interp *interp) /* Interpreter to add commands to. */ +{ + /* + * Add commands for platform specific tests on MacOS here. + */ + + Tcl_CreateCommand(interp, "debugger", DebuggerCmd, + (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); + Tcl_CreateCommand(interp, "testWriteTextResource", WriteTextResource, + (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * DebuggerCmd -- + * + * This procedure simply calls the low level debugger. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +DebuggerCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Not used. */ + int argc, /* Not used. */ + CONST char **argv) /* Not used. */ +{ + Debugger(); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * WriteTextResource -- + * + * This procedure will write a text resource out to the + * application or a given file. The format for this command is + * textwriteresource + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +WriteTextResource( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int argc, /* Number of arguments. */ + CONST char **argv) /* Argument strings. */ +{ + char *errNum = "wrong # args: "; + char *errBad = "bad argument: "; + char *errStr; + CONST char *fileName = NULL, *rsrcName = NULL; + CONST char *data = NULL; + int rsrcID = -1, i, protectIt = 0; + short fileRef = -1; + OSErr err; + Handle dataHandle; + Str255 resourceName; + FSSpec fileSpec; + + /* + * Process the arguments. + */ + for (i = 1 ; i < argc ; i++) { + if (!strcmp(argv[i], "-rsrc")) { + rsrcName = argv[i + 1]; + i++; + } else if (!strcmp(argv[i], "-rsrcid")) { + rsrcID = atoi(argv[i + 1]); + i++; + } else if (!strcmp(argv[i], "-file")) { + fileName = argv[i + 1]; + i++; + } else if (!strcmp(argv[i], "-protected")) { + protectIt = 1; + } else { + data = argv[i]; + } + } + + if ((rsrcName == NULL && rsrcID < 0) || + (fileName == NULL) || (data == NULL)) { + errStr = errBad; + goto sourceFmtErr; + } + + /* + * Open the resource file. + */ + err = FSpLocationFromPath(strlen(fileName), fileName, &fileSpec); + if (!(err == noErr || err == fnfErr)) { + Tcl_AppendResult(interp, "couldn't validate file name", (char *) NULL); + return TCL_ERROR; + } + + if (err == fnfErr) { + FSpCreateResFile(&fileSpec, 'WIsH', 'rsrc', smSystemScript); + } + fileRef = FSpOpenResFile(&fileSpec, fsRdWrPerm); + if (fileRef == -1) { + Tcl_AppendResult(interp, "couldn't open resource file", (char *) NULL); + return TCL_ERROR; + } + + UseResFile(fileRef); + + /* + * Prepare data needed to create resource. + */ + if (rsrcID < 0) { + rsrcID = UniqueID('TEXT'); + } + + strcpy((char *) resourceName, rsrcName); + c2pstr((char *) resourceName); + + dataHandle = NewHandle(strlen(data)); + HLock(dataHandle); + strcpy(*dataHandle, data); + HUnlock(dataHandle); + + /* + * Add the resource to the file and close it. + */ + AddResource(dataHandle, 'TEXT', rsrcID, resourceName); + + UpdateResFile(fileRef); + if (protectIt) { + SetResAttrs(Get1Resource('TEXT', rsrcID), resProtected); + } + + CloseResFile(fileRef); + return TCL_OK; + + sourceFmtErr: + Tcl_AppendResult(interp, errStr, "error in \"", argv[0], "\"", + (char *) NULL); + return TCL_ERROR; +} diff --git a/mac/tclMacThrd.c b/mac/tclMacThrd.c new file mode 100644 index 0000000..4d98d9c --- /dev/null +++ b/mac/tclMacThrd.c @@ -0,0 +1,871 @@ +/* + * tclMacThrd.c -- + * + * This file implements the Mac-specific thread support. + * + * Copyright (c) 1991-1994 The Regents of the University of California. + * Copyright (c) 1994-1998 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * SCCS: @(#) tclMacThrd.c 1.2 98/02/23 16:48:07 + */ + +#include "tclInt.h" +#include "tclPort.h" +#include "tclMacInt.h" +#include <Threads.h> +#include <Gestalt.h> + +#define TCL_MAC_THRD_DEFAULT_STACK (256*1024) + + +typedef struct TclMacThrdData { + ThreadID threadID; + VOID *data; + struct TclMacThrdData *next; +} TclMacThrdData; + +/* + * This is an array of the Thread Data Keys. It is a process-wide table. + * Its size is originally set to 32, but it can grow if needed. + */ + +static TclMacThrdData **tclMacDataKeyArray; +#define TCL_MAC_INITIAL_KEYSIZE 32 + +/* + * These two bits of data store the current maximum number of keys + * and the keyCounter (which is the number of occupied slots in the + * KeyData array. + * + */ + +static int maxNumKeys = 0; +static int keyCounter = 0; + +/* + * Prototypes for functions used only in this file + */ + +TclMacThrdData *GetThreadDataStruct(Tcl_ThreadDataKey keyVal); +TclMacThrdData *RemoveThreadDataStruct(Tcl_ThreadDataKey keyVal); + +/* + * Note: The race evoked by the emulation layer for joinable threads + * (see ../win/tclWinThrd.c) cannot occur on this platform due to + * the cooperative implementation of multithreading. + */ + +/* + *---------------------------------------------------------------------- + * + * TclMacHaveThreads -- + * + * Do we have the Thread Manager? + * + * Results: + * 1 if the ThreadManager is present, 0 otherwise. + * + * Side effects: + * If this is the first time this is called, the return is cached. + * + *---------------------------------------------------------------------- + */ + +int +TclMacHaveThreads(void) +{ + static initialized = false; + static int tclMacHaveThreads = false; + long response = 0; + OSErr err = noErr; + + if (!initialized) { + err = Gestalt(gestaltThreadMgrAttr, &response); + if (err == noErr) { + tclMacHaveThreads = response | (1 << gestaltThreadMgrPresent); + } + } + + return tclMacHaveThreads; +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_CreateThread -- + * + * This procedure creates a new thread. + * + * Results: + * TCL_OK if the thread could be created. The thread ID is + * returned in a parameter. + * + * Side effects: + * A new thread is created. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_CreateThread(idPtr, proc, clientData, stackSize, flags) + Tcl_ThreadId *idPtr; /* Return, the ID of the thread */ + Tcl_ThreadCreateProc proc; /* Main() function of the thread */ + ClientData clientData; /* The one argument to Main() */ + int stackSize; /* Size of stack for the new thread */ + int flags; /* Flags controlling behaviour of + * the new thread */ +{ + if (!TclMacHaveThreads()) { + return TCL_ERROR; + } + + if (stackSize == TCL_THREAD_STACK_DEFAULT) { + stackSize = TCL_MAC_THRD_DEFAULT_STACK; + } + +#if TARGET_CPU_68K && TARGET_RT_MAC_CFM + { + ThreadEntryProcPtr entryProc; + entryProc = NewThreadEntryUPP(proc); + + NewThread(kCooperativeThread, entryProc, (void *) clientData, + stackSize, kCreateIfNeeded, NULL, (ThreadID *) idPtr); + } +#else + NewThread(kCooperativeThread, proc, (void *) clientData, + stackSize, kCreateIfNeeded, NULL, (ThreadID *) idPtr); +#endif + if ((ThreadID) *idPtr == kNoThreadID) { + return TCL_ERROR; + } else { + if (flags & TCL_THREAD_JOINABLE) { + TclRememberJoinableThread (*idPtr); + } + + return TCL_OK; + } + +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_JoinThread -- + * + * This procedure waits upon the exit of the specified thread. + * + * Results: + * TCL_OK if the wait was successful, TCL_ERROR else. + * + * Side effects: + * The result area is set to the exit code of the thread we + * waited upon. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_JoinThread(threadId, result) + Tcl_ThreadId threadId; /* Id of the thread to wait upon */ + int* result; /* Reference to the storage the result + * of the thread we wait upon will be + * written into. */ +{ + if (!TclMacHaveThreads()) { + return TCL_ERROR; + } + + return TclJoinThread (threadId, result); +} + +/* + *---------------------------------------------------------------------- + * + * TclpThreadExit -- + * + * This procedure terminates the current thread. + * + * Results: + * None. + * + * Side effects: + * This procedure terminates the current thread. + * + *---------------------------------------------------------------------- + */ + +void +TclpThreadExit(status) + int status; +{ + ThreadID curThread; + + if (!TclMacHaveThreads()) { + return; + } + + GetCurrentThread(&curThread); + TclSignalExitThread ((Tcl_ThreadId) curThread, status); + + DisposeThread(curThread, NULL, false); +} + + +/* + *---------------------------------------------------------------------- + * + * Tcl_GetCurrentThread -- + * + * This procedure returns the ID of the currently running thread. + * + * Results: + * A thread ID. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_ThreadId +Tcl_GetCurrentThread() +{ +#ifdef TCL_THREADS + ThreadID curThread; + + if (!TclMacHaveThreads()) { + return (Tcl_ThreadId) 0; + } else { + GetCurrentThread(&curThread); + return (Tcl_ThreadId) curThread; + } +#else + return (Tcl_ThreadId) 0; +#endif +} + + +/* + *---------------------------------------------------------------------- + * + * TclpInitLock + * + * This procedure is used to grab a lock that serializes initialization + * and finalization of Tcl. On some platforms this may also initialize + * the mutex used to serialize creation of more mutexes and thread + * local storage keys. + * + * Results: + * None. + * + * Side effects: + * Acquire the initialization mutex. + * + *---------------------------------------------------------------------- + */ + +void +TclpInitLock() +{ +#ifdef TCL_THREADS + /* There is nothing to do on the Mac. */; +#endif +} + + +/* + *---------------------------------------------------------------------- + * + * TclpInitUnlock + * + * This procedure is used to release a lock that serializes initialization + * and finalization of Tcl. + * + * Results: + * None. + * + * Side effects: + * Release the initialization mutex. + * + *---------------------------------------------------------------------- + */ + +void +TclpInitUnlock() +{ +#ifdef TCL_THREADS + /* There is nothing to do on the Mac */; +#endif +} + +/* + *---------------------------------------------------------------------- + * + * TclpMasterLock + * + * This procedure is used to grab a lock that serializes creation + * and finalization of serialization objects. This interface is + * only needed in finalization; it is hidden during + * creation of the objects. + * + * This lock must be different than the initLock because the + * initLock is held during creation of syncronization objects. + * + * Results: + * None. + * + * Side effects: + * Acquire the master mutex. + * + *---------------------------------------------------------------------- + */ + +void +TclpMasterLock() +{ +#ifdef TCL_THREADS + /* There is nothing to do on the Mac */; +#endif +} + + +/* + *---------------------------------------------------------------------- + * + * TclpMasterUnlock + * + * This procedure is used to release a lock that serializes creation + * and finalization of synchronization objects. + * + * Results: + * None. + * + * Side effects: + * Release the master mutex. + * + *---------------------------------------------------------------------- + */ + +void +TclpMasterUnlock() +{ +#ifdef TCL_THREADS + /* There is nothing to do on the Mac */ +#endif +} + + +/* + *---------------------------------------------------------------------- + * + * Tcl_GetAllocMutex + * + * This procedure returns a pointer to a statically initialized + * mutex for use by the memory allocator. The alloctor must + * use this lock, because all other locks are allocated... + * + * Results: + * A pointer to a mutex that is suitable for passing to + * Tcl_MutexLock and Tcl_MutexUnlock. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +Tcl_Mutex * +Tcl_GetAllocMutex() +{ + /* There is nothing to do on the Mac */ + return NULL; +} + +#ifdef TCL_THREADS + +/* + *---------------------------------------------------------------------- + * + * Tcl_MutexLock -- + * + * This procedure is invoked to lock a mutex. This procedure + * handles initializing the mutex, if necessary. The caller + * can rely on the fact that Tcl_Mutex is an opaque pointer. + * This routine will change that pointer from NULL after first use. + * + * Results: + * None. + * + * Side effects: + * May block the current thread. The mutex is aquired when + * this returns. Will allocate memory for a pthread_mutex_t + * and initialize this the first time this Tcl_Mutex is used. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_MutexLock(mutexPtr) + Tcl_Mutex *mutexPtr; /* Really (pthread_mutex_t **) */ +{ +/* There is nothing to do on the Mac */ +} + + +/* + *---------------------------------------------------------------------- + * + * TclpMutexUnlock -- + * + * This procedure is invoked to unlock a mutex. The mutex must + * have been locked by Tcl_MutexLock. + * + * Results: + * None. + * + * Side effects: + * The mutex is released when this returns. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_MutexUnlock(mutexPtr) + Tcl_Mutex *mutexPtr; /* Really (pthread_mutex_t **) */ +{ +/* There is nothing to do on the Mac */ +} + + +/* + *---------------------------------------------------------------------- + * + * TclpFinalizeMutex -- + * + * This procedure is invoked to clean up one mutex. This is only + * safe to call at the end of time. + * + * This assumes the Master Lock is held. + * + * Results: + * None. + * + * Side effects: + * The mutex list is deallocated. + * + *---------------------------------------------------------------------- + */ + +void +TclpFinalizeMutex(mutexPtr) + Tcl_Mutex *mutexPtr; +{ +/* There is nothing to do on the Mac */ +} + + +/* + *---------------------------------------------------------------------- + * + * TclpThreadDataKeyInit -- + * + * This procedure initializes a thread specific data block key. + * Each thread has table of pointers to thread specific data. + * all threads agree on which table entry is used by each module. + * this is remembered in a "data key", that is just an index into + * this table. To allow self initialization, the interface + * passes a pointer to this key and the first thread to use + * the key fills in the pointer to the key. The key should be + * a process-wide static. + * + * There is no system-wide support for thread specific data on the + * Mac. So we implement this as an array of pointers. The keys are + * allocated sequentially, and each key maps to a slot in the table. + * The table element points to a linked list of the instances of + * the data for each thread. + * + * Results: + * None. + * + * Side effects: + * Will bump the key counter if this is the first time this key + * has been initialized. May grow the DataKeyArray if that is + * necessary. + * + *---------------------------------------------------------------------- + */ + +void +TclpThreadDataKeyInit(keyPtr) + Tcl_ThreadDataKey *keyPtr; /* Identifier for the data chunk, + * really (pthread_key_t **) */ +{ + + if (*keyPtr == NULL) { + keyCounter += 1; + *keyPtr = (Tcl_ThreadDataKey) keyCounter; + if (keyCounter > maxNumKeys) { + TclMacThrdData **newArray; + int i, oldMax = maxNumKeys; + + maxNumKeys = maxNumKeys + TCL_MAC_INITIAL_KEYSIZE; + + newArray = (TclMacThrdData **) + ckalloc(maxNumKeys * sizeof(TclMacThrdData *)); + + for (i = 0; i < oldMax; i++) { + newArray[i] = tclMacDataKeyArray[i]; + } + for (i = oldMax; i < maxNumKeys; i++) { + newArray[i] = NULL; + } + + if (tclMacDataKeyArray != NULL) { + ckfree((char *) tclMacDataKeyArray); + } + tclMacDataKeyArray = newArray; + + } + /* TclRememberDataKey(keyPtr); */ + } +} + +/* + *---------------------------------------------------------------------- + * + * TclpThreadDataKeyGet -- + * + * This procedure returns a pointer to a block of thread local storage. + * + * Results: + * A thread-specific pointer to the data structure, or NULL + * if the memory has not been assigned to this key for this thread. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +VOID * +TclpThreadDataKeyGet(keyPtr) + Tcl_ThreadDataKey *keyPtr; /* Identifier for the data chunk, + * really (pthread_key_t **) */ +{ + TclMacThrdData *dataPtr; + + dataPtr = GetThreadDataStruct(*keyPtr); + + if (dataPtr == NULL) { + return NULL; + } else { + return dataPtr->data; + } +} + + +/* + *---------------------------------------------------------------------- + * + * TclpThreadDataKeySet -- + * + * This procedure sets the pointer to a block of thread local storage. + * + * Results: + * None. + * + * Side effects: + * Sets up the thread so future calls to TclpThreadDataKeyGet with + * this key will return the data pointer. + * + *---------------------------------------------------------------------- + */ + +void +TclpThreadDataKeySet(keyPtr, data) + Tcl_ThreadDataKey *keyPtr; /* Identifier for the data chunk, + * really (pthread_key_t **) */ + VOID *data; /* Thread local storage */ +{ + TclMacThrdData *dataPtr; + ThreadID curThread; + + dataPtr = GetThreadDataStruct(*keyPtr); + + /* + * Is it legal to reset the thread data like this? + * And if so, who owns the memory? + */ + + if (dataPtr != NULL) { + dataPtr->data = data; + } else { + dataPtr = (TclMacThrdData *) ckalloc(sizeof(TclMacThrdData)); + GetCurrentThread(&curThread); + dataPtr->threadID = curThread; + dataPtr->data = data; + dataPtr->next = tclMacDataKeyArray[(int) *keyPtr - 1]; + tclMacDataKeyArray[(int) *keyPtr - 1] = dataPtr; + } +} + +/* + *---------------------------------------------------------------------- + * + * TclpFinalizeThreadData -- + * + * This procedure cleans up the thread-local storage. This is + * called once for each thread. + * + * Results: + * None. + * + * Side effects: + * Frees up all thread local storage. + * + *---------------------------------------------------------------------- + */ + +void +TclpFinalizeThreadData(keyPtr) + Tcl_ThreadDataKey *keyPtr; +{ + TclMacThrdData *dataPtr; + + if (*keyPtr != NULL) { + dataPtr = RemoveThreadDataStruct(*keyPtr); + + if ((dataPtr != NULL) && (dataPtr->data != NULL)) { + ckfree((char *) dataPtr->data); + ckfree((char *) dataPtr); + } + } +} + +/* + *---------------------------------------------------------------------- + * + * TclpFinalizeThreadDataKey -- + * + * This procedure is invoked to clean up one key. This is a + * process-wide storage identifier. The thread finalization code + * cleans up the thread local storage itself. + * + * On the Mac, there is really nothing to do here, since the key + * is just an array index. But we set the key to 0 just in case + * someone else is relying on that. + * + * Results: + * None. + * + * Side effects: + * The keyPtr value is set to 0. + * + *---------------------------------------------------------------------- + */ + +void +TclpFinalizeThreadDataKey(keyPtr) + Tcl_ThreadDataKey *keyPtr; +{ + ckfree((char *) tclMacDataKeyArray[(int) *keyPtr - 1]); + tclMacDataKeyArray[(int) *keyPtr - 1] = NULL; + *keyPtr = NULL; +} + + +/* + *---------------------------------------------------------------------- + * + * GetThreadDataStruct -- + * + * This procedure gets the data structure corresponding to + * keyVal for the current process. + * + * Results: + * The requested key data. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +TclMacThrdData * +GetThreadDataStruct(keyVal) + Tcl_ThreadDataKey keyVal; +{ + ThreadID curThread; + TclMacThrdData *dataPtr; + + /* + * The keyPtr will only be greater than keyCounter is someone + * has passed us a key without getting the value from + * TclpInitDataKey. + */ + + if ((int) keyVal <= 0) { + return NULL; + } else if ((int) keyVal > keyCounter) { + Tcl_Panic("illegal data key value"); + } + + GetCurrentThread(&curThread); + + for (dataPtr = tclMacDataKeyArray[(int) keyVal - 1]; dataPtr != NULL; + dataPtr = dataPtr->next) { + if (dataPtr->threadID == curThread) { + break; + } + } + + return dataPtr; +} + + +/* + *---------------------------------------------------------------------- + * + * RemoveThreadDataStruct -- + * + * This procedure removes the data structure corresponding to + * keyVal for the current process from the list kept for keyVal. + * + * Results: + * The requested key data is removed from the list, and a pointer + * to it is returned. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +TclMacThrdData * +RemoveThreadDataStruct(keyVal) + Tcl_ThreadDataKey keyVal; +{ + ThreadID curThread; + TclMacThrdData *dataPtr, *prevPtr; + + + if ((int) keyVal <= 0) { + return NULL; + } else if ((int) keyVal > keyCounter) { + Tcl_Panic("illegal data key value"); + } + + GetCurrentThread(&curThread); + + for (dataPtr = tclMacDataKeyArray[(int) keyVal - 1], prevPtr = NULL; + dataPtr != NULL; + prevPtr = dataPtr, dataPtr = dataPtr->next) { + if (dataPtr->threadID == curThread) { + break; + } + } + + if (dataPtr == NULL) { + /* No body */ + } else if ( prevPtr == NULL) { + tclMacDataKeyArray[(int) keyVal - 1] = dataPtr->next; + } else { + prevPtr->next = dataPtr->next; + } + + return dataPtr; +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_ConditionWait -- + * + * This procedure is invoked to wait on a condition variable. + * On the Mac, mutexes are no-ops, and we just yield. After + * all, it is the application's job to loop till the condition + * variable is changed... + * + * + * Results: + * None. + * + * Side effects: + * Will block the current thread till someone else yields. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_ConditionWait(condPtr, mutexPtr, timePtr) + Tcl_Condition *condPtr; /* Really (pthread_cond_t **) */ + Tcl_Mutex *mutexPtr; /* Really (pthread_mutex_t **) */ + Tcl_Time *timePtr; /* Timeout on waiting period */ +{ + if (TclMacHaveThreads()) { + YieldToAnyThread(); + } +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_ConditionNotify -- + * + * This procedure is invoked to signal a condition variable. + * + * The mutex must be held during this call to avoid races, + * but this interface does not enforce that. + * + * Results: + * None. + * + * Side effects: + * May unblock another thread. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_ConditionNotify(condPtr) + Tcl_Condition *condPtr; +{ + if (TclMacHaveThreads()) { + YieldToAnyThread(); + } +} + + +/* + *---------------------------------------------------------------------- + * + * TclpFinalizeCondition -- + * + * This procedure is invoked to clean up a condition variable. + * This is only safe to call at the end of time. + * + * This assumes the Master Lock is held. + * + * Results: + * None. + * + * Side effects: + * The condition variable is deallocated. + * + *---------------------------------------------------------------------- + */ + +void +TclpFinalizeCondition(condPtr) + Tcl_Condition *condPtr; +{ + /* Nothing to do on the Mac */ +} + + + +#endif /* TCL_THREADS */ + diff --git a/mac/tclMacThrd.h b/mac/tclMacThrd.h new file mode 100644 index 0000000..22f2c83 --- /dev/null +++ b/mac/tclMacThrd.h @@ -0,0 +1,20 @@ +/* + * tclUnixThrd.h -- + * + * This header file defines things for thread support. + * + * Copyright (c) 1998 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * SCCS: @(#) + */ + +#ifndef _TCLMACTHRD +#define _TCLMACTHRD + +#ifdef TCL_THREADS + +#endif /* TCL_THREADS */ +#endif /* _TCLMACTHRD */ diff --git a/mac/tclMacTime.c b/mac/tclMacTime.c new file mode 100644 index 0000000..d585ee7 --- /dev/null +++ b/mac/tclMacTime.c @@ -0,0 +1,436 @@ +/* + * tclMacTime.c -- + * + * Contains Macintosh specific versions of Tcl functions that + * obtain time values from the operating system. + * + * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacTime.c,v 1.8 2003/05/18 19:48:26 kennykb Exp $ + */ + +#include "tclInt.h" +#include "tclPort.h" +#include "tclMacInt.h" +#include <OSUtils.h> +#include <Timer.h> +#include <time.h> + +/* + * Static variables used by the Tcl_GetTime function. + */ + +static int initalized = false; +static unsigned long baseSeconds; +static UnsignedWide microOffset; + +static int gmt_initialized = false; +static long gmt_offset; +static int gmt_isdst; +TCL_DECLARE_MUTEX(gmtMutex) + +static int gmt_lastGetDateUseGMT = 0; + +typedef struct _TABLE { + char *name; + int type; + time_t value; +} TABLE; + + +#define HOUR(x) ((time_t) (3600 * x)) + +#define tZONE 0 +#define tDAYZONE 1 + + +/* + * inverse timezone table, adapted from tclDate.c by removing duplicates and + * adding some made up names for unusual daylight savings + */ +static TABLE invTimezoneTable[] = { + { "Z", -1, HOUR( 36) }, /* Unknown */ + { "GMT", tZONE, HOUR( 0) }, /* Greenwich Mean */ + { "BST", tDAYZONE, HOUR( 0) }, /* British Summer */ + { "WAT", tZONE, HOUR( 1) }, /* West Africa */ + { "WADST", tDAYZONE, HOUR( 1) }, /* West Africa Daylight*/ + { "AT", tZONE, HOUR( 2) }, /* Azores Daylight*/ + { "ADST", tDAYZONE, HOUR( 2) }, /* Azores */ + { "NFT", tZONE, HOUR( 7/2) }, /* Newfoundland */ + { "NDT", tDAYZONE, HOUR( 7/2) }, /* Newfoundland Daylight */ + { "AST", tZONE, HOUR( 4) }, /* Atlantic Standard */ + { "ADT", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */ + { "EST", tZONE, HOUR( 5) }, /* Eastern Standard */ + { "EDT", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */ + { "CST", tZONE, HOUR( 6) }, /* Central Standard */ + { "CDT", tDAYZONE, HOUR( 6) }, /* Central Daylight */ + { "MST", tZONE, HOUR( 7) }, /* Mountain Standard */ + { "MDT", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */ + { "PST", tZONE, HOUR( 8) }, /* Pacific Standard */ + { "PDT", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */ + { "YST", tZONE, HOUR( 9) }, /* Yukon Standard */ + { "YDT", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */ + { "HST", tZONE, HOUR(10) }, /* Hawaii Standard */ + { "HDT", tDAYZONE, HOUR(10) }, /* Hawaii Daylight */ + { "NT", tZONE, HOUR(11) }, /* Nome */ + { "NST", tDAYZONE, HOUR(11) }, /* Nome Daylight*/ + { "IDLW", tZONE, HOUR(12) }, /* International Date Line West */ + { "CET", tZONE, -HOUR( 1) }, /* Central European */ + { "CEST", tDAYZONE, -HOUR( 1) }, /* Central European Summer */ + { "EET", tZONE, -HOUR( 2) }, /* Eastern Europe, USSR Zone 1 */ + { "EEST", tDAYZONE, -HOUR( 2) }, /* Eastern Europe, USSR Zone 1 Daylight*/ + { "BT", tZONE, -HOUR( 3) }, /* Baghdad, USSR Zone 2 */ + { "BDST", tDAYZONE, -HOUR( 3) }, /* Baghdad, USSR Zone 2 Daylight*/ + { "IT", tZONE, -HOUR( 7/2) }, /* Iran */ + { "IDST", tDAYZONE, -HOUR( 7/2) }, /* Iran Daylight*/ + { "ZP4", tZONE, -HOUR( 4) }, /* USSR Zone 3 */ + { "ZP4S", tDAYZONE, -HOUR( 4) }, /* USSR Zone 3 */ + { "ZP5", tZONE, -HOUR( 5) }, /* USSR Zone 4 */ + { "ZP5S", tDAYZONE, -HOUR( 5) }, /* USSR Zone 4 */ + { "IST", tZONE, -HOUR(11/2) }, /* Indian Standard */ + { "ISDST", tDAYZONE, -HOUR(11/2) }, /* Indian Standard */ + { "ZP6", tZONE, -HOUR( 6) }, /* USSR Zone 5 */ + { "ZP6S", tDAYZONE, -HOUR( 6) }, /* USSR Zone 5 */ + { "WAST", tZONE, -HOUR( 7) }, /* West Australian Standard */ + { "WADT", tDAYZONE, -HOUR( 7) }, /* West Australian Daylight */ + { "JT", tZONE, -HOUR(15/2) }, /* Java (3pm in Cronusland!) */ + { "JDST", tDAYZONE, -HOUR(15/2) }, /* Java (3pm in Cronusland!) */ + { "CCT", tZONE, -HOUR( 8) }, /* China Coast, USSR Zone 7 */ + { "CCST", tDAYZONE, -HOUR( 8) }, /* China Coast, USSR Zone 7 */ + { "JST", tZONE, -HOUR( 9) }, /* Japan Standard, USSR Zone 8 */ + { "JSDST", tDAYZONE, -HOUR( 9) }, /* Japan Standard, USSR Zone 8 */ + { "CAST", tZONE, -HOUR(19/2) }, /* Central Australian Standard */ + { "CADT", tDAYZONE, -HOUR(19/2) }, /* Central Australian Daylight */ + { "EAST", tZONE, -HOUR(10) }, /* Eastern Australian Standard */ + { "EADT", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */ + { "NZT", tZONE, -HOUR(12) }, /* New Zealand */ + { "NZDT", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */ + { NULL } +}; + +/* + * Prototypes for procedures that are private to this file: + */ + +static void SubtractUnsignedWide _ANSI_ARGS_((UnsignedWide *x, + UnsignedWide *y, UnsignedWide *result)); + +/* + *----------------------------------------------------------------------------- + * + * TclpGetGMTOffset -- + * + * This procedure gets the offset seconds that needs to be _added_ to tcl time + * in seconds (i.e. GMT time) to get local time needed as input to various + * Mac OS APIs, to convert Mac OS API output to tcl time, _subtract_ this value. + * + * Results: + * Number of seconds separating GMT time and mac. + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +long +TclpGetGMTOffset() +{ + if (gmt_initialized == false) { + MachineLocation loc; + + Tcl_MutexLock(&gmtMutex); + ReadLocation(&loc); + gmt_offset = loc.u.gmtDelta & 0x00ffffff; + if (gmt_offset & 0x00800000) { + gmt_offset = gmt_offset | 0xff000000; + } + gmt_isdst=(loc.u.dlsDelta < 0); + gmt_initialized = true; + Tcl_MutexUnlock(&gmtMutex); + } + return (gmt_offset); +} + +/* + *----------------------------------------------------------------------------- + * + * TclpGetSeconds -- + * + * This procedure returns the number of seconds from the epoch. On + * the Macintosh the epoch is Midnight Jan 1, 1904. Unfortunatly, + * the Macintosh doesn't tie the epoch to a particular time zone. For + * Tcl we tie the epoch to GMT. This makes the time zone date parsing + * code work. The epoch for Mac-Tcl is: Midnight Jan 1, 1904 GMT. + * + * Results: + * Number of seconds from the epoch in GMT. + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +unsigned long +TclpGetSeconds() +{ + unsigned long seconds; + + GetDateTime(&seconds); + return (seconds - TclpGetGMTOffset() + tcl_mac_epoch_offset); +} + +/* + *----------------------------------------------------------------------------- + * + * TclpGetClicks -- + * + * This procedure returns a value that represents the highest resolution + * clock available on the system. There are no garantees on what the + * resolution will be. In Tcl we will call this value a "click". The + * start time is also system dependant. + * + * Results: + * Number of clicks from some start time. + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +unsigned long +TclpGetClicks() +{ + UnsignedWide micros; + + Microseconds(µs); + return micros.lo; +} + +/* + *---------------------------------------------------------------------- + * + * TclpGetTimeZone -- + * + * Get the current time zone. + * + * Results: + * The return value is the local time zone, measured in + * minutes away from GMT (-ve for east, +ve for west). + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TclpGetTimeZone ( + unsigned long currentTime) /* Ignored on Mac. */ +{ + long offset; + + /* + * Convert the Mac offset from seconds to minutes and + * add an hour if we have daylight savings time. + */ + offset = -TclpGetGMTOffset(); + offset /= 60; + if (gmt_isdst) { + offset += 60; + } + + return offset; +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_GetTime -- + * + * Gets the current system time in seconds and microseconds + * since the beginning of the epoch: 00:00 UCT, January 1, 1970. + * + * Results: + * Returns the current time (in the local timezone) in timePtr. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +Tcl_GetTime( + Tcl_Time *timePtr) /* Location to store time information. */ +{ + UnsignedWide micro; +#ifndef NO_LONG_LONG + long long *microPtr; +#endif + + if (initalized == false) { + GetDateTime(&baseSeconds); + /* + * Remove the local offset that ReadDateTime() adds. + */ + baseSeconds -= TclpGetGMTOffset() - tcl_mac_epoch_offset; + Microseconds(µOffset); + initalized = true; + } + + Microseconds(µ); + +#ifndef NO_LONG_LONG + microPtr = (long long *) µ + *microPtr -= *((long long *) µOffset); + timePtr->sec = baseSeconds + (*microPtr / 1000000); + timePtr->usec = *microPtr % 1000000; +#else + SubtractUnsignedWide(µ, µOffset, µ); + + /* + * This lovely computation is equal to: base + (micro / 1000000) + * For the .hi part the ratio of 0x100000000 / 1000000 has been + * reduced to avoid overflow. This computation certainly has + * problems as the .hi part gets large. However, your application + * would have to run for a long time to make that happen. + */ + + timePtr->sec = baseSeconds + (micro.lo / 1000000) + + (long) (micro.hi * ((double) 33554432.0 / 15625.0)); + timePtr->usec = micro.lo % 1000000; +#endif +} + +/* + *---------------------------------------------------------------------- + * + * TclpGetDate -- + * + * Converts raw seconds to a struct tm data structure. The + * returned time will be for Greenwich Mean Time if the useGMT flag + * is set. Otherwise, the returned time will be for the local + * time zone. This function is meant to be used as a replacement + * for localtime and gmtime which is broken on most ANSI libs + * on the Macintosh. + * + * Results: + * None. + * + * Side effects: + * The passed in struct tm data structure is modified. + * + *---------------------------------------------------------------------- + */ + +struct tm * +TclpGetDate( + TclpTime_t time, /* Time struct to fill. */ + int useGMT) /* True if date should reflect GNT time. */ +{ + const time_t *tp = (const time_t *)time; + DateTimeRec dtr; + unsigned long offset=0L; + static struct tm statictime; + static const short monthday[12] = + {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; + + if(useGMT) + SecondsToDate(*tp - tcl_mac_epoch_offset, &dtr); + else + SecondsToDate(*tp + TclpGetGMTOffset() - tcl_mac_epoch_offset, &dtr); + + statictime.tm_sec = dtr.second; + statictime.tm_min = dtr.minute; + statictime.tm_hour = dtr.hour; + statictime.tm_mday = dtr.day; + statictime.tm_mon = dtr.month - 1; + statictime.tm_year = dtr.year - 1900; + statictime.tm_wday = dtr.dayOfWeek - 1; + statictime.tm_yday = monthday[statictime.tm_mon] + + statictime.tm_mday - 1; + if (1 < statictime.tm_mon && !(statictime.tm_year & 3)) { + ++statictime.tm_yday; + } + if(useGMT) + statictime.tm_isdst = 0; + else + statictime.tm_isdst = gmt_isdst; + gmt_lastGetDateUseGMT=useGMT; /* hack to make TclpGetTZName below work */ + return(&statictime); +} + +/* + *---------------------------------------------------------------------- + * + * TclpGetTZName -- + * + * Gets the current timezone string. + * + * Results: + * Returns a pointer to a static string, or NULL on failure. + * The static string is in UTF-8 encoding. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +char * +TclpGetTZName(int dst) +{ + register TABLE *tp; + long zonevalue=-TclpGetGMTOffset(); + + if (gmt_isdst) + zonevalue += HOUR(1); + + if(gmt_lastGetDateUseGMT) /* hack: if last TclpGetDate was called */ + zonevalue=0; /* with useGMT==1 then we're using GMT */ + + for (tp = invTimezoneTable; tp->name; tp++) { + if ((tp->value == zonevalue) && (tp->type == dst)) break; + } + if(!tp->name) + tp = invTimezoneTable; /* default to unknown */ + + return tp->name; +} + +#ifdef NO_LONG_LONG +/* + *---------------------------------------------------------------------- + * + * SubtractUnsignedWide -- + * + * Subtracts one UnsignedWide value from another. + * + * Results: + * The subtracted value. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static void +SubtractUnsignedWide( + UnsignedWide *x, /* Ptr to wide int. */ + UnsignedWide *y, /* Ptr to wide int. */ + UnsignedWide *result) /* Ptr to result. */ +{ + result->hi = x->hi - y->hi; + if (x->lo < y->lo) { + result->hi--; + } + result->lo = x->lo - y->lo; +} +#endif diff --git a/mac/tclMacUnix.c b/mac/tclMacUnix.c new file mode 100644 index 0000000..81eb225 --- /dev/null +++ b/mac/tclMacUnix.c @@ -0,0 +1,425 @@ +/* + * tclMacUnix.c -- + * + * This file contains routines to implement several features + * available to the Unix implementation, but that require + * extra work to do on a Macintosh. These include routines + * Unix Tcl normally hands off to the Unix OS. + * + * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacUnix.c,v 1.5 2002/10/09 11:54:45 das Exp $ + */ + +#include <Files.h> +#include <Strings.h> +#include <TextUtils.h> +#include <Finder.h> +#include <FSpCompat.h> +#include <Aliases.h> +#include <Errors.h> + +#include "tclInt.h" +#include "tclMacInt.h" + +/* + * The following two Includes are from the More Files package + */ +#include "FileCopy.h" +#include "MoreFiles.h" +#include "MoreFilesExtras.h" + +/* + * The following may not be defined in some versions of + * MPW header files. + */ +#ifndef kIsInvisible +#define kIsInvisible 0x4000 +#endif +#ifndef kIsAlias +#define kIsAlias 0x8000 +#endif + +/* + * Missing error codes + */ +#define usageErr 500 +#define noSourceErr 501 +#define isDirErr 502 + + +/* + *---------------------------------------------------------------------- + * + * Tcl_EchoCmd -- + * + * Implements the TCL echo command: + * echo ?str ...? + * + * Results: + * Always returns TCL_OK. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_EchoCmd( + ClientData dummy, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int argc, /* Number of arguments. */ + CONST char **argv) /* Argument strings. */ +{ + Tcl_Channel chan; + int mode, result, i; + + chan = Tcl_GetChannel(interp, "stdout", &mode); + if (chan == (Tcl_Channel) NULL) { + return TCL_ERROR; + } + for (i = 1; i < argc; i++) { + result = Tcl_WriteChars(chan, argv[i], -1); + if (result < 0) { + Tcl_AppendResult(interp, "echo: ", Tcl_GetChannelName(chan), + ": ", Tcl_PosixError(interp), (char *) NULL); + return TCL_ERROR; + } + if (i < (argc - 1)) { + Tcl_WriteChars(chan, " ", -1); + } + } + Tcl_WriteChars(chan, "\n", -1); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_LsObjCmd -- + * + * This procedure is invoked to process the "ls" Tcl command. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ +int +Tcl_LsObjCmd( + ClientData dummy, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *CONST objv[]) /* Argument strings. */ +{ +#define STRING_LENGTH 80 +#define CR '\n' + int i, j; + int fieldLength, len = 0, maxLen = 0, perLine; + OSErr err; + CInfoPBRec paramBlock; + HFileInfo *hpb = (HFileInfo *)¶mBlock; + DirInfo *dpb = (DirInfo *)¶mBlock; + char theFile[256]; + char theLine[STRING_LENGTH + 2]; + int fFlag = false, pFlag = false, aFlag = false, lFlag = false, + cFlag = false, hFlag = false; + char *argv; + Tcl_Obj *newObjv[2], *resultObjPtr; + + /* + * Process command flags. End if argument doesn't start + * with a dash or is a dash by itself. The remaining arguments + * should be files. + */ + for (i = 1; i < objc; i++) { + argv = Tcl_GetString(objv[i]); + if (argv[0] != '-') { + break; + } + + if (!strcmp(argv, "-")) { + i++; + break; + } + + for (j = 1 ; argv[j] ; ++j) { + switch(argv[j]) { + case 'a': + case 'A': + aFlag = true; + break; + case '1': + cFlag = false; + break; + case 'C': + cFlag = true; + break; + case 'F': + fFlag = true; + break; + case 'H': + hFlag = true; + break; + case 'p': + pFlag = true; + break; + case 'l': + pFlag = false; + lFlag = true; + break; + default: + Tcl_AppendResult(interp, "error - unknown flag ", + "usage: ls -apCFHl1 ?files? ", NULL); + return TCL_ERROR; + } + } + } + + objv += i; + objc -= i; + + /* + * No file specifications means we search for all files. + * Glob will be doing most of the work. + */ + if (!objc) { + objc = 1; + newObjv[0] = Tcl_NewStringObj("*", -1); + newObjv[1] = NULL; + objv = newObjv; + } + + if (Tcl_GlobObjCmd(NULL, interp, objc + 1, objv - 1) != TCL_OK) { + Tcl_ResetResult(interp); + return TCL_ERROR; + } + + resultObjPtr = Tcl_GetObjResult(interp); + Tcl_IncrRefCount(resultObjPtr); + if (Tcl_ListObjGetElements(interp, resultObjPtr, &objc, (Tcl_Obj ***)&objv) != TCL_OK) { + Tcl_DecrRefCount(resultObjPtr); + return TCL_ERROR; + } + + Tcl_ResetResult(interp); + + /* + * There are two major methods for listing files: the long + * method and the normal method. + */ + if (lFlag) { + char creator[5], type[5], time[16], date[16]; + char lineTag; + long size; + unsigned short flags; + Tcl_Obj *objPtr; + char *string; + int length; + + /* + * Print the header for long listing. + */ + if (hFlag) { + sprintf(theLine, "T %7s %8s %8s %4s %4s %6s %s", + "Size", "ModTime", "ModDate", + "CRTR", "TYPE", "Flags", "Name"); + Tcl_AppendResult(interp, theLine, "\n", NULL); + Tcl_AppendResult(interp, + "-------------------------------------------------------------\n", + NULL); + } + + for (i = 0; i < objc; i++) { + strcpy(theFile, Tcl_GetString(objv[i])); + + c2pstr(theFile); + hpb->ioCompletion = NULL; + hpb->ioVRefNum = 0; + hpb->ioFDirIndex = 0; + hpb->ioNamePtr = (StringPtr) theFile; + hpb->ioDirID = 0L; + err = PBGetCatInfoSync(¶mBlock); + p2cstr((StringPtr) theFile); + + if (hpb->ioFlAttrib & 16) { + /* + * For directories use zero as the size, use no Creator + * type, and use 'DIR ' as the file type. + */ + if ((aFlag == false) && (dpb->ioDrUsrWds.frFlags & 0x1000)) { + continue; + } + lineTag = 'D'; + size = 0; + IUTimeString(dpb->ioDrMdDat, false, (unsigned char *)time); + p2cstr((StringPtr)time); + IUDateString(dpb->ioDrMdDat, shortDate, (unsigned char *)date); + p2cstr((StringPtr)date); + strcpy(creator, " "); + strcpy(type, "DIR "); + flags = dpb->ioDrUsrWds.frFlags; + if (fFlag || pFlag) { + strcat(theFile, ":"); + } + } else { + /* + * All information for files should be printed. This + * includes size, modtime, moddate, creator type, file + * type, flags, anf file name. + */ + if ((aFlag == false) && + (hpb->ioFlFndrInfo.fdFlags & kIsInvisible)) { + continue; + } + lineTag = 'F'; + size = hpb->ioFlLgLen + hpb->ioFlRLgLen; + IUTimeString(hpb->ioFlMdDat, false, (unsigned char *)time); + p2cstr((StringPtr)time); + IUDateString(hpb->ioFlMdDat, shortDate, (unsigned char *)date); + p2cstr((StringPtr)date); + strncpy(creator, (char *) &hpb->ioFlFndrInfo.fdCreator, 4); + creator[4] = 0; + strncpy(type, (char *) &hpb->ioFlFndrInfo.fdType, 4); + type[4] = 0; + flags = hpb->ioFlFndrInfo.fdFlags; + if (fFlag) { + if (hpb->ioFlFndrInfo.fdFlags & kIsAlias) { + strcat(theFile, "@"); + } else if (hpb->ioFlFndrInfo.fdType == 'APPL') { + strcat(theFile, "*"); + } + } + } + + sprintf(theLine, "%c %7ld %8s %8s %-4.4s %-4.4s 0x%4.4X %s", + lineTag, size, time, date, creator, type, flags, theFile); + + Tcl_AppendResult(interp, theLine, "\n", NULL); + + } + + objPtr = Tcl_GetObjResult(interp); + string = Tcl_GetStringFromObj(objPtr, &length); + if ((length > 0) && (string[length - 1] == '\n')) { + Tcl_SetObjLength(objPtr, length - 1); + } + } else { + /* + * Not in long format. We only print files names. If the + * -C flag is set we need to print in multiple coloumns. + */ + int argCount, linePos; + Boolean needNewLine = false; + + /* + * Fiend the field length: the length each string printed + * to the terminal will be. + */ + if (!cFlag) { + perLine = 1; + fieldLength = STRING_LENGTH; + } else { + for (i = 0; i < objc; i++) { + argv = Tcl_GetString(objv[i]); + len = strlen(argv); + if (len > maxLen) { + maxLen = len; + } + } + fieldLength = maxLen + 3; + perLine = STRING_LENGTH / fieldLength; + } + + argCount = 0; + linePos = 0; + memset(theLine, ' ', STRING_LENGTH); + while (argCount < objc) { + strcpy(theFile, Tcl_GetString(objv[argCount])); + + c2pstr(theFile); + hpb->ioCompletion = NULL; + hpb->ioVRefNum = 0; + hpb->ioFDirIndex = 0; + hpb->ioNamePtr = (StringPtr) theFile; + hpb->ioDirID = 0L; + err = PBGetCatInfoSync(¶mBlock); + p2cstr((StringPtr) theFile); + + if (hpb->ioFlAttrib & 16) { + /* + * Directory. If -a show hidden files. If -f or -p + * denote that this is a directory. + */ + if ((aFlag == false) && (dpb->ioDrUsrWds.frFlags & 0x1000)) { + argCount++; + continue; + } + if (fFlag || pFlag) { + strcat(theFile, ":"); + } + } else { + /* + * File: If -a show hidden files, if -f show links + * (aliases) and executables (APPLs). + */ + if ((aFlag == false) && + (hpb->ioFlFndrInfo.fdFlags & kIsInvisible)) { + argCount++; + continue; + } + if (fFlag) { + if (hpb->ioFlFndrInfo.fdFlags & kIsAlias) { + strcat(theFile, "@"); + } else if (hpb->ioFlFndrInfo.fdType == 'APPL') { + strcat(theFile, "*"); + } + } + } + + /* + * Print the item, taking into account multi- + * coloum output. + */ + strncpy(theLine + (linePos * fieldLength), theFile, + strlen(theFile)); + linePos++; + + if (linePos == perLine) { + theLine[STRING_LENGTH] = '\0'; + if (needNewLine) { + Tcl_AppendResult(interp, "\n", theLine, NULL); + } else { + Tcl_AppendResult(interp, theLine, NULL); + needNewLine = true; + } + linePos = 0; + memset(theLine, ' ', STRING_LENGTH); + } + + argCount++; + } + + if (linePos != 0) { + theLine[STRING_LENGTH] = '\0'; + if (needNewLine) { + Tcl_AppendResult(interp, "\n", theLine, NULL); + } else { + Tcl_AppendResult(interp, theLine, NULL); + } + } + } + + Tcl_DecrRefCount(resultObjPtr); + + return TCL_OK; +} diff --git a/mac/tclMacUtil.c b/mac/tclMacUtil.c new file mode 100644 index 0000000..ab65815 --- /dev/null +++ b/mac/tclMacUtil.c @@ -0,0 +1,514 @@ +/* + * tclMacUtil.c -- + * + * This contains utility functions used to help with + * implementing Macintosh specific portions of the Tcl port. + * + * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center + * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclMacUtil.c,v 1.7 2003/03/03 20:22:44 das Exp $ + */ + +#include "tcl.h" +#include "tclInt.h" +#include "tclMacInt.h" +#include "tclMath.h" +#include "tclMacPort.h" + +#include <Aliases.h> +#include <Errors.h> +#include <Files.h> +#include <Folders.h> +#include <FSpCompat.h> +#include <Strings.h> +#include <TextUtils.h> +#include <MoreFilesExtras.h> + +/* + * The following two Includes are from the More Files package. + */ +#include <FileCopy.h> +#include <MoreFiles.h> + +/* + *---------------------------------------------------------------------- + * + * hypotd -- + * + * The standard math function hypot is not supported by Think C. + * It is included here so everything works. It is supported by + * CodeWarrior Pro 1, but the 68K version does not support doubles. + * So we hack it in. + * + * Results: + * Result of computation. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +#if defined(THINK_C) +double hypotd(double x, double y); + +double +hypotd( + double x, /* X value */ + double y) /* Y value */ +{ + double sum; + + sum = x*x + y*y; + return sqrt(sum); +} +#endif + +/* + *---------------------------------------------------------------------- + * + * FSpGetDefaultDir -- + * + * This function gets the current default directory. + * + * Results: + * The provided FSSpec is changed to point to the "default" + * directory. The function returns what ever errors + * FSMakeFSSpecCompat may encounter. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +FSpGetDefaultDir( + FSSpecPtr dirSpec) /* On return the default directory. */ +{ + OSErr err; + short vRefNum = 0; + long int dirID = 0; + + err = HGetVol(NULL, &vRefNum, &dirID); + + if (err == noErr) { + err = FSMakeFSSpecCompat(vRefNum, dirID, (ConstStr255Param) NULL, + dirSpec); + } + + return err; +} + +/* + *---------------------------------------------------------------------- + * + * FSpSetDefaultDir -- + * + * This function sets the default directory to the directory + * pointed to by the provided FSSpec. + * + * Results: + * The function returns what ever errors HSetVol may encounter. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +FSpSetDefaultDir( + FSSpecPtr dirSpec) /* The new default directory. */ +{ + OSErr err; + + /* + * The following special case is needed to work around a bug + * in the Macintosh OS. (Acutally PC Exchange.) + */ + + if (dirSpec->parID == fsRtParID) { + err = HSetVol(NULL, dirSpec->vRefNum, fsRtDirID); + } else { + err = HSetVol(dirSpec->name, dirSpec->vRefNum, dirSpec->parID); + } + + return err; +} + +/* + *---------------------------------------------------------------------- + * + * FSpFindFolder -- + * + * This function is a version of the FindFolder function that + * returns the result as a FSSpec rather than a vRefNum and dirID. + * + * Results: + * Results will be simaler to that of the FindFolder function. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +OSErr +FSpFindFolder( + short vRefNum, /* Volume reference number. */ + OSType folderType, /* Folder type taken by FindFolder. */ + Boolean createFolder, /* Should we create it if non-existant. */ + FSSpec *spec) /* Pointer to resulting directory. */ +{ + short foundVRefNum; + long foundDirID; + OSErr err; + + err = FindFolder(vRefNum, folderType, createFolder, + &foundVRefNum, &foundDirID); + if (err != noErr) { + return err; + } + + err = FSMakeFSSpecCompat(foundVRefNum, foundDirID, "\p", spec); + return err; +} + +static int +FSpLocationFromPathAlias _ANSI_ARGS_((int length, CONST char *path, + FSSpecPtr fileSpecPtr, Boolean resolveLink)); + +/* + *---------------------------------------------------------------------- + * + * FSpLocationFromPath -- + * + * This function obtains an FSSpec for a given macintosh path. + * Unlike the More Files function FSpLocationFromFullPath, this + * function will also accept partial paths and resolve any aliases + * along the path. + * + * Results: + * OSErr code. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +FSpLocationFromPath( + int length, /* Length of path. */ + CONST char *path, /* The path to convert. */ + FSSpecPtr fileSpecPtr) /* On return the spec for the path. */ +{ + return FSpLocationFromPathAlias(length, path, fileSpecPtr, TRUE); +} + +/* + *---------------------------------------------------------------------- + * + * FSpLLocationFromPath -- + * + * This function obtains an FSSpec for a given macintosh path. + * Unlike the More Files function FSpLocationFromFullPath, this + * function will also accept partial paths and resolve any aliases + * along the path expect for the last path component. + * + * Results: + * OSErr code. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +FSpLLocationFromPath( + int length, /* Length of path. */ + CONST char *path, /* The path to convert. */ + FSSpecPtr fileSpecPtr) /* On return the spec for the path. */ +{ + return FSpLocationFromPathAlias(length, path, fileSpecPtr, FALSE); +} + +static int +FSpLocationFromPathAlias( + int length, /* Length of path. */ + CONST char *path, /* The path to convert. */ + FSSpecPtr fileSpecPtr, /* On return the spec for the path. */ + Boolean resolveLink) /* Resolve the last path component? */ +{ + Str255 fileName; + OSErr err; + short vRefNum; + long dirID; + int pos, cur; + Boolean isDirectory; + Boolean wasAlias=FALSE; + FSSpec lastFileSpec; + + /* + * Check to see if this is a full path. If partial + * we assume that path starts with the current working + * directory. (Ie. volume & dir = 0) + */ + vRefNum = 0; + dirID = 0; + cur = 0; + if (length == 0) { + return fnfErr; + } + if (path[cur] == ':') { + cur++; + if (cur >= length) { + /* + * If path = ":", just return current directory. + */ + FSMakeFSSpecCompat(0, 0, NULL, fileSpecPtr); + return noErr; + } + } else { + while (path[cur] != ':' && cur < length) { + cur++; + } + if (cur > 255) { + return bdNamErr; + } + if (cur < length) { + /* + * This is a full path + */ + cur++; + strncpy((char *) fileName + 1, path, cur); + fileName[0] = cur; + err = FSMakeFSSpecCompat(0, 0, fileName, fileSpecPtr); + if (err != noErr) return err; + FSpGetDirectoryID(fileSpecPtr, &dirID, &isDirectory); + vRefNum = fileSpecPtr->vRefNum; + } else { + cur = 0; + } + } + + isDirectory = 1; + while (cur < length) { + if (!isDirectory) { + return dirNFErr; + } + pos = cur; + while (path[pos] != ':' && pos < length) { + pos++; + } + if (pos == cur) { + /* Move up one dir */ + /* cur++; */ + strcpy((char *) fileName + 1, "::"); + fileName[0] = 2; + } else if (pos - cur > 255) { + return bdNamErr; + } else { + strncpy((char *) fileName + 1, &path[cur], pos - cur); + fileName[0] = pos - cur; + } + err = FSMakeFSSpecCompat(vRefNum, dirID, fileName, fileSpecPtr); + if (err != noErr) return err; + lastFileSpec=*fileSpecPtr; + err = ResolveAliasFile(fileSpecPtr, true, &isDirectory, &wasAlias); + if (err != noErr) { + /* ignore alias resolve errors on last path component */ + if (pos < length) return err; + else *fileSpecPtr=lastFileSpec; + } + FSpGetDirectoryID(fileSpecPtr, &dirID, &isDirectory); + vRefNum = fileSpecPtr->vRefNum; + cur = pos; + if (path[cur] == ':') { + cur++; + } + } + + if(!resolveLink && wasAlias) + *fileSpecPtr=lastFileSpec; + + return noErr; +} + +/* + *---------------------------------------------------------------------- + * + * FSpPathFromLocation -- + * + * This function obtains a full path name for a given macintosh + * FSSpec. Unlike the More Files function FSpGetFullPath, this + * function will return a C string in the Handle. It also will + * create paths for FSSpec that do not yet exist. + * + * Results: + * OSErr code. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +OSErr +FSpPathFromLocation( + FSSpec *spec, /* The location we want a path for. */ + int *length, /* Length of the resulting path. */ + Handle *fullPath) /* Handle to path. */ +{ + OSErr err; + FSSpec tempSpec; + CInfoPBRec pb; + + *fullPath = NULL; + + /* + * Make a copy of the input FSSpec that can be modified. + */ + BlockMoveData(spec, &tempSpec, sizeof(FSSpec)); + + if (tempSpec.parID == fsRtParID) { + /* + * The object is a volume. Add a colon to make it a full + * pathname. Allocate a handle for it and we are done. + */ + tempSpec.name[0] += 2; + tempSpec.name[tempSpec.name[0] - 1] = ':'; + tempSpec.name[tempSpec.name[0]] = '\0'; + + err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); + } else { + /* + * The object isn't a volume. Is the object a file or a directory? + */ + pb.dirInfo.ioNamePtr = tempSpec.name; + pb.dirInfo.ioVRefNum = tempSpec.vRefNum; + pb.dirInfo.ioDrDirID = tempSpec.parID; + pb.dirInfo.ioFDirIndex = 0; + err = PBGetCatInfoSync(&pb); + + if ((err == noErr) || (err == fnfErr)) { + /* + * If the file doesn't currently exist we start over. If the + * directory exists everything will work just fine. Otherwise we + * will just fail later. If the object is a directory, append a + * colon so full pathname ends with colon, but only if the name is + * not empty. NavServices returns FSSpec's with the parent ID set, + * but the name empty... + */ + if (err == fnfErr) { + BlockMoveData(spec, &tempSpec, sizeof(FSSpec)); + } else if ( (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0 ) { + if (tempSpec.name[0] > 0) { + tempSpec.name[0] += 1; + tempSpec.name[tempSpec.name[0]] = ':'; + } + } + + /* + * Create a new Handle for the object - make it a C string. + */ + tempSpec.name[0] += 1; + tempSpec.name[tempSpec.name[0]] = '\0'; + err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); + if (err == noErr) { + /* + * Get the ancestor directory names - loop until we have an + * error or find the root directory. + */ + pb.dirInfo.ioNamePtr = tempSpec.name; + pb.dirInfo.ioVRefNum = tempSpec.vRefNum; + pb.dirInfo.ioDrParID = tempSpec.parID; + do { + pb.dirInfo.ioFDirIndex = -1; + pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID; + err = PBGetCatInfoSync(&pb); + if (err == noErr) { + /* + * Append colon to directory name and add + * directory name to beginning of fullPath. + */ + ++tempSpec.name[0]; + tempSpec.name[tempSpec.name[0]] = ':'; + + (void) Munger(*fullPath, 0, NULL, 0, &tempSpec.name[1], + tempSpec.name[0]); + err = MemError(); + } + } while ( (err == noErr) && + (pb.dirInfo.ioDrDirID != fsRtDirID) ); + } + } + } + + /* + * On error Dispose the handle, set it to NULL & return the err. + * Otherwise, set the length & return. + */ + if (err == noErr) { + *length = GetHandleSize(*fullPath) - 1; + } else { + if ( *fullPath != NULL ) { + DisposeHandle(*fullPath); + } + *fullPath = NULL; + *length = 0; + } + + return err; +} + +/* + *---------------------------------------------------------------------- + * + * GetGlobalMouseTcl -- + * + * This procedure obtains the current mouse position in global + * coordinates. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +GetGlobalMouseTcl( + Point *mouse) /* Mouse position. */ +{ + EventRecord event; + + OSEventAvail(0, &event); + *mouse = event.where; +} + +pascal OSErr FSpGetDirectoryIDTcl (CONST FSSpec * spec, + long * theDirID, Boolean * isDirectory) +{ + return(FSpGetDirectoryID(spec, theDirID, isDirectory)); +} + +pascal short FSpOpenResFileCompatTcl (CONST FSSpec * spec, SignedByte permission) +{ + return(FSpOpenResFileCompat(spec,permission)); +} + +pascal void FSpCreateResFileCompatTcl ( + CONST FSSpec * spec, OSType creator, + OSType fileType, ScriptCode scriptTag) +{ + FSpCreateResFileCompat (spec,creator,fileType,scriptTag); +} diff --git a/mac/tcltkMacBuildSupport.sea.hqx b/mac/tcltkMacBuildSupport.sea.hqx new file mode 100644 index 0000000..0f39e28 --- /dev/null +++ b/mac/tcltkMacBuildSupport.sea.hqx @@ -0,0 +1,3970 @@ +(This file must be converted with BinHex 4.0) +:'(4ME(4V6@&M3R9TE'46GA"`Eh*d,R0PB3""8&"-BA9cG#!!!!&F-!!"NlA#He0 +dG@CQ5A3J+'-T-6Nj0bda16Ni)%&XB@4ND@iJ8hPcG'9YFb`J5@jM,L`JD(4dF$S +[,hH3!bjKE'&NC'PZFhPc,Q0[E5p6G(9QCNPd,`d+'J!&%!!"A$!!N!0b!!%!N!0 +b+G30TD95CA0PFRCPC+@P!+@3"!%!!%3!4,GD)HHjbMAT!*!0&'J"!*!$fJ!E+'8 +!!9Y@!!*dBfadDdeKBd*eD@aN8h9`F'pbG!!!dCB!mJ'%!Y8$FJ(!rj!%!Klrq2r +`bd!!!)!!N!3",JZPN!3"!!!e!!#h@L(RYeSKj`#3!h)!!!(%!*!$FJ!&Qcd!N!j +*BfpZ$3!"fipTBfpZ68&$8d%!N!q!!*!*!HB!N!1$!*!%$`"#`G4pkZC)Fdpk#E" +3,[R(401[QF!K8#m3cp6`UEN(l!F(kE$mF3UPMQ%Cji[M2`6'l@`N5(%)p!jpec$ +iXXJI,GDb'reFiYi1&`4QA#$cfMm*U3HrSJU)q3Y-NAL(FV%[6'K([88c@M9ehcr +RHNJC`RVr%f@Ki9pVfJ5KjNGZr)mi!+@3"!%!!$d!4,5KD[qjbM&r!*!$fJ!"A!# +3"()!$B+V!!!#*3!E*Rm!!9RE!"48Bf`[9'XJ4QpXC'9b!!$YV!![!!X"b3)#!F$ +rN!3"$[rm!&R,4!!!J!#3"k@3"!%!!%3!4,BJ!3+jbL'e!!!"a!!!Z"-!!!(%!"6 +@lJ!!!Sd!&eh"!!#eKJ!&+&"bEcBJ3R9TE'3J8h9`F'pbG#N!!'D$!(`!6`+0!J! +"`!&!!)%$$[rirr$,4!!!J!#3"k@3"!%!!%%!%,B4*!Dja[-2!!!#*3!!&Di!!!) +P!"&Fj!!!0"i!!"('!*!%$`"#G@PXC'PZCb"0B@08Bfa8D`!"q"T849K83eG*43% +!rj!%!*!+J!#3#3'D!*!$k!#3"!m!3X(8LR5QN9I`Z)-Fq$Y-QHk+Q*e3ZSAj*b9 +e*fN`#Q%cH$(X0PVIdXIVaI'B*NFL"q4m8KkAY`LZHTHKMcM,YbZ6E@Hir+([lTr +!H4DFBb0"[)ejqqE$22-d")j2X65`LhV*!M'EVkai@'C&C5&1X3MS0!Y1UiD'E0d +l-3lheaEpDEFFkMe#5pfDI3if*Pm([4e51#pXZf#AMV,bp6fAl2V5HhUe(8XZAp* +'j,M`8+0RS0q+MmrS"MU"GM#%F(P#@)qmrJ9+DKEE-d-49L9RZ(YBRTr9ZIq,f9i +Gl4Sd#AP)a5h`X-6d!%,"e1Si2T,Ni"XaM+Lk0AbK@)D"d+d3b@&mVR[5CH3C#hZ +Ur((1M+#"JTVj2$-cVZUhAm`(-Mm3JJak'DIJAJN5adpNa$TcI[d*KkFXF-erjlf +RQ@Q2MmMPbQ#YLNdUJKJkY-iN&j[CLlp9&%!IL-4FCfhJ$jG0)P8m`YB*`9Z3!"- +V3p*XG0*#1"rZh(0&Y83'9e$jLa[fE3pf6maGMB!Kfml(qePU`adB0&'CC25%cHS +kD"Z,3USPXS!&!j!!fPP1KE&qbMfe2I9fb9[1kK1'B!,eNP8Fa8d-Nh#XA5c+Y0V +IHPC'k,5`LXVqZipRbBj`cMam3!%(I!Ml#&YpiLX[l%H$Jh,0)Z(%h9,&'$AhSbL +4BYjTQU&"mlZ)Y(53!)3"b&d2J)306QURcfPYK,3`UB(-G1T4U3m&FEf'QU9aTY6 +V+VQS&hM-!U[8BA,S(V2&N@`eY6Bq0*R9(I-6Z90lPA4GcY1S!Ym[Dj([k65eDfj +F&N[G"@KqYVRLhT4qCYq(XEVN@2G!aqF-c3`96G283JK)4$9%VEPambHkr)64R82 +H*%G6GFEC[SN80iHal(H1q(peQ(PNX`p-JVTFJUE86(-)[-2Sli-Dp8-YJ(%im,V +3P`JCe`'A)(9TkL[DfCbqe0D+hQV+1l551k61bjUV9eb,DjK"-4kZMA*Lh*faf1Z +0XNYjfIG+m*IAkSNi%*'kC6J`j$HPaR,T)ZP6cDc#b@qC)#Q2`[)4U4X+ih&26b[ +FVab"a%,ahmZRQ5Tr`"PS6kppkK&AC$DVQp-Zd8)BLmN"RH,mZc9RXGUM)b-"!YD +"9Q,(6"NI%*h,)bd3)cp1[H8$CAHi4,RY2L0BFhIQk65P2X9$h5`FY[``JpYqU@P +KM2)$)IJ`qBBP*'+R2Ae,JeNR`P('!4Kj23(QfMJ2-41RfqRUcjKp%$8r'#pHT** +%()39HbF$UfT@d9-4b$,EqX,QNIYrI"LQS-QQ0Cb+RHXAk@+)1Klhi,j5a4`Ufq! +'kP*(PbbGP(4Up@Nb@m2VU0)mil&GjT%'&[$`AaN%[2#YPf8h(FNEmk,T5`J%A,a +2I#r+HFq1,T([rC95&-l@i[Fe8dQ4F'e+ri9$0c)q1fT-m'$T(Fr8EllI1RZMh*H +4G1UV0QAhU-Bdcdf'SSIi"81PK(9+)1JI8-amURk,!4ZU&$!VcQN"0ZZ!X9$NS,S +9f13c)2m(@`[jc*0a25T*X#)*C"5@k#X,bX$QR3HmkNBGi[mFBL"FMTT0!E"%B%N +DdKIkr`HbaZpL#jqXRX*'lSaj,-852Hd4#[QJN!!'PDVTkP*d2LF5e9TLEQ[*R3, +B$mDRdXMYhkiB-`'V*rJ6fqMLFpp5icZdKaU#4[&+G2ep3+(ahG9@fbL,p45%Vq" +T1M)V88G9e4!*Ef++AG5MfeDVr38@0kcHc'p+5)SX$@PG#JZ*AJq)Y2&h4KJTlpK +'pkD1`)H$Ab@eXf'd0rYLB#I")$k,PKHT,Z[8r8`BrLMeXDc12!qITQ8`ZkUradq +45S2'NLCj#L0E8e4@`A%iJ+$@4a'0$6%3(3UHEkUFbdXSd$KUC'GlVh8&iSC5c+3 +ja!*ME%iY$3Z4D%)S'6kS#I&e%MIME%VCL4NK2TT%4B+P`KH[H@hh``S[,+$2GRU +Vbcr*4VcBE6hMI&Eh-fjf9L"QBq'b#phQL*MN9aHTUDVJ&EMr42(H+D2ZqFb4R#c +Ne9mlC++%5CX-ikRKBA3dk[bQ-KN#cPqKNbpdFGZC5eGdN5-2N!!`UU,RXhEqMSA +%30[c@l*0FG*1K%Z@H1QH$#aHGFr`3TM1X[1qGkreFU1@$,CT1d@S)YM@5H@Ul%h +A4kTZBA1hGC+JJ#K#Jp92KM23D64cKI5Lf&&LddN1QRlR!KYX%`m$"ZfUGl3%B'a +r0liHGa1+6)5+eef6X&1#re&jBq2KNU[+QV[qQG!lGG44jJFl[Q3)"6l!c191&ZJ +jNeLA'9-ir,N9NqpfKml!A'CEQ8,hUH5+ji&@JcjY[EaYYYh&90LVbE,m,RjfRZr +T'H86jcKFNP4eN5[&@L2[Mj+0N6CVpPrEIL"4S!%p+"8Y0Z*B!T6Lh8M`pqYBDqd +qamklC8ZGD"Hhfa&E$'"35f3h8&H'Cr,UUG3'M3QHG0Qep90q95f`FiC-BC1MTSY +%'m-HrpH(a5C,I,*`)@K#S-Z$"0JckGN@J'9XYTh-ZiTS93Hl%k+)!RdKEIPbB[@ +4B8M%Uh#"5ifd0'4fGV$,j%SHb'YbpFdc!Qhh3`XTU9hbQY,%(c36)q6CFi$[!QA +-hUTk@(pi2H6fhBkH+hJXrk3XEb0rV15CPS9#KK36lNHa`C9feCeb,M`PrUq8II3 +[R3KUaH6SS@Y)A[p41N@84(Q"b&)jTl@dGlB'kQBLeZeUS05Xp5Q)6h,A4'[C-4) +p%4,'reCEJIG#LbrQ3335CVBae!'p,J06bjpk@j88CimK'+!-r-10%iQTbl+"p94 +@2!'fpj2FI&DLm&hi**+f1DBcK-@jN!!&UK9hZCMYi'DNVHpF',VVcr2R#!f*,Y8 +&bA@&RHLCI0fSHI9hK6p)U-l(Hj+VU3YQ6mK$2KYPZ$&GU$N5XrA),q%$&B9ce(r +qAa85rK9rrC03Dk&mPJ9!Sh,I@f84#$KR,2Mh-bVlJdM(jR5T2rHZB&QM-V&-T)' +E)kC6b"YTD#Q`51eef#CK+(Cj8(XT'Pd!Q+pp#MM9!rYaBBC%)hm8qE)c2`Lk$hT +"NX[%kNm(,'XZlVl#9033r3'MS8(4Iq-ldA0Sc#dhQl%d)N%89GMjNXMMqK29*Xi +PfqTX5LMXQ-9&)3FfRr@$dlU4#Y"%&$Cep'[DLYjC!G%M(E#bEM%r-PX-YBh*efC +29C5ea-d)lFprEb$P)JQYp&*#dQXh1EUjZJ#3!,-)`NMED2pihkIMQ--a"d9%C8R +p*VD52qaMb82HC1$ZDP+mN!"rKG[+*[#q'9pUmlS#6PfIfcIY)*R9-c%$0HF2R@p +8FD'k1#r(NU%*IfqV)eFB`I9bZ9hAL%I1[p8b0"`([Tm#l)#*P)cM*a1i`C6Ii%6 +mCel*clEFVBJ0%AK!TJXkMf,Ub!)2"1c#H)Fbc*0q,e1F"52'["DM#&IVieQU&MH +3!02`L8qRh'4AG8#S%KGMYXA0RPYJQ8EQCbk8Fa%aMhYT`lGd5S&&5))X,RD(jYq +*X-aV%j4l$()),9B%HkCE@3ehl!2@R6&jIjN*2KaiAlCkXHKkr[[a)PUSPeJpZde +%M-+aZfrVXK%X&K4IY0bb@S!FNpfENibGbk(XJ)V[#NNRI&#a`fN&E@h%NPq!a1i +H+N($r)HVjX,68@jV&BjZ')A"'iM!mH"aE&p9(Y$PL%#88S&3(kV!KF*GU2!S(K( +L$9MaFQJhc0MKT+a(XCI'"el#ql+&4+ppRDPU$DX8*a)")-rGb@!jE%)!5JZdFbp +V6JB@!#2[eS(RSRX(X55i[&8X[LKXl$@V5&SX[3JDQ*3GfQH%!(2XjHmZ&Bc#Dr4 +cHhZf@`1iMHl0G0IV((@&Qrd93MjD%KF)[UG#&RA,m[ka4[TqXP4A9CVGF!M4Dqp +hG$9,TD`q$d3CHFN'#N"HaDE,2&BrPF&)#qJHUY[F)'6ZN!#H%Z)3fe0J8DC8fJf +!!c6D#QB9Hi##""+6(`liGp0m#J3eb"jGcDV(FU6rmG22E+fEICcfHXS(D!B%Br, +8C-IjaD)RkYaq@C!!F!#LEXp,)LNlNNB93&dek2J-I#&qVBc6YVHAPq$C-06V$Fr +Y6*A($SE$%4GEekX%C8(3YldCC1TP5QEp(TBQYT`4[Tp4%85X("#ppp,(M,1G#A+ +*++b611JLe*IIV#K[LGE*`4HCFa-hS5T!Mc',mL[9G$b616&RmB#6bUAAcTQ*U"H +lBI#3!!-!rDfSrD5frQeGeFIEXEi8hjrTRdD8lJUkRp&KCq1U-hUjqhJq34l*YG+ +l8`e1dd2h$[rDj+`+*E2aA#(PflSZL+a(Jp!dXBC[RQ24d6dQZ,p!F4Kf*bX"GqD +Ad!)9pfelmR$ip2&RR&VJLQJbParq9h5KU`H2@#B![%k'Z15ZYVJCU4bcE)B9A'Z +Ti[i&(j!!B4ZchNHBZR0@*cPjhPHC2DRaSfGCT-2R,4&l@mRb5%l6Shjif&m0ea, +KC!G0f[aPK("r-(rLIGT5Z((,V10rEF,HSZKJRH%Up+!23m-Kd@I,Q*BcVl-GQNm +jkkFrB4+DH-GkYq+Va*4j,meEl-6,#LaKPPTVq#dFcQmGdNeqHmZ400!`I)IehqF +aj!*-FY`2RES8ETUAl-UBYY0qai)eD&BSqDfNhi[[!LVpHKE`aSC+eT!!M1jZlfF +KqUXN2V6YV'qSJ!568k5m0XaCd28IEiL#$aciJcEh#$JET2dQV'pGllXQ'JiYP*T +q!c1fcMaBY!SB1TPMR6f,%d+2cUP9[K6FPBrF2IZM6QN8SiSD3CKCpGf9k'brrVk +CUN2"PEBk9e$q5VVa@Hl+C9pMUc%lXk'L6bb24B(@[A(ZbRBaQN0J-XSM()`&),6 +raap$#k0mjr,5H6Dj"BPh'++H02UFJI0qk%c9hmPIDU5'dKYk[CjkXU9R$QDX+"j +i$5l'9j5&)"F@m&bEMCMq')qN)([R@3H+rYF'r3QZh4FLdS`bhJZDrT5%QHbiF-e +LblAE,l(FNSM3TY'kB$YL"A2Y9D$NAr(((&3+2j)SaShmKGaEr-E945ajfHBM60b +j6MRT2*QeINA*d9PGpa'9Lp*6(6h[fRE+%2DjQl(FpXQ@2-f&*-p142L@I3)6S%c +j*YJQl"-2kpXPmGYBAErBI-ChT24,Ia2%ZZKi%Kl6K[JjURISC9iY"N2KY(8hD)f +k$2#qfk2m@@eHpqb9N3K,rm-E,ka3RcZCYm"%Gf2mE"cCB&UNfNRf2a!LX,BIe%$ +KN!$GM(Qq(XDKaeQ#U[cENYqfR!Z+r2UYeBKZ[Ip)8KNdp@m)Ij6ISZ*TEEbESE% +S+L@eX6lcY)*XRF(SPedJ#E")9h%0XLZr"AP1q%YVfj,V9$b8,J)B2,[UiMZcjMM +EP[3U0bS0jbUl2+`*2@K(a+2j2A8!I5A8E#*#9VKlF*21`kPEBNNCAZGC+hbHk9G +("Ra`jVdH(9-4YaIK1j3MrZ'JEpjpYHI!b[b,`SaY,[%6+$J#18F+'JUb`aXKI1e +m4J6k9hB$0l,k[BLJpYY8DJ8H#@jN9'Pe58ie&h%B%YPKFj`,'-0PFF)+%JPiFNa +$DlBl!&YN8UZ92V@Rb#dPSk8kGNEmEXCbIe@6bUfiU3Vf0%H@k2#ieZYGB+#Lk,m +NjPZU31DiZLi6lM4f0CEq3K+jhPHRp!MGc+Z3!18$`2@#[jpIRMIXJa+ea19m8[P +C%M&[K)&k'BPUXGPH@3,,b+h)alA-"peR!9mXSpk#b4,XBVdpjJ8C!&R45c@XNbI +-h,-mR%ed,1VA(CRbCmmfK&EA"l(4ZY)38Zd*$,mSIl$m8DL4IJS0FX)69CVk$Vk +JECm5L2ljXa+m!$Xce-Peh%`LZPk,qB2V,c#MC[)m-X&r3%e*M$FH$E[4c"qAmUH +-qKSIDcaU[Vd9+A(p3'Y-QBJKh4-2PJ#Z6H`Z4UZ"I0MZAVkX)I"JU[if%U!Ga3a +SMHc"iT9@Cb,2YCG-Q`*pEUPjYHTDmdjXPFIlReNLkJpI+2fCL`bX+`cHVD5&+Y[ +6G6!&ESaK!0ET9FINZll0fVMSZkfEHl-%S0m(G`ci*Le)GhT-H,HPYDVF2YL81%X +`$"YJ&*6!XYF44mjaj-)PeFjE8'4S,kjk0,(UjEpJm#5fX@Gi,0lRD),f5!r,mhX +5Z(%2&,pIJkqhk-De0r%1"5+R11qHi@d8)03(L4jFb*h$L!8VqU'1J8k0r(DC,,, +Ni,cK*5cKGT&0E"q4FN3-F*Ml-2rcYbG#0J$"&8SMKq(2j$SmkAV3LKS"TB3N3h1 +A+aGa1*99cdShc0B#emfJldNZCl!N#aN*iAj&Eki-LfiF#j63b`r11e3Q5JcIA15 +kTEJN%8a`*if)$dX0Ld-2jPU1ZaB)V$YTm"i8+&G0JcbG)G8)4H9+,$,H(Zjp#Nb +#'HNrN5laLaMdD34(kSHKNML,J+@3"!%!!$m!%,BJ"!bja[+l!!!#M3!!(1X!!!) +P!!pj#`!!$NJ!!!BP!*!%$`"$9b"3FQmf)'0SB@jRCA-!!6bN9%9B9%0A588"!2q +3"!#3#S!!N!N"QJ#3!kF!N!32!%,"e3hVJ)DL+(k5(ekhZa[@hQ)a8$28*ae,e$- +Kl!1M-Tk(*K"6N!$V98I5XC5'52IeC1`E`U66Bb#Jkb!HYl6pC6PY61KFbUJ9qJT +-J6)FLq@pSS1l8(MXlkI3c554bSRJfjA29@bY`PcqA8IpU'lUA6(HFc)pi'"k*4k +V+`p@'9H!Nbed'ZHVqH12UhdhdMa($Q#3!(94,[UT65#Y3hj@A3KMXcdjl%"#`G8 +25AAp3DGeN3%,QDiR)5[1r65qVB06hC))(iml#TrVTAQbhaScA-iFG2`JU[&95Xr +dJM9p9N2Kh-kk8(i!E)eAUX#U%%R*AR'-aAFq66A9K[B)5$r$cUK(&[["$0dXjE4 +RFFV'1*JEe3E90B"r-%K&(@+P3d*pkd%RC#iSP#NrDNa(MkK,ANm5(EG)13Gj[-e +TC0Rrc3([FFd#0NXGU0chFr9jIdX0q3Hb+LJSHd,mrlm!131FfI"QKIDEeXXMVil +j*9'TM415fX13!",ec066E)cN@[[`,D(pDKL2J)LeChPZNK#Gccd3p!ZXq9&V&*I +L@#j4Qp4k2H*&!@UHT"!X#Z%*#THD30pU!3##P[i!)k&8Bd,E6K+(,09j11!jmHV +,QaZ2,E*l4pF@1LC8i8m$m0YUlP%aKaK4pNXa2"e5i@T(J&pP86M%PQAV@+G&%4[ +cPKXV"@-b4HkYM[$d)#dLRkac'NkpXdENi04'A%pV%e8&%&P*iT'+l$Q*LA""%(0 +BrD(d0IK4X5Gqa&m8,06dU(PTVJ2'2(bLj5KmK4eBZbD8JI+DDmCDZECX,dXraHR +@XDZK42DE"@AVB4Ik,FNU")rfqPA&9*jaQ0S1DEab65IRUc,`2dV(qLbP9J4ZKI+ +GMhf$NRDX3pbZPMI*4jFKaCHfq3ClFc6ZDP'SfY6@r%XU3,Ub34e[!+m+l(p$F!K +ea*rI#IQ`&-#[qQMm+DSBc*dIVHa9#i&aJb*JI*IPNVGZE*NL2DZ3!'$9BZk(0%8 +"mKcLU0L[QRY%Ld3'Yd286XeKDLE2VR$UK3SHc%a#UN-rcdf$6YcD$1T#lb4@ReE +'Y%C,MJ`-ZIZ05Qe6(2@#64NQTBiPER15$m1A6$65SqBXD0+1j-)UMkD2f9%c%84 +B8MQE@ChI`@A6"dIh+laG#!Q"T3-"PrlJ&A4")qSR9a-AYjH6T,q&*KR-X81(cA) +bND8C&23hm95A"r-q"rrFk-JJ&5hmm-IaER"b%4L8AXZma+fS1R)YDU4VEdeGj!& +#ZNcM&-X3QV$R56VENZiJkQ-GqXX#AfSMLc!6ZT6@6JF(a1%mHEF28Q4bkM!RULc +F#`2M#IQ)@%cXAKMimSf0CjH,JB`ha-Q3!(S9!J"d`6'AUaE#NP-0,CAdrjpeT"[ +`&M'!l(`BUIPHCCUF-8*cfPDL[(E-ADp*4D`e%DQdJd2r&$F4YpTh5Gh()TpT6&L +KG1dTq-S,cMqfF*,c)B'Zl3)22-m3B*RYMLqKLD'1I8J(eUhAT!NSi'#ke9%#Y+b +##1(fS82dd9FNL4%*8DBmE@ha*TBf5k`5+),FTpbEcb`HYA4Y++-iZ$PH1G9d"C1 +&fRd%"!Y&Q[(cX6alDi[+R%U1QN5jb6pbKM@b!dY(DN%[36THL)&XU+6f6G!ZH5( +MMiqJcNChq8hM*U+"h,9[3XVdY0TVQc0(+Ur"YK6TSH4$RHXbpY)Sq5FRRfr4Fjr +dE`8)6I!8Y&bRTV'lJ4I!IXG3GV@Z0VS'KNXX#epS`3Lk3*SF2fSZq1dMG9m#%4K +Ijf5rF58+9bH8#DR"#m5[mmNML'%Z#Yi@"83rV!i2ICMKrTL',Y4`(f4)YLrTmBK +6A"ClFhIlXiG9fq"ZGA6q,ff5RCC2i&kc6dC0*[4-lfN#-,#2RmVX2N`5DRZ66Pi +3ISZd`a[$8[AZMSINU3[fEI880PXQY8H@Y9`Y53f+31V)c3m%Z53N+SBrPHX$JBR +!baE0U0"r4HB,0Nr5%L,TErh,4&B#5-5"r"XmaMcfSE#0Ar10Va38c30%Qfh((Yp +XYZNbR5%dqVPI,LU-a99J-Pm`eL@c0QK!0dUNF8biQK[!'b+1A#mUpFXjJ)EUPKm +XU%cF0!a1Gh0"-+(MS&5'&j[B*JUV"2mlYU[)$(dH1!lZ'K!AhM4k$rBkkG&lh0c +j6%c`5eSablY%64kbIrQZU&hilqeMNTa$ECFkajl)!mUXB,KN%[b$&$0bq'HPE!% +Q*0@Sff,K%LfpZq`98HlqV#V'QT6!1S'QLleBX3AJf1N8-bba4rqqY6iV#Alc9Z+ +6D0HqS@3mL[b@+Ue"XQDrVMGrGm2Jp1e9`+6%9LjbYAZDi[!!TC!%!3!!2`"%Y%a +f[ER+)DJ!!"@Z!!#Q"`!!!L8!$q*Z!!!G6J!@lCd!!)Lj!!C0Eh*P4QPXCA-J-5i +e,M-!!1Lh!+X!MJ,9!J!"`2q3"!-HrrcrmXY%!!#!!*!(TC!%!3!!03!!Y`$fFEF +!pR%!!"cV!!!GdJ!!(1X!"CVe!*!15@0[EJd!!Fh8D@0[ENe"3e0"!,(JXH!!N!U +!!*!*!4i!N!-G!*!%$`"#`G5I66Y4QLC-XLL#I[0id6aLSH3I'-#V81EJ!+@3"!% +!!$d!%,9j5)QjaU+b!!!G6J!!)`m!!"cV!!hE@!!!#HN!!!0J!*!%$`"0Eh*P4QP +XCA-ZCAK`!!(m2&4&@&4$9dP&!3$rN!3!N!U!!*!*!CS!!!&Z!*!%$`"#`G8(%b3 +"`b25lJXE%")r[3j980d'(SNJ8$qqG6jMYDjl-BeDdS-RA`!E49VD"RdrI@lFrL' +hV@e[QadRPja6)elNKm0QHLBqB!ceeCI!p,`eQ8fIHV6Y+[H9qHl[lFbjkCdheQe +rV-+4p"h'66Z3!-VPNQ3BET0SAB10fdCE*lHaEZJ%V@MCiip5e9)%HXDV))0Vl0A +MHZpBq3G6D'FM`lE,"*5PScmaM4TG103i#FC8jQIfKqHLXN%UaQ3N6"m$llG&U[X +*8jET[rF#*MlXDKeE-N'9e[Gh8Q2BdIThar3aY*T9)Zb[S)MMZ#LCR5+i-R9BqDD +`%VGq'eaU*%r6R1*,@f&[A@%EihD'P,mEQ5P`H@b+"52lT("6iJ$h-qe`I3f5pQ4 +QLP!r1%N&Ga8(0Z49Qj`UeI`N8#P&dQp!F''2jp8TeN`@,2T,UM06$66RI1hNIJT +*#JV5HZj+XJ,!C&rc!ME)b*IUSZVLIl1B3X(8hC5Z1SUfeJYkk[H8!d*rLMc%d&B +RlY%mUHF'([KE"Qde$bAPF'R`Z8%KJB)MiD*!CZ+E%#,bH%bkF`FFCRUIh(r,dPY +K46jl8qbfQq'RlBSPk&"R)`165TiB!HDlk%*Z5P(fHl5YeD,HUeEMe5Q9&'G5(iZ +AZke,0mGK"c@Fb!Y9[9Q8,Ch-a!2(YQ66&Ai5'+'cm!b&5p`5VAPQ@5rV,'h#6dl ++[NLRPQ5,MAeSbfp9`LGFmLZRmMBj0-1&5rR*ILr"34'bXTN)Nk#,L!5I(I0'pZU +'2SDpk,-R,-q)p8#'k``$3Kq-GH6@9C'"LSUcJjU9pi2DqI+,l0HGYkX@U2k05!G +I$Ek`0A8JQ@G`iYcB@d&Ep,hMbVACqiX9c4h$4'SA*XVi2&T0-+ipF5Ic4M1dHM- +b[DY[S"E9`Dhj4U+!p#*c[UecGHF%'M5M,pUC-VQBZ3Z9'lM599P8X@c*iApV5!V +V5jFKdrEX6jUkk)6**cH&&q4@c4EC!15UjUlH1mRCQP6&YAe1h!Tp5kMAR0"9UM$ +BUX#M5J@'"DEZT#eJLpq@2[CkDD,Zp"1@$$!)P6R'*YH3!*NAG!mC6fSIDF`aiP, +rbK$lTp!LDB"rCM04T0NYDaq44q%lp'6BkY14-RL$hYbe9Xhm-@Bb4'i5@ZrF$4S +ElfP-(3p64+GNJC!!9p'[c-Qf"24bKrHDTj)dmU@M*JL+jaUd&KA'bh%B0j)dX'$ +5mB8QD#p1`SVm,Mih,8'bp(80Z85HdmqQSU"$0KBkjEGp2H@(Tp64BUmZl4++,UC +2mXR8bRDk6rJ[`Nd@,iZCHmYC$$qb3CVk$pATBGr3k5$-cD(8adXH!NLC[!M6J3i +!R#bGPj@q`)Q2dKPRdSlP,$rPE+rD*XNbH1qIpcb%iZ1UVBQk95cAc@NYR'S"qce +I'Ap0,a*l@R`+P!$hN!!*)V@-FQ[URklX`i6l89q495RR([[KjP2AJ)6`cQ+ibT5 +k%J0%pB,'mf0bdBa,F++N[&dXHl6TpV8(C![%BP&662Pkh6)a!4`e'-[LNkK&2") +kAL`CMhKeT'p8("(i[m-C2,P8E11d2X5aA&T&`N46SXL[N9TTVJJZ+c6["0NS'!p +[f1GqLkXkkI6km49Rc*%A(8B,`Mi!4rKM@Gi!TC!%!3!!23#!Y`54PlR+)9`!!"h +5!!"a4`!!(1X!$3S%!!IrI!!!6GF!N!32!%e[FQ9'D@aPFbjYBh!!!%#b68e3FN0 +A588"!2q3"!#3#S"`!*!'3X(8aNfkPhLk2cj#2+31a9UdABaeEQbY%,BTkA6ND2k +RqIYXVm9X@[1c+eD2BFSFJYjZYG1k"JL8RcLkM9SkrDUbc@KVV[Frl0*YB5B!3U+ +41(E-6N"F*141%iQ`DRlPi2%II9KLq)lih5P,C6EbHHYA9[N![2bQBTdpJjr5fXN +(e+@a8q%#IEDKj@qEd#-#KB,3"V9Q0a9ZDhQ')RDX'm*)LQf93QY8)PpYRCIF+f& +jb3"&)M0j"jCG",KpCj!!HLM%Qkm9PLN"YH&ljN2EE[GCQjQj`!q+@%@DDjLH#"T +F-UB)lXHXf$!YZJ2%e5-0S1`E8r)YST2aJc,6U!E6Y(S`Z&fTCGl-RX*qmL$S#ih +Mh!9F"9$*-YlPh@*#-iJSSFIT&2XaTB``Al3Se*dkCV"-Cmk8j`leq84-"dEPZ&5 +HJ*h6%qjVM2d+"mN4DDUlB"Rl()e-X4#KVNp$$Kr5IpPl6RpabU1Qf!V2Vb)+)EQ +M-a+)SUk)E*lHdjXd#rqRS2Qk[cGeNaH`mIH[l6Af8-R&)M0QJ+K&-p-9FSG,qN# +XVYi*3"IBl0,Zl*@2(3Xkm`N-(C'SGYH-+pG$RET2aj+PbD3iN!#KVFK2$U!edCV +r+T6pr+$`B&'h@!0[kVTBfa%N,C3kMMdfE%H(96N[PGN9Q*V"-9mV(B26I'JQ`Zl +rBS&bE)[5PfB-GV9E4[Zl5'p4J-U)m)P)!qN2bLjZliL`krc$XiC#TTK[T9NP&pb +lEkh@2(5T5)mBHNkIF,d9Zb$KXYj2@8k&r&(j'D$(p)RRIj!!EQDH%L-8&IQQ1a" +'rkN3("Ij20imE4!aVR,%c6Gh*CH,r&GG5aZT-%`(mcCGhB#fX0-G[f5ZmLeY(,3 +',(EUKd&9@V$1lT2T#&HTaH6Uh(h,Km"0$Zf+#j'SDmJK0GdU+3&9!,SEcHHFd"L +@$58!*X-IC,+RJKbD')q@JMfJXYU(T[`CM1iI*',"6)%ld3Xl4&Kf)&C@ci%h-%D +L6H-&5BI[&)Hm,+AY(I(kUJ0N)T3$6+3J9BJ,*Zaq,(6Thcc-9LP3M9XIAEBRbAa +[j1mlmF6k!X(Bk%-,SLbGME&K)`GK6ceH##hEIpFAcB0eG-k1i$VN#b)(4&-UpRD +!HE1LQ&aqmR&dl&bMjh%C9A$[#*F+qJGJ1$9%`E8cFemM%&N!9GqFkr'q8#BL%I@ +YbMiB2Qe&&p(J5(VAJpQ9V9kYHfGI-4aR"!l`Ce#@ArZHN!"aaBYIi8V6TaiXEm& +C``plh"`Iml)1+0DSq$V+!#3L)f#bY[[2,Yr5Dp[*m$l`lb`9ki"1Bj!!BF-'-@U +1M8"[b[1l),+Udm44EmSCC,2E8`HRX"YA#h+B3Ei1-qSp@VB'9H5fYSMp*QVjrk( +'Kk[Br[H2#Cm(F9(+,Nrr@8IGD89cDYQNF$Q-$e6$b#*5'FUTe9'%T#UA$aSH80r +$8aRkkXeMaJBbBbI#dkTCfMLLN!#q+882-*m"Fk@rA+N3bT0$9LEJaf28RACQ68D +m[S9N[XfVfr+[Ki#e55+V0S6L-,QRL29d@T-B+*GNXeP6M4p$N!#BRm!T(QKEjma +4&*0LaeiDRN92$IPfqMQ6D$&j`d3%'VGT4U`(qF+hKeE%!M0J@rj+(KC03hE!bMc +RBSj@B#lMCkA42JAGmA`&*54+BMf$4ba5M86a-@85pkUi%LAZ"@@XJ4*9Ki%b,G, +P!a)dM@NC,V150,6PN[T[["kX[mIkIY$d1L'Z9`eRNe9$cG+p&eaXmPh3eKCh$+5 +hk,Ta@DP"&KB[#G)MNP+3!#4af6*&%qcDlQBiX(`pBL3jCiG6"iAm+f5H&")6p#! +YcGG$8X$0GBM@d5lXEe0EA$R@NZISZD0qT*VA"V-Yl5G86-5Cr"#%$NS#fY`IMrD +P5XPcb,!AXdJ)NA#F3GZR2*!!APh8e49E3j&r%!d(&pP,lfIY5P8GGC9(9L%EDaD +`T$bRQNM&`AT2H)hGGf8M)Gdl'"')'$!Nci(RMYZ9%CHYCE[G1X65Z-)2#CJ#4JI +%DfaE[Y+P,TiQ2(MP5hI[)4VT,T[R"*RmQbMVhl1Xl[ENLl5p(l6IR%!"Nq!e3+D +m(6h-1XaX*KS-J6VHHh5Dc`5EdI03ILFADaRZDJff6+rA`A-8aUr0M5pebdBL@[! +Fb@1842Va0IiR9"*MY8$rKMJ0BGaFpKH9QLFjI)+F"#AqI)Pl2#-(EdVYTeLlNBd +Ril(,hdik85Ncqh%6P6!@63f+,HXIIU+1aS*qeeU&Ei1&&'VJ1j!!eJ*'VIf%H-T +Bq$*,bL(bQIEJ[VI@1dlFTD0FTBCpJ*E5MZJ#"Gci+52VHm64`(FQ`be86c)k6CE +4L[mS#j!!29+Da@c)LeYdrl%4h2'GalG9HE6ML%HU5"ZPV4M2$VrihT3$m5qA#K3 +maE4h`H`PX(e-C`lG-4L$Ih(#*Tq$Zmd9MUHX&P$1!3VDQl3[N6RZ8*`Nm"l!$FZ +MC9+L$ANchb*rFKM9RiEcSDUfRiFTda[ZbJb&9MCTNbL)&jNNME1mq9Lb9cZQ[Q6 +b!r3b)f5c60X!a1NQS-l[Jr#[bH,P4"4RYf,@0Q8%-pmGPK9X2pQ'FPT9(d(d,6M +[dT!!bS,Z@Z8ajBHJ*lN0U["@FZhJ3&*Vi+`A"q9ZUPLIJh),6kESCJIES+*JCUl +HL0K0Df-DkLK[Kd5*U&VP1'(#0@jBNbq(SVZ,1,5%l,S3SQMQXliYi%5lBc)(G)e +QFH$C)'JBk#F'%h4Y3E5`PUh'r3plX19X4-q+#$RAY#jC$)b[65T8Iiic8iA9P3b +B$eRN4VFSARM12r22RfFj1h!"h#cdH1(G$b3XNLf*kD`qhF`k@Lb!cf!!Z!Bb%+J +-",`jpKHNcKFSUN,dT+Nr%$fp#k4j"pe@I&I4#V%fkqeYA5Gkm,YBk0M`4qShbk# +ef-p,5f)[k!I[i62,i86p5)0'#M%Mb-#AKAi,k`@'88'bbMUam&ArLKHM99KDVEV +B)N#'!llAQ(5Qa-B$4j)SUL)!HRlX&1GVki['QeQZr-#b*plVUE@q)p1TD*@dcZS +0%G-9aejq3C+`BBpXh)p&'BQdpSke*,hS`iiKfEb-V*kMV[)PGm4+V'fH+6b4H", +(m([JBX0A"qSliIH6EeeVkDm&!UL9,$Ab(Q'd@fMJLiJY*)q'JEeidNFXj)2Qc#5 +"ANXk84NhYC0`c@"KFEJSCCU'FKC`k0'1P2e+T(!&G1XLDpMPS1jpRiBbU@[f4q& +f*P*P&mEH$"3TC!5qI*k9D@+KpCjI09Ie`ED*heUq[P9T-Uk8Aqaf)VAD8L-3!IK +RXX,D@`C3r1%8V*e&d-BkS"E1qQ+ZqTiXM6Md5eA8HTLf)#%LEeF66#c@6a*m"Xh +[IJAqKUcQZfLa*i3#pI[rChL-jmP1l++'+9hS3"6"[3c(#*c-4DkXX(,8+00CM*1 +p4qT"JcV9e+q&TMbPd02@hV"lF[8a#e%X`-@%e@m,#+`6*F),L#Xp!aI3q[-@k)C +laJDpeBMKP,H64b!N(+pA063q69T2%ZbZlVU!PQjR)00EH1'CS[VB!*4$K8#4-#& +@J3YeX%i6GX)ipErFA-+rj2JZYRIpcCh'c,Eh098D(k&cjqPB,S8@1M!L5mj6Ar` +pk1%rJI8UQkLV')e2Ep6LjVjG1,k(d&+b!1!c@JCH-pH[1fljJF)%"MkKrr'Iq0Q +GX%+3!-jc90D%JSmrSC@MV0&ph6fBMYAi(VFd"8JZ9N,k%[BFPpS6X5e3IeK9*J) +QjfSD0-i*2&%@(13e8jj`+BLjMZJ[5b)Y(8%5)N[*6C(APDS&M1([merR[0F,Z(' +9p8*eSSqG%G82&"U+hCE6eSBmGh-*@-D&d'R[L!QqdNCQVq8i+i(X',QA6j`Hh+% +$+8p#m"I4Hq$jlbQq0!N5mZ,N5BhPA[IaarNK8S@icjK*PQq'ERq`3kpp0UlDY0P +rfV%&S5LF0%qD#`EXdkj#+Z@,#+HMcMK$*F8F"`TKK6PBb%(GCrqiL3j,*XrH*E1 +bk$k8CXC#2b6MP$4)B&&Bd&LD[f#F$bTlD#$3GVpBaXTrZ)Xa+r`eiBBl04MKPYD +H2NPL5NhI5HP+8a1*-pfU`d1YqU2!f2YGIhqd`NA$F'4L51aA36LNa4erRjT`,,, +PGV@NUr(rra%C[5"*-9R[j#SBe,B),6,i`iVKfiq1%4)@C&j-'D9%dbG0BF0('SP +bilbH9+*%jfk,Li1!H(,(LpKKQABBc!Q,eU0P9K6-$T1$998S8X5G(JKfKMFl`A" +08$6!'LFkj3-K%j(2RVPEY!Q&AFqC%AfdHD1)Bm)1H0J8![$+IQe"G@r')H%BX#E +M&aH@'C!!ailTj2ajX%K!HbYE"'25bEcd0k)#$MSTNq252EZ`'@UhI0(#PkkS#Jh +'d5*[NEcA5rN[JXJeC`PP(F3ElG$mf1VDjK2Q'AcYmKL"(4TLhq4$SRqk8#ja(rb +UCR@a+V0INLlaX@B@EcGmNj8MA0fmT2@cjQN"iIUXjp6ZR[[0"kCV58SX0*dDVdi +diX84VV5$Qa-()J)Jk,$kd8bpJIjVbEBDTK#%K[&6ZJkQHbCXMDjZe)&-fN&ZlYe +G4kEbJ6djrS4B@QFpDF[B,(b`#Ta``F!Lf#6FC6PDSPXfc4NMb2ShP1H9'PUYVlj +#hCX"-BI%D,P9&NbM#"`-5JJKaAmd2Vm!IAkfQZCZP6Z-"$P@Nl,i*+Z8-ZYRXD* +,%6eA1@$d4SYiIK1jqU%C*LR+irV`Nh3I8++,KQS`0ZQU2RQDDdSmH1[%0EA'V!m +(&T`HmFXiXe9HA$if@U-`Yp1jTMQ'+PZ90NENTMS4YX@&a0IfU5XR5"$(*,mJLD, +1BCL3!)@IK8-!q@0B8Mac`XGF9Ta(dT5m[bp[+MBXmVQ$e)mVNmRRRcV1"cN@53J +,G%ERY5N1Tkm!"%CD`M34Xp#0qG%B1ND*Yh-,Y5($SD[95$Xm+$q-*2pUa-R&lhd +1kmUhAK'&fcCiAV9(Ea%M6[8J*T2pS`Iqh+Z+%BRIARMb+'lM&f%%1H*8SG`1$SF +jc2Y#2"e%!0B&9NI`dY+"lqfZ(d"QC5Z0e"Cjl6Q)$**G!HiAU0K1hd+biFIiU9Y +XJ49)9-lAQGj0DTlGr+@+!AJ4IDYL"h,2#3MPZCrN1jG$p+)KRQD@LL-'E(%"*f[ +`#YYK5*aj8q+6UIJkG1l`J3l+[I$"3+dpjhYeP$F!((D3!$EqU!da(,bH5"0N!ec +X"LF&*PRqGX`Z-6dbm+Aa4bBUrD&AjBBerbqc4HITFbH3!)'dU(EZI3NMf!B*Mm' +8N[lZ8ql[(VP0Rm5`elp*DYAeTjPp5SVpS-@5L)EfY)L9MXq8ZirV#m1c`ke8H1[ +b)l0)Dqk6&eV9VC8`ai5"R,e"G*3e-G6RUUEZGK9*DAIjiE*eTrJ3V"!"3ikF[[0 +khp"59d[qVJU-8MCK@6FbkGD04UC6,J'Yb[e6Z5r$Y,-A30a`83qJ[q!Z'R689Q4 +!pFXq"em9918RkLjX5[,TGA!JRP,925!rRZ%jIBh$3R!(A[B+d"+(Mr-'8kc&rNm +9AD`VC*bLC6q0JKS585qXVJ+6kAd`I8AT'TGk6S3LD*4i5rlTYq(%i@YId0G2bm, +L[9dc[$'4hABJE'B@k3pP`ZppL06G"rc*$DHA!h$YV8NM1T!!UU5)AKLf0SL!"XI +G3HDfkT*iYB0(3)HU)epl)"`ScX'-ikjqEmH645ME,A$TF5rG3h%kYI2QSP@@C!) +fG3k[8Y-mJM'lVrXGRqEMYrfLS514JrCJBUC2VI)F@c0l45`1+q++fr`e`"EQjm( +d$"L*4kBKc'V,6C!!TJ@!,H&rB+FBBUC'R3a'h)[`48G6G#XFZ9eG9e3@kadJr-B +j'(T3N!#PS%!bJHF*8BJ9dd9reX1bQV`4a3J"rTR8,'@ALE%Fb"NmH(1S`i,CFFC +[#k*Ed5d11E98*`*N0akImXrUNhdN+Uilcf+X'e!+K6rR-8FeaZ%Uqk8h#cH,"T! +!Y6B'rFmS04d6S5B3'-ISLD+09ZeeSL9fH@RDX,mp-U&+@8j*AK"Bd*eRL#LGp5S +%FMNjKl)@+UNNd9@IJRTRRF@LfM9r-!VdjDZGX$RYK0$HjFLcVCe#+efH9*Qj-U6 +&**!!"K&h*Xi$-r5ai'%*clh1RD$m(U#jIL'KS`Ja[@4([SCS@L!5D[S'E9S8l4( +PqGde@I4cf*RZIZ1H!(Z"PT%)4&3YE&IX36p+edMJciM"3Pj*"e0F+P0,k+8pl!2 +KTmXTe9,2jGeQr2UAHP8J0fd,pLri["13!&Nd0D%`S60`T*2JQepY42m!MGHU4B9 +!IA-&8)(jMk%I6HY`bJ53!#V0eLJ``1A%rU@#dVi0T0NVB@F#e6DFmfdiXCI!eB` +ie-48$6rjL0Zfqi2254ZkIRK8N!"G#jJHB(BrIXCpFi'NQd#%-ZUl4f9bPF3U!pp +UCYT81$N*0-)-5+@kQTEpNh!4p"lJp1PHl@fhjBp)dGh'4mT"9kBTl@d'5$dcM0d +VLk!V-"0eYhAaNC,Tm2Cm3S0-*EJ1De""m%`HNMjc%kSKjKlZ`q$!Rq'Q3T@4Ak5 +kIq3&2-+$A,k[EdUU#0XN[KHF*hGr@-UG*H`i*P1-Zdl'J$H3!)R#pQ0peaAN-I& +jA`N%+Z-a)(iCd+UD'$@UG1h-I(CTKCmkccfKZZq2+'Ye',`)hiSU8I0fDXM&q!H +rDK!mS'RA+J,A9-2fC9mL8&8,DT8RT[fcN44EG06HFr#S,4VJeI"NaB,%i+FA&4( +aQ4Z`%+1)HEaD3elV0FD1G8dE-r*2CT4&"N59GL6ITIFP5UKR`1*9K"eMQ3`a*a2 +DQ))L8fprCZJSpjGRZA!95Y"qELf5@%I`L"!MRRPQT8(8*V6LCDDY%!@lSS5('3, +&L3`Ch2PI#04NNld#SR455H!)302TA`48%A%Ymj2qlpVKb$!(4NAYAJpM+MZC%h1 +3!-8iI-Xq`TM(%AiM`aMNTE!e+-CE9"YZS26mVTjB&GU3!,I3(fG5b(,N%1,FFRF +BPM2Tb`qee)2A4'JLTJQ&a%%Z"!f2YQD`b'GS2A%"4dC%h0@lN!##EA%8aPa6Q)0 +1k@ilXAVTamjGCiRDP[ZiLeXFp,TjU"CJf2q,Ea%BJhMreX)6D`B!*r6%iiCL@II +k5h[)Z#Lm!BKm9qm*5ZbLVeaYUD#0M4L*Fk+IPVFAR2UM(L[RNRq+`@qBI4F)-KI +)IahmqVZR%)(`Z,@%`hHYPj&Qr"1%aeTBMM9r+%XGbQMG*CXVI%,8N!#A4pIaa`N +DUr%jfjh(@56eaP3`di0Nrp6`U3i'#1-EheQE%VPXdbBRcPp-24U(GAeh+T!!T$A +@X1,J@4bTe`4jdBX+6F09%L,Pk(2jZC[HVr)c+6`%HbXqL,Jhfm2[SAZ@4cI02!+ +abQUQ(h5E1mk+NFi%1Jj4#TjQipL2kC!!(rqYG5Mj()4HmAKPL*G!M"61mE`jUb[ +&[-)rAj,#hR5DVlT(%$Z9bY[J"&)(5D)0hh#L+hDD*QF911EA#M3#*4LXlicZ3-q +hQ-lELjm$le-hhNq'[1!dK)rG!def53r8`p%AB0V%(2(YR"T3(qrl-('&CBaNj'B +TaJFfNp5q*r3jK5A#J%U4TpQQBl8+jdlCE`l%hjQh'#"A)A,%IF!ImBhhepqN*GU +1MZdjE%c20#e,bPmGd[B[kcU1!H4"*DIcZ+-@e`p0F)LpQ2'c@QLc*U[MZdla8#@ +TH2fRA'U9[%%RiIdE@*bQf,i`ETl%Z0*cpa9LVY,1[p,1m3SfpUIp[a[Alj!!Cd) +&@9JR6@ShcK1Q,*bKNTB@0DcCALm$r60l-d`VAbGF$3Pme(jVK$j4VRc+`-3,Jq5 +aC9AV0"$Nl&L+q)F#&m@*1LEiT8!H@JPiZFFQmALBC5BJ1UUBpde'[&4EFSFR[BZ +f#jI-aNdH`K43e+1RVB'm5NKlSQR'(B26@PSlap2j9b,qHiL#m9cUZFaj39&(SKr +,rNk+"cT$LmT4%8RE9$`Ih,!C`mE6YQe6iM0BhA@9+QeTEba`*2Zi8hTZHh"MX"1 +AVT,beUVeUh5fE6J)![r[L9DlJE4a5EfCh$e`aRYl)9(DNG&ReCjh+)&VRG5)U-b +6ULMe(I+E!"KfY*5dj)X8YLil4FTHNQM6+pf4mhE`*R,!rFe%0UNc#RIf)jIbr-# +l#FY"6[A@DV4'0+%peSK#4*ZhcPaY[4brD,4@ETHLd2AfrIPU&e4,+GqAI[,jP0j +XU8QrUV%+1FXM[hS0+Dm#`(laFCa3K6VFr(&D)dP%m6U9*`2mr0DZG#cVK)Ffdhd +fQ32r@(2G"8d0a0X#pb(U4fHB&mj"1c,m[[(PUSR*b+PM#a#q3f32!hV1V`%$Uf) +M`C!!$hm9#%'[$Hr6j%UrNQBQf&`1"SPGEI%+"8eE8q*`Kjql-lf00'F1QclXdfS +3*4F,(BBEH9DpA%4QM+E%,*E$k4ECM[he-94(T-%K2i)ZPX**&QTKAbIh(m+eYpN +,Kb*qGB6aqe5lLE!qmTI+cl,TZimcFX+8ibS"4A`90TNF9,ZJ3&#CbG3eGKS(,R+ +,X"e$"E+Jh!Z065-*j9f8qFjU+US($Yphkc+U0bRfS8!j(%)@6`UF&JL*!D8q+L( +kZj!!l'BCUSG%6Um%K+`dK(Ki1"l!XjAQV$TRNr21KJCNq(Q#rV6lDhU-rVM%9f1 +`+3i@2,rVpMB,lb&pQh+#K+R&,DTMb8C8"q38%V'@`Eer%&`jN!#)0a*EC3m6%S+ +e)cEMa$m!Uf@KM&E+m"a`rZp'rNZr2H[6Q15-!aa1qfrb,$U*PlUkprcBdU`$eJc +HU(Xp"ZR[fbEJIQ+6e2L9RpGZ)0%h(00LZKr"`lGTHdN4[Pm$@X#p%M1jC!Q)3H1 +!S(9i4pRSIQTkmhHbTNJD@['1F*-+dD!Q8Y!Z1p&"k8cPJINbK-1B63PKh$p3RZ% +m)MIKZS2lNCG(%2&*d0!ELZ2[Y$fHP@$Z30BJGaB+Eq)Ff3V*8hh)j!,e2Lf,K+( +UZ6F"fU&0NG%9emAq9c$'3[M0a8!6(mP8aQM@Ib9c"-HRX$VT14ArIS`[aFV(b"+ +-5,AlVL-3RqL5qGB&l)FA-*3`QCK*C%hir#i$5MN1qpZ8qAP)EF)[YDAk[-aGhH- +SAA'fT38ZVEf9J*D8aVHdT$IiBp29%M&FkHM1KUF*6R&4M1JK*66NI!@@E92J1Fl +#d'*ab!cf5YSN,hLce,&5%9)EVmLZA!V1AiFrJ62FNZa%6$ZqDAq#r6XS@91HDbX +8+#X(*Hr3I`6SE2+9BNQC@``R)q3D$p&P8B(6-[`mQ3Fb(DBB0P@6D-*"-1BHY+k +K8amZ9V5J-E@ZVE3`XJ&H3EfQ+*-82IP@U1L&U!Qk)lD0A5!50#NJ-bL[5Vb*%rK +EhHUM%8&E2mi8qK1LpH&4#6![QR#Ec-K4GUDZ$Q5'GZGAr#4M%hTabS9TS+b$Y6m +"(,,ALi85*B3-BdYG%a)+VPl(5eiTTFC*KYQ8*iSGibBBAK1Ea)#ACQUG@XB-j'J +Q3$@$+931`f%!k@-'&lh3[QeD!`LRTH%@8-m)%$CDFcY9*cJ!S#Ll!LmCRj18d-h +RCIfRP*X&*9A$C9l&D03c-r((#h'M($'JZLBcHRZ"A)1mrp'cUc2i$0Ak6j!![Nb +6[PL5C-e,CKLSHE)qVBG`999`,P+cDG,NfcRm"9P&S`a0C`ZSB%6I4-BZQ[rUjkJ +5q5Q`fch*NPGLpcLJU+a18&@AJcN`jBdpfb@9NT9h(cJpKEb$rLr1)P[Q$K"0D$e +T2)%,+Z&JK#eTAS@K2Rj-`),*UZf!$Ca,5T5@@XNCGBk+fFc&%ZI0*L-i$09h'RA +ahd82D+3kl&6Kbk)9+ae3XG3ZGILZ&K+-fd29*d9`5V9lpbPaeG!N@XeVAcKceTp +UadcicfiE`1JaVjJajDDV1G+$a)Z(edU5$h25!H"f,RMSUUcMh&66Za-0U@iEeeE +Y#SN31A%b)Jc`04FmaBe`efZLbr0)`*!!8RJDf`PYrrPT9RD83T%Y6"S3"'-&4)I +KpBZkaU[J"+Tb#8I[+2d9kR#qU"KEU$qc+HH64(&UCB%S&B+!haJ1(CkX5b!frEJ +J5RmP#XclL1RRVKE+Kk,lhD9Q33GLG!+0#aN(RLEX9aKh(rL'%NChlGJEZ%hUGb) +1X+&!`Rq5hF&Mi-KBrPa0hjL4a5GJ!&H(BiBMrPPX!PC$PJ`'(8rPLqrCC#Q133U +rF+N*cfr"XPpLk)8+IeDl)ip'9kM5B(5k0**"E8MNiKChT"URLjlr,C!!#eCkF[F +k$kJ@HUekIDi[HkRRpMjS'f$d`)eZj`+r"cVM9N$0M#j4X+(UQHQi$4%Nq*L#TF8 +C+Rk*)N@M4AA`UhpDTDJ*"CHSeGmPP2+FdT6h*VGJMU*0jTT!5YES)AlFG3T5KN# +!Xc'e1lhkR33r$,iC`"0I6m)fZ,%d-JXDlAlj"SJCf8SF(ZrJJ!FarR#K&(Z[93( +Y,KCKL5aM+j%GRS$F-J5i5T!!TpeJF49ECGNRFr1+Dd#mpMRN$)Z2VUY@6dmA%&$ +$'9Mj5+4#,L6cKcXpa#QSAcU[N5m0hUTKGQf2,)U%*GV#-YSe%paQB[bTNQQ,#*- +8"024dP,mDSH#ql[FdfLH8+54&0E@YH6e5ZpTiU2ddpaq%ip3(T!!SMMMqq'LaZ9 +prSmecbaS&"H&#M*3l$2AaK*5-SUkC,m6rqAY2epID5Z88NNbG&A$+)@U$DUNKQr +!rUV,2[!%rPQj!r[VmilJirNfre"%'YjJBpQX15El-CBiJQXT0cb#bD'Qh0ha)f3 +iJS0'BD"H!Ajf#R9`h-c*!b![B5CM6P4c(iKZPr4mTFlfY"q)-Ckc[C29AP-j$@` +XYJ98iUmQ1N'9Nl"4+pp!bf(rCIbAr#5KYC0Z5`c)8ZZQaA*V[1-N4e!f5U21chK +50P6T!%R3q0aeD#+h+$`Pl6,SP(aLG,$2IVdJXKb-lX1lVDE"B"9aaqG!,3DpF0@ +epKrUf+6p1mBB3J`dG$6L0B0RAKUY0DhP'83!qF%j6m30mRdbc1%LlJA6mkPGRUP +#F2'bZXH)B8iGGpBRb%d$1-PjI0Ti-4'3!)8C$plU$+XC@),&hl-#mrARDmbYEMR +H,Y6hi@!*$h2aB3&Qp1mP#II[T!B9#'6*p"KSiiGhc[X##AIL!3(Z!UI`!JAq*#X +&TGN2aQG68&1Bkd5d#fA%p,+#A8S9TU"rq!UPF[jFVmjc)Z)k0EKEm62E*a["1DI +X$j5ShE*)8I"GkR#RMdf,!cZCVebrbKH`K@rm&`P%ET6cAae'er'cJ!SjcbHXEk# +&NHC(-pG[5)+(B3@"RAaJ1Ae*N4P,mp+"mHRi(HAEFrAXIQrjp*'X!B'EQPXaiCJ +a3b!#TEVD4MUA*e1bPqTbYUBQCdTa)NXIfX1Pp&PcI&i!qc+pd0VlqG3&JI(,5ij +IdJ)-r3rNhr$VP)#**5MDqHT1[6##K1"`X++EY#bQYiA`N!"@0KqQlh("Q9'B'ik +Fk1Xd"N6N2%0c&j)rP*lGF(jBf6AF&(UYcY+5+Tdie%"q%fP4qqcGHp(0+ap4LQD +!rfFb4aeDCj)&BM*dMXfY!F+D6EI+)3c6JMNcffjh()jXBC*I"KZ1X5pkf4Pq29N +D@H11KJe6GZYcELb8jl(I&*e+1a%@"&%a'qE4r4kL*(0Q%92+jb(NbU#HT[SfSM* +5IcVa`@(iSff*1hr#m3`iXK`A,'AYDFHDH1e`VL%hTKcT%U2ll*(%*MXXPEaF#lX +90SNRJHRVlr5N3`5R"(br'%#3!)I!rM-!3+*pmSmJMB,Z+8kJTlTah4LC+m)HeL` +U5ppHGPUBLIDZZMfiA8lhH$IbPVjmVkhb9RRKq0P-"pCq0ZK'!aUIe!l2GmmR3[r +0Nj!!,UbZpHr8b9G3``e[pY-'A[0`T8)MVQ0FI[6Ti%RJ%rUZ201e5q%VXLD@2Y6 +b`EM1XTTmE%$*&M%@NQ9ed4VHEZ0TDXI,-KbZ'!CV'mjT"40+8)dV2pIiKHArCa- +X1Jm6d$V9fN($,(8JSb(!b8[T38[qHplMVMYl'SXja&3'Y8FYA&8e`"c-a`f!fCk +5G43UYTe'Z1BQhV#9kZ&&HG+ZSRVP(ii1HUk$iH29-3eDikN(b,["STHE#6D+G#D +!XKa)I*Ek3&HRlrNpF'+a+4[XfPB[%"AD18X)ZrDGPQ*CcE*eXbR(QjIBQpqC)"R +f`Gb#iFC3IS%S)X8MH"')'#mrl!+DiSqb-*T$'VDkicAS69aaL5(%qcU*1Vp,MZr +5p2@VS`M@j0-jkQN)EpPVPqE3fKp234#UT8SLlI`X(Mfc6eG-dqHqY'*ilYTZl18 +Cm,,iQlGd$1e9+U#U3m2C!`,@idZ04-iKQ4Edd+bSF[BiJZ$a8f5Kj!bE-(U68Q4 +N""I*9DpdXE9GkYjV9!a[(UmfjM"-pQ+"CNFCZM5rhql29FcPlB*mbFkL*CeYL`r +JMN,RCSZBlS6*IRpi+@fLLc%qcZYUID-p+qpc`cP3+ZZI4hT+("Y"PQ6)lS9CMQ0 +P)0iKQ[,2#bY#dJK6Yr'S@&r4Mme"4K9-3&&F[9H%Ff9qaq!PAIU1Mp(0r[@h2DI +(c#r9A5Cj*[1dXA#m+$-T8S2PNYQ2-i#Qqkd+p#J`Sh8iL4e`#&N#8XfQ3i!ZPJF +"*J`Ua0Xb(5DK5KIRd'+SBAGj`3Y6Q,XBJ2-HdjP@'3XVrdLaeAcCGA$F`)&ki!6 +U"dc%J,d80AY8Ja)ld@kRI`+G[DFj)jI)CER0[8Ea#kpE%*CNFXr#N!"2[dFi*@T +d0"QfiE12$i#dXMfQaFI[*8JU8PimSm%I4hp9S@-PBZjLRT!!)!*r#Dl)jaRVEf8 +Lr"A8PhG$KT[+-%lbE[AF-3Vh[cdqbQTbRpXSX!5%D8L+&S$5i9XI9$UG#Vp+L,Y +Br0!)Ib[RJaK0B'LaI83Bf+EV&Y6(P15*Mk1#kqHqr+U8Ma'3!1U%dE41Z5YJrKQ +RA'*[3("f4dF!P-ikp'#clp%q`NJ6d4hX")(C-E(V0,fcBiU%dLAVMpQ%8&`0G12 +H`+1$aX(,$*8(9cE1Fl#SUZdl2&85MBC"eMV3jAJQb+Z"HSZ2qLR#`kMUXXHjLHN +b9DZZKPY8#98c#Z$)+4Llhk-h1ICiTVUkMAD5#&Xj4$3#S9dRj(M'f*SUK[6dDr6 +4)``,(J)GDj6a9+$RkMZhPD4dpPGLHd9-"$m)rJ[*%*AEb[e05KUXhVYeLkKM`4F +3kjY2"l+lZDePqkHk'-qPVI6mI'XL%qC$bC6QV9hDC[T&bmaD*V(GP,FGR030$bl +qr!C,G6*Ea(@kr+5Ypkc6m'$GYfk6K25+df-963+I$KA,H*%a-%35P!@'bIVCE[4 +2)4-#ZX#T!"62!eLj&CGq+daT-b0DXG38%9@&0MkfP'fk$RINUI03D$#RZe!#SkN +YJZ([!-"Um*k4j1&eGIh5jlLMSQl5GI)QIaR5![fE`"[%-NL,Q9SqT)"NVSi%bX5 +N!MD'bKa`(!@G9SE2"P(k**0%Q@fV)$JLc#d4dZ)IPj`B+4rmq&*iDbZ[fQ1K4cq +k9CTQ8,'V5XBrJK'MjFI-Yf`4i$8j!QDNrdARP,,8*XJE'DKZ([hJB+YH!D%L4lD +P'F60jLZm+FFVSHXB6SeJ$meifJ)ldpA1[)jKqmHp&ri%2[,5`q&4%VQ(cqjf6*j +rKSN#Iq6(bY8k2!k%R-aeEPeM)+'hUbqqLIQ3!(UYJeaLKeI'"UXFU#i&YPMbfBj +9DZG0ZT1@('!p)'e+k+UICi6kAB0j)ld!GlN,iBQ@l[0dc"[H`,JENDK-)V(5[Ge ++Qf(2*jCcafr2NJ'Ed%#Ql@,jURG"Q[jSa(Q6p%[Y4RcjY1hr'cf"LVGBr,%B +mj%9M2ejDTQ[l`)LppYRkFc$k""kUJCe,rrE89j!!)HSbqTUTBh(&diL!pLE)k,P +L`59YT'YiN!$5JdDUqkcSR-8-DY!a!&2!P`$j)MPRM3m6mm%bB*6JFY&dZ+p3`Z( +5D8K*[Lh&%'2ehT%SYpFYmX*'UrL1E'pcI!KN+&ED@dEQ,[mVH6mf#3!9BHkrc9` +'1N[0YEDhHEb3!&D,JhLfCq08"ri0U&qRH"bTfq1+&5)BcPDPHcdd[mEj-F0R'[U +-j*Ql2SbqF3YF@br5#6j#X$%V#KTIc&[TrSpPHJ3b,ETH6(hdHU,Kh10IC@*qcE$ +11e@ZE*[Yrr*Rmi`m3VibiX!hF6Qah+1%QRD10NMH$cVPkrYSbVE+H!b8E-Y)0BT +9[#haK[pNm1Yp2bldB2C`)TT$K!B$VUF5Ra#")+l40MYTN!$XrkA-#@FdKEd6&e( +#TX%l08)PkM9`QjfN1BkU!X4[NYeFEKXAV)+`a&3PDB+FcSeYCVZpUEq(`)%fhe9 +$Z,[SBrZBf)XJf-RG5"j6X5NlFk$ccYJ0#XDiNE*5[aIa%T'ZjNJGAThm34Q#H!' +i1lSq@+DZ*K[04"3`XX"CN5Ca&qYel(RcK53CdcGlZ9YAQNH(rkAj"$BT3jXaUdd +SPFl103aaX*M0lfDRVkVZDV@RZd6YPTTeb+k29N%GSCAUqBNFqa+`N!#2'FUDI!* +9m!d1UKj#rk#$C+Q+9[(``jZ%RM03QKA,NV"CZq2a+HaFCk+E"M0PAA+&pDXdq(T +h-j[)IGd%'q+1!0kSVJE)0V3dhk,Xej1Gj"8lVQ`-C6NriXTd%Uj'3IESSYdrK(S +'4D65,LUYc`+P993AM!@ZV[4QqIejB5U`d+R`5pCTc%jQ3)a*V(pqZG+kl#p&LYL +QYqiY*a)l49'bX-bCYlV$B'e-PifNNIZeiH(Pbd[pDVl++lqD'`R9HaPUL%5$Lm$ +`K,jr[Kl&!ipFG'85[U8UA3j)TMdE882JpPACHdDHe$kK$FQa%9)Qc[4J[6+R(G5 +1(ePlT@DZ"1qh5l60dH`"fLkA4*F[Z+'N@'@L`hj-5d%U8`T$iS9VC1eN86"PK#B +jG&TcNX)UdbA`TpGRffX#Q-b5DK0%4DdT%,2F#dQJ`2d@Fm'Cph05#jfPd05NGkT +j!@P6iGKU%1BbUFl9BB34)GC`V[aka%8Xd-bdVe1bb`J8aIk0NX`9'f(B!3iTbX* +cA*kq2H(l59)P9Z8@baGNq-&GiJZ0!V%FRbe59-b'bqbVLVX@2LmDQG0'f@B4*qI +j(iNS#ANP,5JVI!4`VA8GfjkHbbA!l""iMG[`'HVm+Ii"CJ0+!bQ'+K#,`d$i`Ej +9K3ia$QJjVZheP@5BHJ3R,N`,!CYeMeNlk58J,A86%Q6%91F2fT31qp'+'RXG)a6 +YR%G(ZH0`kjZi6@qJL4pl!(dc[fYRKlS%G-HemjQEQ0,G&8j+P34I34Q6TP8#$%T +dQ42eKZTYGm,JPLX%K2`+C4f(UZk3!#p'$HPUT[*mi9Cf6B-Til)mM!m9$rRfih8 +LITe89*r(h'DJT1I`N4eK#F5cc!*fXpZN`'MYLrX%fkR$-9k@dYElj2Y3LD@Y'!) +-FT`!LirjG8dAUicm!YR-c2D8MU409f@m8JjL%'YUi2Q5&d$Aeel0FbacGhD09ZG +-(dil#pDA%%9hY2,`KfjD18'SYaV(CP4[j3e,*rI0(*6rGMmb#IY0&"8HeZhXJ*@ +CHc*Vmb2-EA4LTKb+FDrp0cNYUe,9!Q$Y4mP@Q5lVRk%KE$dke&M#`qa5!c,0ahB +a)If$`LKeNRbDihQT@aLQ2GY"bbm%rKbB2S)iEU26qUH4$%U84jV,ki9a-0jba"q +$Y*MpPiR3X462pi)R-EG@r`U6Tp*8&m3B2BP9l*a`c-GDBY&eYjCTr13046d$$Q9 +HHZ*0GXND5PkAj'`%USGPm`6p35)"Z)"H,"AP'4YjXf$VSd-bCY@6UJXZG8c&IA! +E*P%Hq@U)KPMM5-0#qqP@Jq$FMXRAF[mk",k)-N1,0,XHk*dE$LCQ"0,)Tj6j463 +RDc"rZE4(6e3!X$[V59bQI8R!"N,$KHmq*fi5HPC)(XVEc#9SaAZ#qK"(S+IN*AM +Z`e21cAJ9i(HKPQEE&V$qZUJSbUa$Dk(F$N(QPp!%"L6+RE8fL#HF@I`FIShN5$F +Uq#*86Tq-Fqd"&5R!d+iGJkcl$Y%2c5Ki,!'ZN!$&#Ec$0pE%6+Lqf`eVFi+)##' +a00`IRKiV%2b[LGp2ZcS`PC)@2@PTZU[4UMIMi`J4k3j[9'PVp!IXp%+ablH6K6C +Nc%5(XS-jV"rGhjM$kHhTU0`[iN-8#E*Z0X9((bH!IS@66QQY44G5p46#6e%`#XL +FZGe'NVHAjd@k,35HUHJ`TaaYeq#$C"'qA@C*dVF2Xal)8H[380e%II[YAqP*DcF +I2J3LcQZBeaRmMG5#F'3E1h#U+J&*(JmSM9j2[-Mc2IGI)M-bEY55P1lfe`pM$p! +'3-SHLlkq%r3#b`lKKBpK[#B1'(c-r&p(NcG,Y`-'$kNNe-MSD3Hd`iXpmdVrd(6 +[4#&d90[1bHR&(md!8DL%2p2DeREGaiNA5@T,2fhK+FACMYS2[aD2E0ZE1466i8h +Lf)Y%0!HQb@JQMB!0bQNJ[1Rki*+XJFYcQqR!#)5HVI!m5B3hE4RQLPEq`UdCiPC +ZZTMf8NHCQ-DTJ%"Br'kI2(IR)A6i`[3qlSelrIIB`8C`$ebPe$8HJJL9f-a4QHm +#Vdi4JjQJAb(#$Y'X5TZeZC+eZ8@D8FHaE51hpTF38l%#0YVK[fFSUVad*dmX9#R +3V-ElCX5G@UCr0"qH*K#VUpJJk1&C6NNd#23DRFT!-[a&TN,mDSB%p`eJa6Q[bN8 +R4r+Er&AG1b%LiVDQKHG+-IZ'"242$CqaqSlQCbjMek63,k(f,(*J!F@Sc25M02V +J9mB[F1IN%I'FF)pJ5E!5X"%ckReEmkdY1MaCbIA@piLH9rS"r6BaLJLiT#"q+G& +29Pp*,E!K+Y*4Rd$RMmX'9Abd%'J%hYIr'fcNMbY+FCGR'[!)HlD$3M5MRJ%'m#S +9VJBrKPjT`9-RAZc"#D"fA+C5eqRi0J1,1I)AF+e"U2iNJDXJqrj[dMk-B(hSR!G +$-B9`UM"N`NJaDFp)C0*Vr8@SkLqXUGR,`jA[Q)fQFmpZ8VfBZ#cPjm@'@GL-Zm$ +k)N@ER,d2K!2LG,BPK($[3SUbpTGH,3B'e2PZ![pIaad$V'4'(KPLP!2aSkU9'Ld +VrLl+iG3*XX(CVUSddT1%H,fDeAH$&8SN+&hbD6[#&e)6$c`TH[Rif8eE06"68,E +'U3,rV-B'fTY*5dkGa&pab8IfDbq'K3CQY"B'[8le-Jrq3aqXS&"1e&PbY#+26(R +lhpPR!K&@j4ZZ'JK4,SKpBS@eIaBj&eU3!2#kG2+4Mb4fZR*r8#P`!bL2P5D-d$2 +jXqf`EFD@ihTa'-G-QNq*hhBS&hfXY"$ZG9@iq3c6Zi2J9R$d$35+fVETcJNN(Ef +UY@q+h5SMU"eRGBjMrC+mchS5AJX9q"lbr40pjK",9Rm53q-1(8B93Hdqi'+,E$L +,ibrQ'MVZHH"DJJd$)@*,U2i,&hl'MfF@ZAP!I4ZT2SAcdfXK"eQ`q[NQ()mPV$m +8IZJ'[kHMPmj$U1B%0*RCRqdKdVBeQjDhp,h4')%PU!3+EK+X"JC6Jl24VamCD3[ +KL'hT15A"099+EQ(hdK41Ump-KA#4#%QYXd83f%IJQ,'R4Zqch"'c+%Vj),3PSl6 +&4fr3@C8%Caf`&D2*KH0iX-6dL$jD6+MMSk'$TXI(h@MQP8fL,F4'+2[jj5RNP)d +IpY8UNXc4Y@HmQ,GUZr`2m`*Im4T!5dqEdS3PP)%B,+'#G5!j&1CXRq[-TBpL2H! +YIS4JV1i)fT!!)CCC'K3NSA1eXV(k8NZ(eTAFA(48a3CR8V93!jh3Xp%GfmC4c@h +1fM+"&0Chr2Ec4Z4eM)I,2EM6%K,21(rM"8D*V[EBikL54kh2Z(ZJ%aec%lA9m4S +eeJkm5J-k&aDj@R@&9TX@hFN*Z-&F-cb*#qhPAZ`JP'q3!(YT!i2)beP3KilP&B& +@9al4aCfUX9#YH`lA,NQ*+GS#4Gb22"@Z`d8S,dc#rhVV3ppH3RY)QM[bSAjZ%5q +[IkiLj`R'V##c(@E)0[QBhM2L8T*$EH15k-raS(YKSETRATk`)G)m@+cZLi#@lBV +l1H(lE33C2p&c*[ZK(UElmaXll+Z*TT`'U9X[S)#k6J!SYPc"&2YDDAJ0cVb5qj! +!r9UIDlVSE`#&2"K6,@LJBpBN&ACSpY&H@0SRN!!IS[X`K4PEj!6kC84lX,3A#9Q +c26B#J%ZVjTeMi(,Q)ae)2kT[HMGfeqNreb2r-!e+TVV8QGd!-%8BLhm@R)*B29& +qc`5L4j)b+%#59TA6Ph)))bD@lD`L),kjSVY&Q[TiBXh@'Z8JVCJScIdb"X3q[Xe +LiRGDcRPQLJCNcSFTibGq3N4[94*QCXj[Sl38h-8'p+E2TDS36U5MKBm@*+rbplp +hE&RmLd"VR$E0GM$-8#a8&#Tm'lcM8Vq*SLBSLP!Bp!2-hrQX4Y3c-$-,(a,VX%I +cTEG9ZpR9AZQk4+P0L&X+#ZUl3!V,8YSR#!aH0R*i-2,cRilABCS`&9%2ib"ZAB1 +IJ0%2Y#3QSd$[Xj!!RjelD(,RE%L&bI9aLlCGH[ha`!mJ@N`Jm"&-kaddepX3&c$ +C`KE[$3X"0@h,N!#@m"TIqA$IUajd@RY-R@aF@jDRQZk,4*!!m9N&m5e)f6jcm8l +0)TSQXpUQbF89A"E(A'[4eH#FH[a-%NEc1a2*(S"R!m1V$P4H@GX[)KhXL*(#9#q +D(jZ)hT!!GpTBl9CZj$-X*!PIE4@`SqM0D3Q9TRi&`[,$'E#%[H"mFH0'N9[1!*a +U2*L$6(I8qL)@krG[&Q$5VVjYSIR4@Z%5ASIF*l4q%DQCGjcM)Q#c(QEUIk19Y2, +ES56+c!L5T"$$cFkT0Z@p[Y"P5([c03Uc15GYi$2ZKD81b'4F@ApV!ZaqK%-APaI ++(aT6ILAS'j0$HS[8HX5$NV-cY6!Tc4daHDS!hQT2@iqLjP5fqjY9i$raI-m%b!+ +heG*&kd!rUq9*TQ*`)#ljb+h0hCqKKQhTDQ-R0K1lmIU[cI1,I)Dqjr'-%HmhVfB +'A"22i&Xe*m'q3cf-`!dXQ#a0U&@U#br2IGcjiSIXSRj!(PeQGDZpEceH1Ij6F+K +Ed`XAC8@PD5rqa$mdRd,Iq5))[+(eJ`Z+SQDR,T2D8dF[i%+p$V!2&6*GG3*RP2$ ++@"-%YMAAepJ9YBXBZ6rXdY)@&bYp"$"iQI(rr0`UCkej3GNQem$H-iEd%I(Yq8p +iC,m!%3ThJd"`5*RB5-UcMi5LpFlPc,IrAR*A64qZ`*U)qHpQU1pP([r[U1N!fKX +rj5-69(QV#bqqXXbb$hqI`0j)U&'2Vb2rIq4&UGD3!#4Eb&'F*8k0K4X)%1%6Q2i +GHIaRc(hXeRr!`G@b83M5$2c4c1Z9S*HqeZQhpEb[!k3IQfj["1&NS4)N&Udke55 +'EeeS@5(kE3@#ZLD1L6BI,M&VqmdY%L%C44QV@eDN(GPqBqP'%*Hbe8T%j1T!L@' +QqUlh,dESfp5N2+AT(3EYA&!h(Z0b2"#9EjhQYqF)%c'B1pIJD4r#f[bAD%@0eNZ +G)P45%GR6X,(6)N16aJB)M)V+b$+"aGX030VpbpI'dME#E*K'8RI15I`4)YKBbJL +0Z#&(4cEBYI3`Jl+2(8+`q@baB&!)f(P6RGE434-d1F'V&$+90eX'f!6bLe&Qh"a +JBVaS3QfhP2#*8JCUU[12*+dN9#m+i$fp2bZSS`2qlB)"RS5q)'J[pQ,#JD+#LVj +TFEA9!(lRVZdM(dE+iiY&BUNNA"GMHSLBRqDN1[N,eV)Y@LUFAUFae)XN2eFihi1 +kVK#"A$ke$KA"l`V63aI5XKp$$,5&F$"hF2K#PN``#Njr$*2%Mej5"DRKNGfEpXL +,TPZQ5BP*"EC9TCGFZ0(reLJFph)*XKB8ch4i"lHk@564#d9*-lC`,FdUXGF13Q2 +E#IBU(`3P0DhI3V)%NE"*VMX1HFQ3!,)6rPB-fXpS2k+T1eZ0%k3+5@R)(8)*KkI +N)[YAf8@r3"B`r!%&X-fCKm"@3Xi'#lRmKjpXTMQX"i1*UFfa9P0I(qMYf6jJ&3` +N@KFT22+`q`UJh$Yf3,3XRh(3i9EY[QiaFhpiD1#QCM@XERMS$DD`kC1a,li1"bB +kTBkFP&NYZTJcQ[AdKpTrm1'4eC[-RANDAVF2Q#hl6k,@NT4fY#JN)heHKa"[@f0 +Q'Y2*"38!h"c!6FZ`(2VFk'8d'LP)`5flmVa8BNGL(q)b&8&R8Y+bXpUem#HNZ), +D1l2dVH@Zm,SJT3-ZdYl5)JXed!-%&f#5ih($Y4Ta`@%P`VqLC[L-#VQ,"RTi""C +Y4ZVEEK'#h`NH9LMbbq#P62MldKQM)9rFKA!1XraKAdBcpc9M9ZFj$`PE`[`8bJ5 +6K!kfTM(ThHe'Jdi8X6pNMQ$J9lLkke8Ci&Z%0j%@T6JI8L(Z!Da""c)81l2G`Kd +P+mppr["R2hN[ZB6Z9Ei+Z"THGicXYTYP(TSPP0,HGMEfik#VSPUK[+`Tk'X-QT% +EmS9YJ9$623RPhNBR*p@TT(h3l&qMbJj%!$FBd"bpe(Y5HSih313jV**JJ`$J'Gk +8p4q3!2)6E1&bQLZ3!$3P[!RNdF6pkmNXeS9A05MA)ql6JL)*[m`I,&H,'Y%U$!3 +&6,F+hBd'GYp[2macpN@m)UC&#AG9(#fZ%2NR$PD-@%pPr$2B!B$kr6m-4*M!dkE +1S6`p)+5[&4cmMjCpTEAMraN0"N,A20lCY`UNmkjm86Am(E%Rq"1!e!#5A*h#aI` +aQ4%kC5LD#LfN8`5dqE5b4raH4mDZFf1(DEj+UeUXfLDKFA'0LQY*)4BJfe[p@QL +p8%+S03QG6$h2,T@$U8j9ChA5Cl3$@`I",Zr2LfCY0ZD[Yc2#eSXfKiVYi2m[8'R +5Ek0GJq$6P0dZUf3FDeXEb4"!PAL2Pj!!1IRZSR'(BT1,Jl%De#$4N9c,5b!Fj6F +abkP)CV0h)M-9rTh"5jSM90!5feEJ$YXlkk84*fm9KeL18E&UXjS"VQYYd9ZR4-4 +2e8eJe6SdZaVd)K@&AQFFlqUlDJ"NFF54(mILh)LJ49TPG"[c*9*C0@IQKTeae[l +jd,1rIALke9fp+'8rCHFXMc2bUVepp&#jVrm823I0p-0RdqeLfC1N83`E&Q-dYk) +3a5",US($N!$3a9&88f-cD)'e2Cjq(fKKd2F3*Z$9fL2pd)6,8')k$E$haYal9*X ++Eiked+f&CRaXh$Nah'QZUH1,Sp+`#1ID1Aj,mZZ0H0dc,lrPGVCf1a,f@!BL&Yj +3ibph$)6HP*8"kmrh@hjY'AaV+chF88iU+(h*LfPG4J"IKYK8cMR5eJ8B4GkL*63 +XBCim4VaFY0URB5Eh@aEY,&HLmr)#Z5LI&c#0KY&*B8"U,`Zq2&i!`)CFr+R[dSU +S2TaI20V@&df*L2hFrC1QT8)&`klZj)ceAjFGQrJR"H@ekjk&&N3fFZFd545aNZY +iLl3J$@K0F*MR-JeM8Mb"12`GQ!JmKHUMjYQ51%FH2`4c0Uri#HhQLFDPlEE2dh# +Yj6f`NC5jlEk$MQIhDF6,i-9BB9RGa'FV[8U#*'d[J$Y5f[GfbU%b-hE@$kmhV8! +&jQ*hG[Q&(H&pEXb08H%ScC*HLk5D4bLZ%cFTC&"(4(R2LE6ZB$d11-**X"@D@[6 +Y)fD0L86Yl(QPb+6,[HP-ie2#daQV"%NVSF#SVC(8Vl!Q+%cE6+-!F)PFD8kE@'[ +iZT8ZRc08j[kH0IHQ'&V6KT@Z&dJV25Z0r@)a@F%mS*r9TeT-YShE)$*HSG46a*G +2fGI(9$G8VreclpEF%aMPe[k(%J1f"Kk2)pbla8ef8450a()&Ik@#9)bp+@&!E'D +R$f+%HNdAq+(Fe#29-42YfD[-#5,K[*ZP-2#pGP@bea1N8XP-J-8L0RV@r[(Q&Zr +X6-dlerIDD)#`PC(YGbE%mE1$6)HrQAJD3C,6`ZSa(1$1EX&a+8kEL[M30hAI3al +L0'q6(8&2S(&-IJ9Lk9k*r6*mDamr3+LcHce1K,pMfYJ[eP28HT1*pZH8Yq%r2Hf +*kV$#@NM1p"VP!ecb"FpR20e8Zl2DBKpCfXjb1(,[6XFBUCpK-ZpSI-fRh2$r%04 +H'DC*&+q-LieX![@@$l0+Gf*qjNXh6qkjf*h#FJmi`PUi%"X,h&THH[9H0L2b8R8 +`2))Y1'X'6JN(CM`5"H'3!$2XmmF1C2'Xr$fF!$'[Jp8FV,q0LM9XRFGTl@YKbi1 +6A&%M#qbAjMS)afb%5@`3@4`e)VNhd@ZkjqPJjb(da'3&1dk!LL6I#',E4H')C+8 +apU2(-Pf(#Rd`amJQhCp[!4YQFc-%@d1k%3C,'40%GmlX*CF'T81d)kFEeFJ2r(3 +4EF$-%#lJNV4A,ZKm*!"E3(Vc2L&3E$DbPdLmJL2[CSeUm*i2Mr3MU,BMrqj61b% +[Fm0`6khk53UHbEee`KrDhY0rIcCE!I4TDR+%@8l[kNQZZja'a-#VYGYbY@rV&Qe +AXZlpV`XcHrpEJb)mZ6e)Fb(0BiR!GCR2G3-*Z9!ZJ%K%NPV[X9c49Q+b[3"i5Di +ibEpadNl(mY+kZ"@mY[a#ejZD'5C`0qR8lG,Q0`81FaM6b-mmbJC2B`R+,$3jNVP +Dhb5j(f%d$,3BAAmhGLQQBG@[Ye1MQ(B,%ak4E!(RlmSrc,)-m!'YN!"J%RhGj!V +6F1iTiPcm0&K"EHAjhhfjRPM1%aHa5CmTZG@r-mC%-YZdhPiB9iAVSamkMa8I+q1 +PlYA5VA&bH@0K35F5YHFFh2Vl@H@#J,5`p%Z*`G+J2l8M*0R[3(rrLhF8hZeD!`B +DI!1#4(abd8M+E4m(QMVe0ULI!-j%%V'S!BBIDLJb,R+XZNa-9$cb5,jahj43YlY +SLlS0@dApIL'R1b[LR4"ViMe1`82Zq!"KA@mqpHZABD2XLYIiVr[d[XPJMGk6l5p +8(+qNpZ"H0D#2*E`DR9%1$,qP#M*MZ1Ij(243bEfddRjYfY"5)[N,N!!&UFpX8`( +Q+Ub6M'1h&GQ2lG5K!NidjV6LbjmJaP9X2CSdPP*Nm4ALiQ4QMCfq4(p##rfBYqB +QmM4mGj!!eqe34RNEEkS3,XGG(2ZBCJ&m`S`BqLD61d161M)+#M,K3PhKM&XVmj9 +!kFE2`CNTb642C4l")hkU#mF5Z(#m,8dc"cZ+6AVKB4%lCSd2q)p[30$hbpQqMkq +q8""h@Lirf8reMGpDa!YD1epK1d)+pCK(9j'bXJ,2kQXh4,9$S*AdB#6RqriTaZE +B%1m5!M2*rPj&2&fC,[A+3G8F4Mb9q"jb1'2M5DGL"Y&12"&P8`d%h"aFPK@S%8& +Imb#%AAJVBB'@##afI2)DS042R+,U@Yj9VDeFa5LYS&['$`QK&+f!TV"F[3&JcS@ +U%hckUAP-(bB#p&FMN!!i#RH!aJhN&pP5E('*('L[8[m)f"ZE#mM3k"q+dJ*MUCc +X@F8J2KqCAD,$Z,afl04Sm0*6Ta42aT%`@BY)ZZ@#q`VchjX!H[CLRj@f!0@5Jm, +2QS4Uj`*q8eYDS14)S4T0KF1$CIb"6+khUV&+$J`qX`j+Vlm`&0Q-A!m04,B8Ke$ +ihb92[eVk3Y@*DVEc%J8fA9F`fM,G&lbbaiM04RBL9ec$N!"CIZ"9a`SE,"Al"1J +eiieM60-15jdjdYAB,lPYIeVD@&Ra,'U@PDA[4cV+Q38*rDX!,4h+(9AG)k'%j'+ +00Nh1LmDS"&hT8%RfmZ%$-9FmP(hZ@1BEj3fp@TkVd#frfrM(QAYdf@)TqLR"b6V +9Me"8GY![X9EbB142Tkfl*2UGSDMi%al,,'Z%91'jCZRKL84)ak0PbEY"$,!H[Ff +TUHZMkH+S@4%&*[+IkXD%KpG*!,'YK496iS1Sp9XQ@(fRP!#hUN"4(5rJq9dQBZ4 +r`K(`RaLqrjE)SIQ4h)"$X80+(f+3!&!P[5bYCh@YK&8#0rBlJ'h5jqHA(I`4KK( +!Ii8hflG)PD#49'3@eFRUkN!CIRblFb4Nbjb$[p%!Gd1+3""GIDfqf0Yqd1h"TR% +3hb46h1lIUG8N*X88E+L6hk`q#8HNI%r2QY*meIjrGN+kb3(5ql-1A2[j6iHUYj' +e(T!!-CQbhLUDIZTa*fhm1k4A$X)m-K9q*5baV4ap1IfF-LpCPAUXC2rdeHqM"q' +&6MrEjdhUNRe!k##*'5Y#)HaZ20LC3Tf8@Za6!`9H!V"ER88(i'Y0Y'kd-r'FcTb +D,lEh,@#Nid%GC#8#D'fDrKc3UB%MUdS2LZP`KP9KmeC6jR6P)`"H!"eI45lZ!ml +IBJGCV2Z#40fJUFUp314#l(b@,3D-[PYT9295L,UU4#Idi+5XFr9K&c*`j&['VpK +)3)5`"FYUT#)J`Db"LK2'!b!Q-!TdS&1p1I(fTLTa1PSXPBqIHSJ,MTINh2I@)fL +i[fd!*N`pS[%#+d!iiU3S[XH$D&p-NKR8R'Sq0CUm6RlSrD1f3E9p8Q)S+)Z"5QZ +V0R'Nij%iH-C5f!'6FU6KX5R"aiU9!"0TF2jTkZbQC@cHapS86mS'DNUL32q!SJL +YAATd#d`BG`(4a@'UppjZET0@2488@&i[)E`SeY++",0Mf%RBPIc!k545"cfU0d* +(0qfV1$aIlSDm4XEUQl4h('`6,"FYcX-R(EY*5%+@bc1i135jTC9PJU8'qd$K`&4 +$L!9e&$mrhXkDbf3ABS4m0'[Ac)#(#"IKF2B(1`@U!@mV*3)frVe2!kcRE60iKp' +1,A'89D6Jl&ERe&"M3XZmc%&2DJmIq*Fi"E)ldDi4IjlRS9mHZ+2LST%`p+,1pCF +QcZ4FJKd,iRhdA@)qq``958a"q93k5pF[de2,&&MU%bIMm#8Fd+PXD6kmZGA-+e' +#JEEY+8&B"2*iSb-lkjIF0p$(SjQ@6P,@"-L!Pi4pNmZ)J1#*1$lkYTjmQ-5M,4a +@d$lR(dR)"IQqD5X,YKLPP3UB`$!qY(FLj2Jilckq#m"'9*q%J`r1*m2`h3cj@f, ++ac*0X9beQ+#49IEVGlF6mE"2m(RH3+VNCPjG6#i&+-`,ZQU$a$b3!"AKP(`ee1R +&`S$r#IGRml&3ff%kLH@fH"U+[Kb)++Rj"&Pk@H5r*qT[phr4rIJa)0Ha$K(*Yp@ +h&Nka9hp!aF((N!"H*$GHMQ0Qh,V5V#%S-k%8'H5c)P2JDk4e('2%2SbA`2B`R3i +C81i*pT6jX5`5+'aiZSjGBr&2+aY"18%j%)&&Z`dZ3`'jV!IC)-EbbYeE2AC4jG` ++aXd8H&8#U`,IG8c8aLrpLcAe(dl0lB,Pr3l)e6MQRB1bblBEZkZLI!EMH"#Pb$I +-`Yf*9bX'#Tm1SYac)U4&83-!1qlT4HEVEFA0#6,63pE6eUBQjYK8q8!dL-U-PpC +,r&'mp328bR&rMC5U[ieacr"UUXpS3`&cm%)eReJdIcrQZDY0FQFMc"0f$cA%K+l +lTfI6A6j+4B"Z1c)JrXP3G2ZG3%QRbj'Q&Q(8'mVR,D#Qm'Nlj%'%`G!EI!m%h$p +H&Pq3!$VS4-9HZ$Cc!2iR4TlVm6k$#SkFRF6kl9RBZpMTR`PZBS#lMp[)`JTCVC* +Y@Ml#Q8pF$Fc3`Nq&UDMpNr1ANFkU'X!%0d-2#mp(icr&'YmbkcKRJi0h$ph9X%$ +Z#KYdqNmAUIMRh@bI#FA%aAJ5mYaKq3!-*c4+e'fGRVXS#KLKM,bQJq3bPH1'kEB +BIUG&15+2(,1aG2HNTeB54P&I)AMVa-TVeMAlijJlB'K9&0ekH`k%h,L4LPTk%AJ +DhIh[KbM56G+1SdNI*hBG00%G""k!2pkJl`+GKhHeJ(d'F+&Lf2Z@XPl*dfrmd+( +L&a,haf)&61(1DQ8jbZ"B)BAU"HMY(P%fXUY,cMqkm@fS`mX$V)eV5Vm,96M*&bI +M)[j"H,(ihfXM!q08(2iE8BeD8D94[#@4Z6RilBRr-DJ(4Jak,*-q*laJ1p*08Uc +@0X"*i`0eH*5S6"""QQTq!&DLC%N*Ua*Qf59Y%`KC@kF`%h6#`j6aMjPa*!6AG,L +QNBh53IDp#HrD,XeYfKlDAYBFFYTUDr"h6Bi80CHCP!qJ#0hbP!qlrH2R!!r)UlB +EAPBVm1+JC!!1hI1EX'k[pQH1LGQ!Sj!!Ch-aFA9PF(5K9bY8fJKiZARBeQ32T"1 +9rM1V@88-HK"M(U-PX%!cH&ADA`219S51RBBl5+XU+RejqflC-aBSC`4kaL3mlGp +ra1EAFNX2q,6VrbfKJR#Gb&3HIEp1Z4"@fi@U@620AT0F*@Z*-pVN`#($hEpMEX[ +hj33X8GF34eqlKq#T0J@)(LD2ZMe1ZQC2"Dl6)AphMLRe589$5,P,&r,r*$Ih3F8 +K03U-PdlD(*ZR(kD0eYp#)+BM0hQSXaRh@@,p+CBRddl)1F9S[*YD5jr@A$#eqi0 +RJD2b,Fb(,R$2YD&fS!A2"SNb-(hN0T%5$$'Ca"(m0cA[iDZ[,R)Z%JPck1k#$8b +9E,hlarNU(YZ4q[Ql21HY4N@FSI2R`26E)5NjPK(`cm#r#L"+2!qpDeY"&G51B+N +q+8f,AY(9[P2Ub1@L&f(@5dK4HImVpIjjMS'lJ5TRp*8eJ4pq#5)KPJfD#&TGR9- +GR#pJ#3TbR)M8-aC6deN-#Z)Z`m"qi&2IFEr$*f8FcVMHR$ck"2hpm(`#3M-lrK` +V&C11"jp2TDd!TC!%!3!!33!3ZFSKJVR+)B)!!#-2!!#L13!!(1X!%F3)!!lGN3! +!-)d!N!32!%e[FQ9'D@aPFbjYBh!ZH'eX!!"c`94&@&4$9dP&!3$rN!3!N!U!!*! +(3X(8LN*8U`-`iJEf8fGVT,ÞS)3ZX`a4"SN6,%hDX%J$p0DcZB+`Q)C9Ae01 +09CZhU+*[TE`@6Gcp#)q,"#TkHAdQ'q`DiI"hGkLXG4'1hXS@[38XI-50(LVj9ml +6pm,(H1NESEKbBm)Q6c`6bS4kZC8%NGXU@CKDpI%cMQUHG*V'3eH4U2iUjdbZH49 +Y)%aqT8R!qR$AiZUYj"QTPp!HpVKfTN0*'8mhk*-UYUkPl(V+IETGQH)-A[i-Hd- +Y(qKLIN!pYfKQYHNrMr58#rlZ`$-,@[f[4+QBN!$)bkBL06m2,aIPHhDf$!DGEef +iV4Sl(ZXC*H$+biT#J&2r30CZcM,L1lH'`bf,#V"NU"NC4)`)ar3"fr)Q0bkNj$m +5Dq9Gf"#H#hIP%#2eJ0k6Z8#K@$rJJcD51+*X)VibIL&falF80(FA-mQEpmaULIk +rm+(S[4Y'iK3'5EQMRjq(kfbYD,C333K4AL,ceAE-A5q+`N0B)qM@(PEHH'II8KN +Jr(Zj9PcB-cC9c3CkA60"IVA`lSfF6`ffQiN`0JkA'-jkZkP`i(b8(2C5VF)L+[j +`19B2A3G+9AUXkBi"lYGY%)BZ*Si&qPf)lqCSjM%*"8!+G"%S0+Vl*+TTAFdfr#% +HP1$lRS@Da"41PA8HGJjfIp"hDLl(r'L'QM!fQDapK,am*rkRTb"V'dl36HPNXcr +ke1J`HX4&V601AJ5+RaB0UqSX$pc)ZK#fIL-iP!Il"D`#HjE6A[a*%L9*6jC*4B3 +Q+(mdh`YS,$cKI8cPMf,1q2'k5Jl&,V0,+$MY3r$51hhH9jb8HF#)%X#5"3N6!Y9 +F@R*XBD3Vb-MD8GbS9Gp$RB,LjHBd42SjYbI[*cTpq!D%l[HYce*He1)daFihE'3 +!ph'XJ195pIj&0[4l%DX@3hEl$'6dck4mm*-SG&JK%NbfrJ`)AL'PBGH1`)6cVCU +#ViVE0d#6'([lmZqbP3&&-k'qTbSZB)*pRqhVca*)!MdCbr"3&'S4JU&-2Ee8eBH +l[5+Xp'ck#d2(KPBk#hID@MD-UHIl"+AjYY`b9V3Vi(VFcQCU)&8AK@f5cL2IfP+ +$m3A+fLGT1S1IUYjXq$B!BVN6#QUZbjQF*2SALa[Ri3aU0)5RM')DmrNm'#$AEJ0 +be+9,ZHVJF()N(b31NSZp*(%)JH6e*XcrJdPKD+h"M8)mrVeH8Z%88f1M'DXB)5# +b[,VUFEcJ3$e9R41Vf99(YmBmH*A@cUl1IjY+!U@A@'aZADfhYhI-ALrdB+TIk52 +!3+22Bd*Vl)qd@c)!j!riGAliMMJE&bBV*r5KE!$-G1i5(q5-58dV3EL,N!!66k) ++`CThRmLN%+eJYHR"k4,"9JA",Keh`,G#NEDq4R3q5@p!QdfZ0Ncm"9KmNbpDmX+ +T,TKZ2YS54i)e2Q,VkG!H'q"+D"eGY(&dI%"ZK%-k26G6P@$8H!+VGL#0JJm&)M9 +I1B*+V@86mCeTU)k8*"%GmESJl)h#bY+eX#q@GEb!e(KDme)8TepTLCMck2$jr[j +Q#`bZ5JY%6pkDA%6NL-dYiKJphK9BZ&E2TaXlm+b@kem&UBR6[kVj0cF84'8HQY, +CfX9Nm59kKhNQd,HPM4[9Cr8blMaAaDGLN!#B`hM3phkJjkQDD!jq8"CLGh!q&TV +KLb&iF6@m@#i!G&RJGcTKhjRGE4kT*0Uk!IQ+)9hFmfJjk62RTSj['V889-U`R8N +CE#184B"2V%cH3mFNTm(dMPT)r@'PSrE*0c,,$j+9M!Hb@NU[V+$11D+C2l2HX6L +@XZrLqf,,&F#0(GrTTcK"+kIVIJ+c3D#cL3f4ZTq(&Tj%6$fN)(#AYjkdG!kcJK[ +I--,MFmZSaF8DU6jaf+Sh-iSB9rYr$'HfMSLZl)Bpe,epHf(&+VIC[!'A50LL+pM +(Z)BLm"SEpUd,dUic%h%pST[T#1'pNFE$95k9q1-A-cZNi$4h3ILfGeNVG*YipQS +6(`A(,D9aam'jXqj2lI"SAULE5"d6Q1+aL3T3%NF)p)&SU3bqrACLb3mZbQ6)#ba +Z`!)!Ur-QbMKqqeN&hd@TSp1QE@@DG8@pliVNU8BE6QV`[H'fl@3r(d8!mG+C'pe +CJPQ@q(r5@(b5c-4,&q*VIeRKfVa4bNF[XU2H0r,4YM1*)rCMIL(,G3hZ+4BN8M) +[i(BkPBAjmQ9H2`eL8e-X+f32eJhGA8d*J0fTmq&$+SEHNBl@Kl[[2EFK,cdf(Cl +dfC3,b1IM`186ijLjbGL6h3BQTbcH9f`K@DX(0qAaaq!GBm#mXUTQ%+[MRp1qp4l +Qh3l"U1GmQpYI-XrRDbleq)IY+Hr849b#)11VH*!!H,M2CG5E5hTimP99*43VjrV +fIEKp!(@aJmNI3l&UThFQABqeCQ6h8I0d-aml49S&-0b'N[8kfkM-TB($'mi%A#* +)IN%VU1j6XC4BSae+56H'$m0jpK%4%rqMl4M*,Y`k##RYR1f"1V15*ae[IM0&ja+ +aa5YUV08'b*mU`C(jDNh(5c-AMkMEM*3,qqh4k,pP24'd8@ZUK'VK0@PiHZ9Bl&N +GmL0-%MR(,C+eEU`#K@J"Y4h4+KX[`b)[ceFCqE2(5VEj,KMA3eY,pUA#(6Uc5Ia +f3Jj@D#NkUiJ4KF,eAIfbX%q'eUfFGB&JHqNd@%dkF#$RGePF3r!SHC4S#'V+J#P +f2dE[@CB6)-%3bVHLc@haU+Qq44Ql41pqerEUTr&RI6cVX9B)jaj-UcAPRXY($,b +XB(QlY+NDk,"h'2V8-[VAhidb*(Eiie![T2riVm'%lXFiiNP!@T!!(EM3cj,eDj4 +#JRE`6KT+T2*EQS1#S-l('rafDRp*Ni%)Sb-E,S[fk,2)mf"m3GjNXTI)9*BEFkA +)Uq``D!pI!)m`TR-C2ABr'R,ZBe29ieBYLFPm`d'ck5kMZF'JK9cPN4@3!*RE#p4 +eTkikb$@f3rYbJq%2cGJ6NeA+TF23l&6Lh[5%[$pjaB#(BF-Uq*Xl115Nf'M2eR5 +,i[Hk9b8"[J5F2P)rm-,jTlH(QhEQCdSHAebm,Iq$%B0KL,I$rJJf%R3d$U,%1Af +PTUQUm)Yb5#l*&Upm*1%Sa&ae*K*YBQ-iVK%$A1V*pSM0pM"8@m#&-9F1X+RH'%L +(*23bk%5GAj+Q3i%1[#JbG[A(q"F[e3(f*)a!0-SDp6l9bbQ5Lm@k8L`N#1$fVNj +TeH@'JC),VideU%QGY-d2Z4)$)3JSMr'6rfB),Jrc9e3`kL%+qh#85U'T')U9@Y+ +6ZK*$NIr&!X%fSDp#"`ZJmL,IP*AaDF0@)k2YYP,11q*PIT`eh#d[mQ*a,lIliq2 +c1[2VJ9imUaQi-LKf3F*P%iE`pNfiAdFTd$edQrA68DCr'ET$[$4PT0AH$6+IjKQ +jJ(S[+85XTe(&Y&6MQF$d#N2*XDFdF8r'*N'Bm`)$ic5V"MEJiSS"3Fl%*Zp*9aS +6kbe19*pENY6+2hFLNF+GQl(aB8kRi1UIF4fJ`QP$)29*hMHUXb1*LMl(ljh8Q`! +ZB4#Vdb-Uc+@G0-jKG-!+c&UUUS0rBX+I5p*HSK1,S@BI9E9G64E6B$Rr$MG26pU +B$E#$Br!p+fV+EjC8kRLHcKT6LAp*,FeUM2%Yi($'4TGSHYb'4k5PJU"48@+XSA1 +Hpb@(fpHABTR`pE%S8,"r9CLm61RMV,3bSD'd5bmPBV"ZDrDVMh$J696[-ac"GJR +#dmc&F%"ph5lBc[1fLr-CkAG#Qd'NqZjGp,J[+Mk-JXr'fl9L%[dk)+jK`)XY5,j +eq5&jlNU&UP)LP9MM386+1+j)Al9$-lFHeVjcpb6V8('jcE6YfE,309,RD'3#GDk +lMiY84jU1!6afUaEGpV9@5bMNpQr@dSiE6Am&"IacGS&9q'+$(SkR`0dP-JP-EJ- +-NAC1a6mKY*4AH,5QimBR#h2ep&2"648re,8NRh&A#2Rm(`Hk(D`1"E[8YNHjKYY +#Ke*0R$UClk0h0*+Mk8I*3m4MSp`bj'0qjmL81+SS0D,rLpqMGK)+rUSX!@IC)4r +maj1MCDpe*6$V&2d[KXe&$-f6e,Yr5F2cGr&aH2Y83Nf&9$%e[p$BArNUjd4"p%p +UcZMI@FYB,S5*3@9'rmh"X5[LA[IdUXh+lTfMlk9CSri*H1Jr0*Tc9"MjSR,S'"Z +-NFcd)U"[H"pF*8&&hjffk4U*F9aC%63ek,A-(jTHr8Mc"jMq#R'$`R&4Y@c9N8C +F0hlYIHZ9&"D3!'MG5Bf2La%leUR*rI'B("dMq8i&A9V2eL8--9%S`M68L3U6C*' +!N!$6f5qLc+VXYX%XeZKh!Sd%4NdJTmXeNjGN,dI&%Ip-#2$)l*PL!U0$$EeG(l" +e+j``(rk@G9G-%k5-$cC+&LH&0qTV+F4-5K2*bhS&mURV"',Hm!4P8hP84VdHfD4 +Hi,5r1MD0(jX+C3Ef@8R"UTk+T"Pf4&3`HGj(UE,5)C*i+!`Ea+P$c@'i%bMVrKU +XEG$0)+hY#Ye1$-N8k!S2Bq-5%ma#dB!jIr`aAlq,I4N)R8l4ql1Zp4-%T*fcq&@ +KQFjDRMB4U(0"0M'd&1CIkKdAc*&G5b%SqSQf'e1&dQK[%He-49Brr9)'0a`cTjX +MleUQ44,f,),464lSKBa1H)$TZ[If"[Hr9fhrb,QXMI#-RmUr$8i4,)F5PBF5#E& +eq!4b$4H-DrGakL$M-q[kaj%#BVX0l9e[Mcf#d83-$BS+6UEBbC!!T-SUXHm'Z1h +NTVAj1Y!+-dVPBU+D,KV%$5`#@KbNk[aSRiGQ[9jVUUj`iHei+1[5*TH63('JCFJ +%STGB$mCY8qcqN!$`GcP8fKL9A(QSYiFf0'`rbZ+65ldRjdieH,Q[6DXqj#0FM1V +LTJ9KmGdPqUeqV[24+JlCLYij[VC9d9a2$,(%Q$8XmS[2TmmA8%D$6XR24Ia$FC1 +YTI+EVS9qb+0)UqS+X5a9"(MC,Ekfk![pe+0!EQ[PkN,K)6EH!!,b3kC(3mh2LXJ +'aB%%P*+J!$h,,S08B4QapCp)0*S-!fT)i,X%kXr9!3SQ-Q[(DVV8[,hk'K'V%mq +*f8PLh)j9kP@MNJHF83fB2!*iYiQY%RZMjh1FG,qH8YGH18@2-66@UiELe+Cj!*[ +Z+'-!)IGY&-PXa*+1S))+@cmBU8$6ZF$kmL8TTU)Ek-XHpp-R(G[[dmAcq9FH*Jb +[J,eTFYKP#CrP83Y'Z%RbrD%ZPX2)(PlCj0+IfID0Z[48eT*XLhfPll[j$IBMEB` +IBUeT($1MJ$Yh6$9"T'rN"6[XM-Rhk6R5([KafHKeZ1XUcRda-N!J[e+`bF1C@cY +FK+U[E+%JL04JMFATC%I&e1el`12D`TfSX39i[r,bkBr(D#!@mHb02CTf*2LI6bZ +IjSp3ZF[iLNID8Pbmh40*[3+K,)Ur&ZGp0%h*L5I,@S'dB*3U$IQA2d@R"HV["Gk +Pf+aiTpTEe3EIT3KFJ[D!,45A(ZBc$VPPGlX6ppXeJjCV%+c*6jeq0SB%YdGmX!k +bLVf8CeIBY'f,llmNh"8dfZ%c451`F5q&Y@H'AI#,'@B9cQ5R%h-pCX'CbD(&bY0 +ia%08ACcL-#2Ni-F2haYBG-bV8BCTj4R0&#N'hcTG(,j%qlkIp"%hhQ"')0`+L&d +i9-4hF+Erb*36D16XqT@J5qa!2KM9!D-`$5Bf!M"5JDUNY$@8fa&pV"iTC,N2'9N +'kr5J9Z8H1r"A,[eBIX+e`mXp@R@)CTUlQRRbYQ[XB[5KaM!c%JV92F0)qE5dkE8 +8cc&*q8aUY''A0AMV'P11R@)K29-Y6UF86$L2!M(3rea`Vm!)80&(fRkIYURGRr5 +V$f0*YDf)`4GY@a4rNF3p'mBG$Rb3!)jUB*,+UH[#jDAeAGbPbPq`UZmHVNIk`1! +CYp8e+E!(0iZ)8)P0[k2&#F5ie(r(rA9E1-)`R#A&KCq[&Fm'Lq-SMSC9i5#8NV! +caSP525UV9(K4G`G@dIh,%r@J[cdSNURE@Ep"#(BmIDAfkA""C2rKpH3"'ELYrIG +(HGpdfl2%943GVYVCK%[D@F`jLU"M66+f1#er%Dr&kiX1Y6U`ZM$RUSEJRD21@Mi +28mI#[8fqhqje"!4QYTM8diF5q2Sfa[-J%+$aR2pjGBf9rCX[d!kD&I3XP`hR*Pb +r[YI!bjqhSJVDXAM&YrFCCG!U-@-AUhB5dd(!i'TkZ[Z$fQDGrVl[Mq2[EDXhUK9 +SiY3f+rJj`3SGik8p3+3QiX*5%8@mm0Z4&Ah-AhB1AGiL*R9(q,M[L@q`%Bk2&U5 +3!&,!kp[5f0E9P[eVT!*H5Y-[iAThK6CSQ@eP@GN$*!Ge!c$4@aKQp*e3#jiNB3H +amj!!VEEJ*"6"!3,%25V9c)dirm@R3MrRIKfZ$q#YRL%YC&dk'G50PB"0RBPMDT[ +A3Yd,I9E"96a*YIX[U9"GBKKhIRRZLq-(8C0`PeSPN!!fHU)FNDXSAk'heYVp"Ke +RCC0jVmPpc+*aH#26+$@NbK,EJhhAPM6+%8KSTD1i@2DZf[AAF3[5*cXac"ACD16 +#)GV'GrUU0HJH6iNrXUY9[S@Y!q$*qi4-+$(6")f'LRjNbMC,(0U6')V4$QfF`qR ++H%+$F!QBClJ!E'N-4(M#c#'%Zqe,44$Dib&@[A1@V&,ZFC(ZAN1J)6,JdkHmZi! +5HKZQAF15A$S2h%T[aImHqQ3SSApDlK[mj)DGpbD0Y$+M)4[,%KbKC*5Ekd#%A6V +46S9ec%"Jc*)qUK%RA#CD0!$9[JPC6@f9)i"-%23JFKm"$`RklK2r"4cBL02k$jP +B#U#2jC'lIjiY"4B1#lHl'R'dVr'LelBUVcXkp!2pm@qEpI#@l#DBqh3a2'0!p,D +-9Bl)kURAdU($E3Te"dbiS$@p`UU-j"!cDU5ScmFXVF@1C`10d'RSN!"1%[Ui3-G +cSaIGUK2cI6'F4-'f&Q4Me@5JdAbZ5YZ[[p9c4'm-1Z*H43+2L8ETLVl40jkIiGM +6pMe#2(AC*Ci"'66KB+Xq(DQLk31$GCVci$V2Uj3`)15e,TX%F`$4Rl4"$,R$D"& +Vf8iIi0MHD-A!(L9Ip`ecTL*lNQ3jIl0EDlCeUP5U*9AQ-ke6d+DlY80*Zi1YXbS +Yq$FJaL8SkE*4*$-aBEr''Xp#@D&&4+k9KH1A2IGkUDjBU3X*pXZ,i0hB0)8X"h) +NU-Ii&FB6NRD%-C8fPH8H66ZS,5'ZpRe1)+VXh$K![9Bhfj2BM9KcVPDfU#'A@Pq +d*m46f%[[YP1&DKMj`C'B%MYbK8!6N!#Z)jdH'Ih6MYE5!,YcT-&qX@qrCXQ!JT2 +,-`(&cVlih-"b5TiP3`i4V,,4%VUrZ-ZdTK+B!,(Jr63RZaZp&%'jNZShb5+01eU +PKAKqf(FkF)HLSIbeN!!r69i@[*e9-d"3MJYIXM5``a6fDV#Dd%m#"qFCIaU-r9A +NUhIZiY8B3B$KB248F1dC31UHDT+(-,b9,c!C,!bErS8hk@PpcF`ESVpkpDfAk[$ +mAPF)!QpB+LkkS&T&+rR`X3aa`mM5&Ym,8`(PC,2q1QhSI!ZU0!A4IaGX&SMleMq +aY8K2A9H3!"ZTh*USGrdI6lB(f)0f!mQV3ehMXqjYCX+NS5,p4CV+VQ4')"VepdG +J4UFpLPDEja2&SjMEZGdcSIXiHX&FPqQ3!05#Mirq68%IEZCHBXGR#KeD"UhJ$'3 +@"D6f-iCZbq-&4AJ9Y-NYb458"KJ02*h+LmFc,I9%@aQ"bKiQ'3'3!2M6#,a+K0# +aFE'fLeh#E''LA0!PbMNV&rrFPPXfbARKXSc#"abGX(be"D(NE0Ir-+,%8"Khe'P +-#`2EAcV@abTaq$)NHi8U(#61GKQ%0"&IcYIXIRBj"Z[(%Hk[`Gmrh9YH3Y26TNc +cPb`)H+CSGN"d9rR&)ik,m,pUH%4055@e%C('J#l1$$JPYR[GZifC'H(9[m"[ca@ +I(dkF&p%8-c11Y-eMGT&@fbVeeK$5CU@rG@Qi6ilQBIhDUUTXVp5Bpd,rqXb"VMd +fkd"(+(RASPBVK52TPEmDTDfZHYk&-Kc5ekY"P[RmEa*CPpc1e%drT9YhLjXK4Pi +5f[YhP(YDf5rdmZ'[h[8JXEAL`3PV%+*LEd3Zbl#CN!#JqM85jl+H[UHCrK`4GZC +#f![,pKML!)&HEcKjdXj@P#4F4(Tl+[Klj!aL'dE"C'#VDHUqr$I8fjC2)IJ[F1J +T@N+@#bAIAaBHrK&JE9`F1pTMFEf2TUiFL5rA2hS-1[@dDc'&22*M+H4j2,,&1fZ +eD,#1LYGUcG*BXS[4pZKQD`3I91aDAh2@$lQ%*EilVZ@mY!)+qqAPN!$lDPc&3Q2 +0q%lMT+HJSA%j)J4j5XFLXMe[e#)09h3G,mHb`Cp&FBar*erY-Z85!ae'-!AeS5* +A$Q-[ATA(8NHJpbdi5!E+8!HBT+bX6D@,M6[)0dMI0d@YCdN#BJU%TXY(qfZcQU+ +JJcZ,*EERedM`Qd`e*qprR*&S6RH#eFmCJ(&Z%K)U88Z[B[Ad2!4pSrqB(kh4Zp5 +UcMT'K([MVJPP*`Xf#0blAl%Ckf3p[J'm9R`D$d(i-eaRCTcQG$fRk&l&L!Zh#+T +E**!!9mri2GSpP2XXQRH5`Mbe#!+IU"Y,,FZN#2cX`)iL-J0pB5qYahQIXjXl4P! +6Y&dpZ*!!GEDKZXPe+1*GXVGNr5l$GR@eDCG*Ek1Gakk-FL,[BeZd4ZrHGikJ#TC +aEC!!2ANZI$5KVprVJ!11eS$dl@Fl`5CA&XK5,1lddZ(!)k#0Sa-J-GqeEPXL"Z% +4IUZU3ECJI(K-)KjJZfkl%A3#d98dV0DP&'-L$VSGZcp(Eqr6lTUfL'Ze$fJfF28 +XX!U3!!(Ffi2U,MIQldHGTD-r$Xq0JQ[)0`a*1X2%ZUjVCGjUjmDAqbp1$DTM!B* +"J4TH)GPUC*0%,qqfTlpfb%$"X4DiUKZ5C#$hZ4jp!2BpeiaS0H,,P5)X5pa(pJd +#pJhkJ,p%fK)!cRcM5c3Kk-U51ZM#3$L48j,e-'L00kCcEDk@imXTr*lD@BQdJql +5LYNV!M%3'fMfp&0b@1JfUPHKek2@cPKNcb081h$2Ql0J@+!X#(h8U`[,L%%b@AH +3!(+*#UjC4#@A,"5KI"&@RJhASk5G"IC38"e4b)M6!L[d,&2qdD$lGe@#p&+$eXI +0Gl&$6DS)li)3-pC2)k4Zk8pS8QEP`Lr)'cl6fYY6Y0D2&i@lmRA@)cdN)m&ea*p +pYe*$R`li"35+HZ#-Y`2GS`6`jlVepQE'56-`U6Q%AFf3!,"r,mcSNj+ZJa-C@,S +R%+LeZTID!!jCck%d,qPM4[IB2Xd)!!P1pbEPl1LG4,+$,$dG`aBB5l4LCYdl6aP +4$kUZD5cVR3aU+AT-0b2(j3ZXime9Q"5EN[lCmL'B4TrHV(-qp(("UpX4D+3e&-@ +X,@E#Q#kVMZ[!VF&608SX49G$hA929fE01*DJ`L5$JMqIF&bU`A!rVrh6f[#!19A +V',Pc&R)ScQ#5p**IK[dcpfP8pD&#a(HiBP,2ULVhX!l82ILZ*8N!hSV([h"#bP6 +,p6U$(FUdNSF@Nla5$C51PBS&KU1fm8"0PmKRXQN!LZ2[X(LBr3ji926jRFS!9MM +H@*JE6+'5&d"3Nm2FTc&`fe2AC,fer)iE-,&QM!f'dTLqP)r&E`aCGMG#iAT[449 +3!C0ic1$NeaX'm,0fd4BC5A4X(YLKS$0VST6HJ%1L6(&lHY#0Xc0QZPj"h6J&qPU +RfYRlLUi4mdI)2Lam5R`*5`d&eZ,2A4&b#&H)6h,pe#NAb3h`FP0QGr68)jBY*[' +BY5CH,1d3-&43$bF*l6qXYIk8lFIR268F-FNHXlhGPfRjRLi3JJ4T-+LQFUVCq)r +kCM%SN5(frf*0ja35[jdQY`[3Yka6D,@Q4-jQlrQSS@1h`jkM+0MXpf-jT,KYk&E +ZKKD2Q'XL[Lj"J)3#KXp-Sm58SKKeVAqYYCKIVJ`@k-DBFHQCbC(LR(D8B4-S10P +ZUBGVeSRdpQP(bS&c,i`PZ8#dN!#-pHJjh$%%2mY,@YkR9Y-(ZJ-qRLCUBSiQTYK +dTU'qU6bhQe))!4N!%I1GZXd59P0hV6MmT#8(#)Ar*H1QZf#NhiT'GR[b'4#lNqa +GM(9aFAY+-)'I'[Xd(45RJdPXr6dDcl,%iL"6iNrdP11[E)[SCX9qDjQUbhDP!21 +6''ARYLB'`m8@pS16C4U(GX5F&XHG$I'rBeXUNdD-U34[4rG!+*PkXLN@pTSFYfG +%,Y$U663K8,FD$9+8*NZYNT!!@JbT,L8`'N,@cKG"6AV'PDdI+Y()aj`"(-R6(,* +3SSMJ4q'4Y@P@HhqdFl9qr!+MaP3QDTU*,+cdQHpYqU"0CK1fXh-K@V-G4HZ!-TP +VFJY%k3i$+)(5lahdj'j,`0Xqie5fGVa4mL96BYY'83HZ+lF6+J@83pZdfNC@&L, +qCReXZUL(kPNpQp4(T,`1YjD%AEV[qmF@c%Iki4%N!$BhcEJ3DJUfXiqDaqQEiE@ +a'CSDM`NqB[2)P`XaPLSbhXQcM-ldEe#lNqrrJA$VY"!e%lj2Uj'4X!&I(',M8e( +ddDK1MjfX!la,362Gkl)YS3Yf&@C5[)U4ELbI*[YpLBSPN!"RiU%@dL6lP1A6QYQ +,-KS"rq2,LhYG1[(qfJNrlCU(`KmEbQ814FlcZ%La1J&-0j3CdfBNkU8()+2YhAb +R1hN5D*a%Y!p"#3EU@XI$fXAXI+jB'[PI[la[01Gh-Yai`)mYeeA!1f&cA0I""Gm +[8G4-TD@KPJMYM1K$R8EZ(K0eDPTlb6kSNc&h0kZq%hTcK0YJe4VM1*PmYLbk4SR +ZDF,fTB+#J*490kIbjk!p3-6QhAkqld)V0@+BCAJjrBR5,(e*VNV"`4R0VCZr06[ ++4"*L-$m6rI6qfjT!A1Hpl5%Fre8FmLMF,%+)6#68DNIl6Z5bNPkh1eB&8E59%@[ +!mX,earh,8PMiV15Fl+j&"f3-e8')fSpTdJ)$3MG$KU5Nejd6D6ELk&@3!!XQ6)Z +l'a`m),m,QG(HZASf6[,"#FKbJ-`S"B`+dT[2CheVMCH48lr`fK)mpENGTR3(1Xj +afJ&TPCr"Q*M%*jI1'G9$"S'8(KKjm"h(V0D6V)%QEK'5jM2VEF53!+1a*U-`(c) +SDB%55mVpYC)pS[U+#0M9SllQZ`,6jVjQ4G$"(SDh!b&SGI&LJVB4$4$NZe,Fl8$ +bT%-f(UX9%F++BX$2D#Sa8j[IQfK(d*m2$!0pZ3PLala,"$-NhEBleeE131M[bT2 +BG)XS%A(-93l0,,*&qYeQ*mBiSpHHBS`VQd8kBhC`f2Nf9m3BIbN4FA*m%S`GpI( +6bUk)b4[$eFP+Ep*SmU99%B"Z!,pZQCiJJ2ldmaqCSP8A$P(dV1!GI$6bCi4"i#1 +F'500+[6K*ld)`Nm)pD)4%EN'Vl5Jf9F%mePaL@#aeVC#Pm3TJb+B%SddiU`kFm2 +9`bMM)kDV(0J3TY@1(UfH%31rcC+'"*RXYTQ@jY*M4bcYYq6c-A1ZY$*@PBFjC*A +`M6`HXLbD#eNH6DAl@GUDdU"QrFFm54eS(cBK21kGr9`&rAQ@Ga@"[leQ,(Sc%rD +i4pfieILNpLi(Hc!q6@eSIDZCe9KdJjqZV#ImdF(f0RbIi@+LpaT@%DF%42J)UXJ +2*$AEKfbii#iCphljbQ-f&0irIBSiY9Tf&$JHrpdU5'RY8&HfbcAcNV6Q3Ff!i$) +MQMfkJlSDK2le+Dlp1[+fEEH$N`Qrl*!!!YFV98Hh%HUbm"1!'aA[,'3IP,&GEdS +9B1'GeRjG"IrcFY45qAMaEV&rBBd6d+mJ3YC09[$[eG&JkXQe`Lm1e9+%3@(ZIRQ +*b`Yac)4-cqJqj[9MXK)jDkXi$QD4Z`Qrbk85BeYm4kCZCD6)JP"qNh2YHK"jaSE +dbkV1kVB[MQ&Ibh9`A5I&D'%8(r%H#iT%kfF10j,T)6fjHlrI[dIa*B3$2$ZfNhK +&J32R'!p`HSc-,cJS+Z64(56MD+m*Hj!!*[#3!1d$(M"Zj1INFeP)*0M5T"`mTEJ +`LXFje)qT@V(6#X0(aHTj%)#Kc`qjVl0hqr!e(pfRE9q*9X6eTjm4)!QR-c!1TD' +Ea"MXJK4L12GPbrf9GRikF"c*ai6+Ff0Vbi)Rbd"J$N(e90XFTRa(ULB((ad'd`k +c05KVi3%[H[6@4fq*hrji0V1)!AhVZkDJKjAAQ95*&chk$fAP-fm1`)6Pp,jV'fT +2+42#Jjja[f[PDJN5+'faAPd)Ih''pGLAa-)eCMVM-&D$&QESm5FlqpG4`Nf@NqY +Yi4@,$[#ZJZ[-(%-hqj%Rk#IjV#aKTF,qXE8!$52j1kPV-RY"%r3chBBhk1jA[lZ +HTV'U`18C-"Q&l8$5,BYrE-GqCP9@0Hec6l!-iL%0Fq)-hemM%'cR$,"Q`D$-IQX +Q+QI0!E#C2[&P@Lq2c1LPF2P*mH"bapVq[Rf"ZSGaMje`4@NDJqCR"A@&!j93XM% +G8&&[Fal,'EGP+aq'[L)!C!KJSSD6)5#e,k$4[CA5ZT8C3UXGPYR2,0bb+@)-Fek +bS6"MA$I,lS"$!'[[XKiHNf26d5Qa[chVl"GV``jEri,$#)9+4SKCZYBe+A-cIMN +-f!@9G(L4Fiq*XlrAVQ%#)[TIVc&DbXYkRB"QlZh5T%6C@"imQ)p-!'G8(1(MM'A +Lh'h--LVId'$")ak6qKj@!d(LP'VE%H(mb2%'NL,C(HAbBPT19(9,"c&-KK3Xif# +#HV433AiTX**ATr3Jb'dA&PDI1-MD@H@C$4KCI2TZb2LMQdFlf&rC+jh-c(qqEj, ++[FrQ@k&%Uh%8(J6p*PemR+Pb$EHB*MdSm*TIrhLVNBEc$UP&q&4(Pl5c'PF*ViH +,*Zik15rU-IA3dZ-KJJ-VbNCIm+@DL5jQ3i*$Y,jHZ&NRZ'![fTF6",*0lmVG++S +5liEC['['l`0V$cS+e3`8ApB9T),S9C5HdLp$Uj5CV$adlBhQFXL0j[Kc4Fb#)8S +3Ld$X&YK)@(QJqdrPB!FqdCC((ldl%R!SmpbP%MdheQ$NN!#MFN[e#AD4R,1+M,Y +2cYf6p4cQ*6@dCFrLE#MIQmX![lRZ0%H&5A0["[1`YXSMD3$0YhSSYd$q`$FG+@, +e5qX'$RlR"HDl5DkpDjK8[*1A4AZM(0,kPr6Qm-*e,b&@XK,DPK[U0RS)V"YLRfR +E,lpS&[fHlS#EM)6'E-QBNcC&H)IeKYQKTRFc*@2#UiH%04#jlZID`MTpfPXmc'8 +F`F`Re[r(UCXZ$2IEBq!3*%RPc)pTBikCkM4qUqQGK-[5aMiBS!+i+8,BXj!!3N+ +1mR#khp8EkZS&)X"XFYpGU5(rBdj`MYI#1!Yqaq@425fdDk1&XjLRhH)U83Y@4Pa +,2'q0hRMeJBq8XFZ9EZ%2Vjj0dSDS3bmDbKb+J#QXZjMi@%mk-h!1(iFlCX2PdVV +8V26QEH'`Z&0aiq'*UB4TNaGDeIM[m%Rp'5J$A[l+@)QrJK[&I5X48,la@jU(*Lc +Q[[KR4SLG+!F@`1VG&6GB8Ne'IZTa(Vr`qPap-l3KDT@Y,eDC)XA`2a#("`3p'5` +1%eL!lqcmPD'pi[32S0MF4(LkC*flMpQY1dl8!aZj%P&mU38GNci4JpQpi#&U429 +#@bK0,#VT4I'J-S@,0!)EQY(L(-ZG9@-M'IG5hB8AJ#m*q299q-)UA)+@ReAG,V# +H3$&9(pAh[KdLAN,5T&Qbr@kefifi&`C'ec&8Q`fl,(b!k'T[D3&X1r33iQ,X"cX +,SDV5iAXSX!1DT29ZP3H6dNU8X$GEUC%ckS+1%02Gl1pR+@hJVJYYY6H@,YRKHS[ +p&iCkZT[S@kpU4hTCjY"1TH,d`89EJ8FF#a1+lk'A89'*Ye%[c6Sbq1j4ReH#Kf4 +YT!#i0%[,2CELC-YNqLcX*2NSr*)djkc$6%Z`%9)45`P`SaYbQ$aTDr@F9@6V$B2 +rZDlQjXDJ(Lie1ELQ!0jjTBi`M!YV9R#[F`24qp4ref#3!#q'fD"iKE9%qU[r4Ki +%YH$e2Y&Mdqeb("Q%+GY5"GG!6*SkD8Rj(ieae#[k&Rf`ZC`LDpMdcrA@h2,+A48 +dN!$i3Z&H1&$jhh4!aD$KKYJRq%64EdQ3!,afZ*l,8hL@Xq&-DQKBL&S4`c,MGUQ +SJ0i-((4d84iMN!"1,VSR56K"38Sl@&ql[MX!l)+Y-4Zf266aD40%m54fFm204rN +eB0f-Rj&2h2RprB119R3fGEK`T06+KfMGQVQMF#BMC`+K-kU'%'HZ%HSX-p![f,( ++#44B1deM(MUmCcKl2rJ,SD1@A11THN)%B9Lb*eZ&3NRL3ZmpLD[!q!&5-5jPV&$ +KkQSX(3J,YGSqlUakAD+r4b[A+P3,HF)*"!4SS[fU2+d!'k8Z,9"[KhPmajRCMU( +#CB`,(`I!ZaF0fABe`q(9)[KmPZPA!KcNF,,`e,XkXl1I%94)8b8adYGSj'G8NAl +0mrfFR[#kF@R#VCH6Rrc(S+KC3kT,NZ-*-hqIEq+aC+1$jHJJRZ9KQ0Q*ZijkJL8 +[e(',q48E0b&Kl9$S"#ffVPDc#8iA[rQ,VVDmUD*j`2TKkXmIMFJ9pM$0Kk,KmeZ +6V[*XqCrJ-d"LfRreJTTd,q8aP,6aUEXrfik5FkFabH,V3[1Y2bqVee0bRR$X6FQ +JjAm`'5fkFYXb,eXl`M[&@"Xea*q8Xr+M"95!TS)$bU(VKNIV3&lP3Eh$)l1@$El +Zf*!!2-HZMBM'S,&ZKXDC4d%NDlq514aLkB'+VB*fa`1#8X&(rq!Z,i,12AkICMZ +N"'iebXDFp[*K(SaBmm4EMPL[&4pjB2&Ne89TXB"kd4Urrq[l+k*$2#bJ2J0MRQ9 +Q"E,UC[HQ3B)*1*NfAb8)$qrSX([%X@'@%I5qA-09DY"K"$$F+*!!eK`IK!@1aU0 +!bGJ+iGNVqS6%U#%dbj%Y'GFSHlK[8DT[dQM!8pk1+1Ze0e-AA-%3LQIkHqZ!a#! +5ImSmFVcc0EKQNH)aq21(d%@$6-IAfbkq-ql3j+8#N9CK'j!!K,(&"r(1,areGCr +SCG0'TE[h)PCH9%aS+'G'E)cpQDqHQECUi0X2[Y)'@R@CXp!@0,kNdqc1TJ92b,V +24@pPdVU"2KAB(mf-fhN(aiNVlpGAUiTP1qZQ-HNl$0,+Xl$Il#-l*Aim%,kLAK3 +rdF39Ap%ECM(R-G[LRTER[HEaeGfMUQc!-AaQCmcHRdQDfJ%$jfYr-R"hI1Xlr!L +68@[CefhVc,CZji-,YQ8B*KbURdmTahT%pXaYU2(hd"Erf26KFmVM$Qi+d%5U@R@ +rQC&a%pJjk[*`a5cef##L@cT'B6XP5i82HJB,I)A6pE%RDV3ll&1RamXX+dZqj+) +TGa)Na,P![+JSKGA$kqR[JAFQmXD3!)LjT2UM@l$rTS8['EB53`43&1AN#mbR4Tb +NNb(3S'$CG2jVV+CAH2r1,KS8VjNmp1*l"V0UaKC8%00IQ+U,4+'*(pcqceXp@&L +jY1Z,ZSD3!$8jMr5ZPT1$88C*pp0"3Upl![I,ji,"N[3LckFEQK#UA3PpKViiHq1 +@)e$CKc+Z0NiIKLRMDiDZ&NZ2*8U3!$P@+9V#`aMFSS*cR2P'`LQJ&S+FQIF&D4[ +6eHUX&b%-GdehT(MiG'A[qdM2rK$cA0@3!))E5"RfI'%8r4H9bd892eV4AZPc54m +Qc@95CFF*fS54L,eRFdGfV%ZMP[@VS$8M1BM1eAHM-@m!+N4I&6Y(dNV0-+cCIH- +rb,c#6UcNZ(q!BL6Q!e#RMaK&m!&h(-#KI1"6aQf+H6JDCk'EN!!a-+34@GF94J1 +i0V8)hBrblG1ZKc+N96m61GUB41V*jYkKDXabce2FI+@SB`&G-0[8Z!rKDCJ,A)N +QM",MFN$10C65aFX!6()BcUp2V0*YS&Hq4r&b90C)-Q-#+j)!GbYhJNeek[3e0DB +V3*c1N9M'3LB(SX&f@A)"Y%1GkBmP'Z4`IX1K$IS465VIDQ)l1$2I,HBJB)4AAZ8 +'aa-S*@$!`N%@f0*0[#"Ej4,-DA$H"TH3!-AA4b$qQZcr0E!iIPRIa('f3ML6hfl +elEj#8kmMGBAcD"U,263qfSk`!c%JDpTA"mmql9[cB%C@N!#Xi9I6jFYfHi(Ak+X +@SU"aL+(hh,2rK3+J3BXQRkS@e3ZRY85USU@5VN54BhS'l[G+HK)6hTQr5N,Ah`6 +Z+c+V9rkUldBj!+"K1ZTB1Vk`"q%mh2dq6')6YmRl[rEN4-R-21+T8-+FQr0hCbU +Jq)@j!4pIf++P`Y0[CLGR3ddNE'e#NeFkMNUF28cm(I`'BDbaeS%M5M"*(ElhJdr +LTl)Tl26@@p$H5&rPEplHQM[2QK`KHFi`U2E)b0EC#"YEJ$b(+T%Dbb[EirYl@Y0 +0&6@3!%'%-A2edf54)`FB'0i#cJFE4ClkqRC#Qq$5N!0H5XPY2d5%UpakDf`p%(e +VSKX9+qT69rr)[8Ak80bVS#c4UG8NCZ4F)8rE3a15!BH[qZh+6miFI3Em-H#14-p +PfE)ZSTImah$6Dk+R`9#b13*ZldGjYje'dUd%30h4`a*Z1UdPI+C`J4V(&-"64H4 +rBKR6hEQQm8PS*bIeTbTGEf@+`#6!i&GhA1P4B8&&R$ri[,VN&h2#I&FB-l&+",+ +a&B#PN!3"!!!q!!#f'm*aZFBeSJ!!F8F!!+3Z!!!Fk`!1,I!!N!j0Eh*P4QPXCA- +ZFR0bB`!"MfT58e*$4'peC`%!rj!%!*!+J!#3#3(&!!!"K3#3"!m!3X(8XV*A0IP +,Jh@K8-dE%&f2l-$qV2QP!a%bb$pIf3Gj6mN,IN85ifB[0GI2a'CF*GrLi6B6MEl +FZANkMYamSJMNejRUdYqM`Y)%BiJk,L)lF)*KT)2Rh"C+,3XHF#GB,QY$Z01Q!-A +kV&DFZlm*9VS*0i1H*aR`-A63,CSapI+l!KMmX(`Ef`fmHJkL&&UB)!kR5HGKaeT +b8UpR`UkidP&B#-XqMK9d)a86`hIEe1*G@#ZfG&H1ar!iG$5''ApLcrP(B3LdEEB +H4qm'VkeHCpD+LjNe*#PH1hSCINTfS`Y&IV**iM%#q`DL*9p2''9N16BhX$H91eq +KmPl"l28H5L4X$e"(N`k@fep("haf-c`S`*0qK4"2@"9%P3CMPD0lq@a#rqq90Ua +S5eCFCCVT4X9(UPHZkYM**%TTb(amR2@bX"f'11+kYq@6eDQ@LirVQ`&GbHN$ab( +m`JdCEIk8066pqhKhmjj!M6cF%@h!LLCe#N$b'[")X%"!b%r(X*mCD1#+BJ#PN!3 +"!!"(!"#eC)cZYddAq3!!SMN!!+AA!!!Fk`!A'Ni!N!13!!#3!hB!N!32!%e[FQ9 +'D@aPFd0KFQ*[EP"bC@CTH#jS!!%pD94&@&4$9dP&!3$rN!3!N!U!!*!*!CS!N!1 +k!*!%$`"#`G89'GalIN(V$qaIh*Z,&+VR"ZQ3!+8L3d[pK4B&%*1Q1`qd3h9d(hQ +iq@)bL9G(hSf[hmV%PR&hDmj$$[SX#h0c85CTmBAH3-QqkZ%)Ub3`pq"A@$ZAGKU +d62I2[mUp$$1YZbf4idTPHR,c,B@K+(+Qjm4&N!",LKb5hr&mlkDLQVZ-&'J"Z@E +"6BU'Sl`TX&1c@6MCd-'E`FQh@AiUEr"`%l-5iaqfj8bX#+TpIXhm*69V'JlVfEI +#`%,"e*PXVMAQ-B1-8kp&c8(eVTG&RV6#*Qf*b!Z&mr'+P6NqE"'6qN%&Gr)BKmZ +Bm2Z,&k&#pBZA)pYeKi%pGDqCK93Mjb0T%@+(Y"IrhTA40bJR#8R0lAc`Gm[e6h) +QT)*cYP3b)5,Z,eJ`ci,MhIXi!`P1&'#PN!3"!!!`!%!!N!UN,J#3"KcV!!"Mf2q +3"!#3#U@3"!%!!%%!3,BJ!5Li)pl@!!!Fk`!!X6i!!!)P!"&#[3!!TQ`!!"-e!!! ++dJ!(8R9ZG'PYC5"-D@*bBA*TCA-!!1hD!,J!6!'E!I%"`2q3"!-HrrMrm-Y%!!# +!!*!(TC!%!3!!4J!!Yr1jUVR+)8`!!+B(!!#S!J!!TJF!&QN8!*!16@pbC8CTE'9 +c3eFZ3f&bBQpZ,N4-6!!"QMacD'aL2j!%J3$rN!3!N!U!!*!*!Y-!!!%H!*!%$`" +#`G5+G3CkX1hNA6&qT0!`-Xp`C0)-Y),CVLhPJk$Nm[$&f+c@%Ja5JcABj$)161E +3hTY$V-!dI,QAm%B-8P"q#aR8MTq8B$efc2``Mejq%aL$LA[2p94VY6)#f`UbYN3 +bH1MF)$lMN9h$"""C(9`$Jj,K3RT"&MXbU&!263hq2Q5Ae)5ll@92l3-BhmTe4Sk +3!"RB%$SmE%aLMLETQMCU@1h!qY9AhRe&dmp'A64S((N@S3D4rXaC!lDi%Q@Ajf3 +q)B(C&9GMMlfcafb+G+QZGG,#d'ZPDK"XCRATZ&JrEjGXiHPd"(ZciM)f2rr#1X4 +N2rf!Gm3R6`*riUJI&E0c@kd)`U[0[YaTXcElTaT1aJI3AdG&(lhS[)d4ZFILm+@ +3"!%!!%B!!,IcZDUjbL&,!!#QE!!!UCN!!+B(!"Cq5`#3$Ne[FQ9'D@aPFd0A,N0 +'66BiDbj%6%`!!9SXFfKXBMq3")%!rj!%!*!+J!#3#3,6!!!"(`#3"!m!3X(8LR8 +'HV$Yj&daIU63-$,2F'65$,5#fDiYjB1Jj2,`aGLXeK)-8S-ef13b$NcQd0kE3kc +!0(bjPk[k[&*3IJXCe)kL[$0N`L![!SF@A05"D0IHAT@qclLj!jpFb!%`KfXM`Yc +aC&A211k`)&fQ5MMLmXV$2F4H,p)DZdjJ"NFd[UP[f[kQq!dAZ`Eqpb)"&K'+9ZT +4EN@E6Hj#%(Ue+f2Sb[pikfP0K,6DD%%3DY)DP3&!k!JbR1pih"@r8LV"l6d`KYV +m)E`2raUY&Cm4!fraIK`FR2bhhSX4!Yiq&SF1RM5-rcG@-qHpHYhY'd4QAd$(hcP +1la"`MV8m-P'ckHT8eC@0,BaX,aD80M)6'c+d(0V*GZF@%5Ck6**((!#PN!3"!!" +$!!#hmlQUZFSK5`!!U!)!!+XV!!#Q"`!6SlF!N!j0Eh*P4QPXCA0$9bj38%-Z4%a +-!!(fB(0SE')rN!5"!2q3"!#3#S!!N!N#cJ!!!4d!N!32!%,"e)Te"RSaAb4G-Ak +Ncb*JMh"Nb`4@JYQZ,H@$S16bm-ABUihe2@RaQZab'3FQFfK[ANS4'H#cZJrP+GZ +aEd!)3T3#j5i8b0-IPqSJ0@0B3Rqe(LHZA'c9+TeKG1c$3aFGKBJaK-j!Gd2%GlS +Z*fak@XQk%T,"9fM-!mMZcQ*V$P1c3B%*Jb[%bdTk4j($eaC#HeeBeCI1Cp&FjEA +-*Q42U5d%P#GY"dIIEM)$9kLD[,%SGKU4D*Ajq054A'!q'+PLPH#!)[$pJ#,*01r +aA0D2ML!UrQ8D4fMFDPP2Fpd"UNRlF"Q@%6A*NRe'Dc6bNHY(H4D'e@epMdilfPM +j+q$qrF`HK,Ph`KN%fF,HjReI&[T,K2[jq"3LqX6UB+@3"!%!!%!!!,Id-B1hp$' +$!!#TQ3!!V+%!!+B(!"!@K!#3$Ne66#"$,N0'66Bi5bj%6%`!!4hGFfKXBQ0QE@H +!!2q3"!#3#S!!N!N#V3!!!33!N!32!%,"e-LrjC2Z&PX(i`b,J"3hd&qQJ[d-FT, +Dkq+,q"GJ[TpJ`fHQ1UZQfe9[0!0!6ZmmG4aBjhlbN!"P415aUR'1bdHSQiLkm2R +`4`[2NfRcMJK41+42)qp8BiJB2!,pBK*%I'l3B66LHIVRZ3dk)Y)EQmKXE)piU(m +q+-m5AD5!cDAki@"fa`k2GPPkZSjii3NSaXfbpI!B,K!,fK&%S",(f#SmKcLX+Pb +)MA8963iS4iXa@SDrS&9`R!LY5H&-jE8TVdIlP'Rh(Nh$BjQ*89QN$Rk!1"m859K +rf%jed29A1T&6"8YrL"EkcHqI1Tr0L`Kd5V*&H30q24+CacJR@G-"6X&a3+@3"!% +!!%B!!,Id-B1hp$'$!!#V+`!!VKm!!+B(!"Cri3#3$Ne66#"09e*eER4TE@9-D@* +$4Ndf1%X!!5frFfKXBQ0QE@H!!2q3"!#3#S!!N!N#Z3!!!3B!N!32!%,"e-LrjC5 +)DNX(iYmYf+0[PjAkjL6!m`m+ai+,q"GJ[U+4&[VjbjA6EDUhQ"N#RGjfLl4Th4( +Nh8YjE&L)Y$0k3`84kdCCQ3Gj`ebT#qrckhR*8S`c)*'MmHBJQ!GM@L"AT,YH(@( +[1dZf8YCA%U5q+3YhKD))a55GUALHr`"PQJC01F&kK!"+)0#AjSU8bqEBNX3$r+0 +KDBHS6V#b)DDmIkp9KFFL++aQ18@,`k4$f'-A&SN2&3LVJMaP3D*S-R0abMJRUB9 +(rSNE"KRHG2US#P"#D8BKQA(9Z83NmQLf+TIIcTqAL5F"UiR@X96p6cY+qE$4XS9 +hf*-bIr#"0aK@)E(Q'!#PN!3"!!"#!!#hp$'$Yr3aJ`!!V+%!!+qB!!#Q"`!5Zhd +!N!j09ep08d`Z3f&bBQpZ,P0SE')!!8fQFfKXBQ0QE@H!!2q3"!#3#S!!N!N#X3! +!!38!N!32!%,"e-LrjC3KKkX(bB6DA#1E*eNdrZJ*YGed+"e"kZf#-G%K0&K1-)( +PPJCj*)-M,j[LImi4Hj)j0C9iQ940G3RU0ql'@"ea+Q+$`L(6l0H&&AJ!jHDY[3- +39dQ15IDi+BA2*l$@H(rqD3BCl53'0TkcV6CLR$jIbfP`9V(iLb[M[pG#[V`c95q +aqf8c4H@4`KreqT6GGQrM%e8N$[Bkrh(i@GNTFRlNf%l66%r(J&`VJ6A*AFp-'2A +K@LD-i1JV(YiQd)j+X3+kXdMPHMY""Em$-@k#82+B#3cl#5KmqAG[A[+EN!!rV68 +rXQ*r(Fm(Q-CaVV206kkcVCM`-2-"Ir%LY8'aC3#PN!3"!!!r!!#hp$'$Yr3aJ`! +!VKm!!,%1!!#Q"`!2&`S!N!j09ep08d`Z8&"$,P0SE')!!DRAFfKXBQ0QE@H!!2q +3"!#3#S!!N!N#UJ!!!38!N!32!%,"e-LrjC1kT3X(j`@J,T0[Pj@@KZH$aKeBIA! +ATHb'B@f95#&-cb)"5`VeSQrr4B#`JcH5mNJA#jp%FQJB3U*eQ'jH@Yj@)D1UllP +*2R6+HE$@IGhX&Bb`%+5-%pMY0!peiF$ACKr6J&58a*GXbqlQKc!&d&1,Z%im4T% +J9Qia'6+IJXXUSX3Aj$"8@&Gj5dR3'I@l(JYiK8jq&b*E*+bK5iDT4YqB@UpBKN4 +JJbJ)3*1dXb"[p'G'i2Q"hIM8AD5`4LZYMc8,$hQP)1Gc`#4KK,Mr0U*U05E5$3m +4Uc&bc)"aS92N5q36FTlL(Pl'8`%AH[9!N!#c2UD,mZr$#0P"NjbVL!#PN!3"!!! +`!%!!N!U[Q!#3"UB(!!$N8rq3"!#3#U@3"!%!!$X!%,M8$'Die!dH!!#Q"`!!Yq- +!!!)P!!XXK`!!&EX!!!A0!*!%$`"658p9@#j`BA4MD!!"-+K849K83eG*43%!rj! +%!*!+J!#3#3'D!*!$D`#3"!m!3X(8LR5S%[ccd)#%E942VNJ1jkhchrY9S&b[J"m +Yqq8p3G`(#3J-3,Zp,A2NfMkSZk"EQH)$'2QJ5ZdMJ5Ec4B20(GCiT&L6GIGRhH* +XVd[rmKFkNY@0he'#M8%)k#(bM(f`rd6hS6BhfY"#`G51HMXG3eUAqXGfi3iMXM@ +8eClMCPHb&-XD4Nc$QS%0Y[@BSEIik,HA,@0`"i8*42fbP@IhLVr0BmIdX(B5XYF +l#id@$!D$cJ[#X8&5H'V8($*$%h43VlCXNFFe+M9eNm%lAdd[RIPYh%#ele3k1"h +KQU@lTa)1ErN'm+*i1HP*i4AJY%[&hehZU1H,BYKF%THF8k'`l#2)h,G4%[Ha@E$ +UA"ThEMJ(9kpP24c8TH0Q4Mc*KSe*)j-h05FJmZ#-0@1HV5mE&2S)0!X0&cN0(PK +9*V)AV,3"ierDU)!"fM+SIT!!qXZLNZ"l!+hYAePmD3K#IDC-NTZ[5@bV@j'b5hr +5-GX(Xb1GR8a+[c%#SZ-YQEf%`XXTj$[Le9Uik[l4d#2E0AC+0Iq54N1e3KB!I,H +,((55#bH,f$-6cXV'BmVK`*+0*-e90#$Pqh",6ilFSd`#rDjA3[KQJNmRYF@dI$5 +c@SBl'U@L&a2)Z)qQm3U,"VrATpc9rXM66X`lK3JqFrb*+'Ki'lXC+@BMp4kU-f8 +)(1%UdKPKR#2fNS+%LS[2pdBIm!RLE'DS0RdHH"Y5JMkK5rAbrphdi`qb-+#h#Ja +)N!"ee!X)'@r&%JE&B-5kqGb,0iiR%rS6qI`&Z,i)HQ`(`#+aAReBDebq2K)J0,2 +pQ)lQa*K4iRHeGUi5db-cB`6Y@89IU@&XCT@4*rPPARm[D!cB-[*I()l*Q*LmN9S +N1NqGd[A@YSGrf3kA*+jV&%rh1G`&Y,&[iEXl2A-E!iVVb4q#K8h)RBL-`2cr,c5 +Xq1&Ab'h6+`&Z*lI13!VcmG!)RbVl#&P%%BU(lIX)MIJArEHZU5kcHd&YrkA3[58 +1LEHm[PBpRULIUbfF!IXqAkej@Naf6EII!9p+k-dXdrA(U'pGRNGXPG8SFcZ2h1) +f#H*VB`1me*-Gj4!B4Q[31S$2FbE@jKNb+K)j5LB2!40cp$[N2q3UFRkV1F[0+RS +brG)2iG*6kJm(Tp2d44GraTY-3V[LbqhH*!"M)ZaC8#!)@3KB40+&q#E$q[CG`kQ +c89i3rMmQl-IkRcpPFCKBaV2*CqeUdELr`GYK`YCVCbZr1#@1U(P'FK4llIXab(G +VNGm[FEF9%m3Z@)aQYX6*LLaUIkY8a`N+!'$rl&(R*-brB2Jrd-8ArF`RERRE$Gc +%4q5C3EVYEHE8YKqFaaX[YY5C("PlpUcP8'AYe4j2SM(R[9M%fC@V86,GMU[SH#p +BRKf)khSP%,cijHR+6(2i-4qJa)%EF3mrLK'$)idBAkTc@E%E2j2YUqA[*cCX4iI +'Xmm6-6%UKX(L*B%rS[U0`'NDZ"2AEkGj"2Gf3&l+FGa3aNBLm*!!TJ,6"@ImG9+ +3!2J6Fl)8$8N2U'eam'55(L@6S$R91)N,1r`3d'lK#c6,bh,k%+plCZT(b$`6@V$ +b3"kj)%@al)h`9j1*![#R-AI$`d#m5c@LZiQd4UADejTPEb#QfB[,%(d%lAjDrFK +JANppLZ65Ar01IhJl!bBdGp!386r2(TKCAX8Vf&R,E%"'LlI`@I!%`p#eCAY%N!" +LMf#S35Y1EbKT%2Yb!cp3FM(a`F5#B3eiF-rRI%jh'1%NjH8I-YUJ*+$VeXbE*6Q +H#!#C1EK!Jd-*kq#EIrXB+*Q-fIh*fAj&r"kcm"baZmM6'9G0I@iCL%rC8lG0"@' +",-iSla#KXImU30V@m0TpA',K6N3SV+d3DSFV4`P8!5I-J'b!1h*$"D5((A*mr8f +YleiT0f0el"#9ZA3"UI*ap#aePl0"4KD6fkr,@p*b8#-V3rL[2'`8,G8-laiiA#B +,JXX#JC!!%q8K@Ce8DZRbe@-T5GPqmEr6$-+C[relb$!L43E)[H$meVXS90(hVZ@ +V9$Jq#,KmVQK@'Ip-)MpC-9%"CrH$DlKHN!$6ESDr5r$G$cIM39*2*3+1+P'HP5C +NGF%MHkSb$Z6&5q!"M")5ClSmUN&G(D#!r"BajI(Zp6%!TC!%!3!!-!"!!*!+X6i +!N!B#*3!!#2crN!3!N!UPN!3"!!!e!%#d(A&SYr3`M3!!!L8!!31k!!!"a!!&,[3 +!!,KX!!-CmJ!!5di!"%*eD@aN!!!*aJ!f!%-#h!)h!F!!`!#"!`lrq2r`bd3!!)! +!N!HPN!3"!!!i!%#f#%[MZFSec`!!Z"-!!00J!!#i%`!)"6m!!,M)!!""2!!!'TJ +!"#K$BA*LEfiT!!"M8J")!'N#13)V!F$rN!3$([rirr$,3!!!J!#3"k@3"!%!!%- +!3,BAYX'f*KNU!!#iE!!![F%!!,KX!"-8LJ!!Z5m!!!KL!!!%NJ!$+&0eF("[FR3 +J6'PLFQ&bD@9c+3!!q4!!6`"@!N%#!!(!rj!%!`lrq2r`bd!!!)!!N!HPN!3"!!! +e!!#f&lE"YKHf`3!!Z-J!!,S@!!#ib!!&ZHB!N!j*BfpZ$3!"Cl&TBfpZ68&$8d% +!XH#ai!#3#S!!N!N"jJ#3!i!!N!32!%,"e+,![f6NI0d+dKR3"qIiU-$mII[XG$0 +D@+,$Gdk#0&52j1BCd8`Pl-5%8846FB@%fUNDlE0"XR'&YHPV%Qe*S9GE030`N!" +9-EUe*eM,IfAF5aFcd8"fAEjE2@A6LDZ%e@q`2"QrMeVLhUC'(,QV6$&P5EMc!&Q +$[bmmBRbN!+@3"!%!!%B!!,BJ(CQjbL(a!!#j,`!!Zl8!!,M)!"B*P!#3$Ne[FQ9 +'D@aPFd0A,N0KFQ*[ELj%6%`!!@!4FfKXBMq3")!!rj!%!*!+J!#3#3,A!!!"*`# +3"!m!3X(8LR8'Hl!,C&f,MQ63-$,2F'6J(A!E2(HBZP!Z3A-#KPR[CJ[Ca1BYbL4 +i%Yi$"h'S+"'bfa4AB0-MMiSCbdji48+92Ab$mSGdNbDkEH0GC[CZ)@ALljKQU@6 +YI2)Dla9Rb2dUTL1*5QXZZbM2KedAi'`E'V#B,HF&TBc$R2pL%GlEir6mKV$`iLl +8FrK1K5kc8dEe-pd5)`NFJ))5#"RjUa9DXT%&1Fh"`UcB%,"L10F-EK`2kbl+S$K +@JZ"a#Zr6p%+JHTefeVaciLFfPNEq+iEQhqYQ0p4JK*U0UPIfeLk%`1l#3%*`3b@ +T[68M036UE&hJFYl0P'D!!)(k4bR)k(`ieD&XGPjcFMLbk)!,!h'e3D@[qRIqNke +mh`"G@l4)bhFS!+@3"!%!!%)!!,BJ(CQjbMCK!!#k&J!![C%!!,M)!"+3!!3!N!j +09ep08d`Z3f&bBQpZ,P0SE')!!ELQFfKXBQ0QE@H!!2q3"!#3#S!!N!N$T3!!!@J +!N!32!%,"e2)G%@H4F2*ZM6J6+"A*-mSq$0rFT@0kSZ5fT@bjKE"[*,3#KXJCL&q +JaZilrjP`pE!HT&0GYF`H8jJ,k[a+k%m8(*2eBXBZ361I5F,mbTGi*C%iY+qD#j! +!TMDQ`8%c6QHQ$R#rBf-TdPmd%R+b-#FUrrFqPrDDSZbJFYQA!*P&R,f$&QfA%m# +%T[BhfY5N6kk4MFPpIIFiaP++YMIPD8AN(RaPCmRE*L"`*"T$DGGUc,&&H2(T*-+ ++IdML!Mb@+DS9+8ckm,RI)pE4(0,lE03@e8d2EPpF!Y*fkI$&[lbiB%U')eb[+eY +1TZi*pIX@L`#BS"Na-8C"k5d6cQjfc,A*M[@)Z,Yi(XBl#LM#PAam3!0P*A8f5km +AdNdb3r%5LGV`dNX+Y[66A,#lNfE(FQRRYq2ZRF'3!jXl0CRG62rM+l@H'k&3%)N +FJZ*6JUab'PICEI(8)I2(bL$X6Zb`[N'%*e@BR!#PN!3"!!!`!%!!N!UlY3#3"VM +)!!!GYrq3"!#3#U@3"!%!!$8!!,B)5q1f#%[M!!#ib!!![[8!!,KX!!@K$`#3$NP +MEfi0!!&M,'PMEfj0380633#ai,(J!*!+J!#3#3(Q!*!$c3#3"!m!3X(9'K`iM&U +E%LIfj)N+[0G%EAlahS2&B5A#&XUH%QdSf'9hQeZlG#I2kL!Iki0r$S0)X-QR&0k +9F[DTpQTcaUf0F!35MGf#UhF3R3@4mRG[TcBB1!X"D%6!X%&HfV3KHQbXNq(p#[r +,b,QfcE2%a[kChdEa`DF8qkP+e5F"ddFYGVQMQ*l5XYdCZ!R5LmH*C%Rk6K@9T@I +&01G()&IrqI&KQE[k,aqEc)S)ie8'I8KITKjDlMU-3DliH)P+NKaL(&04'T)614F +`ah"$!+@3"!%!!%X!3,BJ&cbf*KNV!!#p`3!!c"F!!,KX!"ZLjJ!![f3!!#*(!!! +-X`!%F(0PG@4[3f&bBQpZ8h9`F'pbG#"6Eh9bBf9c!!#eEJ#h!IB#U31J!F$rN!3 +$$[rirr$,3!!!J!#3"k@3"!%!!$8!!,BJ&cbf)"Fm!!#qp3!!`%S!!,le!!AYV3# +3$NPMEfi0!!&S[QPMEfj0380633#ai,(J!*!+J!#3#3(Q!*!$I`#3"!m!3X(8SX# +rC14mh3V5'G!(k#"aKEJECJ2jrL!jjSaSP+STm92c)@lSl4Ma1DGj!L!eABiE@") +!-Y6UV9&YDidDkIkQ1jKArl-dm1l163PSX%lTrLF5MTkjDa8@l9Hhbq"S8k@0X9R +Y*r'I80eU8%bH6T[GC&"dc@-0FQp%JYM+!+@3"!%!!%8!%,B(cVkf@Q8[!!#rC!! +!b!J!!,le!"ALN3!!'9`!!!DJ!*!%$`"`Ff9eC'p$BA*LEfj6GA"`Eh*d,Q-!!6b +N9%9B9%0A588"!2q3"!#3#S!!N!N"QJ#3!kF!N!32!%,"e*cHM&S+,A4SLT'PBQA +GG`3BJP[K918&ZFGFaLYZf511'f&fP[PSB!&IEqlZ'cm9c[Y4N!!YYZ+Ee%qr@Xf +P$fAc9q[N)amN)8jmC'BA@'MicCrQa8ak*3id-`JGB'(3ZGk'mqUB4FXZak,Z0qK +X#KPDemKHH0+X4P[%8IL!+F*amf&6!-E@-c5-3(Ub+(k1h`04`MMC-dc2+'h`VRB +8HFL824c3!%,"e)E(S'`jYFjSHiCA3cbU*2)QIaDjjl*b`SI(X8pcbR0GXa(STV1 +P3iGi*BPJMc2aZHKlLGQJiGrTpYVEGRYD"&+1(-C','APL2B(RE(kAPM#Cb+@e4N +B)k"3X,a1)l(23cYSp[,eA5D#b[5B%%5S#5e#%KB-q%SZJ#QEXXE)`9NTrXcq4$b +6!IdIf6'83&EGC)hkA@Vma5JSeIVYrBKR$hqQ'bam(L9ZT*b8Z)hTqLM9%8!Z@23 +#)Kpi+lLF04*RA!re15KQ%m%cAqRhXU!@M1&UhBrdqlEeG*E3&qq*C4-X`l4mTdA +Rp1Q4C9(Qh9[rG"alX+2eTZaS%8djVh)LHldCR[CdpQNMLAcR8Y-2GaS9hjh-6d2 +,(b6P4)f8US,5!N(,EE'RLke@lGMq!1!#3ZdHp+'#G%L9!8E26i-#)5blddDMRS+ +JA,@KY5mmJYLC*46i--Y`S2JH2,S%CT`+12baCdmd#aM,Ik6!frTLLI9+"L,KqLQ +3!*,)D%#&`"G%+,p(40Rkp06IGQ'9QAe$`URTBGJ*UTT4BNFi!hi+459MUajHGMY +rbf"FV)#3!%@k`@R64S6&f9iEh[!GH+kZ![LZ*fB'4Aa@Cm3%U8#"a!*LpJmNHYQ +pir!Zi6A)!XaXdaFe[ZGc)fJ&TE`8K1X*RR+&h`5IS3rU%rq6T2%N)Y2b4J(0j`- +9RQah`jS!Yq[Ap*(beqjI$2K!TEEe3MbeeKYVjAr4[#b$TK18cpJk)-Sf+BNP[1* +`K[0p9Z0462pZrS,5lm-k1$m!aqi9ZZa9q+qEeL4r$Nf2C`1F"KT`b,8AppfMFEq +"02@M3'9(Q!CQhT)-C[5(rikHrST@EJQG-2YHM@4qV%*N!ZNld#8Rjb9)pmA*,0* +)qe"eH#F@lfla&KCK-%TU($YZ`UP[$prDiF9-aHkb@XG'rHKN3j!!KVqlAhR1#k, +3EY`MLFCFq8@r!!-aEA6`'D*-'YHD6Q9)S"kE0U,BGaIp"T5%U5F3pR%i,8,(cfi +pT@I5bXNPHQeNKd5XAkd5%EaCadcaEp(EhlC#VcP`@6%Ii&ChDYch+4bI6%55iX4 +Q$VGMa1'mN55QKX9[LmDhBQEjY&(Jip#PphU(dA'&phf)6eA9L(IPjdDl[%V+F2Q +SLlq9,D@C92i4cNYVapNMS%p"@G,AV[ChcmqETmEIiqiR0hZm5"jIp`HH`&0rC6c +iiE+H6jkq8`FL'R'`Tm'H,@19KLaEcii)8,m!d)bSPRja"65%a[(+6GRPK+Q0%$R +Api(+#%0eTmFbpGe#CN2[#XPcGQ(hC3TUZJGErch!qmA&)bI6T(-p2*&B"9p9j3S +'HeI0e)DjU$iQdC%JU2iGGlNN5"D"Zh50f3GrHkq0@KbG3Nb5Q4rh(K8)fX!4*NC +UeHDKkVfYq51NGMXQrQ9C(+dZP6"&VY#HIcPEf3aN,LG90YHRklI(hNma3"TiP"P +LMZ@k"(Z-GJjLEj!!#j,flljC"iEaqpJ'CJ%ae#K[NMkEZi!4%`K$5-Z,-JeATc8 +RC!j0&'1$Frk()fUYjr)fJVia)iDQ#iVT1PL$jPfAQ'CP@bj9bZhIk`P'XK9j-H9 +jcj(BjBqb%GHYA+baJf%bp&+0$80#TSpVHM3&C!9"JhqqA'219Qbc"(T(RTDdfQS +NAb[((*REeSmmipmdNK%2l#DH"@(Gp#V--AV+)JbV[8%)1XGTi5mh)3faK(&iC[) +AeEVfdYaFZ,k,4mMNKLXYYUT["GXHQaR"U9k`!qb[cq1IUDI+B[E1kpCXDYekYrJ +jJjci&al`m59f+[+2,IUTjbCR1k$[@2%('FH6BYD2i[*DfBJ#cN%"K@MZj,3N)fC +%&XbYYcjf$-T`%dZhJYMP-LE94UdDeac&k6%)@-G#l'8f`-8!UVccG#!Id"TE&6% +H&!9AQr8Jfh,RLG$XB$MG`9829V)#b1ES#%Q`ic#IKNeiVrplArIIT!d+ZHf`cKK +5)NIIeXLmL5!NpE*E-Dd#R1pD9+!YADp'9@BjSGpC'd!15A8MBa[1l0K-iMHlkM- +Y++DK&N"$3"qfMa2!F"#K21#+d0+!%p,0djYN9eiUjjFhBGeDDdl@8e32K[kVFB8 +`mTQ1XR)rXd6FlCHf'K`VGF%-H5Bl[AiD0pk(YaLRVb93D-!9#&pmiYB5HmX@AYb +@Sl1bMmlGR6mU,R%[0iaM!UU0SPa@K55@GI'N6',k$,lmq,PeC!iX%KGrhe5Qh#) +`&4*SUAj&``-)Zif#0$FqZJCI,f39+kb,3e+!TC!%!3!!4`!3YJJ$[lB)@cd!!-" ++!!$+#3!![[8!&fNm!!!"F3#3!r)!N!32!("cCA9NEd0KFQ*[EP0eF("[FR3ZCAK +`!!(rK&4&@&4$9dP&!3$rN!3!N!U!!*!*!CS!N!1@!*!%$`"#`G64NCm8$IbF5eT +hS,X-IFf+rhi(p%6HSN%T&bZl-rmSVH$lZc32+p3Ul#)ZrYP6l[5U2#DlVSMlMDT +N5Upec&X)S-9H14!p'@(qKfGA*9rE$Pb,'p4a81%k[@)22eY)N!$X%H$[Yd(!Id) +hPNfY9a89,4R$cjm30[QeCI$8NPAbJG)HVS$i+MVVfD+j+Z39jhBhCDL!3X(8b6L +j'REmq*T")-`TD`MT*B*@Y0k$Ck6MY&%'&JAY2k98-X)r-KB#2Vq`BB&[Xrp3AKA +0ACeY+-pEI[C"9che)T8S)cKmBmI,EKEfl'bHTbdc525Fq)HdTQP!khjHkj4mR2% +1,VjK2E52R3mSR[IE+4V88D0e-"TjE%ql1Sd22ab3!)j!Yh1S%,HD2"F30$'#(Hl +E$95CNNBri,ZM%Ck#GD9&NQG(YY$N@B,'(,eDpZd3Fc$2GcDcIBBDUAQ8lXCX006 +P3i@Mcc)0Xp'2&MAMSD81m)+EUYk$Pp"!p1DV8q9Vi@!f4P4Kbf#4m,'dD`f!TC! +%!3!!53!3YJK0V,B)BTX!!-J)!!$,j`!![[8!'GbA!*!$aJ#3!id!N!32!("cCA9 +NEd0KFQ*[EP0eF("[FR48CA0d,Q-!!6[&9%9B9%0A588"!2q3"!#3#S!!N!N"QJ# +3!pB!N!32!%,"e++rrjhVBX8"%VHjeXH3!(JDmHMI,e$k$8mJ4[LGU"l@+'1j#Zp +2H1!X!X4XHRP36CeP@c'0[`d[MiIUc$(Y)rB5f4dijG9'4M-+Z62[06$SD@f9$G0 +J#KN2rD%ci3[K%d3J1ep!NCm!`cXRTqZ@`'eRc"(&+R"X"&NrT6b`ree'mFqZ`fe +m1HPhHMXYC4@UCHCC"SV6iUeF*#T9DK@&q!hiT5LeiHYB4c22+R+k4fP"+YQSiVa +Zm4H4+beqBS!S3D)B5B1q#L$,6,a,-PcCddIDdBqS3X(8aP!C'YG0Km99"Y#,k!5 +9*3iPac#Z24b4iIk#q'#*aLcJVkJM180"RX-F$i#0l+0Rj11"@Aj+Cd`bkd#U!!G +%c6jTeG+K!05#U$QMZdQJ$[K!ch4Z$0@0lprdP3Z2EC1+MR2NFGZ$q5$8JFb%GV# +H2+AJ"Yk*-98D33d0T`9p1"AY96U'q083M2C!TC!%!3!!-!"!!*!+bJN!N!Dqp3! +!!@lrN!3!N!UPN!3"!!")!!#h6DV+Ydfr23!![[8!!0-`!!#iE!!BUhF!!!l+!!! +&i3#3"!m!F(0PG@4[3f&bBQpZ8h9`F'pbG#jcD'aL!!(I@A0SE')rN!3"!2q3"!# +3#S!!N!N&i`#3!li!N!32!%,"e*Al%##fEPM[BIN4+#qd,!G*CAUdi`f%8-)rP!Z +Ep(k3!"UP1p(0VkUUVT!!(@15E"lr"C)5B%Rfl#!pYCY2%RRf`,Ida+aH2*k&FBd +lS`6rp"+6U6A0IJfL9jE'ZMZ8ak0Kr(`MXbY4"'ZE'SqMq%I&XKk-(0bS[(9L0Ar +ElPR`*3E1S%dA-ifdb"K+8e0cJ[E0mES8"NZ,bUJ'd*CQ[e#B-r)41l3AMb2De%b +m6DDJ)Q!L#4fGi$HTNd8-`%,"e4r5SrS*-X4([KP!1bFF$FLe2cBjBC3#`&F2DT[ +`K$VU%r4)S"IHDC*@,JcNf"!q-d`T`#[!pBUR&P)A%#kdej'idfe%NZ"jXGm!C%( +![EmTePKh1`FAH6MR5+Q`H3"JcNNRU%JBX&m%k'[k(SU4,-qf&24N)cUE+UpYJSC +P&PV59"cbq!qkY''6@EL3!-Ql2hl(JNqYKjQeH'eh4,i,KF#01(l6KN8ZPCp"qH, +-r&0&e*rf9BS*0'S@6cYi2!!c#eqc4K0!6FPRXkDE'+dHjH631IGrFTQMIdlYGU[ +&Vh*@Fe["Dfr0(B(!*VdYV`%RmCEl'`%CkIh(UFCm2)lIU8ehSlK["[%!&$[-MH( +(Mp(&Dm@&ecG9'6V$If(F$,q*XPhE'ZXX#Jrmp8*f%b@'c,C!@NlDamTma)ajc%" +K6aqVTL(!*'&2GT!!"Tmb$pe9eUIMci%3pAFd'k*6GQC"l6ERQddJJ-G&8TTb4M, +IAScIV-a4dfNG!V@2ICR)AUTKaUfMc@dC0TNPR3Ef,YC9NHNAH#ALh-d&EmAV)A, +jNFh")[M[6b2Zl2K'ePEZrQ5Yk'STN6NS@MDHl!V!@P)Mf'l&5Q@6j+6M-&"lD'K +T[lCDcM*h3GeTB%r22YpZ4X+Uk[IC!3&&q"V@$laTl3"8IVfJm$%Sjlp@GJpA9"@ +QQFM4rPXlP@Tcf"9FGPLQdR"ZfM%2mNk'99m,[U(ckMRNlVC#+MSEBQL'5riZj!j +`reZT%MjZP)0Z4,VM@$01Fk'qP'(YeJ5ZTVCQrY`U06!`aT!!H&`XqMLk$NK8pL6 +A"4$Ijr1e6C!!BjQ$-E$hih#D6plU*BJjB9kMAlpId`c5M'p*HC-93qjGD)aJ+SK +[5!6`KY)fj8ffd!L-51[-VSV1mSI(RX0518-TXHDlBF%KN!$!Rpm'QE0L929Q(Y1 +D&HYrkbP5%9mA02V'p4UiI"&Rd4+CSqY2QTa836Kk[XAK)MPB)`NMVb1f!JIbKUf +2MXhG3e4KE5K&Ea5$E*a@P&A5B+`rjpD8)e1Ejj4LDL@65+F'jM*NH1bPS#H1aE8 +QDV!2Tcj!pfQP#PV3MEAmKlEplNP9Z+BHENCNRUj%JmPlp`GiANDqEk*3+JGjY9# +h*Ye)JmIVXIRZF[m!)&b3!)f5e()ZXqR'8$90jU9p2#X(#c4[F+V91`Vbp,K)ZXk +MfThP1F[(GHGJ#`IK-cVXAGZ#aEa,q1[AP#QQkCY#9YN$,T!!HU1R@T'd5D@p6@p +3YQ32r!I'$*I2`f6XJ%-JQhk!8EGjSfekmiX'SDiZHcR-mC&["HadNPY["dZ'5-E +hC#0k)m8QU@a`-pl2KZf'bECdhj!!63UCfY1cllhZXa`dfMT,R$j+N!#KjK+"6&i +8laVM2&r$(1jb2`dH'(cUQC*BADNFU6Y0F5mCA'G+qI@#1'bZ0)NK)2aHq`C-P&0 +4P@mFPKBSAlZ4"JKi8'R-R6C@-f#p+NcP$c'!U)NXeER%VeEESV'D#d&eakEDU-5 +-qm4N'86P&+F("TA13F`*2Dp-EJed-QK*52C*#Va%Xi),E''I+Arp8TMrDKUE9S0 +'kI$RHICEV"'Db,S6Lj6KTCL*pVUF2LEZ"IlQKMLCHImSM1iE+XZkZM0cGkqhb9U +M)DKE(#VNY$X*8J%QUREC2`f5Rq`d!dAKBTHUTci`Nq!-(qL!C0m8@C48a0$!0S3 +Kd%VmlljZ$E5%rjHRCT!!b[ia3[60I["$N!!ZeKV91-FpGd[e4M%j+(TjNA*NU2) +rrbVraQFJPUk)&IRdeR4*E2294lCp68q4#0B25d-U)D,e12qerNT1RrMepiAUq$0 +33*fE@cR%"#pE!ZA%`iVdhpqBF$&j"0"EJC!!1!N[QrkP&Mm8F,'Vmd$&DXb8SD( +@@Xj2mF1)AJbF*'(d1jD58N!2l`LGmN(fT1('*[bfK8"*L"Z1HIFi+S)MHiSU*R8 +VX4GU8S,E#9&pk#JI`RCCAkXK$1Vi1,)JaX1NT5c5lh#VS6JIEN&!QL&%,``!TC! +%!3!!-!"!!*!+c"F!N!DiE!!!%G[rN!3!N!UPN!3"!!"$!%#f&i+MY`Y51J!!Z'` +!!0fp!!#i%`!6a8)!!02(!!!4T`!!#IB!"LK6GA"`Eh*d)%aTBR*KFQPPFbN!!&f +0!,F",J+T!YJ"`2q3"!-HrrMrm-Y%!!#!!*!(TC!%!3!!03!!YKH#SlBAJU-!!00 +J!!$9#3!!df!!"GM,!*!15@0[EJd!!D*ED@0[ENe"3e0"!,(JXH!!N!U!!*!*!HB +!N!2E!*!%$`"#`G56kGAZ`HYlHG!LV4m!frPBR2QHBhj!4Bri+(X,#ZMR4&*VXRk +UJ2CF84B$f[$`jeE&C(!CPPM06$CM"2QiPiL#!4612e-a%Ip2YG$!,!l#+MY0TYD ++1A4VLliK,m`9H5dYeAUNfjE1JeU!1fcIY2iTqMle`m&L,`,Sk#cA2cLpLVKCp!E +J0[*I%SQ)IYLR64S'"eVk[,Qq0J'kaI5'ZHA22R5Q@r[Zr1GC'1$,'QD$SELMES) +Jmf6d*$A5G*PedZ!4QXX'd2M*kUE6rbfiVMXJ[c)jlhqE"!#PN!3"!!"'!!#f)"f +-ZFSKi3!!dmF!!0DU!!$6B!!@)G-!N!j0Eh*P4QPXCA0$9bj$4Ndf1'XZ4%a-!!' +JrR0SE')rN!5!!2q3"!#3#S!!N!N#e`!!!5N!N!32!%,"e)Te"RZ`#f4GLijNd$! +bch"Ni"e`'cahQ,T3,N&c!SCClfB,fF6Q,FSNH",H!`FrCbJ4Y398@hj'aN$0p6T +2ZHd*PCfr%RPrj0MLr[QJ2B)RN6M!i`36+jRf2KZQdS(Erm[BlQacqa5Qjd3hL8` +6JK1bP'H1XAI%UDZQDI'p%&E[Dka-TBm2PT6KDf1T9*HcX!$p6hPbQU44'`Mc[kk +X9NNc4-*J`,Nc,5hHFTHl&&Z6PaQ#'ff-eRrLb13G2U&S#j%(hI-0QqD,Nl-KmfN +)5i!9a8!NY+d9+cQZiMAqU[r"5DN4+R2F"hYPkZ)J8,Cd)`9$BP&JH+6%q*3#bUl +GpQcVfVp9fA1-J,-UPF-&DDdprikSSSi(kZE2KC@[B833j(#+V!*-!+@3"!%!!%- +!!,BJ(BfjbL(T!!$9#3!!f%3!!00J!"0%'!#3$Ne[FQ9'D@aPFd0A,P"33bj%6%` +!!@`MFfKXBMq3")!!rj!%!*!+J!#3#3,5!!!"*3#3"!m!3X(8LR8'Hc"mT&f,MQ6 +2)Q#2F'6C&4)E2(HBZP!Z3A-#KPTEU*dlUR-@j4)m#@m"JjqcP!h#RDr391PEXjk +-Fcdrq1+C[ClBHhTNSL8ce&KS)l+L3G+a6q(X)%hj-P&q(LDUMA90,Aa*HAQ9RbC +@'`V4j9Q1SfTAC)CQ5RSr1'Y-f&-ZK5@kLRM3`HCKfVJha*mJNNEUiD6If-P-m,e +'T(MIGhG8aE(h!`fRN3CYPKZkXrFD2UPYR@MIJ14*2N)6'(4mrK,`Fkb&dq86e12 +N8dbp-&8FmMJ%fI3d%%PEU,mZ$D#I6"0)!,3TL2c2l-ZNFlPfH+"(*GQG"iq@02G +(&UI4+cpGN!"+&SX$pFX2TRB&6(P([AFA"4+bIDM0FNCqHHBF0083TC!%!3!!3!! +!YL!GMER+0Q%!!0DU!!$D(3!!df!!%-B&!*!1690-)%-Z3dC00MK,,N4-6!!"L%a +cD'aLBfCYCi!!rj!%!*!+J!#3#31K!!!"C`#3"!m!3X(8mKd4CehrSQk01"-S&FM +UB29A1Abr!31UHSKpUM"i9L5kKlVB'*(NJUGP*"KIjC2i`4(G9HE$SC2&+TVE2D9 +D"(*#l2k9,V@DdIc)kMk!XcAIfdj&#Pc@PG3hpkmr$E5iKVl+05F"D`d!(picSpD +hAM3!NI$i1C!!#MJ8PMIl[R%DmSF+!ZK@f+[FCbkAhi+9jMQ@TdU3!,&8f4NTq-) +1kj!!fHG[eSf0QG$kdb,@YkASG(dErZKA#iYpL$08FJFFUbk%-,FfGQ,NA@Dj&&E +0hLBVCe6YGqadpSA5$KpN-cr8NRU3!1"6B+,T4mG)jTUm(D5l2q@*RdiS9$iQ)d2 ++BKdJp"MMr$TbF6j$#0(SkZP[j4Rmd!@JSfeN!IG(eL%mfDlbeCm`%0+lcYLGpP& +4DC*0#"$#Di,@+L&!l,-&'q(p(&XC8A90ad5&)@)2'RbBdFj-4k-+6,LBb'r6 +YhYN&JMdBM5(!TC!%!3!!4J!!YL!GMER+0Q)!!0K%!!$ErJ!!df!!&S#I!*!1690 +-)%eA8R9ZG'PYC8aTBN0'66Bi5`!"'*acD'aLBfCYCi!!rj!%!*!+J!#3#31Y!!! +"D3#3"!m!3X(8mKd4CrK6NQk01"-S&FMR#VK"@Abr!31UV%pGUM"i9L5kKlVB'*( +NJUGP%IH+DUH5Y6*S1TG$5fi3A)-XG-$e2aaCKDK[dU-0F,fp6!rZ86rBLZH)8b8 +`-ZiA6`S04K%$HUkT#6kbId(iY*CQf9I!8,6@LBR@D'K1FG&#`DEi@J,VCP5pX[% +hUj,9BUDb0c[PKcCIY+,"BbrMkZZ`cKj@KliX$2+b1jhS*KAQ%LN5!1kaIf$(hXH +NCV"JUp5Q@MTbfj5e#Ai8l)hpL#)#E1eZ$a`"Tb$*XEI@G6#iNhId53Q)HZDUf@F +eKD3"1)re9!ir!C,I$3a-Z8RiFa+(BALXiGj,lKbbk#Cp@RjI3&eaDm$C4`IedkX +"ldTe$Na(d6d"+L%qHSVT(p,#hr@$6h(l4H1J2NCfR%-4V8JfIRHrNKBPYhbHJ`0 +rDAK8+"qrbUSAQR,'V2D%3`9LdM3E2ADpF45m5XV5++@3"!%!!$m!!,BJ(BbjbL( +Y!!$D(3!!hBd!!00J!!q+m3#3$NeAAde66#j38%-Z8fKXBJ!"UB*cD'aLBfCYCi! +!rj!%!*!+J!#3#3,+!!!"(J#3"!m!3X(8LR8'HM&I*&f,N!"hdA516h"Nb`4@'cb +()K"dJSlcrH*6q+Kl%(q'!JhL9I&,c@%,Z124l4`5cS%J-XCrhZjhYqcNM%1+Y%& +Pa&BpAVM4hk)2$eRV#4p!jB@5!cXh1a)'r"e3hN,Vj8E3cZ$CiJ#BP[ai8$)X3$D +jL-UQfF&,FCRqqe6UJ-l%ff9akFHVSp8V#6UmeDVfp&h,%HlhmHcbLIhSb"`JeHA +T$a[ZMh'lNhPkZ861("hrTR!8#9VlEd+@,D)*L+YGjUGC#5LIKJFMNlfGfNCU+Kk +8[,3hqM3R2I3fAfF8M'-a%F*,16XIhYGd8R1mqSR!1SpmClj3jk5P%Tq'1YY@G"L +b-&R#b#CErc2,G#3S,REC`rc+%!#PN!3"!!!`!%!!N!VErJ#3"Y0J!!$B1[q3"!# +3#U@3"!%!!$-!3,3GFA1hp$#T!!$6B!!"!`3!!,J6!!2LJ`!!hK3!!XF2!!!Nm!! +#G'0X!!#Xd!#*!-d"j3*p!F!!(`!I!alrq2r`bd3!!)!!N!HPN!3"!!"'!!#f"mk +IYddDp3!!hEd!!1mC!!$G[3!@HS)!!3[r!!!3Q`#3"!m!F(0PG@4[3f&bBQpZ8h9 +`F'pbG#l2J!!!Km0069"b3eG*43%!rj!%!*!+J!#3"d,"e-G'He+T[B,$K$G423b +kbq(X6fqaq@HSFciK6fUE8)6qhQiYA!EIp1L[!16L#KTZYB[#')IPISbk2HHH,#M +4+'("V4Dcqchp(khNfF,B0FYkr-ReGFaUYAN@KZkm!ZDBT!2iD+RcT8cZ!#Nc,J8 +0(hb9*&ZcU3bR*mJFqVF41cl#aFi)@MA6NJ62IU'$,a`YRkH-MM!K2mBD!A$BPe8 +EN!$4G8UUD@&R+1dENaTlHiD)prrpem8RhP$FD'Ilfm,!)V+c*e&YjV%KlU6YeL8 +kL%ach4(!2dHiJpdJ%MiT+bKUq-XLmm+*dJ@aA+8%4EUX628U[Y`5@CER4a)-GDi +@3QC(08q'*+VM`V0BrV&Q8$,1UTLk#)PNq9X1b,Dbh#5V"F3hU6`2V2NJ$ek@9$l +Sj2T$)RT&[SEiZ'6p*jf&LGB+3T0I$,Gq"lMll44Y@RM,Pi%mM[fpp53bDhc"*-C +Z0#"-US+1X2Lab%IM!X[6+5YY%M#03&(@Pka*#9iYkHpmF`0!k"jN8P)V+p*4&6! +Dfq2JUiTk*q@@98DiRB)ePVMS$%3BYMrFq2IDL84854(%Z+4GEm8[5iG&aiS`p$Y +H$l4p''8aa5f%dNRJ'G3M[rMPaQ@eq4BK3Ycd(J2fZ$8Zam)eTTMGiCdKEmD#Tj+ +[h-dMSQ"El0A28`kK&I!jEb#H'SBSmL4$NHR%rm"(m44Df@kL[V'p4B!rJ9'*(R) +X1Fp`cf@+jNYl,6!rEbPk0GS2q0qHi0F,@$M(H-Qb1ZT!GK)'c'F*3*flVRq9m&a +pZqLPqdmV5#jJ,)"C2kA#p0Mpm0U&dkUPq8l5U1lJ[b&0ZVbl9k[V-QkZ54$QP,l +[2E2DSK1LaG3$,)2#C6UJiD4r1V&&@ea20SU,,980QH&P0$b(i'%6bSSh**h@!A3 +*DXR`N!$i[jdKeN+c1bIN4+!`eKZ-8JZF[mXL,@+kHEDb([A&p9k!NK%rHE"L'J$ +lP4&*YH*40-[[AP)6[lRpkh!2[F8[&3(R%B'RMQc@XN-M90ri8`N"-M4+K'c(!i1 +U0f"cY6BeBQ4A!1ceGSlI@Kk#%[@CC65a3!EE$DS"@2*9@pe4`%b,aq((JC-`0ZU +rH-Qq65'JHNh+R+CL`cX,@BmG)MZ,mhI$qT`X1SCJ(VFqZb8$*+6ce+DrA`p#K+k +YhcG,T%DiQRR3CfGXm&HE&[9UJA!10iFfk59JL'*Jf3I%rHThjUZAL`#DBArb%,5 +aU3m#E*+FrEj15*m(Q86pP"'aXk@9UVCE"%-'&3`NffBCdcadA8a4%,$G2R(lN8X +pqHaZZ1lCr!)rK&fh1%'$e&A%Sl6#*mBYj)N%4K30!#mSdIhrDdISSXZ5QZFl4i9 +!&I($04DTl#-dH2Q!!ad-X#ihj4X!++X("pVZKNQ&FS66k9EVBcphVe&aFHQSEKE +88Zrl2mN-)1E06PrBeJKl'UN`-R1`3&I9[q2pa1LP[fm)H@Il@-mJ)jrGY**q1XK ++8AQ(9J*16YG(!qMmN92U8P52aeN4RIeH5(KF!KrGLjF,d1Qmfb1&&[BaFT(@ibV +%RH@pj+aQN!#J&AL!K3`b#Am'JL53!00U%AlbH+&)BJB%fN$a@F0lhj%U4,rQF-V +mAR`dlq+$k6aIPrK3M3kj$TXq8AeBEr5UM-k1'3rBJ23"KE3`B2$IpP3F4A4JS+4 +2P6kf('a[[jH4fPX)bcND[f8&acTaiFX1eIS-l1G0k!)&Gi@(e$D5hQ`HQlPXfMp +ebeIq-aUi5M#!pJVmC6[QKJZNMKic'&VF3RS)'-@MD`FlIQARB,a$04@DH+Ia$`J +Q)ihIJ0*lZ&'Ncir1X,hl2HNrP,8X*Y3YePQb39fY!1AXaIP3r,(V%`'F[Jk3!#G +*P2*,Dhq8412YXBElqjCQ'M)a2JQE&G)UIL9T[fiVI1`6N!$P)RHRND"Q!-0D-YF +GD,FLF0rL3l32CDPS%N9%c!MdA!+af1e3XUdFCiRSKNMZML288BAmh3eS`(Z"!If +K4Bp*AqT34-!#0ZJjaf1U5V+eIJER3bmFMaZrEFf+$,,(@2%Yd"NG!KX&kPr#IZb +LjGCVdlL,i4Xq@-d$MVV+#Y2q@mH%1%c&DQAY&GU&[Y1419M,JmbrJC!!c*[eCIh +KciVpl!Dl10eGVEKGqc1ZM1T0[01`[L@i[96A9cp#*fD5)aiIV%QiKF#jabeYbHr +2&CXJRk`j'IHAMR&cmC!!pQCc1GQcFqAqUl"RUjY%-e6cbSJ+JmEr[iDVIm4aTee +*$"T$lihTXSG12S4cH14&%eq#pDC"(U"#2#`0mhYG#pX-ll6S2Z4GiVZ(Ah#!Gf* +050blHDGR4aGXFR@r&&TGMK8*&9XH-XNX94p'8%Kk$BHM`pT[)3GGX2cQrEGTIHV +M1(5mX&Hc+*N%0lH[XV!bA!"He`DmHm9)I"3*qCYQP10#CSTfaCDfmqA21)#8!P5 +YkK+H0krR!#DRl"Y0X8d8F`hRS26j`)&9qZ0bT,Ba(4(8P23dK,kjV#FJ&Af`Q+3 +CP#M"Kr!QCEV3)G9K5UQ5Zk4$S``eZL*jZP3X&FDh`dVD"5`fdj+-![PU[aAP'dV +Q2VqF"mTU5RPb4I-'F2,J0f2#hfF'6L08e"U"#$SQ6L%"1ML-GH@!mi-HG6Z8QJ9 +$)jJ+a6+Y5RJ)QimY05'%EA4FGF12'291U)C'AQ"Lb0B'%&*Z+XIc`Zkbl883!EN +Decl+laCA@qhQJ5,KGlJFCd0fm-#3!0bp#KC3KiPC85#JF@30@mkDeQDZXHS"SIk +3!1G*6Jj0#QmCi8aJEj@#E'[@FF'0%2#QL69f,P4e368&fAM&)V`-42SFFYV5`38 +$fL0E(4`q#5HA(r`mc6eSc&*iRm-FQU1FhcTkb`V6@eDH9b1kqi,#5JVFjR*VpT! +!qX1)%FHR8QQmaFF-M8q,S8UPJ&Tc9Vm-38h6KL+!9,VB6!A0I@Y3[Mhb@SCa-dM +qHc[&EqP*j*6IV+KD0%NLPlj!K&X,ec!4YicJ#hkQd#cG@9['H6jFXd3cH(%jkFl +9CDG'i'@Aa1*af`F'F8"-B)&1SBF1Fi`%RP,i@Nej,KUI&4e3-Vc4AD-hZd6LB3i +0%GSbZ%,`-UUdfl3`L"%U@m9!AAN@mJNEJ6+bccIAbR'Nl!S!&0icKmKL8rPA0eQ +(3UP4iNC+$D&EqAd*pJ01fp*L9b8+40ZkLHIN)0JDFTQpfC8)P4dmHj@5CZ)"-rR +YJS51V%[KMepA41ZCqb$kGrFT&)fNN9P!XMZ`ciaZSMBZj8PLZ#6N!Rl!IS9dPNV +`e-2(dkFjM[p+PEJ9B@D@1XNS)kIEmZH)@5k)-H-pd*@hETD(cHq)c,J@"2dcMm1 +!ACiCrQcmI2k)MD+BI'$6Pf0SCqLTdf1LJBLXfaB5M2i!"%N9ME(GHQb(k6i9I28 +Eb@,T-'YF983AGmZe3eZ'JcB(j"cP*!Ja@$A61HGG"EQd*Z$P49S8,#(P6jD[-Vq +0T$5L*LXjEDNR5ZXKEd@P)9!H3MC+MBlMYlpr&LL0DfH1'X%q86e8B'&G'"a-+pD +Bdf$"ajcbGQAb+J-P*BQdC1+6H46+q$kDip@VC)M#fiU*Z$@!%"aQp2B)Y'Blh+S +9+ZjMH"k2E`T+C0Ci-"U[[JD#*CmCHr(JpbU(c"5&e+h3GHeRYJ+0m@ckdN0cXPj +X!$U,+&YkJf,'3-RD,8Q9d*c[M4U2D6L5N!$4$mbUSJNb*#!$ipF2QmEj!QKm@Me +0EU1p8cD*Fb4YidlqR($N6[-,f2h$Xe1@q`d92bUNSLlSGV`RU4H+H@P'd8*#S9Q +BRDYj$$hd3l6G0(2&[D05*l*flPqEa[c5M!C5TciqK6",i0-EFlAMbehpeXeKkek +,(0QASi#9&N6CaET6ZD`C#h0qF,!%N!"$I&@p8He%HJ3X25`Y0"*["3H9&p[lD!k +GeP-4DUX0'b+XBJfUh2*LF-!jD%52mUrJ2e9fqqT-4Icd1KA`a)fMkA*Z*dk"%%f +l8)ZaEehRYI,Bj3Z[-KE)qZM8`8UjCbhBRT[k+3"qV'NbNNBd)VcF3R5M`*K#dc` +RhGAZE0"LY6(S"12dqLXS5H4-AJrKLNm@-lrjiQ(4"P$q&f1A8`q+c%9p(B4"hK+ +R,)0ZF#*f6#jX-arq!)FG+aa2#KXX*i-HaiBN4*U'8&kYpV5dj,klAe8PZ+!JFMZ +,f&X@"mF,DM`,k%8M4",qTTLH#3-("$$aSUSa&C+KPeDACaZDKE95+kUJ"Xl)L-9 +a`lD+0NDV`)&*h5P5Z6%1pdT0FM#e5HFJhZ[q5[mJJ$F"'P1kZED1c`4dG@E%G$8 +V3Y2I+'af`EeDYDDTcZQM@6@pZrTG5XPXbIQJY-lIr0X9##NXq8GmB,)EDmf4LZ2 +qaJ6Ij*lXh@1[L*!!i[l)LUaHGhQH#%qi,aUA*U`-QIPk&U"j%DImMAiBGh-kSG8 +GUP+XZ&46BJaXm"P1[(KTP6U0qHYcQG-AdN02h0fK#0$d6"'iVZlh-RQEI5%H`1K +#6B9#rMM!L(EfMjl(T51r'ASTiFZq)ckrKhD0CVeP`3d"G3`8h(6Qb0cY[aJRJ8' +rcMrZb@V%@k(H4pj#,i5DYCh2FQPT%IL+)c$rj)'-YRSBII`CbPR((GlcZ60VUrp +ZYC38M80N)-m6QGUUD%PrKdh11S)d0jG`qhe1,%PUZH2UHK8e&NZ&Id,RYE#*lLV +H(h3(R$AP3$+-SX1L9J`f%A22`@l+#MZ)'HSmJAGXZM-U4AMSBjXFfFHBDUc0%@Q +rK+Ua"43Xe@[1S+d"2XCp3')9c6mMLF#Fa*HErARilMEr!0Z6TJ,93dq&TS"61le +S4e-Q@d5Zcf"kMNZhGmhcC(6a-R4Aqi%0m!VXXUD5Se)lCaa+F6Y4H9JR3Yqq*Ep +c#!Y`Hcj$#bf1&&Ai+"GX!3DS`M)$'AaU)LQK`8qmKBC6-'"h-L[i`)E0PP%$2@& +L+Ue[0PTB)p0[U11YCj2RU(@a-LR3E6qR5%Y)@-8%LM#-ADMN+,MFC6Bl@UY0e$m +&$`!pNi[206'P2)2LlC3q$RC)l-lQD`ZS&-Zi0SXSDZIHc1fBP%,2'*Nc83eQ`RL +pqcV[%F&)"mq2NTJj%hIS8%2)h[K#B+YK%Z!mJbp0@3S6"81eZY`*[hme)96Z%0p +iP6-r%*IR&(@USIS-rarp(k![U*01LJfk[qPABjC4+1lDU-1C(E!NZ*MBXB[KY#' +K8rh'%I#qGi8,+aT2&0MILY"cib[RJ[-F$T`GRjKSN3!@3jhZ"d$L68,dGJ@LZIB +LDUqr'dClP3qJI'qdi4J6h[l#--VlHpM)5VGGc'8`NG`mb!1XQ(A9F(-%@#aCefq +A2"ZVTTq6Xe2(&"!(V0ch8'6$+YIq),r&$m@5bDQql%aCl*j!1&p``%M"Armj2+) +T+a))JZcm-&0N0FQ*r-Vm$@DU0q8Ga*,+KaXGmXFZ+RLBM)jYXh63MECqPN6Vk3b +6bQETl&ifHYC(R2(`cPq5A9N3&C,RI*Z@$MZ'5`23$b$%'c+BEhTrf#S8$!D-H#f +r#4l0Z6HTME(fT'8Z#Sa1hj49&aLR$DJ0EN%U#Ql`18aj,SSlcYA6BdXGhSI09cJ +Kj2G)A6XfDiY`j5Ae$I*eV2LXd,9IcaZRaYmrif+(NJ!1VQP+V@EhL@R[VED[kK! +C3KJVH@6PEr,TH4&YTS$bleF+Q@'HX@[STC!%!3!!5J!3Yr3Yq,Id,IJ!!0i8!!% +#e!!!hEd!'YM4!!'l%!!!%dd!N!32!("cCA9NEd0KFQ*[EP0eF("[FR3Zci!ZH'e +X!!"c`94&@&4$9dP&!3$rN!3!N!U!!*!(3X(8lP[kGrJKe!QJHNbLUM#k`m('ZF& +M!NPN,RC*UY#S)QYB$rP(cJ[(M'HqleCTQ!bA%`98V$*adhY$6[kPk`0,PI1A-&e +he9M!0f)Y`Qpi1QKGCCUNP,f4[FDmA#C8k8jpLe&NBAQM6,TclSTmId6[V6-6,k3 +[*ah%55(K0d'a$Y6j2D3K$J%Z[cF9'Ar#!@QFh6M65q8IB'iZkh1Ul#%'@EGI336 +fk,Q*0-IQ$m@ZNAc!8+6C9a,+&m+1,kKjQ5NkMp9Bk#Q[pVJ)r!VeIh96(2dLh(% +GKj6X3Pq&XrebG`GlC5q8BTJqUM"`HD!HJD`f$ahm[k10q5,jR!RhULTfZ8ed[Hr +Db#rp'`U)ZE4r'(Lk!9EEQh%r"AijUDiYmh3hcBDLeP"k,YAU!6C*X2iAVp9(YpI +mjAQijFd!fCl*EHTk"#r*)JAZ,@1X6BUIFBQI,'5$)1[IEDFp)IY$*BrA@VGYX%Q +1E*''RJi1p,+iR-@Rf*GkTjM-HF338S-06**ZJpC!f+cE(a3mi"[4kmS'ZPk@h-r +a,5k`*q9CB1"9@C%*P++J'1,T[D(Q1dfFjc(4Z!4FZa41Id34pYlm+6EdY6lhheN ++[6)BmH1Nq)%6RfH&r&QPNfE4XaS!YN6)Vb[6ZDN%dSiLqh,*TmRji9+ZH'`MjUL +mZ+KSQer%'jG2T#4Cd)Bk$2q@+q@+6ZjeKqTjP"Jk[9,308Aq"T@hBYFSMICfX&* +!r'V#G83RMEcBXX*,j4RGSSG'Ek&9cAjKILIImc"!`CVJRiK0VF&3)DTJm`k6Y+r +h1NckmreC)6Y+pDpJVh5pLJ9LH[+AhjYGj9jUbXQJEG$Lm@d,b8A'UL!*D,+a0X9 +CBKlQZ1%A(H&p$5UF34Sd$%lH[2m*F9$Kl1%e*dRc&#-rbbMHl$e(2NP'j&KM,[" +6'jMPS,2@b9Zi8DqJZM*(U09YT*RfQJk"Y$SESkD)""Q#hC!!DPk8Y-P25GL6f&C +aF%Tj!MINEa!'@*0['aa1#m([CUqPa))pV'Al&LEiKPX+dSj"p#Zi0@PYMM8V(,# +j`DpR!GGZ9hfm"bIS+EEVb#SeECc`J1*1AP9`-@9$akRB0mN#`&*T4`R+98Y1'R+ +S9(RNk1JD9CERC`5mfVdY+`U"kMB8HD4e#T!!NK3+m+rd$`0HVCX8LJ(jFI%bBqr +Fd[A-GZN0aiZ,VYjCCNUh[KZ[ZR9AmNhLL2idY1lPEl+Xrh"Fq$*%$XTh5DmDhb2 +5bc$*bm5,&BdIaVGd80,lRJ98!kf4i"4bq0$qr2fN84MX'`98J+m!%&(6Y*ll-dE +)V-L6m(rF83$@la-Da#qifZ*0,pAF[@6FYlJQrfPIQ,3LFaKV'GFH,FfTDYBQl8T +@bDEjqU-b5Ipic2l@,P#NTJ4M9cEk!P*I6c4(NS98)SPYIDA@)mDD%2a@ej'Q'Vq +J64K#jU2Sf53ieCIG,,f)"k8Sc3Q[ia)e,Y("fFAeGk4I$Q+SYA(GTTb8U)SpHPR +6fRU#2(l-(Z((d!A@arRD89YRCLHNi&SN[Jk18r9#42rF)ZaRA3rd4Tl5Y(Xb1%I +jj%M%I$bpPqm*&H`5FLLehbJkI,8%D&FNc(X'XL$Ti-J#R5+)GcqC90MS$UBlQq4 +C'L4q"l9LAiFLJG9+i[$(U&L4k!VSI22PUG0RV&-"SS))6(-JC,,RrHH+NU3kk,6 +0jI8d,(&SRGjc,,I9p0cNDcJ,8,Gc0fZ,Fm5`JJ(kZB'f'k@9HH*`@dhmcqmcKEI +&mHPYkI8i(Y[D89cTJ$-@24TEl6rbL+3MiG[Y$1eSqINE*N"RkK$jVd4FNi@K*ck +%d+4[JiUKPiQj6,+0UXNiZEpP$LVDX,[VParHH4I%2eX1fp)D18G@mC!!2D[QXhU +dT%Qclm(*Y)MH,I8i83kZ900S+q9-#lUKq*C38HdQ3(5bqSbH3rYfm@[Cc`qK9(6 +U%Q%#T+K31l8YXbXE$[9*5hD0`bVeH'$,M[3lal"V0NY*RAJD&VLI5M4mqJ1A)91 +lqa$B"Q(6Lk&cbhRC"Re3dr[@Ab+j(MQcqEA"I&T2Im6HY3j(*U#95N4!E)`[M4l +$8TPaA8SP6fBi6Bl#FAJXZV&qL-cTlaqG$4UDjBjS6E`"@EZR28NE6@23(1)d+Y[ +a"JqqQ'Z)qH8rXerQ`Hq+0Lbb)5%EJ"aRf1ZA'm"LD5'N&dD5PmHJehK[XI9f9"$ +kEm2i14#2DDYB$120rfQK"dJ3f,@k(TL1[1,jb$DIARBXMdVF%DlRBMRkqk2*LeS +&Q@H3!',D*PaEN!#XSd6fU*Um*HDJRBHB4e+Bc-5S-G*N+NhMVM-Pr)"9XIfHa-d +V*1%i3#hiqPKG(YF@UiaCYTXIkY&q+Xa[kh2(&F(%aFhMAZU"!9&A%05AL)$L3fL +6rR@[BCSrSQGQK3!P%a0MfVJ2SY-V5TUe9L%@2cpSS+Lc5*'#d6`X'P-NpGFAUPf +,*"aPK1kDNmdXq%Uk!heXYZ$3B!UKJe6*Pei6E9rINZr'r%b,"Maf6`"e![HpCkF +0UHV[rpqII#IaN!$L8LDM)F[3X[LV0"j6QH+BXh2SD%HM4-58l2`VjLl)qRTa!Y" +b*+GmfXe`-64RfL"ZHX99ESK*lUcM%JD6`+KD%+#X4bQCZ"KlhY6iTpM-i`Nk`S% +)[QJK69VHQC!!HP'Y1I(2LrQrG3qK`[8bV5hE[K1IjMJlfb146Y+Z*)0Yq)'GV+i +[dhqBH%eVh"Zibf(AfZZ9$S(c0jc28hSNGMIRiddM&*ISe9YhhEY9GK"eN4MZ+M3 +[b5lV$Rj[e14DRNmA,bqLApM&TY4cC5X&m,X(B2G*"1R*e(!`CG,4`+#A&l3jaJK +6[-NF-52Fr5$2qh+'N9%%,))+cISja"cj9(6U(mGF#F4NZT9@@%8-ACZm-G"3&F- +HIhMmXEFCj`X@a904-ZBT9Xc8F),,mp!4G9P)#(i$Y*r+m8%1pmE#p"AYVC)81C% +KQSQD%Sdf`Ra-XK+%ZGHjiYIh$`je5Amrc!RhrF`'PGI[EAL*-,bLVL)%Jeb2jr3 +Z[(&$irFUI$8ePQ0Up(HG+K+e-*h(kN[d#6AQUIkF+M@,Ra[LlHBNhJT243Rl@$I +HRM-T9kR9&dBa0R3#614ed['a5q23MNES*DU'lIC*$!p1&$ST90Q52l-5h!QE#K) +cH$EcH(Jqq4dpR%SY(Pm,Dp[6cq6jlJHR@$cjqNU4PPiTc'3#DLl6kKD@8hbRc%T +QkQF#&[JMBT(a#k-#jHBCY'VKGM)pQB@cDf1'rDjddP81h%k)EM(5%0DLQCD*5r% +!S(EP6dcT&,f#j[CCCpl%00X9XQ9"r5%)%Z2&r3C@Q99cV,C,"5L-idMQ0)lFak[ +#a3[Q5Qdj"R&r*b(V51fBXle%L-Q@-$HrHNDl[U#l,H339qeF(@QBJKMZS-A(eGd +01ZV2)M"`YB)SdJSXGaCjYqRXZBD-0!`!)(j,a1kjp,Qik["5c2"dN63[#dF6L,8 +K`5CJD8hJQ-cmPkC,VqhV8m9,"+`p3D@5d+@cm[hTh`1[KXIm5arV,b1a`edSc[e +M+JV@T0!2%$1RklCPGJ)*0-j0j4rPG)dX(UHXB,a`4*VcE6m"q!kmKRBPL90S,Y* +Xh)1dR!pE62ChNI9h8,c+1*E`bBa(iXi0U#1H866*f0YcY00S(iS2R2FPU@SR*jc +ZXN`PiF+`P1"iUm`r#)1GpSJQ,U6fJ1NrQXY-3-bRcN&X!BH(LR5*6(lk$0cK#1E +NDd@m-&k!TN8I9cC+fUS49SG[D*@`k@!QF5N([c'kS&(KSGDP3--diBSkrp@Db04 +JXhmU))K+B0#-L4'"YZ'%26-J[$(UR"[P[HDVQXH[,cY`S%TP5XUm+m!$ab&3hQf +YR(0i-llSeA[$ibR94@G1K(4IA-*`Dd#"i@ef&IrkAp-3ifF4!da%[kcJ0hZ#K*P +N(fj",AV)%Q,lARJY(4G*V0F#id&B(Kk[h,Y5)cCNNA%h0ANV!q@JabBr`!2YdeI +XiMRDDHIZ9[2iT2e9,@*e`5G(8N$,k%UMl2qim5F`+PAfJ[eEVS5`'JrP)eZ#amc +L@bp5dYDZCc"hfB!m[6B$DNRI@2C+91#R@8ULJeJ(qS,Xpb6Zd&6*4hK36VdGJr- +6CCZMAQ5,E&lNX0qNa-M*hN)HUX,3dbm+E`2c6)%BT@cYPlH1[c3Z'5UlAH&-e-J +r+Y$US+id,AZ,DZ9ATN"&)GP-`Kq@GCBXkVdaI[`,#%9+V@5ZlbGK'pRRff2@*MP +`l[+*E`fDflj"b(j4pI%iRf`Irf#ZNfh!T#%@3ijd$8kXSM#RRA3@%6A`lkfiXPE +GGiVKd)qfYrT$H)'BdENX-+N(c-&DPL,R5AV1AaFUpCS`4CS2c+,#pQm&A*,NMfR +p,IblZkT"[J`a9N9UiXHRJ%V$P%X'f&-`rM9BZmfTle5hNfN6KGU%lQFSba-*GZG +%Dc(J"m3*EdQ(V+5G-j2b"hPq`AU('f-J6b6@P3JfTKKmZ4Q$GcP5&#"Q)+-KPk) +H1#+4D@4kpEE!1CK"hd%i4fQ0"RPhVIj2Vi)pVLfeIU,`QATKT@9FDQ9*hI0pE[X +D-M3eldqKS5baVRCa(RKHJQ-J5MiC**Ka+U#L@UakD(4S"&![!NrFE*LhK,%DLDA +cdGii1(r2PbGdARQV10F+l#MMe&G4VS"XN6%951VRBE%%Z,2d@l*(kCK`ICb3!*2 +[T#,TKi58)#f9)k2X(q(FQJk"&5MiXq%qTAr#$6[)+l*2!TDK9'`!61)SeNL&Y,c +,IY(P!Y6-0V%J6-dJ[e-VUFeGKfk3!-5LY$p"RCh&j!ahAVH0*`6h)*Aqbic(+$8 +(dR8rAGdIUH['[XmX`f45EBBMTHMc+e3G!+mJNV,KRNd0LF&Y4iHa&r%bf2Bf0[l +j3EHk(ab1-TS+Vi[*5&AlRIk[q"(6dfGT3,qcCPDSYZ`)1'`4jS`,9)6aQ%M%A!R +M-D!1Mp%KE@m`p#dFb'8'Gah@&Y-BJ$lNf0NUhHShHH2Z'4!TJ)1MPV%El8a"-I) +BSjH*!&@rJMmffB6bXD@1"a6MZNGqJ,bc%eBFZcpfCDlS!NS[H)$"ff9&mk&rAXZ +YH!U)9mfkpVMM5C,ZFcSR,!ZAU2`$)(e)#be'0Bi&@4+0mMESGE8a1rLi2UUFKh3 +-G)ji,1EGaQX-I@!$F28r1dr9@j0Spj1PZPi-Vlk[K!ATN!#8C+qaFlAU[*([3$% +'bZ3)fAHLCHpD@@ZdhAi(Aq)ZZjV4b0lm)NiZM"'H#!"irbGc,933dIibI*@r$3Q +cJrC4Z+J[38AP`lI`C1EQNVmflcd$5diq(a*eTjEVIlAp`!%TMcCr!"*cUp!T$9p +Nq!D#rC,$PQcm9IY'S4fFXYV-D+JEHUc8C+2(#a3F0&PV4Qm"N!$c)CN@`dQ0Aj! +!M$VD`3mQM,H3!(P(Di,29$[@&+M[)QJJ[lF9UYYjhP"2Hme43P[@[b%LqMNm-X" +@2Z2!hm*RCir$0!a`db2V"b$ih5rJ`a43hi$@b3clpF'3!#KAd0D4)(6N6UYd%0q +UU,q0IVjd1p$AAMjmHRXPm2F%c(E0'PbH"S2(HJEraja6[22qLXdEPG@G,KPjJ26 +c0f`(hArbk%Dkfj[*H*!!Q`Z(*UiY#qCULAXTaPV'0q*-KC[X&LLUJ")TM[!3BVI +c1b,9-lN-SNC+q+3qVQ@e3*j[EBhe'lYURAMQ2`bI@ISd1$XDKCX0mAA,1b)0T`F +L!`mmf0iLZ1'2dD&2T[FPq)b@)aLf*N2)Zr9fc@fC&Z+CKacLm$0TZ4VB!$HS2,c +mQRY-UpPE*9C8qdXDY&35Eqbde($I%rkl'#Y`p45brbm3r36E,#T`C($DRS,,,hM +2KM[d-%l*fHpJ,%0VJq[U2kS*AXIJhb#PVL@Z,i@ekN@(He3a&[NGM@F*ek56'k` +&HPBYX[ARB6-FU!&ci!8@Cj4+US6XLGfLqPYm-[qH+&)%D2jbYcGBZGV8KTKk9c* +kX[@FDf2`8*'SU-bfeABGL'61&h!5&Tc(Hp+iH#p5dD6M%ZMaLR&Ur%KULKl(,PX +1qQ@+m1F@CYhhPR$DF`dVV-SEr&G9)Z30-5C!Gl(rjQ(@ka%krL,cmleT$R(@(6J +)*P#[CGaPmY`84A@582#YG9pdXmI&U@GcHK)R,Z&3X5M0dc,$-*FdVImpU'jqE3j +BrGZ["EZYXUqGZT+E$idG"1G,C3b+Z9B0HM,"%X41hkId!Prm$6FU&RpT(1VL'6i +9h(J8EMC@NHZHUi3pVm3hEk+JV+G0hdaDc!aV3eH8l1f`)F$q&A'(+NIUQcLpKk1 +`E*XkEE(q9@&J0fpReC9%Gd1YAqF9[[mTjDSb@NR1TcN`F$Nr90XJ0QdXm9E458% +8C$`Q2Aa6phUPQ#k9@5((Ie$#ieFU-XBI9SeLlhY%fV+8h[e-N!!ikHQRZJ#dCDG +29V8eHI@rV04`HfIh2UJpi9H20mII5UF8cL48+'D`'Skm0KlRNGdc1&1K"rSdP&D +E!fD64`h9U6dX%"j&I2kKTMalqQcQk'EPl-0$6(Z"Jpe$'@Lp+T5SPY3[8'K),4d +K!lE&l68PBTGXA[-M0qdA0cm3I4d'8S6Gmdq0Pl09rJaj6b,c[+@3"!%!!$!!3!# +3#ZmC!*!'hEd!!0[mrj!%!*!+TC!%!3!!-J"!Y"eaGVId-*)!!0fp!!%$LJ!!Z"- +!!VU*!!%$@J#3"c!!!(4V!!!Hd3$4!$3#!`(P!F!!$`!2!alrr2rPbd3!!)!!N!H +PN!3"!!!`!%!!N!N"!`3!N!8"!`3!!&'Yrj!%!*!+TC!%!3!!-!"!!*!*!3-%!*! +'Z"-!!'Fcrj!%!*!+TC!%!3!!33!3Yr1kGER+0Q)!!,J6!!%&I!!!!F3!%@FF!*! +13R9TE'4TEQFJ6@&M9'0X9'X!!F%h9%9B9%0A58@"!!$!!J%!N!U!!*!*!j!!!!! +"6`#3"!m!3X(8mKd4CBm$dQk01"-S&K&*dK%16E*5[T*9K,aQbQKl8JPkjAe"Ab1 +1JFEEQiKMEBVVjDTj2$F@E$@i+9q`Mk1SDe+*dq8@dJ1M&"rp25I(1G&fr9(Y54+ +j$D!BlTHIIX%'4fdHp%5Y*b9Sll%`HS6dehHZd[5(S3Npa%D8hrmF2#+GD+@*jL6 +Xli-4ANL$Uf#9Gi8Q#"&3BPb'U['-*Z(Ci[`#F#p9LPAJq@*dhqhNqYKHTGLbNq- +ZSP8J@"lm,pi-#5pTm#(M3HEGThi8A*)S+1m"@&*`X8TH0[GXQI5*9`-qR9kD!6j +*+HbQ+1d0le5ZMp2GTP8qd#34TfK!6kNaN!!VNEeQ,KYh22@mZGU9#XU93eMRj68 +X+Tr'lB,3'e&LZeH'D)R,qeJJj8JNqIK*&qb(B5`[U3E3V0S'dibD1R1%BVklZG' +dK8d"CN%!TC!%!3!!-`"!Y[,b!EEbmJ%!!31k!!%)&`!!!F3!!`9#!!%&d`!!!Fm +!!!*%!!4$9P-!!,Fk!*!)3!#3$i!!N!HPN!3"!!!h!"#fm[)"Yr3D'J!""A`!!3C +"!!%&I!!(lI`!N!-6!*!$%f!T!*!%4@jdFQPPF`!!Nr0849K83eG*43%!XH#ai!# +3#S!!N!G%,h4ME#q3"!e%,h4V,j!%$D@3"!%!!$S!%,EbmJ'fm[)"!!%&d`!""U` +!!39m!!T'H3#3!`d!N!-0%p3!N!45CA"[FfPdEh*j!!#6me4&@&4$9dP&!3#ai,( +J!*!+J!#3"bpMGR0bEfpd,h4ME!fPN!3"!!!d!"#fm[)"Yr39*!!""N%!!3H2!!% +&I!!%61%!N!-i!*!$1-M6!*!%8Qp[G!!"-N0849K83eG*43%!XH#ai!#3#S!!N!N +"GJ#3!d8!N!32!%,"e4[e("HEj*8ma$,1k0CR*e8pmQCV5KfrDe)K#(BJS%%'81Q +rlr8NrKT#'p*,!mBUpI"N%8,S(Z!p,2l"b*!!HJ)T0#!kF(0PFRCPFMTKEQpZH@e +[GA0!BhCc,R4ME#jcEh9bBf9QEh*RC5jZCA3k,f0fFh*[Eh3[G'0X$D@3"!%!!$- +!%,EbmJ'fm[)"!!%'V!!""qF!!39m!!0lQ!#3!`%!N!-"aF%!N!48B@F!!*2c9%9 +B9%0A588"!,(JXH!!N!U!!*!($D@3"!%!!$!!3!#3#3%(M`#3"3%&I!!!mTArN!3 +!N!UPN!3"!!"#!!#dSQ-cYkH3!%m!!39m!!%2-3!!!F3!%JL,!*!14(*KCb!Q)%4 +bEh!J9'0XCA4c!!%&2f&NFR"A5A0)K3#3!`)"!*!+J!#3#4@l!!!'TJ#3"!m!3X( +9(-Pmlka0CPUrlX"K#20p"G6"GrNb,Y6*15!jZP$GffpU)RC@9!3GbJPrbk-9#3D +Mm6J4l1K4D9e(G#eUpl4-+AVqrm+3!"B'FEH)-*bEIKaR8fmQZ$#F9f[-2C+(P`T +852,C1PZE-fCR,cH#8BPI!9YaceJ@kE6FpjKRK!(*B[-ZXCD#T6fe1,%G&c)4Z&a +)UP%@dUq,H4%N)',VH"2%bYjC(Lh1N6CmYhE,qAm6J&haVCUX`lcFj+le'RrY`13 +8iA@cM20MUJBFQ$Z9a)G*RTY8aK0e5ZT1%BX%iFQY,5S`#*Ep4m&G@QD2M*I`J($ +6UGi1lcUr[eJhc$5fhCFL[(-iY*r"d-),9QP,SXL1rREFDSIS,2SI8qVdhX['54S +SqL2kmLY1lSGX'25!h(HjpN9KS*!!XNYFmam3&R[@,J6ql),AIV,iQi@HU[9%8Qm +89pb(-fR+k1XfCdJ,8rAB4Ea!-b)1[-0f-'&dL(qhrZXk5frNb[M9a!IXJFGa(AD +Kr1&Vcf,KqBHeP@8e@)rK#XNqqpf5Sm$N&e$ekdp96S9a@`*[TKikRi61S%*aGhb +CEcld6akmdqa[K(,q4*AmF!RhjT2(S9b`jQ-5LRi2L5CDGp(m,c2GDM3i%0($Vdi +4Z)r!CPSZ3H*$Jc52XXBmE`9"PBI'XLGpamF@([3e1pMM&$*br@L#k"f+U*(#E%E +Jc(,[qMi6#`2D3DhK[0jFTJ"FQFV3*5MC3hUhaK`!9P)@S,GD`!TRr(e(Pk*lS9Y +bSqRp+XmV#T@3!%GNHDZV%4)Y1mRP+NG'3*c1"6EJXL2&9U!(GPULK`(QPl-A(Tl +*ARma'K*j!$lChIq@jIE*mVPmS*+QB'Udli)11qkHl5SfqK,0mjk[pN)ANV)%fTp +fJ`S'fH[UQEN$k[UJE`LG`f9f6PaF42j"k)6BCH$1r&a3UQY+pDee1,EGZ9Nkrd[ +c)BXXA@I&81b&kN+5)bPMHL3cEF5@I9EQRP!jb)fYKr[VK6JZZE[N,DHG8hqV%S3 +qXXiSY-Pc(LcpXX`kjHJ`@'`Xa'@)DlRNeT4F"[JK-ql&M4kX`iZXM[GCSd[q@bG +#-`!C'9LUT36-8,SEj0J!4I640p#cmr@$"IcEA-SrRKKT)dC+SAZmcUYelqdE+(- +-d&,`IP'13UDc-55AYkd6Yr'AFLjAZlCQJFAVcqcLHIXjF2iE!IZ[8GYm0&PfbC- +9f+l%,jM"&MX%Y2Up!P-`%)iVQHY%!9k@TENkT6&-#Vf*UBCIQN*km[rf`$SlSR9 +)$LA#rr*U#!GiAdDFc+j8&aQj(e+e4KH#VQ,QQDm8j#V"$8&4M25`UrBhqA*F4E6 +Fb,2X$6C`*Ck`mT-ZcamDd,+bQFk9UMXGbTe9B[SYahB6J4&FADFYZ31$QX%5J#p +,!GEELhi+d"VTr`$I1D0P-YNk9E[`13R2Y16p6BKc`KfG)0K3qBLaMqZ-c!8FmV4 +)@Pf%)pRCLAeA4XPf0(,N1*2I&JhjX+HRj#-GaMH*5f9dYPL`Y,C+hI@EPk@90aY +pB*m,R68R0,ffi039-Q-+h3`)h,#hMVS'RaPDV2dN1K,AXA1!F"pPY#QkaVPZcH' +U@`hMU+Y2#XLJQ%(EH!)B6c(Y($4m)TZklG3r%[mLMqF3*iH`1f*aR44P(%KlDQc +bT5j-XCU'm#Tc-i**(Ii@`XK8)c,*Ci%$aH$0I8'&%-$!6%pN)$$*6(EBGkS%@F% +E*lhN05C#B*ETr$MF&a&NcbZR2+2HUC0i#P,N3kf2%E&Tj`G((SJaQM(SNR3'Q9C +iqFlb,A&[a"iUI$VV@m52Kql[!"e"ZRGl6[SelEfZ#P%lL%am,MmI5@p3eRQd0hM +M'RmM(k'%Y6@`H!-NC3j8Tl9EjGhd*+[TA,ZfN!!(f6!h2`-6,M*HlNGC[NC5TPY +PX'*,1iiD-`Y5MD3!'KX#e"`+qdF*,l'S[rGjpDM(5P!+e,rfBRQ+Vh,SEC!!*II +9J5TmSa5,V#Yd15re6UMa#h,$"(l"q4mDm,GIYIJe2Z@kU9Zf-JfUXT45ReQT@VK +-i"BCXd)cc3k*11iALHVaVHc2DQ*(khU#k*SH0'-'(qbcL4%IXjXRrD1P@%a6J(, +JD*-Dc"T2F*&`*c88bjJ03G,'f(Z'iRC[J"!XE$'BEkfLBT!!0-56LX`q`6U0Rja +QLT8`QM$b1kFP!B+bQB"+LAQ-i%qE2hcp`@SaZE"#lCD(AR)q4fFkem@eY@JpHTZ +ElC1U'$EdhJH8(JFjYc-'Pm0bj4DK62Y93+@3"!%!!%%!%,EifXQjbM&f!!%)&`! +"2jd!!!(%!"'5f!!!4em!!"M4!*!%$`"0B@-J9'0X,e4V)&*PB@4YC3!"-mY849K +8G(4iG!%!!%!"J3#3#S!!N!NDb!!!&bJ!N!32!%,"e(6[5Y5K+*!!@)9UEf!V&TD +[Y14lJe5&[3A,"(pe10@Zi#HDUDK32Sjk@p"jcASU5G+eRQk"2ml80XB*c"'M3m, +PMQAPVG&B&+8*GjYT1dr@FT0fYAPG)4!d`0f6-Zd"5+FTCVB#5,8lil'@K1!ChTJ +fGQ%0+)VA"E8+IRQTp+cCCpK50DhBTK$M`Di`E%5$ie+iEHJKp3d&G9d&iPpHqrb +Thmd5Z1Rb+RlQ#-60SkrliZ'c(E!)DQKrmI85XCbIA9YS2(m3'iEiNLl1qDc4kCf +jqP)2mZbc68bT*&!ZmBhb1'MhEp[PU2H#mFpi%,aP(EG$CUa1HILj3AIQ#XaR&1@ +Z!T30[D1im)2$41jIdFql2UkIKN0beH*ii85h![L%98%38#-QFI+P-[m)XdFQ6kq +IKd-q'BH!NS0B+i2+"FaB6[3X51+ZX+4BAN*0I*6b6rcd"eCALbZYG(r64,GCT`4 +GV""%a2HC*SYF$Qi)"ZT9$)e&%S%VjSkb#TBU*MhNkVd'rEa!4aG*P1CfApEmK8+ +mc(5THDh,!R4S2%Q9ZLX4$bDCCdV0$aX+B)q!&+*mGJ0)ANUJiNV(!3+Sq[prR*! +!SD"&qZ6E$V'AQX8GV%S@"LZ++BUlb6r+-&Z'6#,`#A68DYS0f[N@d9$`55($G!* +CLCiJEQ%C[Ml0BY182rfGLdr4Nb4#4ljd[Dp0$(V4TCKG$GX&-rmr'K-aQicjCr" +MDrH4U8PJ%flF'YS6C$'h#iUGaGIp((BX'*T@FM%(8XKjH6q'kDpp"d@H*kAK@M" +$)9'FR!$@ai-a[Xa4XD948a+P-d`jZhTSihMlhN[[1VCM%fp"TC!!,9+2M4+AH15 +IXq2&3&iIM-C+mdE#,ZYN+GJX*KpBM-FP80aGQcD"hakd[he"+bB2GDd*J!PlF#L +CFE'9+'ADD'AZjmb8Eqh+jIU4,k$9U(S@M6iY2U5+m9k6BqbUJ`DDT6Kj[4Yfcdp +[S(%ZpcRbLq1Tb9ZPKGQBV46XfD!I#DEq4ad69c&kEe-K4$J!5VP`BaQ,$Y15N85 +mNJ85FpMAA+(`"P6&U@5kmFc-&,fYde[UKe6kiq(j+ph$LYi`'f$2X`Z2l4kZq1m +Yf4G5kqT+cD[FPlRVfGD[e)qUp4VICcLFPLM%)80'mUJ,1GG5QmI)JVHSl#)1dpV +51a26c(iDT1@je$#kT$&q,X)PZjTVIj!!M9E'NKa@LIKMPZ"2Bc&e$b(S*!rZ9hV +P`Fj3V`c!U2-R&P#UXR0iR8%)HcTE1`cY(16G)NIp,)(N1&FP@*Z%A6pQ-BZrB(F +BNXI-,S4k%)Kl+Ki"#q$j5Mj'mSTi)5GraLR2%5@3!(6J`AM`%rd5qjP'i8(MpX+ +LbqGV2(&iZJTYPP2b`fBpK)EhiqL55h)Vj`VV!JX@CBEIUT(QSQ&ZV#VLj95c+E( +D!TYA[8@N%DUApM35elUeR*P6VjTMCdeXMf)$KbaFM#HG$%@Z2M)-GMLF($`jbSQ +kIU8U&N`h-)R5b$&h4lld'l3*+@YA"I*"lk4Ir0Q1,L6FqVdfkX0U*f+2ZXaB-Bh +pi*(142Q1L0!@49ZZmX)[HB[f26jeTTrR6U-X-cCYNh)rj!8@'P`*PiY$*Bk"%Ei +()CXb0jKMUFQ$JES,)h$Ul[6!Bk$)`A,4Bj!!l0XPfaG8P5(,p+[-P"Z)hQlPEf4 +eH'm#C@ET@c#AHUYj2cH!)8ae&fBdIEcG`h@Ejp0qSqb-3IAQNJ-)GSi6BBDL0V' +D-GL-pmX(L03X&JP*Qp!5Fj9B9pXB@lfPd'kGhSDh"6"N`)5KAFAmP[hf2ITYZp( +DLeLR$NjZTe,ZJL(kM9ceDcl+49bQ8A&f"6mKJ(XHB,aqEGqr$Q(#6jGS!V%r@1j +,,aRLa!46l5F6X+H5@Ba0TpBa2`@R9'-0GUJB&TFVQ@Le)ki`kq-BC-c1(1T0-QH +L!p'8T,cl4*Qd)A[6f,T'd`LKP6J@&bhlV!!Se)$K@c4#jbpJ9C[I&k+`9l[@f!e +5mFEPGDXX8C!!ASa+(Y&5Z`pB)6Y0mHM&6*!!#M@0XF4[d(ZF4$rfD8iJKM(Mb-F +4[prN"%Sk@I%Qc9HiJQH26"EmL+i&(%+JJ*,[P9+9R"p(22Z+F0VEBVD(b*4$X"! +mSe`)L[4@Im[3qBA(ZlTFLV`)'X[c@K#Qf[j,2dMHDf+6!I@$jLre-N,JG''!A,$ +#h)D)Z$F$0R++rIA8U*6HHpp*CS,"G!F2BG9"6BbAEPH!1Gl@bUf(RA8F5AbS@U@ +#%K)%VSQB2(RI6mH"#*9@i8S)@N9KE#)me5c6M66BLJ'Ye)81KJ--H+@!61(Q)G* +!X''2HZQ&H+ibN!$81QNap55S5('jD0P5j+RIM)4iHjfLDfXXqjEY3I5#2J&12)p +69dicmZl[bCp5&Y+6+"`NKaJ)PU*bhqbjaNXI$bjrcdPrK#%H(m2*CG&NKXrF8A' +AG3(%QLlMM41q@VlTh,-B0#FAYcD6hY,cYq%4CA)-0PU+h`$-I8Y64jm`e'BmJ)& +"R(aPEq3H5cj8p&TYIJjqL6-)iA)ME%R#DjQ8bkFpd*!!AUB,X26J9Y00%HC`dU8 +AlLXYBLYMBqc12jAjcdjIG"`df,Emh&m#@IDaApe!Tma2"I#8l&H-dc#!I+#8hHE +6HHEQ-Bm24Y%R+G&Y,4U'QL6E`jpM58H,rcI1-4HFrNKA"*XBcL'RfIf@%Q0ZTqr +DKC)hFcc4eDC@MEhf9Uq6dQ9)Bfm*(e$C*5+k)8B6`"iN-SB9rRGBdYE@Z6L"T-j +Ia(P#AX3""@Y0c*Y2`EF[rfVSKl2#-8i#-aG+dfpUVJTp#Z)-pc#bMhk$p%SbSEr +Q0JI'HcEc#mSq6hRNlAmAAp$5+B9$2K*X`MZ)+l6(ipaG$dfMZSb3!$b,"qlmA*! +!&*,fC*BE!&)pITM86"%'L!84HiR+[PA$(rT3TjPmAHTm!N5(`rZ(R6jYP+H`[4V +f)PXAXE*RQQh5dLCZ3e&D"%+cXe'G66ZT'[8B%E10+U*X*ANGLR@D3kk$mlUXAqi +iU4lY,3YNQ'1qA'pMi[1kR'Ch21lqPR3e5pk[amFbC[YCB("Nmkjr`qJpQ"#VXRH +**5Y'4ST9ji$,JD)-"F%%'5&(I!@QaeX%62Z"lpjj(30b0l#QDmT54!lGkR$N1`k +6!6!L!3hmZa65b9*5#mpPR`[RbFNLGVeRMbhZEm5lKC-cSMS`&*`GaqiK6m@$SAB +b50!&%[LV*XGGHAXj%4b+0!mld*D$Ll#b*ikL!QRC$-kI[lM(rICFJLK8,IC2[8+ +!!r#mL*J46C@Tk0LLe`Vce&2bFBh2Vpd-KS25`S8aD@fkRbR#`*IkbPh0RbXpJ5[ +MUpq@BY"A#BD43XhlG%*DMjGL%5bp)kaPM"Y9TB'Kf!6*PQ'#NV[B0Kb[0KakUcQ +a[El11C2kG92B42IB`k`e44iQR*fZmb@e$0`(d@I2DCT1+3*VYI5'XG$RpZ#%%#k +V`Y35emDfd)a$C4[EAdGUf'FaZ1bU+U'@1rQbmf9bN@e!'FUDPXcc!"q,ISP(%(J +(mT!!dTP3j!U,b$Cl0`p9"`#[T,jJUlac-G("ZYdHQfEL,9dYZfLj'Y[%2Sba8q0 +2a"0rc[82cT1VkVCd!&LLQ6YHr(TSPH3+6JhJJBap'B--kI*8TLR*1Dr`X@iq-Ul +2Jc*AGS[4!1!"IYS4'mm"RSIiUSb4GcJ5-&rq$iLaCL5546pCI06,klaMB`[!Nak +)FcJ2Q"0V[lQ1$KpQlY62kSafY(deFZ,R+")Aa8F5qPEd3PIAB98rr'r"4QRD35K +8ijZLa+5)C!H#1d0jIZKaFCNI4DI@S2*m)h5S3%&(!5Zc(+L2E[!r$IqC5#IK"8Q +Z'a"`qd8)p8$53Z4rEpA2Ap4jK4cLR$I(*1H,J3UcrC(ap!kmL`["M559i,#Y)IA +NM2ISi[9P890JIkJh0edBYGZp`QEMMd#a!4""A2[-M&YV[p!"c`Ge2U&YXSY463i +$$22S#ISFIZS`C94346AU!er5H3VjSrKEbSMALJ$DAJFkeeRV5L6#&hpYS",B,*K +QG!9bHc!VEKdTC8K`1k[eVXpD'mYU)3C62`1eC*L,8QFlQkTSI'H1EhC+'*)rGAC +'AAA&J(5`5Z5ZPaY`kM4q@fTNdSk#6IeeP@P-j1NBqNRGPdHU[0$KV@ljmHZMd@# ++J'"4Z'Z(Hiad()rjF"V&eR*ML2GAm%qYkdNUZNQF`$mK%k9lP`NZ9``I(!JjE#) +BpSTEdkD+Mc@E)lrMQfZN)GL#a'M&&VH[clHTM8QrPaiU,Z-ULaU*1hR"YhjHIb@ +dkV"0hi'TMQIbfTjeBQ'M`3JLbRXCTIkIl2h6Yj`ba(HF1$%FaRa%Fb#UjYC8BVU +2R98Tak3He6p&f8fDSj2ZA$%m-2V[M9RpNUaIr-T3Bp*b(5Q-+pTq+LarhGi&L6* +8(k1)JcA+VYVaL`$q*AY`(Ycf(IMrTcJp2cAlcT&Z9Z!@bki4LGGY*9&IJ[D3!'S +!G*,RSGi[Z81r%9#l&HfDIMLJDK-leMdr8)HY(-(#LD(Gi'`%bIQldGRfHINjA1f +K!8Xj"KFf4fkIA1#ciDE@@K&rS&Qf+2H+V2ErcK2PKZJP$ADp1*f&GbX8(h"%(e" +m!T!!ebleeA(SR9IF-AE&A+8l)5mG)UL0kYLilDQ3!0qBf`rEeUTipM*41VSFi$- +A(e)qUAKfS(aU3$i"P+MQG)fpJEYE*H'EaN5%0!")Zaj1rrN[Ek0d%YK6iNRG#Ni +%lPqrk$1b9BQ&e-Jhair'+ipBS3f"E+V,hBYDMr(1EC4-42%1)Q5%"HI,&6iQdFS +,C4(AKZH1b+#bIqXe6,KQNlV9[p-dHR5)GNC%`I+,3&'!MFKK`q$6PkCmVk)))$" +Br)p*iJ"Ck@-V6-QpfrBD9Klh5kcD'lG,)4Z2UG*PPDpY+[GD)a+8Q[Uc(4J5-ZK +(E9DhCHlSp2868CfkmI*0Drl)LqLAe(19SXq2bY!$T1!5XJC#er*Nc-6PlAbkVNk +f,Q0DT"BeT1Yc-4P6rd6LaVGA&BXZ'l+hkbmS[iZ22p+qc2UB-l!3Nc*#Hff"L!J +GrEc3+R52Qb&)AdpmaZ-#kTF+#lb)#Ab2[6cNSICRaCJUf(Y3j$*bd)qVGMAIA8j +GH(k9TVS&#+fQ!(6*hCdSbR9TkCK8c#&4EDlE%P4NUDVAh2d8'kHlS`C@pPF%4fH +U`H@h)9Z&ITLX6DNdFL2H&q&l"BI8*SD(,Q)G4K`qSiZ#jA!P-Bd[('$I-$N#1Da +*38L9edBY)lSG'dp-!Zq3!0dC((GqHD%IqB`*B+%J-jM!IeG#Ye#m5KC,'`+[8"p +riSpMLQb6A3AeiBPijEhQe)1D0Rj2IkJX6#l#EH[X0VS2RKe@fQQYQ4SHY`DR#$H +IcTFFb#hCDj8$j'R`HbfQ-&rH,iH'`b-*9B+bfF$l3k)NhB,j+-SATP[*E)rL-B" +&4'QG2m(XS[d5"Fq!F,!5#FlSjkaSBVIbU!Dd%qVGCFHc3ldM`hX9*mUJ-UrTK%d +pH2LKQK%&Z)kaZEK1LfVS4PKP55JJF&#)[mQ51TPT&+8HYSZ5![S`iFr*f1CdH+c +VhEKR`1YECkNJirYZ"lX"(B`d1kh-dk&pE%I``F'TL0N"`Ra*AGUTZ"pR-ET#ZIf +RjQVPbcd'2$4)I1N#QerG1iMAT$+Vck[1$XTBPD4pFLMjmi8+4G'p,M6e`Kf3!,P +raplmM)FEl1pIGq@2%cpBcFH'5JBpVFFF`Sb"Nip&N!#cNmRL$U#@Dal4r8)*L11 +J+eb%KP`6jakUFq#1NT3Iqf32rp%hc2+BF24pTS2B`-$''a)md5X`2PBYKjR"'IE +Qd1H8d&@+G5UDe*MbRpB6*mbSj6AJmceDRUS1h'N%0hRD!!PQ!R`("&HUrD*$EM` +Rj*V0ZG1G!q'0UfBFIm#bqbrk+@'M"bf99Jl3EZUZiRL14Tb$+VkkJ4+)bdQFR0Q +)8bMYJU"`mHSGM",1Xbae`6p6"QjSaQlb5$4C92b3!*AI9(hH6Z4jY$%5EQ4!V99 ++UIIVf"N1(CFh80TK"%[fa3#QEh$9JS#``a-K#iqS6FEJrl[k5mC0FeE(h64J8SM +3%G[3GGC%Z#hDE,kc$h%D*CC0)pkGj!M6&@VVF#eHqf)9*5FY,aRkDhq-+S*@J6! +hf$#5l'QIqB!@ifjl6&p#!XR)G`X!I-jLe--A*!UjK+)lKb!Ie[*90`206``9-2` +5!N[XAfEBeE&D"LA[dlN6ej!!601C1AE9lB)m$4X'Eph1+Jl#Z"HPhS2$pCG8*m[ +0bCJR$Hq(P2iUG,``j)(BpLSlQ%+S)fq2-p8qk5ET2FJL-S%K+,RBD`FL-II%,8& +PC`)--eKad5kNCSP4-fB[[5[ZK1D@C14k3Sh[)E#hCf5e*Gb,*[-AU2)4j2j%9rj +if**@-T1bp%m4C$R93E4KI`S&[VmGYXL2KIBfrCj#i%j62rH%C2d!PP8[YRTb&*p +'@re4V@+9(2ZF&h[,K5%5d,ji4Aq#+Z2-2X%JpDCrpVE-V,M@8*r2P5F2iGS9fAd +51`EL)3i4K`3%4kGe(@(D65Vk$KXC0lR@NYEd1CH%pU!hlEU3!"[G'"1d5VkM*aq +IYX93pR%9[m'@L,-GpDR2q25"0)pDikpI3X05CJ!D+03UH6Aa(fmVkQ(qqB3'6TB +*bXVR[Qh&'4m'&iX2(MHr[CD*aM&NAN('SR9QUkreB*VB`q"e`qM*YK,f!JE5"8- +,BAZ1+D4j-#r*2i%TCYQ6dKF-iVlS")Zb22bqr5TNlMILJKmaXb4HTia%p6Yp5&h +LEPd#@%J$jY9HSJTJMb((Ze#!bKB-*K`c4HArCr(6@6RS86&bFEj1RNq@N!!%&p* +V3Tqp3j9HNqYQ"U`%0"2qKSdNKJKU")YT$RYCH5L)1c(YYKTh'8EA9@QRT-XVCqa +4ceL8a%bFDTIL[29`E%e$ZfP#k5hY03DlG'm(#4kM0Jbm3*m83VFeFK8[0AQj+r0 +0jlC260q)iq+ZcCkDhI2#!ZMC9kam9[bX`K`i1&KbPM5l&AdYVr`Zm66jBNHkqE$ +D68L3!(-5EGD2V#9c`bP-Dc&pDiBjqe*[)c`TcJe4310$U%h`b#0I%V4UN!!%d6( +5hZQ%#))%Ca'f''XIdP,Iq%ik5iM3bY,"DHDA)L'1T-2JHe@DfbfCpT@V3IYqik+ +,QM)h2YBE@1E[CTDk`+`eEI##KMV18V1)4@Nk4&Eq&`R[GrKJKBAY)$"cFf%,VK6 +GrEd3"hKePBiB,-'E`c&B6)XR$l-XV+rFlDM+lb)e2!91#XY6%MeK[KGNB'M,F%k +N6LBqSZ"KaYX[jG"%RK(NN@Uh+,ZC-#eGjZDIpD9Dr0P3JZcH($%HIC-p*(QYIb4 +&ERa5h9-'V2Sprq%2V,`9"!&2P,lDf,"f##2h5imeMVjF0U'dDbm9HYqDYPPBr)L +-CHJTI`eYU)jR3M"i1BHdBYBC5$&b["'X0UP#$1II6apZY$J6cZ[fZYX!SAqD[,k +LA4YDU4Qd4hJ3lJh,B54D2pALDfkD'9)bTj)E2YjrAcH8l0eKVcZeriHZ%PMIQ&( +BRcQLEA5$U-X8PFZ'FKkq'!,ifPDk0PXp$BZ@RqCV4B`IcV#0RLFUSh!B18KhQbc +EXi4c'a3h"pQ0N!"Y43pUf3[5&0iRS0'2!J2dQ&45h04EHkZ4f%-`eLUMIG+bUI% +1ZBSA*@T3,8q2NJEHbX#J*@1@k&U9"rLBqHf#L5"G`f8He*'@2NSCAGQcMp[mC!@ +mIUi@!J'p,9@Jk,$`*)1RpF)"YlI&'V&eQDN$%RX&J'3chh,XS19fR$fb*mmp+[S +Q&M$pDEHY2DZ)3Cp#i*Tc@!TR(q6*QFCLYeX93a!hh,8*+U`AGddhe(!S8*ND3N- +N53'(bR1R2l4jMFDN@&$((IILQBFfic0r1q*6!bi!3X(8M2d1#,(4h+Hh0L*`3FN +j,0[+@&&ND91DN!$8llX+Lm!@9fEN8&%TQ!KF!Y3ILMe#'aQcS)&)56)FqHArH)C +ThcdKhNrrN@aXZV`R5-)%F%`TE%%&m6"F)r)Sl#F4q2fBDkN9kX$rZ@p(bHd'k[e +L0mjXP,1jk,FV!P)&*SIpr$*XKJerZb0C8pe`LA2J2ph1(r32irF2#'!!0Ppb5@% +VAIe(J`3HlC3i[0XaT6JL-Nm2)IBbETHdR*4krlKJ6Dk2YER(XBAlRN[1`#P%qS6 +38SYJE[-[aqkqfdkBl0p4m[9K*@,UL#4H9jX[`$$%Y8@2,P"+)BN3aVM'r2q'FZ2 +M#aD&,TEE`[GdDlcPEU21*qH3!0UEC+SRe6k@Zqe$Mm!*#KVl+m@cJGXrR8P2CfC +e00UU0Qd$eMl)3HUFQX(UU'"2GRIBXlG@P8Bj(j6N(2qEZBSm+R&(i-iAEIcDk%( +F[fbqh+6$jmB&LJlLGJZ&pMRXhchAk%3T)dN,Na%NJ*XN2,aDFjdB`R-P-FMeN`i +*e*BKaSeaG-pCKm$TJTl)mX5[F!R5mJPNNUjb*Im+fQ6e,!J-JGjH5N2kH3`%U58 +KF,jcjkM81"FU8h6XSl6-BAMI4QfVrYe1C"2Bri2AKTqMk@F'TY9e'1iCQ8kMNaj +SAUe4*I%&Q&)R2dClKlfXMQ+N1`YTCeK8%VPKKIPH)pIJ!C03fe*T8Rf!4U'"3Ai ++#Q&&NHMQUY)1Jd699`X$e(-6kG&"lSYk("802Ve14T0P66p3jPL&acc5efh5QB+ +NA13mPjkA+mTGrm#"f%XEc*2p%p("fd1V5#M,f',BkI2XI,bT,MTVm9N*9G&k0hh +,aBAkbiRNY*eXXK%@Il!5A'TZMch0+XAfd!V14bXCj+(ZM98cq24SPGMTdLkkV(B +&$8!J1IVU5@2VJ3#pZ(S1q-EGbfQ!"MZlAIK4HR%Y3eiUZdmiFeH$1ldbkiF8hrF +brLem`k1-Y6q,GYaNSIVJ`p3@p298PHM(`"Nj6C+%AI+kCP!FJ'(hc`$eF5rN5#j +Y5K-YZC!!8XCIGh&K$CAic!'+$eIeZ1UYm-65@@1Ulj&HC&H0G8Tq5&%5M-UhPZL +E+UKLiaG"1hm45da'#kiUK9,QR4SdrDA8Lm0mh%[LDk166V[dhcQKc466@hibQQI +BIGdfNmq+dr@`)+id[fLm6kaRpG[FTpQL)&qm@6UU2a+,pA-9MVf,I!mI!GU-P'N +#Z@'f)"BUHDScF`bJI'@6,p`$kj'41iila,0jj$@QJC!!Z$`KheCTSSBTMcI(#h* +%C0A)-K,$BUlQJ0cJENq49q`JD-LlN8V6``I1UZi4QGK+'G+ZNmZij%UdmP'cqKJ +,AHCSXEEqPH1p5ANBliq5fDD#La#Sj&dP%4eI+a$Ldk"-'A8``6TajQe"%-,a!&e +ZHNcaTb4X+'NMNU%pBI4Fer#!rFG3CIK$U3j8kN'22SQaTfSRa4'fYlmmiBZ4[51 +'R-H-CqRaXT@3!((m9P+)d8M--%0qJcK!'GP0heV4albQTA2-)FZZRBd@M[MKDi` +VP#U`#$K6",dR(-%(**,i2,N>@hZYCUqb!+R1TKYlbCTjV(c9$kTrLaKK%K#6K +AJ(8X#!d@Q0%eS3VFBPN3lhNAimb1B)T!3k5qK5bVUP@H!Q5HSljf[82SX$lh5hq +I$%@jM`6K62XB,fZ)L'L1dU-bpa`&GCHp823b,Ghe#%#9X$IZDfahNe-+d"8[cJ+ +@MaeA*YVd%*9UM%Nq+qS'ABjMk3BZUmqJ`mGGLmF64ZEL%[fDYq',ll([fSaJ$H! +bSmXfNDElf4AcD%1,J'E@G*!![9A,2,Z)D#MpJMi6M9BBJarD+5Ur1TGr,YkcVh& +qVRfYRijTEY$Ve3i-4+JGZK[5-R2rQe[9cNi[Sj9d0XaMiqC,A-%q0j!!KD'%cVP +CmNb[Z&e9iAj`bA(4p65'KPq`&B+QMB9CY5B6b@DLi,SM'[6j`JdjS'AS5M1`0*A +*rp90GeSGhRP2Pl&Q`k&d*bGdjbhF,3[fI'3G[a&@$,fN,V,DLMHR4$8#%2El0&q +#)8LmE2SQIEp)J69dNV@UjA53!&J`cp+lN!#MVqKfrH4'["T,l8Xj*Tr-EkRKm-d +2R4iA1(#cpB+kjTI!%NVZrh,9H[@`[LGCCH+-)MC%pIF8qYJR(&c%ArTQR+,NMSP +,P"f)*P"X$+K@f2!LF3RlGBVZc9"1X`%0r!T[T592)6ZLV*l,L1JiFk,fQDe`8l8 +#e'F%Y1A0KUH[1HPmHQQk)XJ`'!++'(GIP&K0'(r-8G8JUD54aTc#21ZT,rpH!+B ++9NXE$qSP%qb[L10A$a1F@NSQfR,hSNYP[mVFl+rZMQaP-3&A%L1adb2Q$Xq+%#, +aBN(#N68%ReGXr%I+4,-@d(chfNpEeq`6SbYaaUK`LKFKKm#MBqATNNp#dGEq6II +I,)r4FK[2'hjVPN8b&i,S5A'-Y6df"eK#SAI&b0VbSGZ&Emmk8J#HS3(ReBF%qVc +"T$aA05HY2KVmH,qJ0@UX("JMX'hPXUi!@iiT!cDTiD!8mr###4%R4dlh5pU5P[h +Pjh$b-b@p1Q"6dUKh"BidY5,N$80*H-0j[3'*SU0R)"-,VDB-'eNhL5b`YV5ZaR0 +GI5eLbp69E,3Pje(DGBT6-'#+*S!"@(9KE*)jr$mBlh6%4l4mb)pXbJdU3MEc8@l +K#j)5R08HS+NdA$-H!UF6)Bl0QVeh8,0el"*k1iANi,cqX-IQ3X6lb-3eUS[(SLB +#2#aNQCKXQ%ADQECBkA8!G(@jpiq)1'9%VY+HYa6"S#TI29NXmI-XYT0aE6321bH +0BPQI18,"BAK2KGhrY0j%[BkHYhE96h%T2m0$`eM*K6%26!,`G)r4rN&RZ2"+jUR +5Jaf0+aMpS9H0",i'L@ZeE!d!eqjKk-YV5F@lG-(E"%,k5Z8MLjKYEfAS4(SjfDG +kd&EB-erh2je8PB)jZh$d)`S)jGmIP[LVN!$-#K3M@B$MkKk0&13HFZIIB8@Rml+ +S`)+#pE!eGh,*[cKdSDQ%TR[eH-%a)9fS8h30VeR%T3Pq%I"C16HSYar0B[&X[0% +qmF(,jI@k)kd2)qh1)T(lJFc$-U4hSa-f9Z@5p9$8JZ8`*Nf#ZFlDA-afm9He&)* +HBprE$9I,HEZ3!'PU5Nkp9!8d&2G`MlU#NDTKES#b%,Lc4KU9j!I3SH$-UkAL#kl +*(C!!iZBF`H"0q-9p("lpA[YP@p-8@XZUr&Q)a-f4-G2E9&j)j2RI%Kbij9-UEBM +$8'@F0k41hUSTlpHapq)$-ArhN`AFH%*le11KbYSH0QK)S,h&-`AeNS+Dq$3!#kr +4hFJ(-6hhY(4*hELPdb119fd1P2()l&5'k,@538pP#MK3@*A!@6jPJBmGVIf!j,$ +UD`DS15eil1Y18rBG2b$E+"X(PI[[19j$1VF1L#bf"h"2N!$,VIac3e!FrAG,S)L +3!%BI4jaHkffV5FBlppa`'L)(Fl$JXRRUH(R#qDH'$R)mc[`$")#@'88UBH&k4C2 +X)@VkPMNJEmJjK#$-iY4j#p@@+eh*R%&2kMlbFR90aPG5L0pM'Di)rDVJ"hMm8BX +jRGpLbDDZ&$hdCLN@$h'J"p$If4X9(4))`aI1'%e9cl9E4XdVcD8jG[@8VEMeEp4 +'Lp6kpHqMqaiCdVU%XNZLheQ3!1Fi3d1QETF`@@6efN5Y0`"DEB052XfP+lP(KFB +qB@I%&Ufq$lmT#PY+%FY-k[p%%,eeJ))C1`Fh32beQfV!kLV*MX&J*$9AXDDc3"L +J89HLQFFm[mi(e2P"0,41%Hk(V!dBqLESq*bb&(@l)bK6+Qm64'QX-4U%T6+[hCe +9)DMhVb8G5(c3PUkS'%9ZMK*RST8BcXQQK(rP%,"Z3rVjY+`'+Irc8T33BBM#9Pi +!lqaF3"M@([ZY8jcUBMp%F"IAqCHSB0FjD8Db5@pabp%J4qq8!"RY5qm+D1D'3S2 +ThPUb$b,`J&Q`ASqIS'M1Bqlf6!+qaY42aPC#H%P6dGFQb1A9,4ql#Jf"j,ZjBbd +9M0rL,'B-XAE$H-kN+"dfE!4YRBhc%UZVhJh&qkF&q+aEY%C0$'Y,Yf6GSNa!BD, +m,1m9CqbdSc`8(hE9!M#h(BRE,4+#*Bre,jIFPqUi6iJkp"@Xiibjq3`0XLi"iC5 +jD(`KjZq8NU#e"!4iDIAG5ei!-@LA92X-rBE*XaaL%!p+9aZFIp@S)6FQFTTDbYT +1%bJ1LpAl8aCI`B%lq3Ea)#mjT&3baQ4@1Xh3qKTr-`["iRjMALdMBL,`'+l!I1- +FXdTDT%&8cFR53)5VPe[P'RCdm3P8q4+hq`+&T4YKVh'lVUX2k[HfL(8G+J66PcB +(U-&Dj*INm`IM[[e$9QUI0ma@Pd3pk+i@JI*e6!$TTaQf`GV#4a$e2Am8@9Z8B8R +mkmrr,MIT6Z'V&YT)Np*U-jD"Dh!U,ZZVqVmdSX2E(rPfleIAk'FE&,XI+J'IS&- +f4Nl0BL(f!b+9lb)DID*$TfXcH246$M5(q*X)$mT++,5aiQ,UEXZ0XdH-Qa24lMD +CacZ-qk#%rfQGrD1YKUBNGb*Ij`p@NNSV0l24ClT6`IP)$3e(jCAeqJS#(*NCQhC +p8(QYCM4)dQmb'LPbJf'r#"%A#KMQFdaD&kAqQja!d*hAU!9Dbb&5JCDGfPYdT#V +925b-V1,)2QQ(IVL+-LZ4B%ILlaVNl8cd3[q8C49#-6e6'fG@+,RF`4@Hfq$D"%k +aSRedJ4)%p'IUAfcUC'c)m[hJ$%V$#S+E64l'@D-kM4qmF'6k,G[ZZAdT"(B6r%$ +&ZpZ,k)#$a&1F5`2KqRlN*phCM6((A2m6+TZcIFFR)(VmS0%ZmI`96E!kc+qc0(S +&'K1iCVNZ-8'QA9)E1NjGE`YfRq3lG'959P)jdeqpr5+kc(IQB5L"hC,P"Mca%CJ +rNdpp3`5!ZUidbK(6@Tia!0ZNLN)FA"1Gk@K*PZkch+U5T6D1M90U8TB+1Z8-rh5 +@a`@GiUldCI62a+(U03qj-H9&Nb'k5VS3[N5L0I*#jiA[N!"&JKlPNL(T@%d`B'Z +BdGL04CkJjrGJYrIqV+"`'XhV,2X@'GmFQSB6-0AI4i+`LNa0N!#0Al"G"B2K$e@ +*4mYMRPJ-'-fpV5kb#X9#fL4Fbh@B1l*,UF0X9r0fa`!3eGaS[FqU963jTCR5*PG +jB[E11EP(NbYfUj1$45FCGLJ,9E+[FR!j5INbP0D1kJlC6dKfRrr$Kl!HFJBXGlJ +CTU6J9NE1b$3Fi80c!iA1*ZKc%hIX#mqPUl$F6@Hjm4,5IdK%6%kqec,i'R0ZZe9 +(A"26ei(J-lDQSU@LS(#I9cFcL'%HPc!CJXa"YmhheQ,*P'JdA!5N(8FTMc$30G5 +afF[F#GiL-ZeV,PSSKPXGb"f42qkcaHa[UH6ICqBKamEBEe`QYk5M40-AJkDe![@ +brT-[ccmAV2PI,X`ZhSA3JfALZ$qhN@(i%UUB2lQrh6qVh!@rB$Jl46XX+Klc&PI +[p$&(A"0JT6rp54lMmq`V2VI$[9XRrkJ6+6AI&eA92XF*r&-H*$Ei%e905G%c%[` +(A44mV4h$Rk8+)'klVl%[!-$EIFr@-"mVjl!4FUMV'*IAJI[MS!I![#183)%VZKU +iVaH$SRMZe(R2F2%'F@+N#rX-IbMbCS(hCIASS-5$JAD63PNI+1EG!XT2p4VES*c +C4dLNHDXD+rp())Bd)I@fNKQTI6cS+S`1Brk2"jkb1X1Kr$#iAA@A(C)5i4r8c3Z +66MRqA16[UfpY%4h9+EeK!iMEr%b0%klX'54-mL#HMSRY(GrGEF5RY2GpNPiGE"( +LLAU8r,I%6L3LUL%82rU@Y!DjhS#THaZ1ber+PiC4h6f-mB-8C9%lDYVmBeMd0)P +E5(LbIDL92EK#M0NpZJe&AS!k22"ppQ*APpKm6A)HjDEE(f3GqXqMDAR39E[db*) +iRLEZ@j3@-*0rqjiML#Z[)0Xl`L`GpY`*G)3Q-4@PMDqK1`Mh(fq&H9qd(QDPqjY +F[dYlX-,5BPER$8-bm$NJfTZEa$+FJM[#U@R"mEPP9qjh@3MPdDMZ$9hX`d"jp+% +B`Uhr(k@2*KH%paAI'dFmd&6@hUIl&%*-Jha!#5N"i0QVJ6Mb`AM[XJV(A28VQI" +NR,KjrK&T28+i64i-hB%IABbSei&BjLi$5MqE*JYq25aR@R!FDU*SVP9h"C6lYP5 +FhRF5rr'e89(rjD@PH5CIE$rF'$%m*'Fj`G$9Zb`E-X0pSpGM0RJ8`AV$1U([e-a +l$NZE,JZdpPS`!ck,H)3GM4i9Nf(M&[$Jq3#d4DD3!+1r0afqSqT@HR!Z*+aErFD +'2kMDk0`mIiQ23,,*)5#Ia2@Ib9Pa'NJPb!IR&3R[LcM0JJi`98#'GifJ$M'98hL +Xdk[eJL@0Q58SI"i4PN#Xc0G'D,Zm%%5E!X)*"4im+ZZ!&R4eBYUCiPp68bVHHJl +F-J8%Y6A(-$UM1AfQ8Q3-%&aaUJlTMV52aK&FTldCjR3B)"NDP&pK,DPmH#T(IlA +e3dSU#[k4Z&VHG8'C2f+6[qV,I"`N052fJiHPL8XlHC8d'Qr4U[ami)k#$FJp0Sf +)G+1ZH3Akm`T0+!VlHpI#0a+M`9Xrc8,9IUeAE+jPQS&5-f"8DpbBMJIk"-U-pRU +T&a)"L8mfFSFm%0SL4TCKe$UNV53D5VmKKR90lca6Cl@Y'pA1BC%R8'Bk3ejjI)[ +VK2SmVQqIY(rAb#!AUp+fb[T*-8d8*PDTK!%G,B#H0`aCrS3beGVV$J-m#UfKde` +fcmalF&GJP0ZP2C!!M!mEe6E'Epi+Jieq8"EV2aQAF'bjf-S-ZJedB-+Zp3I1ah` +CpX8QbjI`32TKj%JJCMkk*QAC*N"VQGTr@[R4mF1[qeIVr"3eFG5EFC%4RL@#kZa +"ILHkq(B0f5Th(F`VdFG5a%8$8kmLIiDp$PYahK,GKE04U@&BiaFeB"h*d+dCUYr +-`&b)H5Z%jbPDrlFim39@Qa$T,m'XY5SedI!@+'K'RSITG"$m6FGI`S9dhpCJZ), +QB4TbM%rSTLQdl(D&2C!!A"B)Z+K++1I[5CiFYd(kdqFKemRc$h#4FI6(fb-c#&Q +V3jkDB8I9CZY%NZG2qp(l+%2(IJ8#AP1MV40Z5S0QpHSPB%U,13Za9E@E[L5,&Le +)&rjKcZ"bN!$V'341a6``036h*IM83mB!mbrUSZaT9-!66qL3!0L8`qR*i$HqIJd +&a8j0RSZq%`9#&PYP9("%rY2S@9*DRC`(#H$SLSbV"hSm1rLmHE%U!3)'j%BB6`" +F&-Xr%)bZpGBCU%Xh&!5LXF)lXP22U25kTh5@3CeT%QlYL@3CkeDiEBbMEZDBqjc +Eh3$C$%l$,-Ihe-3ZQb5+0%F4`eqGmbH!,r-HV)ZTUKiJ!$9'DCF*DH*aQqT99er +8apS@i&(A1*lAkM`p6,V4BeJ["%K&T%rZhNaXR3%")P'qkT,T5a)3UVJXAm8DArI +@B(VmdC`)dij8`P5YA3(JP-XFB)`$aX9[,M'e!Lm0hRH0D5UH$SI2QYGHD4(K3Gd +eMH6(Q[504%c"@GVbU063E1)6m&mQdld2I[*9i(k@"pc'edS*,iq@U(DH0'jD82S +GR2Y`!EMf-DICjKNqQD,dp6iJ[3&pbb*l"X&KK+i9NT3QVJZEPi3a(6T@6h+-"AN +E!60+`Pe-8!3XSA,&cCLkKX2&SDNf88-20b3`"*E1q2)F`,@&Zc(L(@52-hm&&d) +',0PJ*LZ`r'FX''0'b!Fe'Pmi1Sl5FbKmr[U4RV4Qche"3P'q,1LUI3B[9rQrMrL +#RBk+B-2G!HJl)"9[hVrkFMXM2Q,2G#)A3Ir8(eY*Prb5#,U#Y+8VH[%MVFM)kPe +X**AaSC0I#dRSUHVi!Fh4"YF0#3Hk@Q*liGG@UDm&E9`&j!bS#VF8f%Z[06rfElR +&Hf+`(dLPBG+0Uc'+qF3LTA3L"Mc@ApX@jFm,LUUC$c,k%KDiB916krYj+%R5X22 +r5%#Nim#G""BXK0L[U,FmUFP%1&&Z))LS12k0H1![+2@S26#!e,b"I$'"E3Tl4"( +#NDh''b3f,L,lYElf)UDe2bpTSq"R(c45PLV*U'@5HqY(jkA&E%ffdpJ2`&YFFFk +cdkYADS$@(A-+QqI3@aQB9l!U$HkXBpR8NFSj38-a5G`CMq%lMf[!-Tl2&jdFjjf +rRNFal+SQ"[--06M00F5Q!F!BFC6eJJ-fNPG25i2*Em`!kh(534)LC-@FeFaClbp +@9PiXbpe-9%$A[c!k2$'&)&Dk1TL3!#!"A9M1+,Mll0Jr95[SV#HG1PGZR4GqDP` +Ic0%)mF#)H`c5RY(@LU`[V,#qYN,96k&M[ikDEhTF(2+-34cP-mH2Z6K1+'mEX+f +9B3EPS&[kEai,CZL$%-9lJZr@FkM8GIJ',A4+IFckG[dGpP,)Mi+&GA`9$TN"T0D +j[6#pQ)#Z'+!)V"4pqd%JJL&YNQpi`+@3"!%!!$d!%,5L@2HdSPMh!!%2-3!"33i +!!!(%!!dF*J#3$NeKBe4ME#"548&%688!!@Xa9%9B9%0A58@"!!#!!B%!N!U!!*! +*!QX!!!%#!*!%$`"#`G6Klm3F&9#AHcaI4ZNj)ck,mGLZP-K4adD5)jSYi+l3#iN +YM&TFJ,25UG+$3U1i2@VI$e)fIF#@e&cH,F)bqLS)JIrG8Mh#PlMqk6*0,c8dRDq +5UX*VB454,R0a2SrC''MPALCdcU8MK1a#ZZ3,*X&Z5fjKa"[$AYmLJk[8,M*djHJ +ejX+&S"XQh3F`96Ge2&ZJ*q#FHV#adc&3'4"Xj6E`+XJGkBb8JZX'#IIjr[,4feP +CU2ZBI+!JMQRM',!TK&(4kB4rC#%Mib(LSk*p856"bb,"p,p0a,U1&,R-q*he8[c +4ir6b"53-dB'm")T`8NM3jZMG4ZAHT3Y9YYqfN!!!TC!%!3!!2!!3Y+*C%V5L@4- +!!6qG!!&#H`!!!F3!$,Rf!*!16@&M9'XJ8N9"4%e&!!(Th94&@&4$9dP&J3!!J!) +"!*!+J!#3#3*V!*!$r`#3"!m!3X(9#B)c4Se[0J-"fCEFXLfeQ!@$TUU)bed4'jX +Z#XFfYLkl2@%X0Td40$r@p#3*[h(-A[rE`&dqI8aGGmXC+NkJ)+'r&(%Aep2M6fN +9K5$1-4I1FJX[9K8ID4m5lpeAbXc*ZU1R[$h#G@a`'@BAAdN(eX`dV'kEb&$V0XE +TFY86R&B9fXlNqNdrGNe4ZY+(p[%lQKL%4$dZLj!!qej2&J1,SD+*YMFD+YF+!$a +KBT(La`lK!j-[ekcr$VrC5dVVLa9U[JNm[3![+@6&,&IH"$2S!'6RQ8K8Um13!&i +[6eHXrISKTbKCMe!qQZCF*3a[Z,km&j%YjX0mr$N&N3kV!!#PN!3"!!!j!!#hmlT +HZFSK(`!"33i!!82c!!!"a!!*[[X!N!j0Eh*P4QPXCA-!!3mJCQ4bF%e"3e1"!!& +!!3%!N!U!!*!*!VB!!!%0!*!%$`"#`G5+G3Ce,aL9eGK"FNBTYEV2HJZ`E2eATDA +*5IH4ZB(Ap@D(1R#h&ieE&@k6iI!l5hKC-ArHe[CbcTL'0kVbSC(6$9q%eN[BMfT +IMNPT,hjp(a5HQ%rVq5YGKJD%38&r4SaIXf9&hk`!99Y+$q0JMcRZJ&[`GB-Qd)K +59biH-[LT94$S9EDk5!5Pm2LDrf2,`E56TMrC2dS'Rl5$Jc9IUaYR%DM%4hp6N5, +%5$&l[C(r[!iLGA*f3A-r6&(bL$1`f$b&$MGVBCZmiqJ6RSBS5l)TbST#TKYEADT +E$dd-M0Z6DBU%$-k%9N-Mf6qBSK&qV-kBNP#24#d'aMZAXCY#e)lBXBFhY#ZJ!rA +r8+@3"!%!!$S!%,5L@1kdSPMZ!!&#H`!"453!!!(%!!TV[`#3$P4ME#"548&%688 +!!9jQ9%9B9%0A58@"!!#!!)%!N!U!!*!*!Q%!N!2&!*!%$`"#`G6)[q9[ia5rrCf +$YG%282R4qUP$0pePH(6PU&["r*U0[-C1YZ-`5PPf['Zq1D6ph#pLG6eHF[karp# +8SjiJ(LI&RZc[Rk62Vr-DFaaL4)RaRqP5fE+Bp[P3h"'+#bQlQUIGaNA-RSGh99' +c!+eF#9Y&j5FkM+H3!2K)Mp92HRk86jUV8q"NrYj$(pCRUhEZ6TY(+@TEAm[AD+" +F1U(M#K4V#mKX'&kV2HKPKEkZMeB(9k0L"dR(+SIY(r-BCbh5)b899qLPN!3"!!! +l!!#f$CC'YM-2dJ!"3r-!!8Ed!!!"a!!,T9d!N!j8Bfa#6d&6D'9XE!!"N!"ZB@4 +bF&4ME%b"!*!$!B%!N!U!!*!*!R!!!!&M!*!%$`"#`G6U30Ad1'NYqHG`L&SklS1 +D%EXE(ZiNlASdi(mef&3#82L3!+TreYT("BiV8)Ia&0B-d9J[8`R"ek2'RX%P6RR +RI4(![Rd,ahc-TI6EFP1U268'Q5Iha&jeHq"qf,#ph3`6Ulp"$9br19SCN6PHHe1 +92X9L8mfjP4+jHK!QA![U3&"L"8GjacfDV'EF(K(B*m-J&%*#AKcT,3(`Ebe8j!6 +C"a3i!8Kl2YpM4LLBMVXbei!"k%NZNe$h&#SP+)U-2,[a1V,Rq[SNN[*1Ve5fZBi +#m+K5(lA6[Y`MkQMmEHfTcPADd8eB"jFT)lM"XST1U[P[9X5)E%&@miP`K"AT[8Y +@A`KT&-6r0Tb8Sa+k-6$a[M%b+93DcCNB1%h#-qC)0$0r'kGJAp52ih+0Q&GF%+d +!BZaX4GN`"%%T$!-Xl`LCMV"rLjmLqh`1Ml3$i#KmRFf2JTVfrfCC,jeqR*5@`h# +%!+@3"!%!!$J!!,5L@'QhASKU!!&&*!!"5&X!!!(%!!K95!#3$P4ME&0SC@aX!!% +NUf&NFR"8Bfa-J3#3")%!N!U!!*!*!QN!N!2p!*!%$`"#`G5f)h82m"l-IhSNb'l +Vh55pGTYQ@B4P@5[m-K-0"3'F(9UQE4"AX+5-Z,GrH5-01c9&`T'r(VTLHV@(X*f +XVl6,Ur8$f2LG[88`VESaiUX%X6kABlH!dMGq6bAYTRS`"GlZaPI[0S'%Nre,hmA +rSkG"I49F!lNNk2dQS(H1aKF-%l0VTVkrjlcCb+*'S%NkZXN$K##Q+I)-RT)@XJ) +Z!&N&56Ei[GPj3V&5I!kKY3hMf$KeIXDB1UTPHR5#J9S(c#!Z4Hb,FeZAe&C*Tf, +S4'HBj2'ZiMrCK)FrXZc`m525l#Ef(Bb1'icSL,hM0`DQ@c`V`Pdb'f"&6`J!TC! +%!3!!1`!!Y+*BaEE0Va)!!8Ed!!&*mJ!!!F3!#h1F!*!19'0X8h4eBLjXD@)!!IA +169"-4N0A58@"!!%!!)%!N!U!!*!*!R!!!!%U!*!%$`"#`G62PkF+-[53!$T8PB9 +*"iKG58(Y*8i@52LT1M(Y[Bec'2M$-GP)MiLEpqF2LS)k,KrCee[UcT0EYj2Spd4 +VUa-P$`2UAq[HJ'(#*eMdfBEC5'5d1[J('eV&"0#QYZ1@mBV`)-djCBMm1$jT,C@ +Vmj)JGFhTJ$0kH4S*"4VYdYhK6EF0"M`f+H'ra5Y8LIZm8MmcDK3GZ8lJZ"0dD*r +FV39RAY!P2DXF#TCmpCLMXSL(j%3IJXkSGM50HibXU$&6"HYMSD5"Gm5i-8NDIQA +*-NH+%c*hL%L)3MPFC2$qQpPB#h)Vr4QY3C5RNBSI&GE'*)%`&jlZYDa%iI)2'M# +++a-Gfdk+iq9-hL"l'P'88',ML2MHY1rbL@'bl1ZeKbN5NDG8l#'8PPH&!+@3"!% +!!%%!!,5L@-DfcDm4!!&)@`!"5jN!!!(%!"&(I!#3$P4ME&0dG@*$4Ndf1%XZE'P +L!!&*$Ne36%C$9dP&J3!"!!'"!*!+J!#3#3*m!!!"0!#3"!m!3X(8SX#rFMl+Shb +dEq9Y'85q-+ZeAp``H)`Q$aDN3fmdmjP-Z@[ppjaj5)8EVYc#1DEm(ANaANZBmSa +mGYE6*KbrqDQ&mIm%i"0qqDZ5Ep0P"Yk`V8M5QC1#[L4AIb-Q43K&$Dm4QmqXb9a +UL%,eViCp9@lrDlr@2H4`6K(i&LfMiH)@MI$k$SA(`)M'"!hm@C!!ZIk$%BEcPEV +5jaM!0Y"LBNbBL3e*0kfTQJ+%JYEqT(l!mJ28b02qNCh#lGF[M2#@+05m2qLUNpk +SmS",KhFAC555D26)f"k5H&0m)4TSY1NDCP6Zddf)mFbhYGEi*c&bd5X4N4h`Ar+ +iYf5Spi38&9jqkIk*hY,3H'eC)DBHmfi#8S3Z*H##@[D$l)9,&$Gl*(H2`0"6Np( +9H@jY(d2R+-MBTC!%!3!!13!3Y+*C#VB(daJ!!8Rb!!&-q`!!!F3!#D3J!*!19'X +J8N9"4%e&!!&Z[P4&@&4$9dP&J3!!J!%"!*!+J!#3#3*I!*!$p`#3"!m!3X(8iHr +%(%"8d,`I'0BH"mdEe(UJqDb8kV(4AF9rF,!FE$D0PQp`r$`b,'P$bR`+c)a*`CC ++Q)39!XCPmMeQbT2AL,8LcSNBX&6NSIX6@HqF!&#kZ@6JG%9%4i*+%U5VHMi'U", +1Ti8MF!`8V)PCFiiX+JRV(Y8EaD,[6ZE@UB'*$[Zq3h&EK0m[a%lh%XJ3X3EhcZP +krQKlJ4pN2)`dqKaEJ3DpE6+X5Jdk@0"fGX,eJAk&mi%pC9f,Z*iibLEAddF)TTp +$U)0!""'jRHMrl'IrDAiYf,`m#6X8*E(f)fKZXVd@b1H-!,'&&'USr[K%BYB$aD8 +VJ+@3"!%!!$S!!,5L@-Lf"p-B!!&,Q3!"6SJ!!!(%!!USmJ#3$P4V8h4eBLjXD@) +!!8)E69"-4N0A58@"!!%!!3%!N!U!!*!*!Qd!!!%K!*!%$`"#`G5L`,pJ(TX6KJ# +4ipN)4FP8kqhqhA&KZ-GAJqh1#EM"3J`b+,YBLi(EpimeK4pBSbM,"[ld"JH*F3+ +kBND@frI$h([6@4rLGp9[l3IRJdM&k+`C"ClU6cQjqQHUUJ9lhC-XR4TY&XNaTAP +mFZ4TDQX19d,!H"(R'ka-jhL@0(a-NhP%LeYM,QSR0-bZF@ZXXPB`&r"1Gb[1NKj +'3+jbmrJ86@4TbfLXPSPfm6(C,bUN$6jG&KFmS'Lr`IA#,(Z%NVDSZF4h6G[F(JU +Tr2LAhqdV"JmBSFale1UfheNX(+P&!f0$Qa`AYYL2m9i9a,M$-L2*miMi'FpD*LS +j315MrQX,8kHpXY@fr`*)Md+h2B33NKJ$Z@)h4phZlTUYHr@!TC!%!3!!3!!!Y+* +Bb,B(daJ!!8cl!!&2k3!!!F3!%'d&!*!19'Y6G(9L3dC00MK,,QaTBJ!"aE408%a +'3eG*4B%!!3!#!3#3#S!!N!N#H3#3!qm!N!32!%,"e,jdKR`3iTfkhi,G6T9caZY +BMTjT%QBTd(CE-$Na(BHN1GECNiG@+Td+HEf'H+iq5PRQ3qBrGdbQYC!!rKXeQGM +"YE!"H4rhJCB3D8'*LLXSZEUE`'-`@kG*pXBaF9"*RVDB4qF&!mYYKc8KQjq,XQC +c*,hHJ'cl0fHZYmpLGdYF,8TmP*YA-N4q)60PT$ka4&d855SaN!$pjT!!hR63"a@ +2S)dp@6mKR+%rqGd-$+A"R$qHQCFP-e3Z!r%6[hBH[)(i(YId[aY4DkPLJI!#feV +#[NAreipm4P-BG*Z3!2rp4*rP1Pq3!'(9-P2ePGiqTB#PN!3"!!"&!%#d+4kjZ#2 +Fk`!"6SJ!!9N0!!!"a!!9kX)!!9"5!!!3j!!!#,X!"e4[Ef`J3fpYE@&ZC#"-B@j +RG@&RC3!!r'N"3`!@!Kd"L3(!!-!"N!-1!(`!AXY!!!#!!*!(TC!%!3!!0J!!Y[& +%T,Ea4+3!!8rT!!&4D!!"6qN!"LI!!*!1G'0X1#id!!%cVQCNFR"03806J3!"!!# +"!*!+J!#3#3)i!*!$VJ#3"!m!3X(8[R4c@UAXkj+@*q"UK-hNc65P8qbjCBr1eSf +69plRCdMLiPSY%-'P[pqk$XZFFB42'$j`[ID-Jl$*c8G&8$Yl2Mkb`IXbZLcX"*V +kXUa$%+i%)2bCbri3pjiFfDD[*%lhXQ0`5NeNi[E9*DT5#"C-S3P1Ta'S5aU#Y0j +%5Hd'D+("2iX1hAZc'PD@P`8"8&l2CPVZ1qrDXTVjCif`ULqTS$k(R33-pqV81J- +!TC!%!3!!1`!!Yqe)blIY5-X!!9"5!!&5L3!"6qN!#bMl!*!19'0X1#id,R0SE') +!!@fJFfKXBP4ME%b"!!#!!)%!N!U!!*!*!N)!N!1d!*!%$`"#`G6dM$A-(U0qfH" +Urf*A(dP4pEQ,,Kd5%#biNb&H%f2JT@1)UiH0C8*XP8+ZfNKGS[-a'Mp-B5c[lI0 +Bj'LVE9D99j)4T&[`A@'j[@Q&cBX9#*ZRc9[$IfkqbY,6*DHL&f1miA0C+TPB)Ja +lL,4E[M$FX*a2iCS0TJYS[&3%"5KCLF4ZZk-*%VR8+V4r%mTf5-fr)rAj5Dm1E() ++p5NDVDFjfPGD3$l)S(jCV4I-!cHbpZ#PN!3"!!""!!#hl8M,Yqe)b`!"8@J!!91 +k!!&2k3!4"U-!N!j8Bf`i,M4$4Ndf1%XZFfKXBJ!"pR4cD'aL9'0X6)%!!-!!J3# +3#S!!N!N#6J#3!li!N!32!%,"e-LrjA`3ijMXTZfAY[8Z53lh1%6Tbc6aP["rF#k +)mMCi0DrJ2ciLq8Y,#&G[9`p21N9e6#rLBRDLe'K)ljIPq!e3E,13!,MQrjrpaTX +%%cdNG!KFF&'maBV!"YL++dHcPC!!2B,+%)--GDNfhRfRJY+`iH80+6LdHG6lHlf +Y,EFQk6HJGfQm-6BTLV9+N3Sa1NYaK&Med80lCp3H$f&#k6U4L4jElZa%,b'+HeM +'ShR(%pQ8ETFCH8-"EI%jX+@3"!%!!%-!!,B0PY'i)pcK!!&5L3!"9B!!!8rT!"- +lb!#3$P4ME'&`F'aPFf0bDA"d,R0SE')!!G&#FfKXBP4ME%b"!!#!!B%!N!U!!*! +*!ei!!!&4!*!%$`"#`G62PkF1Z,EVAc+CkX[GaeaETl`6VHiC$Nq(*VCfB'1jSa' ++V5%D2ip0bXZ)F#ABSfCK0$LX2Jqm$cV3a01UNrS,YBm"08IQM203Dm#ap'qD4f` +E!iBlB&)d238SR@G!jpASDG0$8l1Q$(,)r)I$@k`L*N8lYKjjMiD`FLXkG"UdS#p +KDSR%i!2RNRdHI,"V,M2a%STpZ0)e'DmR9@UU29BS3Rjd8,!Hq9+(5D@j)*Iqr[! +%(FL1R6#e#pC6q%GP%`BJ59eJ)cq92)6SqaUrB6c38jc19LdKMXf,&kUHGPrU#U4 +B6$8#6(#2`'Z"f@Q1`d-XiN'99BqHI0jNp5mRPm-1'YG)kB[DEXXerd'NecGCiAV +[880M*a6re4ILF4EmqPjbD3r)fD!F8mXp0J+pLR3NP[TLbPZ9,BVS0DFZe!h0dNc +S0ljREYR62dJ`jNE!TC!%!3!!03!!Y[&%V,Ea4+`!!91k!!&@N3!"6qN!"46h!*! +1G'Xi,M3!!EM8CQ4bF%e"3e1"!!%!!3%!N!U!!*!*!M3!N!1U!*!%$`"#`G5qG%+ +%4#m)C(9SfdRYU4Z58$DILlN3p+2[,h&HRVTjq543Gp-r(MArFH[[H-e'E2bV)4& +b#9bC))NK&%9`Mi(%mKa[2H98,eH!)b`c#D#XJQRm6j!!+NF&SZ%q"3`GjaJ%ULC +*)k(UK-4L6@X9DbcpNhVel$Kf)b1!%jH5k"&fAFSEQ8([lei6HYq[HTAP&!VX1JG +cI6!!((T906L9Gh5R6XF13NeQ+G5PN!3"!!!k!!#hl8M,Yqe)b`!"9B!!!9HZ!!& +2k3!+Ikd!N!j8DcJZ0#jcD'aL!!%EC(0SE'*8Bfa-J3!!J!%"!*!+J!#3#3)r!*! +$X3#3"!m!3X(8p)`ecqr)kkT!lNaB@b9f+BAIe"8r*'1+"Tj1!bM%+EF`%S+E@dS +2Kj8+M29E!DfG8I)+Yb4JEl#X*BNcl#jT#K0lPN1jFrLaQD8rel$9rZ`cYfFFME' +G+qT**)c@Ir(I(0h%VSiAh1`4M&qVPBNp4RQDEp2&Url-UmGbcC8XJ'rT&bk6SIk +E1)(Q('&A0%[a39l1$kk&iK)ETq,'&b)f'L4YM#R6@@KF@JpTMe1!TC!%!3!!3!! +!Yqe)blIY5-X!!9D4!!&Bh3!"6qN!%*1)!*!19'Xi,M4$4Ndf1%XZFfKXBJ!")9C +cD'aL9'0X6)%!!-!"!3#3#S!!N!N#5`#3!ld!N!32!%,"e-LrjAMCcTM`5,bHd23 +LK1ppdR3*Yhk[EbB"mF8EE'H@1)8&qe[##K[Z8V,*45'4F1YEK6iej8P!"b*%eBL +2aE)GBXI`kd2mj@Z(,$dp"eRB#I5"H%p5)Nk-4BP6cr-R)Nd5&KJ+E1eNR9"dp`N +CG9QEDi,(0X$MkLcm'N`,jM+,ke"j`P8+[!eQ5*cKQ-3`$Z[$NdVQLiVjY8PTSDk +Q4P6Df#djpbACRd@A9fCfhDX*HXqF"Zi1Fc3JJ+@3"!%!!$!!3!#3#3&AVJ#3"3& +2k3!!fV2rN!3!N!UPN!3"!!!m!!#f-bp"YkGR-3!"6qN!!9T+!!!"a!!-kGX!N!j +AD@4RCA3J4'9YEh-!!HZ[B@4bF&G*FdL"!!"!!J%!N!U!!*!*!R%!N!22!*!%$`" +#`G6)[q9dCcJhm#*Zq)VdK2$iRN#q0XIX6`qfUGB1HbS4Aal)iRI,6F0XdJl-hH6 +%Lq662fm"CPc`(rKClf64TbIl1486mc-08E[h#+0Smpk(SkH3!-LSQN$lcKY&!I, +GhAq+b2FDiM$FUSBA@6j%A*4pa#'(X0ZCa&2N$IhFf+ecA3PGJN"q+G$h&,bdJ6P +$hA0B[m@S)$F$LqjMAaQ#*5CeZ`E3F1PNpl@PCIe3i&blBK+2$N-CJ`G1,2E5eV) +4BPN(peRKTUi8QV-hIkJ!TC!%!3!!0!!!YM-2qlBc$rX!!9N0!!&Ed!!!!F3!",d +[!*!19fPcD!!"[keKC(*`9dPc5)%!N!-"!3#3#S!!N!N$2`!!!5!!N!32!%,"e(+ +SSMTD!GR2!ZYAQ(%hfFD,4-KE%flQD)d&i+fa(NmUH4!JRN8i18de0McEKTM1GRY +2lmkJMR%VqS*VqR((JFde[@3X8@(2q%,C3TC%"`8"I20QcjC)PC32q*46*[(hqpq +mp"i9hAAGd8D,46e@#fA3lq@H"l1PS9@5%hLmQ++EA&-XkYDrrP(D0[GVQ(-,%`H +,Tf4lSS"Lk+b-"Te#i9$U`DI2&K1"4[,)iFGerlMV3QV!D-2V!UJfm81Jelm@""6 +@0f$'8(bm0V'!i#mjjSZ2Em!(*mpQH-HJdX5@kd*+8bmK4H6F+Q,X"39NQXC(pjc +L3[PAPJ06"IC3"bfAeA%d[R8P'X2Qh-c225(9VJI'If[GRpkY`b('YibB!+@3"!% +!!$!!3!#3#3&D5J#3"J(%!!!9I2q3"!#3#U@3"!%!!$!!3!#3#J(%!*!(FJ!!mHc +rN!3!N!UPl!!!!3!!!Bp*!!'153!!"'`!N20m!!%!N!9T!'-!I3#I"!*25`#3"cd +!B!$cL&a8D'9bC5"TFb"ZEh3JC@j[G@GS)(*[EfdJEfiJdPi`db"dEb"MEfjdD@j +eC5"9EP0dG@CQD@jR,L!J3@iJB@4NDA4TEfjKE#"H-5"LHA4PFb"KFQ8JEQ9PC'9 +N,J#3!e)!!3#3"@d!CJ#"!+)%!Np,!*!&"!")!'F"!iJb8fpbFRNX)'*eG#"K)'4 +TFfXJFQ9XBA4PC#"PFR*[FL!SAM!T)'KKFb"[Bf0eFR*PC#i!N!0-!!)!N!8a!'F +!43#Y"!44G@Pd!*!&#J"3!"`"%)JD9@j6G(9QCQPZCb"hBA-JFh9MBf9cFfCeE#% +!N!8)!!i!+!!ZS!)!!3#3!he"4%05!`!!IJe6#T1%!D0Y!1`,FJ1dXM)V+q0E6Gj +ElfVhTQiQei!a!%!$!*!$ZV8-J!!*D5Vqi!&9%Lcl5XKE$Z2PFlU&8Bkb2mq2rki +J16HX'[J4bSBeHBCLSfGVm+aH2`AZl![!X+N')MK-9ckpkmZYSaN$a4aC5aXi#`# +3!eS!!3#3"9d!F!"a!+`%!Np,!*!(5J"9!41)1P0[FR*j,L!J5@jcG'&XE'&dD@p +Z)'0KEL"[EQaj)'*P)("PFQC[FQePC#"[EL")4P-JGQpXG@ePFbi!N!0Z!!%!N!9 +S!(S!I!#f"!*25`#3"dJ!AJ%PL%j6EfeP)'PdC@ec)(GPFQ8JFfYTF("PC#"LC@0 +KGA0P)(4SCANJBA*P)'j[G#"cGA"`Eh*dC@3JBRNJG'KTFb"cC@aQ,@9iG(*KBh4 +[FLi!N!0D!!%!N!9G!(!!F3#X"!*25`#3"dS!93%6L$T8D'8JCQPXC5$5AM$6)'e +KH5"LC5"NB@eKCf9N,L!J8'aPBA0P)(9cC5"TG#"hDA4S)'0KGA4TEfiZ!*!$+!! +"!*!&T!#0!,J!d33)3fpZG'PZG@8!N!QH!9l!!J2S!*!$e%&%3e)$!!%5$9-+Qb3 +!1iU)LKA2&Y"cV%4X%28X2hmrl0HG[qIZcJbR@0KK*5TBK999BZ@rm35aUJ8,XQ8 +l6L$jN!!I!93NQ2Se[)@RhFACh8h5b(U5[AdI,N2FaCI(T3X@qBdi9dq9p3XN2%U +1NN'qk(5em(4U&CSL2JAQ6XFXGBZPFi&Plh`8(,JebXbQG8"2"b%-6&H8@CbY`EY +PFb)Ah(i-H"r`2%#L6q-DV)Mdc!mhH5K3fic)FDZRR-9M@e'jc-h@kB'VP$IIbIX +-kIp8rmPY!*!%1J!"!*!&8!"C!'3!N`3#6dX!N!8$!%3!5!$SL"P8D'Pc)'&bBfK +TGQ8JDA-JC'&YB@GPC#iJ!*!%5!!"!*!&4`"D!&X!P!3#6dX!N!8#!%8!-3$SL#G +CEh8JD'&fC5"PER4PFQ9N)'&Z)'PZBfpbFQ9MG#"`BA0cGfpbC#i!N!3-!#J!+!# +f!4`%!999!*!$$!!J!!J!SJ%F!)*993#3!``!BJ#5!2!"Q!#&998!N!--!#J!+!" +e!6`!Ke99!*!$$!"'!+B!ZJ(@!)C993#3!``!)!!)!+)"(!#!998!N!--!#J!+!# +Z!8i!Y999!*!$$J!S!#J!`J'N!)K995J+!*!$$!!S!#J!P!%5!J"993#3!``!+!! +S!)d"&`)"998!N!--#e9Z8h4eCQBJBA-k!*!$#!FJCQpXC'9b!!!%-d&%3e)$!!C +h$9803b)5%HCHEK"N,4P%D[*%*!X3@DZQ*LHh2BZ-i(ERb%Qh-e2bQAph[qrELM` +EhmbhY8#5eFlXbH4*f,ilNa'5j9ENLDc)laq42j1IbEcCeRB454B6XMFYb5)S31) +(rdjCKT&84$LS#cYiiLGf)5c5J1e3aD%@GK*H(mq1D3bR6lpC+R)6)mRY[@4[%r6 +@hmf'R%[)+8FIZEr5&V,ejRAjaL3*5bPTf0kN&a@6NPGC,a$mi-RK`KFHI%V$*QM +4BN6+hFfqTX2b,*5j55k)jb(*(2h&i)XDJqim&Fee*9$cG*JIMZ6*i#SGjViNe#X +q)@+3!*h[`af,NK")heX@$ED[(5XhPA-`LA1fRcbNbSE0RBqrZ,m'l)YVm[NQUD! +A@)"Ck2@aqNDT+'b%UlJKdF4%D4j'8D8QKLJRXm5(8JQR40@4X8N6+L,JmB-'82K +L!,85ECR3J#8d%@TbLdfC`eLTT"qR$+aeU)[Di0J#T6DMFe4B`aLflrdNJ-)Z!m3 +jBTLiESAmcl%RFHbLl9fAJNh,JDRU`pD$+ZFdM(GdeX@!G"Z$#pDfYBXaSNc2)HB +bh"2bA1lEQ20L2d(0f,[Q&#I)A'ZQ2(KBb@@qIDUNT-rSkShVZbh3b(2j4EE#Hi" +%aD`5%YXK48JPi!JpjfESS#*')G-lpU&Zma9#N6ZP%AF+hP-PhjBJ16hDlDNc*qD +mR%1jlK@TB-cEfPh+FK[jplG1#3aZ,GrmP`rLNbG@J3Mpl)N"@`NmD#E1Ye,'NV, +SJ&0-'N"4lGDH(L15jV)kGQArf*KLjXEBBNT+ilSFVqIQ2L6S6,2!-qdr5A,SM5r +Z8%e+qrrFIEa)TAK+(ePf3"KU9mH96KeiJM&J8-CCH2(UplHlTpQ8&pIV!mfS&!e +YS22Y"H59K,,GX(5'$iDUN!!D1!1%4[Dm+R'd+EK+q$Ll6eBP[SHY1Jm&+*f0f9@ +c1LPl$U`!LB0EA#,N"l-#h9`&eEjM4RfXIVf`GZf$Y!rlJeGII3NEUUX[JA!5-Xp +,Z*!!K9k#PFalib#6LH[)jR!53fYB8Y@+#cA4e!fZkRA5eL(bC5reTB0Nq+`1N!# +ULm1*SfpKL@KA(V8&MK(J'6fDpK)ZJ-$X$'lTUd'pQXb1L-Hl60lqhlJ2YkIbbBf +VNkBAI5lbXT26-1CCQI@i%dADZX@J'V("P$45$f-VG@mlh@!+D@pipZKGMr,CUC9 +ZcXXMqF'dI'XXGU%XA8IkajQ+#fPh$2Aj@FVRjqVrINKT#[0r9hl1a'Bar[EhjGL +F9@FZ6fPZ&[UQ90aX9RVbi))fT0[hNY60m9Pip++5qIc2PqqBK`c8pE9GaLXRlhF +Hm(""&mY9YB2CTqfiUkZ$G385RX(1bd[ERX3qk'4JZaVPpDGj!R%'T["3[!PH+Gc +$PhJ`"hHqIVA3@F0Eeq31!*!$'!!d!*!$m`&H!!%"!!%!N!8$k!#3!j3!N!-m!!8 +%)'pQ)!FJDA4PEA-Z"&0dEh!E5A4PEA-JFQ9YB@PZD@jR)(4[)&9Z8h4eCQBk#e9 +Z8h4eCQCTEQFk!!!()N&%3e)$!!a$$Pd,Ui)N2ZS3lhphR)43a5(84'T810%MS(b +[!l0jX'a")SSV8KBVbQ+[0TjCD%NmccDdYChiHr8KY"C`Ue$"QT-,j(X6pKCrEk[ +MlbQ1[`F,Jf69NMUcZp41E&&)`V`NbdLA#L'NpcmKR9KFHflpr3!0jZBd-3%N0#- +e(eAN$UCp52mkb!q(b695LPY'TUCrJZKDII@ppEl(rlRl5i*QejU+Hecc1bIFCcl +8LmMq'HE2p5iMQd2ck0GK'iR"4f5B0#+4`[A)5`SU+5#qB`JLi6#4C5$#4N3T"j5 +b&q`kDKmRkD25CTref,G[hQX6[bdlXT,CV2eiCNcRIkmDr"$QMpZQ'baACk1([14 +ZG(rKLPRjdB)KkRG8V-%Qb30CRXTmIFLEQ2,[2hGPc#&Y,GRT[aZ!E5(qUH'-,&q +GJQ4$8p&Nf&kBLRX-4MpCQfc1YLRrDML6V@Y)C!c*&I[jTB@CGChYNa)'Xb(l9qM +fTBJ"@Y`+Rq9f[9$!2NGf,dSH-S3M+#(m@MEY2-ILikd"AKk6e"Z@KreR@9bQAK1 +b,k1G*0['qM+VPeTedZX2lepCG"lNhPRC'q"lT`YMGRmdEK-qp2GiK1ArlbPS2Pr +ekqN#plr9RC-%I16"lcfRq8SG[*kmBB$)8"q$bdGk`J'qF(1X-2,UN!"KcVEki6! +QBTjilbEecFMq"El@ATMh)eZ+K,#pck8R3D,6%-a6lN5RN5KdS9a`B8d-bCTBAG" +%``&0C$K0X!S9*Q42SN*'DkPkRLTHU5R#h5@jf'aBNrPa[Da*kIYf5C2#frD#*LI +IVRT,Naf2mk8"jMZp!DE`Kjk!&k9YUB#Nq4qc!3rNjTZecIMJXL#cdI)k2,rdMj@ +lXp+"`3J-8Q$`!S2U$RE!Gr!LKi@ep`M62Kk9BRq0LV&%0pV1aj!!ci@XHE"LL$( +6)-CQbLfVfc)L2iZcJeeSLN91T%bMear92q,E$YHlN!"%$E`B3Vj36H)ij""Rd[@ +Z`5P4`q))),0Gm2b)8ded8`4R3NrKJ6KRE#2C`cRB"b!i5"'q1ZI+`BmfijR1,*j +D3iK-MTTbJUMkE)jZ`UQD"VqREF,U!P,'-cihSUB5Ybr%CQam*914B3C*&2P)Ta2 +9Ql#dLQ`pFZ5VSKJa[NZFfZ)3IaX@@cri`,d)r812I!rbrbkkT1m9XL-HNVcbj)P +QmQ6(MK59-CT-I2,I&#QLq"*GL%9BfTL2-Fk1X*jIS3i26Z`hB23`6cHcHPjmGZ( +R"lGe`QMZ[2a!(BfG5(9G'0hX)*A9*cZ"[)KX&qEer$Hrb!kHr))eiJ3$3Y85VFj +harRamBH8Df!5cZ1RT2ZSDA[fX"j&hrbf%d50'*fLHRb&"h)0L*IEBURXpR*`91d +#m0Ea*KFSK-$"4EA@qC8H13T'p%kbT$2b2SCUBDK2F9jm&P&rkl`1%4Q-I$16FbU +kmBq-!3m%KZmHEAVJl0#M4*PEDLV9jE`P0Je89M1JMBk*D)+@BNU&G-bPS4e9)Sk +NARc,J5Cr%%81aPG36hQiF*2Z4#2RBj[L#Tc4EbrcIeYUILh"KM(2SS`1HKN+*Z9 +`#r3(fS1K+)EQAZ#5$PRJ)"F$!5!arpcCTb$NCmpQpM3fTPXrQlYrX@rFmphlpri +S[Xqer'Qcc&+-CMpCedRTEJDRU@9M"EjK&13EDY6J,8cckd*bDEI`XRh5A'LAGrN +0dEKNY@V*+bVZAq1U"(@"`A&D5,*r&lKmi@IjGMNR'ACPTFM082)@Bi9JV4-%Ma[ +R!(Id#*bpX"q5ErJ0,BSd-44+RRkVSN4ZV%TEiR-$&`ZE[+FUQHN@%PGlaMc"iSE +*B#h,@pTS5#4NUf%[qP!mcFa+mpiA#[i9C$Za(e$jaS+#3c,8'RQ@3pk)BRRj$8F +CD&G-rmZK6aBKdR#eA+DYQU'BNYa&2D8*V8I6edFXPh65PjEGIG9Rcj49EEGG2km +9l'KTlJc"FApM-'L)QYIV[(,&'m+e#5rA'&`+PI,B,RHk0LT2qMh"B-P1"Vjr69" +rlq8m`F93NBrYfKkQ+'[`6`c4[&E"8dGC4kMi,mrVKZI5Li*PA6H4$lC*e9EK8Z0 +ZEP&`K-i#FV#4`PZB+NV3#0LYlK-H%i4Mf[T,p&`!4VMqMN$hZqhLC4#[dI%MdJF +*-SUd6cH55!r8)PQ"#"GTMmehZ5"F0Z)V'Hj!ij&NrZU'&Bk6R!aR6"FN81McTE* +rh[cSArRNN53#Y&XT5CqZj9UcTrVkhmb&+%IdBqrd4(lIYN19,4Y@Vl,3ALGAh6! +B@(-dN!#Um%jc"m+CT%+Ta1q!XUXGKPPcA+-f++9)B8H5Sa6hdrBkUpfcB*!!h+R +U+(9mS1ceKX*5FCpTC,4XS,D0fe9f6kkf6"SUcC2KmU#Pd#FKJE!41%C$P8M+2@D +R8*&Q46"%##Yd3rIjqJFI6CMM[Jm!N!-D"J#!!*!$!cBZ-!p6G(9QCNPd)&0&35! +f,M!!N!-1"J#!!*!$!cBZ-!-f,M!!N!-9!&3!C!#,!BB!!3%!N!F%5`#3""J!2!" +!!,!"Q!!"!3#3"`%(!*!'!5*"4%05!`!$LJe6#TXN!(q'4E$G16N6X-81A8Y16ah +E!48$fl(kf!a@pFiq++KBI@c"EUcUaX!rBhp8p,rrEircGPBCaZS!#jNe$9a@MI6 +"MNEhVP-Dl!5cmbJ8h-AL-N+fe,NJbA-,N!$IEi*fJZR44(62+AQc%pfmbHiVKB3 +cc%YDkTT5LKd,2KqEdhm%m(Vq1HV+dqTUrjpIEXHVRre$rrZ4PL8#Z$0USi*Y9X& +)*Va&Ufb-9E9H@cjLQlH&l@%9IG`AaY*D6+58Y!*a(daqM-2AVK[QKkBCkP2EpNh +G$lS3D&U!*`6)!*`!6,hk,3$qkJN$%Am!m+*bi3)3()+!!B*LB#diLj&"M0m-3Z3 +51Z,UBj,-[5Ka(dcIG2P&a#YXbaJ!N!0h384$8J-!!)!08`YE)!-$TQ$$UQUc-,! +")Q*J0dZafeQ9S#"L`alUfF#B96%,BbUkpkG6V!S,L@2)YZ*heJ"5+2hK[F##5VM +&3+GM5$+1VpRh*L)1[qR'r[[BRcTA6bLQN38GNEU#'ELMa4UZU'SRT%mb#Zp&cJ8 +!N!0-!!)!N!8)!$3!'J%EL"Y3E'9KFf8JD@jcCA*d)'4TFfXJAM!JGfPdD$S!N!B +,!!X!+`!VS!)%5`#3"4d!0!!Y!4L)!Pia!*!$1J!"!*!&0J#(!%S!`33#6dX!N!8 +#!%8!,`%rL"PH-#"KF("PBA*c)(4[)'*P)'4KE@&RC@3Z5`#3!kT"4%05!`!!YJe +E#e-`!hGc,@B'l"R6bPA'0c6M[V999XBrEdr[eAUhlMhriKXD!!$`$3!!k$B0!!! +,XLdEJDAi"hCRqrRPV5ecdeE0heRBNa&Y1kd$*bTR@GR*V[*iehG%KH"5a(q#'"5 +q4!bGmd**U)B"*8+!,UJ1hY8&`*1&(+!BY25$@4r[#**R3EiJhiV0BEcLr@Z6"D@ +&%LZ+ZA,FjlR#dP4ijI&K!3#3!``!+!!S!(m"F!5[998!!!%!N!1!!"rr3!!J!L! +!)J53!!!Q#FJ!)K2N!#)J!J!L3!%!))IJJ#%2m%!L($!J*"Rr%#JDLJJb-SSN*M, +b-Nid"MNQCI3b%Q88*!KRr!J%F-!3!MrJ)!%"J%!!KX#!!%!"!!!J!J!!%q3!!!R +)!!!%N!!!!!)J!!!"3!#3!i!!N!H!!"rr`!!rrq!!2rr`!$rrq!!rrr`!2rrq!$r +rr`!rrrq!2rrr`$rrrq!rrrr`2rrrq$rrrr`rrrrqIrq3!crrrriIrrrm$rrrq!I +rrr!$rrrJ!Irr`!$rri!!Irm!!$rq!!!Ir!!!$rJ!!!I`!!!$i!!!!F!!N!1!!*! +(!3!(rri!#!#$!!Q"!S!+3J*!#)3#)!N)!K!,d!2i##!!#!K!!!J)J!!)#3!!#!S +!!!J-!!!)#!!!#!J"q!J)!r`)#!F-#!J'ImJ)"U#)#!bJL!J-!BJ)$3')#"Pp#!J +C4`J)'Im)#"``#!J2q!J)!'!)#!'`#!J!!!J)!!!)$rrrq!IrrJ!2rrm!$rrrJ!r +rrm!2rrrJ$rrrm!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!r +rrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!r +rrrJ2rrri$rrrq!rrrrJ2rrri!!!"!!IrrJ!)!)-!#i%#J!K#!N!*K!)J#%J#%!Z +3!!2i##!!#!K!!!J)J!!)#3!!#!S!!!J-!!!)#!!!#!J"q!J)!r`)#!F-#!J'ImJ +)"U#)#!bJL!J-!BJ)$3')#"Pp#!JC4`J)'Im)#"``#!J2q!J)!'!)#!'`#!J!!!J +)!!!)$rrrq!IrrJ!2rrm!$rrrJ!rrrm!2rrrJ$rrrm!rrrrJ2rrri$rrrq!rrrrJ +2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ +2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri!!!"!!IrrJ! +)!)-!#i%#J!T#!N!+4!)J#NJ#%!T3!rJ))!!)#%!!#!L!!!J*!!!)#J!!#!`!!!J +)!!!)#!(i#!J$r!J)"``)#!Crb!J'S)J)$+#)#!`"L!J0!BJ)'Ad)#"P(#!JCr`J +)($!)#!ri#!J!B!J)!E!)#!!!#!J!!!J2rrri"rrq!!rrr`!2rrq!$rrr`!rrrq! +2rrr`$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ +2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ +2rrri$rrrq!rrrrJ!!!%!N!1!!!!"3!!!!L!!!!53!!!!#FJ!!"2N!!!J!J!!3!% +!!)IJJ!%2m%!#($!J""Rr%!JDLJJ5-SSN*M,b-Nid"MNQCI3b%Q88*!KRr!J%F-! +3!MrJ)!%"J%!!KX#!!%!"!!!J!J!!%q3!!!R)!!!%N!!!!!)J!!!"3!#3!i!!N!H +!!!!"`!!!!q!!!!I`!!!2q!!!(r`!!$rq!!"rr`!!rrq!!Irr`!2rrq!(rrr`$rr +rq"rrrr`rrrrqIrq3!crrrriIrrrm$rrrq!Irrr!$rrrJ!Irr`!$rri!!Irm!!$r +q!!!Ir!!!$rJ!!!I`!!!$i!!!!F!!N!1!!*!)"d&38%`!N!B(8f9R-J!"!*!%"e0 +PCc-!!Rm!N!-(8f9R6J!$r`#3!`G"8&"-!*!'('&eFh3!N!-"5801)`#3"B4'8N9 +'!*!&K!#3!c4"9A-b!*!$!8P$6L-!!`#3!i!!!3#"!!)!JJ!$!)0'8N9'!!-!N!1 +!!!%!J3!#!))!!`#$!*!$)"qT)$%j16!Y16JJ3@aKC'4TEL"6HA0dC@ec,#"*EQ- +Z!*!(9d&%3e)$!!%"$9-#h0B'NrI54Xe&%fd!Y2Nh,VcE64YQ`QbqU`[IK0f`fq6 +GGYA9G@%!#6LPL2pd"ISD0+Bf([[%R@[C6S+*X0-3qX#ck!"SN!$&[[i%[JB!!!3 +!N"'"!*!HJ3$r!*!FJ3"8+rm!N"U"!&6r9#[r!*!BJ3"8rj!$9#[r!*!@J3"8rj! +&9#[r!*!8J3$epT!$92D3"#[r!*!5J3$epT!%q2D3"5[r!*!3J3$ep[D"N!C@prE +f+rm!N!k"!2Afp[hrN!Em9[D3!b[r!*!-J3$ep[C@rhrhN!5"rrIfN!3Vr`#3#S% +!pID3!rcppeCrN!@VN!0rp[BVr`#3#)%!92D3"2prpRmUI`#3!e48IeBVpP3Vr`# +3"S%!92rfN!0@rrMhIbTr!*!$9&5Vpb[fre3Vr`#3")%!92rrpT!$r2hh9P3U9*! +&Ik[hp[Erre3Vr`!!J3"8rj!$92MfrhrfIbU3"948Ihrhq&6rN!08q2m!!2mV92r +rp[C@rrIhIbU"N!5X9+Y@pT!$rrp8q2m!N!6r+e6rp[EmrIC@UbU"pT!$JArrprD +3!rp8q2m!N!Er+e6fp[hppeDVUrq3"RrhpT!$92Mr!*!)rb[fpPEqIrH3"2q"pj! +%pT!$prMr!*!+rb[fpPEprj!'JID3"IIir`#3$2mVpT!'ri(hN!2fN!2hq2m!N!l +r+rD3!rrrq2rrq2D3!rIir`#3%2mVpT!$prIipj!$p[Iir`#3%[mVpT!%92D3!rI +ir`#3&2mV92q3"96ir`#3&[mV92q3!e6ir`#3'2mV92p8q2m!N"Vr+e6ir`#3(2r +ir`#3([m!N$&"[N&%3e)$!)L8%&80C984!#&9lNDI2Tq98TFkPk@C#reCjkb$V48 +jAMZFd(A2QkiZ@qd'6S+ZX+d&h22ZD`aF1&jF`B%,)!lN$%F-QG2$E3JZa#ra1-q +ER'H)ja%daP2Meb"IRcFaZK"$b"cEq[llr$jYIad$)CIAprmj(9Bf%K%#!C!%%3' +3!a&#$J"G!pqDp[N(HU)c#(`r4)(q$+l4p(LfUCZr"#Ra1aIILiA8p6rlPlb5LBH +&EZMVDB*2r$L[K)i5FC!!(hf6L0TLZ[8@@@-q,f!FSN(c`9#*kT%er8fR%pm"XG1 +6b'XkM38%ir19DD!Tf`BLe9Z$9Vm0j0i["hrf&fIb8j!!,*ZbMB%ljp['QVHm0EM +'h,3EberaC36,RAcC5DmR5N,RPjfPea-P`9Dqh!QLF-qbXjhr"K#mMMlZNb!J*K` +$cq3j3bBR6)%Qcjri`24@jlq"MP32)R09mdj"p"ddhcr[EXm4ipLL%%qZr'EmHb+ +!Ra"qJUdj3[l6I`prDRl@&J5abZ+X#!f*rjRkkq53!'-SUcMf!*pf15[iBPr%CDl +r8heX,Kr+cL5Bij'KN8pM%S2D#B+Gq-B"eG3r-`(,E-%S-U"1CXaefCi5[XlY)%M +'4&+-Lfh#P(pPUP#PiMprRISV0FcBe&rCa$N-Qr'cCI3+68@Zm1P4rA6NLX6+ASc +Y'a2ID2jaT#rD*i*j3Z@4Emr[jL5$JeEhjpf*("&GqCracl(jcl(jcd@`iiIT)YE +@mJ0eJ'mpHNG!(6"Ec2AA@f+kP8H)PEpb1D1f(cjKhZVLVbVdaeYrq-59V8IP("3 +Z9M&e9i016"jb(-TYN!$lmlXliN3dEHfhhQ*08PD)bQ)GD$V0"ZPB5%[+6QNP3UR +%h2GGpL*#l0TKRc@T(A6TMra(LG$C3j3G++Sk$U#aNGHdfi%YfVeB4T!!bCKXqmX +EBV3E*'$mKfbj%[RMcS0$M`SaP9jI+062erQhG"k%bJ)3qm*SYrRqM4Y2[5dm-!L +220!8FbCPeci3`6YV4Mr3&#I[e3FRQU3!C4m'@aBb2k"b!f[X*NIAZYP1VqbUcT! +!hkcq5-k@0E+rqK6)rRiE-Fe3l8QBlpSXX*QLMA*fiMYrh#bm)$Z(%[jBp*kpR8$ +`MmdLT2RTbh08ccJ3P#L6j-ljZ#a$L9,EAmV+(&f"!@HS@F@h3F9a+E*bNYL!2hU +1"0N24%(!&lkmP)Ycf1@KeEEKcImJ&U'#3B[@IJ4j6@A%QVF)mC)@-@bY!`96IaL +#jj8)YQEhr!B9`F'1Y,9H#Vk)P%iHN!#h8%4*JCXL#N%DN4qE@K0T-ZiE8kQXb)# +3!*%"d9PcSVXeVmNS*qe28R5EllH*p&$RpS5)*GX#JXMEdFk$VF*XH[qcpS"jk,h +kkiI-*T1TrV1j4k@AB8FQY%F#*T2CC"qIKDDHfHAd@6lE"#'f)#hNN!$%Y)Qr0*[ +D!bRIZ2lSACD'Cc1p0Fp'3Lrr'&YR6*f2UP3P(L,$@B18V4L`)DV(9%8@-E(&,kS +(UP20HFf(Qh+ELUb)(*@+-LLD@jTYcAFMNq1rQM69XkTRb@2'P*a8C-J8hVNi86G +,f-HTJTkd1(hi#FAmC*c0Ff*4&,RUQ%mDDV--jPZ$Dr+D2Qbm&jpTM5Fl&hql'#5 +mU1NY-0BKNh$2L@jMB!,JGRA08`#f'dpmQU[kHZ1N2'Br)m[k5adZZpmBUJFC6jq +*pkQV-3+Qh)b896+p,)qG5Fq`Kc%&+M(pAHILiSe2l9dV'XIiCqP6He@UaX1Q[-D +qTrD+D+1TFr'Zc8$m1A0D5'!a"`I-b"V+@e+(RkV1'6qiaKBh,@kHHrLjd*3YhZG +kbY9m[5Q[q5BLLH"R,P6m4HF-mc8$HbIkS16jTN@U4r"6MBTjXqT&X&66clia@dA +cV`e$[lVjef"V(-KV,P8Y`Q3Mr@MCf*!!f0J3*!Qr3330[Aci!Rkqd,*qJCrhY+c +cfG$Ir1Y6pAeL@0J'QTqN$"@,KF!9CfKri&5hFQ1)UZ[AQ*XI0dkYF69[aEBrG!6 +Y,4-20hpKY0A'S1"Kab,9idieQ3%blUI-D5,daPq#b%TGP`,&'E+5GPNT'`P!&e! +SS5aIFelMD22(9Tie+C,06e-@SNJLkRC92j@`d!Y8mdmEXP`-a2mZ1%R-Mba&N!# +HKi,%!C+DFm6fUVPqQl#Y%9jcIFfaYVeq+PepFir&0Y'V([fVea*LidrTAqP2ll" +X2@,$C+[BH)AqP9kjhV)9)1FGVpN#XqK!b&b[Ff(K`m(,fm6'Ur5[p1V0PUh(E1l ++"amjH[2P6DLUjrEp2DV9[am8)CY[ELm'[R##2@@%!SKTkci,CILEUeZ42BFLf9( +p8AZN#dM1Reb++qIG*N*M!ddIQYrE-G!dcIcCmQ0MA[0lbipY#fM41,,e@%VbjL1 +("jVZ0RmIE(2"pYTKYrRlberV#@cmJ2k9I[$iNDf[c6S'92VNb!e!$*qc3+eXELq +Im(&NqNIEj-JqR@KTVKl)jYRhKG81bJkMV,[K'J"f!if66TdZ3YR@)JRLe8"p5Ab +E51lE*T!!23d5-M*)+F)DEjHcBlVf&XBB*%Cj#$Pr5BJ2BfhqrqAXGM1fh5(IEP! +3XL56K0*%@f5dXRV)`-`S@+`Y4&5@(6$A*!TJl8&VN!#1S#UCd@UQ*D(3I'a@R#k +a"G[Mj6*I96#rGKh-*aA-KeCR9Me$"Yjd4Q(Qcr$-j&a9FI2(p,'1U3T9K8h0+(L +$)YMd6@P5U)@kU3',!-$3EqU&8FBSNBaEbGa",JBihY)ZRVBie8ErG)YG4V9C3CN +hcZ'IhbG#GKlmpRQ*d+hDVqQ1j4Z$de&F'peJES1M8NM+-QdA+EFJ5m9(VqfEV1[ +fH4QDKB4UmmF8pE)QUJ-er&BRQZK#EDZ5a"DkM)%6h6'HI4[e+09$@CGS+&HBrd% +14ZNDpdQElDQ3!!43GSSSrZRSCdfNmI`D9+#0@A*5Bj&GDc50aM8!fa[6Bqha(M% +#a3eM-@903Rd9FYlLB64QG')8cER&a6T%YpSaX144Hd)11MfI5e@41PD"3X5)Rr0 +JNMAG"-Sh1X-L%&&"88*-a)`UbfFS8Y6N4X5,&0S'A)+Q(VJd1C3hc-(!GGBSa-B +d9bD(k2UXqf#SIX2KFCNbVN(56q*`"3kid6aGr1Mj@B*-dcj,2G"mFiSD8D5f$M5 +A8Y-ei*mPS-6a8pe3UTZbE(j4CBXVKL1ciVBJ-U88fH0aR[N14kANRX$H`&1$c6H +Yk@XZI@S)"I2$5dT3--rP4I&DAK3,-8pllHN1A!ZN+0YqZX0bSYZj9aU+8P4L*Ab +`q&%MXS1m0!%hMf+1M'(LXLh1P9r[S#fTR8FMJh[33P$Y$@1E@HRBlU9aC+ENlh2 +6d6dL-MMDM80Q@jQj(J"+X8+"I'ZN`$6"%+hJL*SBSS19%"eS6,",1YQPfUPA0pV +LA8*#Pj!!YAR$R3c'a9+Q4UUf5@@e8mmYELkeYmc)DhlF(L8!J&6Dr%Ae,kaH3[l +40)SXTiFZ`T9*@ecj`VjCHB'96-$r#N`)fG'0F$5#3BP0XX2i5Qe-BBVV*%DBQjV +Bj0ZV2hTP8XJSm"$!+STIb4DY[`!LBN!5m-THir'$@D),JK)NU(de8EbBR8*`m66 +&fl2PGFkZFJ4AFm'jiNGD`B3S%`[Q$MLRI+N86kEGUXqXkZ'"QbVe!"3qeMr8qEb +9QDYU2eAe0(dK0@Z6GMU'k5#ElY*11c$YPDE2'%4X`V5E64Y%V-5dMddE4&!'CT8 +KF""iZrpQU6%2XQ8KPKqm03J5Bb'!IA,MN!"VBl2%[L%aa3'3!(3!lVX,(U$U9aP +XCFG3D3'bRY8Y%8YYcei"m#Z+RaB3q)BR5JXHJ'MC1!8#55[!)%%!cbcKp0Q#-8! +GFNr"CLT@eF)1C`&-GH&))Bl`ib#1f8bjUR&qF+hLB!Z!3&PP!8'R&9F4D,J!"fT +jGAXC'fer*lZJa*&E8!)hdDh%`X3ZJ,KP)-E93q4PilZe-9ca#5DU826dU+UNi`8 +TjV3!'PclTZ0)(6QD5B8,I-m#652[C"F9dV,jQilFSN,+@!)a-`hZC'1QcVkfTP[ +!8231Z@mG!(Np8&58*`+ZcpPVC%XGJ+0D0J6[jDk%`kJXpU)CL8qVCL#LUSSfNRN +)[pfMFfJZflB4Z29%A8VbMXYh@*!!9EicjT%GQMSLc+2aTRpCGiG&0i'Y&G[`)rZ +IU)2!RGbpX!3%NDrSqX&)lb#Q5`L%D%,4,LHGkHf4MPIKdUED$kHE,P`9'k&QC-0 +Y`QZ2FJFdeH&0Qr`aIrk9b0$d[TbY$M!lfdNF)EQ[M!QDfPF'p4M8&b+Pc&LNXMK +Ei+VRbSVLiVU%j[P$'5M)mKHT5L+%*P!%SE'i!C9AMP$GbaA4!6&lQlm%!f9J(fM +),5V+%8ANj&PRZ'"lbEkHSX,QHGa4%k+VRlIe&*5%J6p"&$LSr[DaDUYc4[5,@A' +&'IXP4b@V")K%6Hr'1CNJZ8A0`1b5*iQSC&T8#+H"Y)$NPJJb6b"2L#X%H1rc0Rf +$3(bJ98*1LIaPM,XMPZ`,0P@dCPZ6B#`bjaEDm,1TZ5QkL-!a9BQp(@EaQUSScir +&*994MMUDkal%4!8@1*,Viik)AJ"'MXL3!1'+kDkFkNLIK-Tc,UMXJ!N916BkX+6 +11V#NbTbf9NhES#SIC$`A0Rf6SHSClAEbi19Z-#eHFT@BEN!c6*MH3%0-p1(!+"M +9p-,8*$)!A!iXZ@SG@$b-DEr$a5XZri'!-@10DmR9FPj(lF,G`DBmA)`Zm",!MP- +FB)*cT&-QN!!9Ved1m5BD6*qkPMa+J-J*2@)HKaY%b-ZRZZNiM04Pc[Yh0"'6U"L +0'4FArh[9'N`XZ6,J+[3DQ!KFJpJC49(P9Zh#Zd!K+,H3!#V9jCdceVjHL5hY+Ea +BXJZIKBeT8B66*3ZG&@LSDQ,#Hm+S@Z-##SXIVCNSAUXH!TL!!UjVVCU+1(2ZGLm +(2be!F4S0`GM&+pSaiHA6cr%UGI'MDMEYjY1eE0UI*YUpK',d2!$@deb&#D"f(ZK +59"L*%B26B,BF#"!$!R,6!F&I)+VT4A4!H*H8D,T6"i(D`*+50bd%c""jBULdm1q +0hZSH"'*[i5DSXSk-%%%ck4#DERX,TUj+8iA&01AdIJi"&,!R4b2b[V&3J*S-a)* +Q!Ul#"6f&Qe,Lbbh593e(00dj5@1m"Y1)5N*eNl5eBSfQ@b&)m+C(C1MKaJ-m@d$ +8pX"aRP65JN1NR$hi1BU$$4`m'VCc-[+54e(%hl3'VjFF-1FL-)+C%*NS,Ga%`"U +Ll+LH9&$Sadp8)K9dlBhQQIUDLb"UbMR-5593qpGdNP!!M5*N-DSDB%jCCN+c0md +i53lEVGNdl$bB0dM$GLV8e(*%TljQ8@&dXUSYeq8YK)XJUX6*IB3)c)FLVedRGXI +f+U20!9221BFUVAEZSU)AjY*a5eZZ%)A4Dj!!c9'`$022A8[,d`JB,V8!S1m#'@q ++#8M,lbB$T3[JbYC6F)@#Md[BNjb)b9mSVmVpb[%XUT!!4FqKQ%TG+RYVX'MVSHZ +X3J,SbNVe8@0k#f5T5k35,`UkCiB0+JRN1RVY-9)aJ[8H&#G(#IcQ`6TT6i5pQ,' +cNkD9J5KJidA38@,54bQ#fSR`S"C)NTTi!9"X"5"D[!@Ab,fPKD-RVU#C*F4lMPk +Rcc6`pLXaEKJ!94$GK16EVfLk-I!NS,ilS$j8G)(9&$LL4*1TD#j93V%9E8`A[V' +[l3rIQ022c&"Ml5PSX2B8c5cRLMPNX&B[E3ULEA!!TiC9Lck+G)*(%PU,I-[%T-[ +(CSSh'`SRN!$aLQaa+Q43l,Li!)R!peVRM#dIJX!R$1k!h&Q@Jj6'3(Y(`&IrV0- +Il4#Ui#'l`qM(81hT#19&[DLmPq,MYQr#kl*3PR1EdDCPVV+[0(U*HEJMm,eS%-` +9q,MYp,SXF0U1l*Dh%`b*)jdcrP"kSPY5"Bq-K168$2#40ehP1-`T*(GE4I8PRYN +FlCcV5!YG[5eK'a-eA`iQc&J!X2cP(+HDXVN!r+qYVYN(mJN1ji$i$,01Q'1qi+[ +VN!$H"82e9YHNbj32!R6KMNp%#!Pk&Yfc9e8%pf9U5UpeQK`!AR,PH`Lm$r'VE2G +3`L)-eLA1Y@)3%U(BZ1N#2a)#-kSY6(XalF-L+%*ikBefL9$!QTY8G`@X%GHV,P( +'K9AiZi4hAF,THj@%qU0Tqe5KUbHPi9Te9fJPXKLqY`-&I)2mjSq4U6Taci4)1VT +#&frcY(3&YQ-2hiL#q'"2!['EAcd[bX3Ypk5&e+,#N4EFPGH(UbY`I-cN"*Qj81k +q)5fC,ca'Ifh-hRV$HIMG$GH@f8IH1#p1#pXEHhXMrEH,F@-!VhhhR!GpX3)+2L$ +h*q#8IIL6qkSklb+6S%*9bSDMCI9LRK&A!4I,+)Lf-*9%AD`Gf@UcE'2h[3aAbqM +Xq8kIBlkc*ECVU%6)Ijb,c%9LXh#h!6@j$'Jqk*`,pNLXG(pQbKP8hV'mikRRXFJ +imrXcql'S)j)f&X[YaS0`$K!,rTm-Q4DEEcZCJ89Jj(KkeQeBQ2,bL#'3!*&b2)m +@G9PBd8+`rf"-4a1)BU-hHN%F4"+`PZL&d(i![Yk)+qC6Gd9rHB)bdf-JfA3&6Q1 +jQbTJLM)-()K%Em$Ul'+4YNRZIJD&jGIHYIf`aaaea6h1iDKVRmHTaUI,@B'T,VK +-L&J&VNdDB3l')*Nb4!NTSR2(T8C3+eIPNZ"EJe+&p8+GhBFM)ZEMlS1886j0-JB +aR$#hH*bLk)lC`VlViSpP2el1jXEX+r1kr@[K-Xc0BcM-22aN(J#0bX"H*CPL(T& +SZU)rLq*'Ca5IB*jhdL8K@"46)ND0-lNVi(qK$NQG2N!J(@lk3)k$EHR[PSf-B"K +&TL&8SrDBAHSI1+a)5&H"MmrTIA%XTUiHLd@PiE)a("P,!X8i6%8Ih0'!R#Ch[i% +QS'LjJCV&!2c%#(iq"4JjEKbTMN9GUQRf8,8J3p[4*$``Y"EQQT,8#m"42j,$`#N +#NhJj#L0mqE0B521CpJ+rN!"[S!Dh"i+LEl`X@NhRa6CFdZ-)f,h9S9LS1NLLkA@ +L#Fj&pbDN+a"-929F4*+Mk"I$eEm!D`@aR2L!-c4`KKE1S*Df81fh$q1+mHUS[@* +S-jaV5K&-&SPSp5h[8+)a5A`&2ciYA$`r[VE5&G)QSpMNVI5+"cSSU&`@Mi+PCc@ +@#Z(KM0Zi8RUUqk5!Qk#!5p(T48DY(q6q8J4P*0k!@F4ld!a$BM1K9XHmkXdLJ1+ +ea+4Ql*VQaf!!hN3GLQ8rcp"$XF)!Z1I*&D5jQT4UZP@11a18L@Mc`(hGlabHl6S +*4ic*#DG2lEQV2VC,VBkiUR[d43J3[YXDK&Z6@[8i'YThedl0%L!R41'm[j8R"N& +'NSfLM$I)&1Cd0`j9U"jr"mbUV4Mi9B9F`#p@-j`UDa"X`kTjB'Y4[F!2ISA'l)) +IdH(IF+H0DKbZ-Si3fB#ZaI@2m'XpfQ[9'bDX0RPGSP"*LhI)U@iHN8&"@(L"Ui' +,ib*3BYPeh!P4%SNb`1iCS)ZDq)CIT%2me5e)I1$&*5-JNRRB05d+K+Fi`QTq496 +e&GqX6lpCU2J&MZ+`&N8T'9[91h4S(Mrd!Vr5J0cDeG@m#[D*$@)hVFCqpc[%XT8 +Lf"LUM@Q$IlIHJ2JQYh*P2F!MJ4Z6XBaY8QdM4h9+1%5*&+40Ebjhd`mKS5TP!b4 +"L+X!#E0&Rr!Zk[+*[&P8a0ij+#AhDKU4%Pk9I#%Ppq+N5cI)Cq[LP#daBSZ6f5) +"d*bp+Z8V5UU)"YB,Xq,f+"%ID,Jp-5X1Cb4rG%Me%a#9Vjb5NX@9NQXNQPihJcQ +G-jIU-cLNV#*9#+p1%cYG!0E0Q!!LmVVU8eBNKD-,QpmI!r'fqHeCmHJLe+BK9E& +pLKq"1*BSBACA2&DKRm5@GR8"(AYS&JL)0r`P'E2jD#X!-02#JZ"$42MJ#6LN4#I +U-'9eK#RV8dPCMbjRbST+#QRk&#"p[9ipTRFPj4619bURa!I8Ke4rXVGS'GqLTRc +K*k3dqi&`C@e[`'&lHFSUZ"D[fJc+fJi"GQ3k02pXeHVC[M"F2BpH%kiH#I!fQ#X +[&MNTUH4e1!,`$)aMaKfTCp*6K*6mN!!+E6*(bG%X-[(#V6a*hBJY-$N"ac(e,re +m)LP0f,FB!`T5X5%4h145GD4hPMXk*!*CG'"X[h$djQa+%kf6IhTrp!Sb$BQ-@m1 +El6aV5@i82LbQX%#LCL358epM!EQZ0fmDJHVMLZC$e%2C0&5J(a!M8ehZ69j(Adi +NZNRdb-)qU(EAK#+LaC)@D'qlGQEN8Uc9eYIUIh@*5P8R4Qj!hT0E(-q-iR2JT-p +l!j,MLFLP5"mUPPYhH-fIcEENc-Ae[NP6lL+kf'26ArajYcR[GC!!3#El4c14a9# +2UX4R@[ak5@`69$V`HJPFZa$a8rI+FAZ,0#84ihia&k#0@TV#`4)j6XGiXhh(k1q +jijU@f1l!+f4R-HBIHZ5ipZ"-18i4"mFeLE"A5dN1@AD9'XfTUIh5m9ETL*9R1CC +XKCJ@AGaHdEkSC(2VST+(X$Q3!+IN+)K8)%1@e")M#%p02#,Dp!E*Ap',$TEC%fe +(iG5k5&@m2a"cD0RbrRdKCr-b0TZ#VE8b@m(MM#eTB&-($3NCNG)4'b6`hLLL4rI +K2hXdHS3[+"(UbZM4dGlm8CV-b$PcR%mQ(8IY2XF4*#)0k,-"6%lVQ$dR+d-+9Pp +ldC(pCMdPNrIhN!"cbql2kJ0p!NP$ZH&Il"mkCClBh6[BhpNhf0h@ea[K,VpFb2' +X#fHBN!$BUS5ma)4-Y2926(jRSR2LV&i-"5+!89kfF,1&Mbr15i(-+0#T4*+pUQ# +[1YQ%KV,'L65-U$`[)M!#Qj3G,k)6Qm9b0(hDM@lj4QTQfLj5aF+D2UKik[U()T1 +M%j&4)8Bm3bQCap-cjG5FA2X&jm'8iqR`F*D2ReP+D"CCbl"GAL$iYL'*UhI2Y&M +)G*Dbjb!`fS-+L-#TelM!EJhIfP@UT1#@8C+iCNF0A'T,80P$9DS[*!$M(64V9Bd +JMq@#0CXb1`jE+(%k#C6%AGi0GI@3!dFQ0Ee$[0K4AE'@3@a&Q0KD,[B6ZZi%C43 +Xi1"8%aGp@5rkF0aq,`0PDQRa"JTD%8*8H9@0ZqX6)2"2''I$kAchCaBd'2B%BMC +ba5dD`@EETDe6-)A)5rLjBS`f2Ami[V[HdU1k"(I#J$1d*r$1@G(5`b[La`ZT%2h +TB2FT'%ar@bp((9RcC4`Se#-[5i@6qN6Gd'p&a2J0+BSifL9kC50V-r[0lrH9UF[ +X2AX$G)4-3f,Djj1BLZiMYA8JUm%BD$MN[-PaL)lmk#a9GQ)M3`L9(I+M*cVepXZ +,F'ii&E3aqM&N(UJ6!pN5m#*Y"3%J3XBre0djf(p@ZkAlc2F(U"$hNkS+AiHU9PV +(L2jYK4YBTTf%@U2Q,)''(DNVTJ0C'%RAUCVVR&%k"e%bE(+L1LU8f2$L[XiCZhB +GMN19dEDrU#f%!NK)Fkr5l4VNjbM39be$TKbrRK+,lK%mk&(#kaB36638q"!Tdab +[m4FV(Ae2IiDQdj5MErG-4mKCd4jpmarH$ai09@ClN`i1)fQU1SR'Dhd!dhli!&8 +3QfP3crMFi,fFdI5@cIGC)GamdXPCXD#L*dl*K4f[!IMj`M4SFS1a[X8YLA,DH+5 +f')jJ`mY`l)'4Z$4*VQe$F1q9El4GK+#CDMFe2h&K&e"31hI`D(m'%Ak-)Va(f'9 +**(2&)'(c4Z*F6#RFqL"'%X%hN!"!8(N)'B&3[UU*e!5Qee%m`2!5ej!!i4d)U0e +fA`mF&J[Za4E8h$KD*-%9G6eaVYVA+#[M9K#d"Xj5Ka(UBQBN!$[R`dM1pREf4LE +D+YX+4GFZ')Y(AqR[%BjY3L1ThMlfcU4Uem"Y",4`%'JAJ*AhHq,f%EP08jG!9`R +kSZX(4*KbQlB*Ri6)$b4%e+Km,IS#E5%93#JYqJFrVi5#i-d%&)BfSlIm`R!j$[I +e$NkFDKZPBjd6hm(4iDRqh26-P0c-G&N$Smj-bFa0c6c$"DS*$,C-`Z852mQBQV* +!N@JJqJi4hT)aVbRA!1"Ie[4'[M2D26K*#`9#C+a`0*a'K4k)0-*3q&dD-[F1hGl +I1GRI*`8hZ)!&aEK8d2Y0C1S9Rq$iQr8TSGQdq#`pm),[cCNc3l`!%l&Ya-)[''F +"(HkbYf6aU24,+N3#'bR+-k()&K3ApBC!IfQ`1c,8Dd"!fV"6-Jb!C"8[ST!!U'" +)9qJl6rJidY[@1c%CGY"+59Ip&1@lkhQ&'(9NL8iR1B&e0XmcBB")eHLbp4Y[kiD +!`@j0EbIIH,(jrQq3!0NN4i#!C$UlkahZ0kQJPNc)VdC@VMfdjkmmk+&+iHjPF$0 +$X9+"jS-EJ8CMLa2SrXb6Bh'!8Qp,3FMiT`BS)ZA'fDpaFEPUYcC#rE'BLGa@6SH +,Xr++3[Tdc[L9k)SVA`-)D#M[qS)lf29fjI9!0rThJk,c"lfS`VF*Ykh-ke*pk24 +pc`9A@5PLML0Ld$Q&HSYH`94KQhV2pRG+`DU%4`H+l))'U[,ee8E4P4pPUlC6YDJ +hTf-if0[Caim989)P(KK028A&fej&Tad@!Ub0+KRCA6SA&qU4UVZLhd*i98rmcAT ++f18!d-',5!Np1bm3&iNTAYa5BKYNl"39%h"ZFK'"a&a[&A+F5(@e2C`C&lljQH2 +Bdc0a,,SlV!K'e,d)jD#C3PFKXk#cHEj"@AKp$)K"m4%0AG)Nkl)0Vq@SABX5+T@ +h#)cmpFD1Z0(EF#K(HT@"9iGPpqF@E(D8UYe%$8HLh[%54crab8YCIXjk-KEDpUS +mP@qa5NjJ2[d@pRQEj`-JpP+(,%a*2D5J`LHKr'*Fi1e"pMkLE"a&NVjSR%,&bi[ +'8DV!K$iSXiS668!jIQHLTdlh'j-6cV-bfqi`[f#+*e!L*+D3!*9UliP(Ak00fUH +X8h33"0"@#6L8,AX%,[ES+deF$2*-MH&Lm`4F-9K46)!)[hi2+3l+jq$B6Ki&bk5 +,'DMc046&+2TK9P&FGQ'PC6`1YT&`j+51Ej!!"AC[$leHbCNlH$,PR4+5bUf"4HB +X(eAH)K2MkBPESh'IQSkHBqMdF&6fG0!&S4kh60(f'SmfZ*6U9F%8X0'J!$hBSY3 +!JE*-rD5i8E@krK0bF)aB$JXVSH-RN!$@B,Bd['ZKAV&86A`me+hj(06#rXkchDG +'Y5UP!$8&pb#ekDbmMX!%Zmla%K8VGYPak'PDH+`%F-'ekVH$#A5BpI54fI`&0rq +cpSLZpmBr-SEfEA&5)&$d'9$K86d-jj(3EK+r-Q'QEQjQ[h`[#DIU),T$EIlXNb0 +FU2I`Q1SXa+)l,NN8*dEUb$%jA+3d1IFb61!C$NJJk`8&#$QN2b-e+!)dmD&K)N3 +6-``63CTS0%aiD@)H&ijZRT!!E1bCjCGVMR"bPH8G(NNH454G1Y@TQ4Lk[EGc02+ +jATRI)'@UL4a6MM+V`T9jI`P6CP@B-[[dbVcrTJj*QIj+b[5[8TPq8ZD-F'815S* +i)f*e9E,*EH,QbeBIU4(Q0@J`,`2c1a``pf`a!1DA"bFQ4a&5Q4EdP6fTJ9HG*M) +VPrT9dd6,e'aAETTq8$-a"U"r6`!68`eRmb)J,,M8pm6JcJMh(!(LK4!9@2`ANJM +k[)!h$PXibbEM+PKXmBCXURk3!'c[E'bC*2TTUGSQ3+YH(`bZpNqLNGf,DVklFrF +%!mP493IpV*Z++"8[22,D(3Yjj+e%`8q,B4jj++)I1%b40rYBYU%Upe"KBq80'b) +,S(#YP3S1&VcV$DCc95VH[M1K-5LZ5'mq[,--9'q&e$")V11&KFHk$P9()DN[['T +LL,B`4*1STJS9i%@@DI#!i)Lj@@9lfT&Yhmh"-"FbYSBrF6e0cB)ZQ[+M)5pq`5Y +*(C%Zk8Tk`3*@H`ZfM*F5%$FiMZ-k0cFI"*DE,,(jV)P4i4J-VfMY8kc!j*hG5Fh +`RVLN&Uda35er#l8`RI6h6KVJ@%626M6K5BJDL3a(p84&C-M["l!Y5kp3D"GEYFe +!0iTdQN,aqMbZQY)fEU15qR'4i3CrfAH1'idAFTed&6-%&,%k#a&*8Sfjk9)"[h8 +-bU20M&'a,!&5aMHD1R5rF5bdS`+f#%XJTJ-$,ibjFa'b&CXkHY!&&d40'Ie0(@3 +5f`3*Pm"rGEf#R$(%b"PkJj3DZ53+65&*P!3Q'86aDX8h`"ZG"!)c3XD3!*D3!+' +[X+1%113X4k@pFV9+Z`G9dDM9cd#`%U"FSGm)QVXHUKj4B8e"RA%&mYU+"9Fbh*8 +JJQ-K*B!L!%"PkiR(NP,3+69508QL"V40C3EQ59MV'aJ9k%!5N8Y,UeVI`-FQI,a +4hN(0r*J%E#KF"rr`3(Mc(i"%18dkIN%,,Y$a#eUXDT!!kHQR3R&48UaN&`h(9NT +0bXTXF2cB4!b'TZ4hqiG@d**NedCal6Lr0QT9D`dPb+j5aeSNJTJNrPG90+PA-mK +`jE329bPih3S%,e)+"V#a@YZ4L8eUa5DjN[bF$1*QBLZBf'5FLrfDQLEei$k-JN( +l6*K(Uh!24p%!3%Q#eF,(")mcKAXUXq'5)Q)`!+Jr*B8cq*4G0)@,@[P&8r`Lj59 +4dFSZmF3U!B25"9prK&k'!D+9iE$eZfKNe4IYR"jqd3IDM4M!2GE-VR&kq$9qA%0 +&3C+*MXBUp%fSCfE6K"53!!le$r(@%K1JeJBMY9@*)M,aQD!T&S`8k*9FT4H')[2 +MrU'`%R1p9$#qDK8m@K'ZJSAmNY9+rr@lE'V9PaA,iCGpc09YU(pCXK-EZX#J4$% +9e-$F,p,%!H%iQf-IIcAU%rpcdSq%h814UPJ%`lNClA$S#"'BYVCp#JNil&&+q$e +D06Td3"@c4Dj%UNB[M3l&L#h)f34RUj!!%SM[VYT0M(jLh(eTpp$dXhN%GVE)96B +h-V-8#8C@fXB85"d3qiA0(HPY'-`5rJ8H0(r9ALphfZ@*N!$qjk6`TqQ6)B&b9a% +B$h3%ZJ+$JG(!bB!aX#G`16![d"5B(RJrF%GJBk!d8"K+KMbKpY#QN!!TT!RG'mS ++(3M9KEi+[4LD(DS2h4(D'#S0&3D6`I&J4l!V1"JF$GU$kF'M`BA"fQ"$F'C`ER" +VF+Fhj&9l%pj0hN([U0IZ6IFHpGCi&hKIpml`c[&HkphXhHAfZdIF1[FXYpQpfjh +K6R&Eh&IGMlJAZH[GGlLIG1rbqAh$2Te[PUr2YpYhhRI!GpQh`0IJQqQEkp[UfeR +Q+jXU5j6CbJkAYC@G,MYIYVqXUQaj@AACl,,kXQPP0jIG9lE,(r*Aq%ImlIiGrX0 +qKhqhrq48SIJ(r&502KX6CABf2-5(q@ci'Kmkf2#RI$M'KKIjX)F0[q*$Q3dIiF- +@0Vb6$leX@%e$hbifV1A$c@ci)KrHa)CImZ(GE2L[I2J&'ll&K`eXf-b(Y@cBa)F +,fE#4$iqai4)q6'2$aAaiMJeIjm-6E,L)$c[Cm'dqG,(KcrK`"a[qNJpEfA!f(`k +ci3Ymk'I$k64dPl$KrqE$KpK`"KmqcSEraSGcfI!rq(!Q'hl#KbpJZ48r&P,UETS +L"4"6!fGBb)CFaHjME-L9kNjM3kj'pcQ&U&SZ+Tma5!MV$H!hI$M'AR)&ZA[BN!" +(J9YQSUUdSLSB!eH%@l!KMb,[-icpTrSYH$HbUijaKM[BF$iI[XrBkr#cJ,22CZ* +iG(KI9)KlN6-X9dcp+jqbX#2FQ,`TE-JM`TZKZ1!SCimSTLlb+CGLkJ-q43Vi#5Q +2#j%9$%XiJei"h!bpHJA`b!k5!UETP4GmNQeh'4pHbiE2mH%FG[!IqA!''r+!&Ab +G$ERj"KFS8*K(+!3[BrNHITCcKMd+TG4aKLc&N@0mkM36b30,X)d0Z4%'$bZ-C4P +RhmBBH-!1VQ5)Fi8%e@ci,"q'f2"[D4MDLH8rka%,2F#',r(K0BTVAU*V3ZmTTKE +b+@8!H)42e5UQ[X@RDK46mrR8(XA8Ir+T,)E@crR9pc+'lq,R#QGSB`aFqD($$&% +H-5%EBcp#4XrC53&r)22A'h8SUVMbhfJU8++BQX'R0V0M&*P(q05eLLPZMS(h&FI +Zj&2k!-"4$lbSB1"4(eLZQ1*"*Q"46$A`U9bf[D0F5)`0Vr"KK!f2m'%I'elL`eP +X@-H(1MEmQ!p(f2!U(dECm!-DLL)f[-b(@pL3!%Fl4if'#rR`HUD#,dRjK+c3&i$ +FC-3,E$L2$jHai6IjF$iErLFISSXDm6iV+2CLm8qXL$'b!99A'8bC90$RXaG8m,5 +a!BPbX3&GZBNG)%23X4II`Q#F$3J404Y30HUGHMrbE155"*cNL@rE16Mc,#AX*CH +PX)66P*3U4)Q3!,af5S6)!CLC()#jjD6`YQQ68Br$Ff)dH$ki`'Z5rJ9Rmm@)Y`F +(1d5!(khQ4q2S&1mDlG(TBS%`#ifBKKilTiRG)PfF&jG&ShJ4`j0L*T)K(-"bQXJ +9am3*-8GmJX&bdF!RTiRj`f2L6P)X&V9B(-ALbpJ"I&k-TH1c,*D,6e2X2$l0XC2 +i,)QG`1Ief'jmIKE6i20#c)(2rileiI-IXF2iI",V`UFqYJ1Icf,Em*NCDmIRqc% +CRcQa%A`qM%hK8aLV`+FijXIRX4LmV09)3ZNf+cBYJA[l6SU3!%i,lLd,c!9BpcU +fA!HhlCV!c@*qi-2!YB'GJDf"cB(5d%T4(I)&5N))@+)TY$*3!m!['QS4$D'9'&T +%[AJ1UVK'c"8E!r2&CP%XYJ#%p!Fmk(0)$ZM!C!Zi!%bD!rN"6H#j3(AJI#!'S$+ +0#rJ#b-)"2$!2Lb-81,%iLJ8TNB)*+E%+#e,M)5a5X$L'a6NXAX1#e&L(a@NXINU +"%iXV@*!!'LpKBF)#A3`'PQ,a-4DNaUYBG'$a!4B*,'SSF'*a%BX@,*CMNF6L*5a +#@#a%C*CJmEGB2)2&9eMFKm9h+A"L-4q,Ql"!Pj[L$LcQBI%K&YqN`)R&)eM-`1* +E@-c'BJ%@M9Mm"SYD,0l#JK5`#!Y5`0[-L,jJ4[52h)MqL4[4hGb)rS8EdEAFL+l +K4[3%0k)(Z"(GcieS-cHLhh)MZSmEdDqj%6h%MHKKEN5Ph)Mq`)hS9pb)RZ&'p$9 +Z4$[e4K6d)Z()cq$@lP12LDp,,ZZK,3V$@ZkXS!i'q1!9*jVh1$k0LrS*&h@MAP4 +S"N3YCk,HCk+@+83GFbBJbX`(Yr*"+hlDmG1$(b5dFXSa'd6ZiY[i0Yr'Sh`E*A` +EfrNf#[MP4IabPIEb`lLmQ9hqlqcb$NaDf15rXFPKrN'#6@4TSlJ*HBGEN!"mCLX +51&@MUfUJqYJPMR))LEb#K+VP*563kTLNKipdI%kI@C1'cqJTqRJQ$4mc6BND2V$ +44ebQBf,VbaE1h21bKErd5aqZM!qTfcGD"PFk-rKL)cQTmB-[5JG%&BkRk3GieID +bjAX@C`SAm(qGqrR#iqc"Uk9J1N`6Yc`"CM,`HULUQKRU[c*$E@5'ZTJCDJ-ce0R +-8(r*$(8k-p5IFd0pMK[U$'kSrm!0pCqjSEl($IA(h&$RFN1pLa[U(Ga3rmJ0pAT +ZU(rLK[VI2)T[iP&m-irLrmZMH#12iUdmL[mAMq)R@45I3$6p`DkT(%R4Ci9irDK +c'emFFDkNaCIrk%c5SVBDQGiH#0R#aIk9LhfFLrd,%q[M(5%*4GFP5%c2(m%LN3T +!*K!VH6F@8AZ8Z6G4mJ3EGAFL(5Ni4XkIVF`4K$*k"Xl""Ahq1qIJM[i)%R6AbSl +DXPQ8iAYYp*bT$afeqBc6U"K"ecepk,M(K13a(H+`cX)A2Hd@5ZU1cXdI3@*i1&i +A()-$f$,UD$SN9)dm8ITX'RS&Gc)r9Kf#m,4SVRP08FLHFYf(F8e2NEHYabm+jYP +b#fS6rY%Mk@ZID1C*dl8LR9iNd@p(!XCMjRUU@-aVR0lpdf)YVq3@,")fhD+#kHf +,#QD6'UNkelZS8PDN4kE(#98M*`$*'Cp&3XejZ3QSm9TN!T!!FbLTY`J%N!!I0D( +lX9L&(2cA4#X5N!$*`6ZaN!!GqS4T$$53!&c'Q[!UL36)DY1lR,L$EQpiBLSm*U0 +9d9P$e1p"Y#%6h1qm0m'kEBKj@pkR$Zr3@8``XADQaEi&$Uk(AUh+&mCir5(l6Vc +DJ5iN[A,SXESULa`bZd`Z,2Ter6IqXblkbrFcTZ5CiIpqGRIQ3b"3f``')irP+,V +V3R3NUBX`HL#0[U-YEFG2QkAZ+T!!1,9e!Tfr[HTUVF2!c`G(@q[3I9-d"afZ81H +)hkl,ljBGk0B&(@AaLI2jhE%LDF2IbXl15-r1IRR(2HMJkiCl6Kl2b-j-5mddNRr +Mi(kTmeEY9Ci0&6pI+Il[`L3,5CL8i)55Rh$fe&@bTh8Hr-m(cam[KfQ)Z$M6MXk +$#j4-P6E&1FAU#QcTr0d8',j&ZZYi9PC1+VY'3UUPMeM$8GHb$NPUeRGi!L4@6Mc +mNpE@1Q6&)1(VGJfKFU)ladp$#49P4dTdL"-LLGNX(H@GNIM4-84hC9C*r,3&@[' +f$4#[NijHTrM4heRmk(@,rjH(p1),a(U)ak[#BZNBlkJ&(5RNVdMdILCk4N&d[86 +2+$JX(3XA5J8'%[Yp*"UGRX4(BTNFU'N@YFp2L&Uj(dk&+jmhL`@V)G!"8D+eMMj +JDX@$fDDNECCFXf*Ni(LX*d%[,TP,Kk9NRRSa0-4e8j*,,a3l`V0@Qd3Y@bbMaDh +NQYG)5d+2(9V!$e(AF4D*(CQdZ+E`2*,I&&("bbCVmA#V"AKme8JR1M5$ZfU4JYR +)UcRcmf#6VQ*ShkG[U$NkS+5NSe(8fVdQ$2M%&,U$A""T&!YqT&'T*KYj%fNqQ%E +Xh&"+0ZC6%[%D)ce-CDIjR"DY3Rf(@rK433K3QN8S&6)QSf1)R214c14'jk$N6LZ +@jH2aF8Lmk6"VH)E[iK)NPGpHajcZ(i*C@M4J3DC`"-VR(9C+M)m@Sp*B53pUB9f +!X@SI6Z)CFQC+5Nk+I#&AlNe,(lb3!*ACRfXmQ$kCMTGj5jF5LqiM)Gj!+E"dUEC +FHZ10AX1k[eXadQE8-28K5BlDTZqbVjhF(j!!%+"F9HkJVYrE1d6YG,"NmBlJ5EQ +*fkP53GBq2RG"dE5i+#Pk'9Gd#lUB@mH9[CPe0E%Fh4dJX5pe-##1NL#&iN[d(3p +DebR8AV)#Y6p%QE9-lAeFlEX8DYr&hCm0DXpAU(fAAZfbp"!dr`BS22AmmC51EI+ +C#`FbXp-rfL$PU`ST@C!!P%%Q8hI)0A$P(XI$lQC+#4ZfPqC,b&*A)8DHF!U)VAE +&U61C+8V*,%Y)c40AD616eQ(cVRB1*$T(@QrM430!(3kX4+e"RLJ+'Hab8+m!#9" +LBZKi9lX`UUC6&bXG2aT5UCL3!*8NK!)'G6QP&c0-j[XXQ@qB3)!KBCPE"T63Z3- +K`96KekZLj$P*&592-P@dk&8K-p"fIG6",[D(E@)(1R$L++pfD4qle2JhZG33"45 +3!*LbTMl[jXlj#T@haf(kDSkJ&%NaZXUJ0!K+)kG!5@AbQ`P0iJ+b!5mUZmZM`PX +r`6Zqj8Q'$0hQDDZ#GR3Xk#@R+(50'c@Iiae`Me-P3*HZS%UUG)'KLK+$$T(IECF +'`rRG+T"l!61MLR2$Z'(Q43SpHpFU8'$k!4c[kP9hqmDcL*Z%R0qAbUXqI91Z +V6c&bhG8R$[AJd-R@1P+'l'!GMEG+)Vjqq6SfV"Fb`P9*4C9r[8'0'D*&3VF5N!! +KCFpR%9T50FTF!rd-ZD5K%'BURb&14f#Q9ZV-YSB-N9A&LSaKd8%[+KrA0rpN[rT +'1al5U(`KDj4$)pcM("jlLA,5USE!68``'[rk"J''8l%S"e)A5b#UrTMK!AXN),m +ZI01UK5Y39)9THEL5&0A3CS9UB&MPAm`ZD!qE@2cYqBE(9`TY8NIq-+RjC+j1If3 +*&(&lE"$ZXfQ86!DG2$l3DLD$'1LQLJB'5qUhmHTT*@IL8i8,+F"5ac,I0M+%dUJ +K1#l#'S*4()%5!mHS-BMU+FS,20TbdV"GrS"2EGHiV5pCA`A$9r6!Xrj5RLMR0J) +QQ3SkT3#$JSS&AKC`f`()4H8@(TcAB*-Gh'`1m'j@G@')58(BXL+6*IH+eTS943H +L1&LrL#IlmqmqXY`L"a4-86,RPKSPH-U65@26+A,$N8a[E8m-A83kNiQe,GG-@Z` +PL3Qj2m`NcdZ9'LqNefP4J`T9adJKCd[j#`SZ6#'U`q8V4$A-&8,E(eGfMNJ)D3F +3p0Xk(UMdTPfL[jD5KUTD$*F5k)&%84XT-1J[,jTCrZ9&mqKbFpj2[Lp&3p&@-Qq +TFrRfl$pr-4b1YQLSM,DBVN4Ea&CJ3TXBfZmcifNT$fep01qS8DTaVN@TaMqV8A% +QhpY)S[J3d#cCZFd`q2UpKX(A9PBZmZHU`iTmJ(45NIq(HGHTA(+qQdBLT1*C83# +CVkZSCS@aSB[D0*9+iDkfZ%5R"DE3Y)(ce&9&FGi9&KKdAQr5JJf'&DR5a@AUbX9 +di4HV6EfqfY3mrC68LE-5p#SaPeI9cNhA9lAS*QfpUle(ak@MUdFi(PLJ0K6*%J' +bRESTECPHP4&Upk,$UKRE(fNAH)bkGrUKr1k-#"A$lHI)j9-1'SaeHjHLZ&XR'Hc +fUpU!Y%jLqlEQP5(K*411DI5&G'a`qU&8NfieN582+%5biR2lQ&BN#jLlL[3LP3R +Fp3qC99Bf8RGC$3##-Rd!JY#-C&8-,mkf(feA9$*5*E(pT-iX4e&*Y2#+!aG5491 +bLaJ*Q(,3BmB(UA0(#[`P0KNG!U,a`SX0+[,"I,Pp1DqSC(l91ZQbVppA6P9eZl* ++N!!PC!&bM5T!,QAaM5CF[p,-J35""Ld%NNJ'T0SB*JkG[P3f[k*V&DjJ[$XaFNq +('eJJ66L1jBaEN`bFpA4HT!l-R+%VcellE+6UZ@0j6mT`*I1Q9HkfJ&GdDh"J4U" +%*h3!UP[E1UEDh61U00dRdAASYFZR9k8@ki,cPh0@G(%XXB[fpZ4AU2LII*DDR`B +J@Jj#ICl`VJZNak$f!&cY+'[VJ8Y[G*YEei'ZTU(fqFG)13e)H*943@$p9dM)e&C +Q!r(dUd0bbbPdRrMBiQhZkFG1VVcf@856Ped9lEbBm1)a2HK3MS`mG5Z-+ST(QkX +0$c-e!-VFL03j83Rd!2)*6IIq`(Z0J[jiJHM@1K6PC"jU1D`MFhf(EC4i!mCA&Aj +pZ`$4`bmeI1b$8Q,@,6l@9$l2QmU&LUBb*h8SQXSCLUCbSEDT(*6)%a-2hcL+ELK +Xk$F*DRUXq9QJUJ'#cq%(AG+Pk8RP&kMP,0[4KTBcFc21b!Gc-p1-QDRTQ4PC[pp +3NJ8VXU!3k[)3bR6aSEVY()Cq+kqL*UQ+#J1lH0AP4r4&-hbd4-HR29V``d#b(HD +%Had9IrPKa9mi)'S3ZdpUdK&*SMUXL&JN94ermbZNScc,S)9IT`mkrXk,*bSAZAq +fDa8EHfl&9e$hDM5XVe%fhmUER(MiHTHKJJfVjKmZfDJBE&B-VT'1rQNXr+LKiLj +q+&c8GU%Bq"8$Md*X-3Q)Dk[[3%mqIfaqB"BY`UYd*0rJ+[`&NAKhJ)M9DZF*pe& +Jlm#4[K2GH'Vk2ILKB39[C#33D-iKD#9id%,L#e(0JP+(RT3JUIP#cTRXNmI2C-V +fiaHb3(!L3P0U9ZEaP08$"*r3(eLkP*d)$a!F$,Uq0,cKqkYY8SAq`-,e!B-HQ%- +LbQZNrXTHZCQ**$JlY"&1LC6a%$JNi2FIYDJ$jEfBUAM""0bM"Ilj&LK+iM"6e5) +meV%3$aS2)hic-[+1F*30S"GV8,5Z"YJi3$`-mDCY#LGCE0Xh*J[YC#I[#R8'1RK +c8HBGb*Y)LS3#0)3LX"TGEHDZ5'@84FNII-FhC`[E("+PDEZPBGdm8%2K@M)`BSL +6mQB8SF-93a$4"eC6#mLX!CkP%#+!3B[U-pbm00U*1f4rIMFRDNX6-hR$RD1YRIa +#D[C1I5+S@jRjK)MqC@%KGFSUUX)Q0f25U*`UDT%#4p%1VMbH2&RlmTa%+LJkI%* +lCF&@[NNpbj4d['!R4k6#!*U3!#ND'Y+9#M&d8KP'()+khP38*HVb#QiY`@CldqU +JkiS+13kX)!miR'4'$dR@NLKjGb'DFXN35P,&(l*@4+S`N!")mF3-*cbK@,h+ +hKa@jN5EH5Ber0G1H3Y%i`M)8bc951MD*ihEUe-C2T,P909kS3RbL6Nm3[DYH`D` +NfYD[-JKU!H2+4#G%rEXXdFGL9GUU%0N3j-)[B@5KM"@6[4`eGRpNmFq2b[5MANf +PRJdL0!iEQ20Aa+arL!3b,C!!e9&KEH%C)**V3$5-3&#*e+SP6#X"p)q%&fUi%+B +#VTV`"MNrV#irSSLFpp$JNh8V)+cT0eG4[PP40EUpQ+V43VpLS&B-K**`N!#S+GG +d0ec4L`Yd+eDd[RNYCQQEeiB0&dP0'$!X,["VY-h[!PIP+Qe&D+V59j94ZTjAUkr +lDTi)G%V+)Z30VYdDkT5rQ,Rkd&%L6+VC4(3&JDBb3ELmL'#2)m$QEYB5*IAAJ0L +Vk6CFSUUY6*!!U(ajH@#K!5(9!F8@&GHS&S9GFrGU4aFAb+XX%[4EHrQAFaA9D#& +,a&a)P6Xle+*3fG+`!29bJJVArP8@D4T0hHU)&,eBrVE#P9GNVe69-,8AI9M1GVY +@S-#TFVE@`9jf+EBfA+NBG+dZV+"d"C&aEaMDVZY#6kPmCG@m@RB4L1m*KG1Cr2) +EEF+VZjLip'krm,CRk`cJ9*3kP-GeB39C@'5-r8mPiTLXAV8aP"I*8N*VrL![55@ +ke32CLU)r2"*A(3$+$hMK38MerJS)U"ikhPVc#PJT+f"&C030)l[5(hbM2+#D69h +m[8+Ge95ka,UZACq002R'"Bi%2[*,bNF1PBNHUB'!6LKEH3I@(B'EMQipY-hp481 +@b23Qh,&3UeX1e4`"iIp*15"eL@D)PPBkIN'JUfdEr!NISdT04i3%R6LU)!Kc&8U +XZPXAL9Fp90fT0a,llKXX)f%N,6LGP&HSEYCA`5M3pdmmr,mq*&HBhfj$KGckmcN +JHQi@'Lb'D4+$DJbBDeE"CK6d5HF1($)4F41[afAH"'I0Uh&Lfpi%N!#jN[[@kJj +HqSVHm[mUIEVZJD[@Q3ZTf83@1AR3R[fJhUpX%hN9C+HR(,q3!(i'dpN'al+`c@a +pIldh8kcIc0Er3jY*,AFcUGV0'%!M),CliZ((5N'3!2A53P1AAjH)*1VD)r6iSB[ +rp+jC,#8dm%"X6!"Y$pLZdTqAK$r9aX%GJQL,FdjdEbLb1@Hi*mGe+Mi-fG1iIMp +G6iY`C219k#DN+3A#8BC`p(G&q-,[JM#8Zh'QT0b0-pG(Z4[2rcQ9Zd''!19Ze%M ++hDKCAq9bK2pXbPd2K2AS*ZKbPQ(#Vf9JBU9VqDAhK&hkpqc5R$-EH1&M9rqQ&kj +()D1rd26R+5ii3RqR4'M6$4*#NXlATlJ)4q[285#[$eUV9TED5Yd3GKjm*#-Rqm% +,'CQjHNPGUHQr0fD#F@J`9HLGJ6aGE!0pb)`+YBm1Va%l2-%8pj`M$UpGRV@'R2@ +*T#i,kX+CND'i14FpPeq11HZljE8FCTZiCi1+YPPR-R268hiIjSDY*rH05aGYajp +589Q9($#4P$IQc%b(Mr([%+P$repHZm)YmfZMH*SCCG%KmY"4*$jViG+0#-`p$NH +r"mZ*`3FT#ZNKEl1Xk,*T+!$3"NN1e2`23m"$X%Uc$MIiKHf(q&1fiT+Sp*bXR!F +c8mU6Y8T4@mS4GG"SA+%SAM4iqD0Z+cMJ5RqSJ(&B)VP'di3R1-HLpK)`I!)LGGa +ac@+$h!YRbK%TQFm00QQ+L-bEmSkIZHh"5N@3!$cam"2Mh*RGTb!pP41d[UX-@GU +,+!V)(4p"GkQXIYPbepXJ'-#*rF#SF[TclB[r+TIp[aV+CpplSM+bpaHZ$l+@GjA +BlVJRqfaQEQB+V#Se*b-cGAmk-%IC@8k"6&HdrPQZ5!frJX"Ur+%GF1)#!$a-jVp +#GaSL&0!9Vkc)LP-4[CUK92bIUNPPaGBUM*li8e2,3f4U[4"jIJ@PS3%2M45NJ%L +8rM`%C%jDN!!!489"34fFH2Lq,'S'i2,!US08+LYH9bcUeq@)+Lp)k8@KLr+$&Kh +imSkRC@GPjMV6cfFE5T1`U0)ABF8%[!c33cL+HdY9[!01+%a0McIP$MPi2!!2Q%f +bQKTB$!$T`5AAG8&Nk)+NVe0C$,8e1(Bmkm(M[cq6RCZ$VX,hVa)lk9!l$U(Ih*` +-p!qf5RjM%1`$B$qBHqEm"A[k+M#lS%%F4RJd)L"1b@r$32"R6f$Ki@*f8#'6ZdS +*I'F4EJa-9VQLlS'SR)2T'bK,9%lmF2p9(NM9kaYF&i3P@pT86L"G,e0jd+$HPlY +lhJD`JMm'iL)H&iJr*m)Vrl#K,XXlmGmalm3I-)4jA)GK2&LZBBMe-i`(0m``(Y` +3`hL`(-1S(!@EcfQMS2"[%!@+JKJ!!$!$384$8J-!9V!293XX+3!UEA1rPhGC9d4 +F9L)LSK84dG5-FF`B4prhhAh*mm[)6-e-3FiY'!(#JQDQclZl!L+HcG3D-kGa(-G +Tc*V'-DHJF4bRc$br'XFm0jil*613!b1NjAkH"9`mGp0mrqqk[Zqlc[0Ge`8E()% +%34!%3C!!5)TN4#[@eGApC[e6qRP(X2J9D-%cB)l$R)ET#X0K3Q%Z`h5#kAZ`cA- +UTXP0#%&4j-RGTh+cJdGENZSd3rU&)H2ceE[UC#-32Blr8LfQAbHedcc5,+-fHKP +r6ce!(bI0dBUN22SJk90YY24EBdbdQFp8CaJPdBra2kL2d(G*Ll4X+Cf@*#h3(TH +@'Sp'Cr(&DLP06hT$HeVkXr&8G"Pr6CeLH+-2mUPU!8e,QUfCT-('kHJAk[JpkVr +TlU5"@U9dKSBNhDrG+6eJr$2k,"qN(U@DT,Xde!2M423aEP9$M2,S2r'KkQed4e+ +`GPaUS*5NKl8pdN2'mp(lq("eK(%UqMPqVhU5(N`DUHfAjKSjdA[j0qTZ'TBd5UZ +AFQPqdN,YN!!dccJFEH'4DLFM2$UUMMqM*Y1rNMTV1k4QkT2dGffcp%FM+$U"hkj +Q8,qN[fV[5(mcmU-cq8pUIf0Mp1[mGfS6r5@TVpBSlD+H56rAIT4H0Gk1[X"lUjm +E0k0[m#r9EqNh5GfeLp)RKMXkP[pAh8,r5(TI5j-LU%I5KeU-p)1a+EU9pe*6kA, +5VAZdck3"aPI4+rNjYCZa)RS9Id,pRTj-kU)YPeifYN9ra2qMlU4RNcTSfk@Ye$l +T&He0UD2a9[4UhP800Bj%Eq$AeE9d*5P-@b1YSkY*Pl3[T'['ep(VHC[U)QI5H8f +A%ShlSZ0i['ShP'J(YeP8bDBPFFdLfG$d-*6q"XNdMJl3ih5#EP#G85IAMDXl82G +ihBNk-RYU#r-#4FDBiQAbk(%(9([aM0'kYYUXDa*-Y$Q1)qiDTf[2"h5YY&MADQ' +bB"k"'3fN#4d,1XI"9!)cBic,2RT'VFYZm$bA2F"(ZqbbX!FiN!$MK29`,#&`KHa +8-"m3GTb`BpMH'E@kjS&NSe#h&1VD1&RAC)qZQBXP)rS1[Xcbam5936&"%@P"#CB +r5[D[h,'@j[J0ENY$mTiA,,IClcb*i$aZ861L,!RRQM)YArdBi`jk*fDrC80QmUR +pPND,@fXYYcahH)[Y9*4JDQ[+M2NajK5b[1HBX,!0lZH@j@A6X[XbJLbCm4Be0XE +GP+RmVd#GfXRjM4Xh,3Ehk0a3,BE&Bc%NZiI38d4dD"kb'-aD2+V0)klk#Kl0BqM +FSeSmm3B*V%I9$!rN#dl)`4#-U,(N`3$'bEKd)('Gf--04m9b#[H`(@)aK4XZYK6 +63,&"QU&L&Hjaf$e-)'F+SQH(Y+TP111U2ZCi-De@5cr2HKiAT#Ck1(*a6PcKA(@ +L6bEAG3XhN8"DZ#S'A"L`f'&9ER)P-JBbF6@qJY("ZDY#!$FT0S&@ZF@PQEL5@,( +Gj0#!#Q8XBVGkRUeJ8Zdi9fb#448V1%,CNK"[8EL&i9a1*J4VUebS40AU*E)"Q&e +f[iDiYKr'Y2I,8(LKa@`TG0R0K@3a5ebi'YC40B&4m@mh8b(b8NZK$6dJHD&$l0, +&4ZaA,B@5CLj8R4"K*VEGALKk+Jl&(V-L@$NNJ8-4NL6Nc'+NfJUVK%YLQELUG5[ +%J!AlH,9k9Ia-#U)QeQ%@)P@KQRp&95M)#aA'C6(Er*U"9+,`,CS`5KXM%$j4D6! +#$bJ#169'8M"`c48[cMQ$-"3@5#[SCl"5GQ#$HYi[3*clqk*-eAJQ&b+ZD&3KJFC +,2B)9P1YqGVEE+Bl(kqAdEqCDaDTfSGeeLe'PVG"8Y9NU#V0#'lpmP,D"e!ZMfK9 +4#8"QJb4&%aM*,$$UY8,SJ`'"Ja5cBM-,&K!,1CdUFVYE%M[aQd)f`'ibA&a4R%b +m`K@(jKFReP(X$1PITdfTN!$2eP%dl)iAZi$c-`U8(E*9XE+LR'I,X(a@KGcV99Z +CqJ`Gb[B,"k,DmFVJJ$)@Lb6kU$fX5j*UYm"@$%#0kqMJM3%@98`bZH,p3p31`5E +Ca%!*K3aLaQ@4Q#c&,U&Q5"+h-+X)XBlcM+F+,jD!$LDK$4CcqKGK'#C$Bkc`N!" ++K9#A6HaA8$0YB"9ic[5SdXP4XCSMY!+$K#Ck,&6S)A1K2X"-SJ2J,r4B-,#)JI# +JSX3+2BT0X)UU"cEe#MYQ@q&BlGLLfV&&D)Q"!h8KP-N4mKcBlV!*Q3"PXb$D*E% +5-i`ICAAH,diiG-BLT!NC&HSSU*8H&+q(M4A)ZFr*4LiR3cRX3JqE%)S+UmC$Q)P +-%R05(RK#MdPLRY!%1!%Ki1SPNdF0%`IN!Gi$GqGK'`6&25UM)3i8*q03Vl-G`TJ +80![ZFl+4R`NCKq"5r"'&j4&Pi(#b(8,8HE%m`H9L#a2[hqk!DN`R4kKI%DTL5!5 +Df&&mKBV)S0M+m2&q6N@XJma&2RbU3,XIlb6hpe9q-JjrMbDD[LXjU0@0E`L(kE$ +230rPMQ[+#0U3!0NDkrl+(4%8pBjka@G%"GUXU`kEi&(4lqbi0!'li'L[m&,%[Jj +M9LpdSRe`aUcT3&p!Ic&-X+jprdQ"9Y-!JjHSQZ1UYLS&R5-`UB,"bdHUfSif'$F +--UX9r@2F#CEbd+!UPD('HdFGeeSN#8UmYpjK[,FFR4d`Q9MRV$TJjA`P+[Rec4( +jXCN*kj[3m-`-LP!6Ul[JE1qiT#BhZQ-c0eHKKDcE)DXI1Yh&`(K[*XEak-q'QDY +VbaHTIhPVY5[+(395Z)-LI)Na+8V3`Q(-m4CSFh,%`*Kc'[*U--D,j*ceN!"h8GA +H#PB6hqU4'T'r15,)%R0ViQ,BeMQ0f'D(kBDYkDUf09TpBZZ4mGTm%H[f+FJ@3qc +k`(&V)R`iQ3(4NHJ-%J2MBm+i4i(fX4NQ5pHqLPDe0k(RQfF,R%-M@B(%Cq4[ENV +H'@5*d2)C+8(rMiq#Iah-9PhEeNGeEXpN[)NC3CQEhBf#fCl2#,cHq(JVq#2!ki6 +T#[i)9GZHUGS1Xbh1(9%*1k-X'IEmj-2k4*!!URe5S2KiNH1k,d"m2"a,$%3(Y*i +00lkMUqT-6TZSmS*hYUA!1EZ5REIPalThjMI[M)M+h"c%4"QcMi%P$T*@`f6S@[* +L0A&lCP@"$G$6JM,G4f-cBjSfCq)p+#-rFr-a#*lY0'Ch0N)XMSQPiDSD%418fC4 +FpAA2%K-+kMJU"VIb)jK89e0-Dj3lZC%"jZa)BhB)0*P9S%dVK#Nb3U"3b#kBF*K +')k4eBNYT#YkMAJQ+#%V`"DQ@i$9YQf1LB$HYd@&-DdA(,JE'Y+XBSl*1k`E6h`M +"Yiq3!-X&jd1kMQhG5f,GP`6+D52'!T66DKc'&%q"0U9%$)`T19JEheqQl)H4M*! +![PLl*dad`6-K[4lXDE0-k*GDTQ5+ZpU*63NeTR$QRUBJ29-5d%&kTL!p-haG%i6 +lZ+BTrCPVfJK!hEJ9TVRJ9NLNN!$i8URM8ee9UdiY-kB@X9@RCQ(9%HM!(d`pES3 +%Yebe4LV3KTEi9jekh,rU6*KH-0eKEXFjkZ938m'c3bILEeSQHfTlBfSIKc%9"6A +e*jMHaP#X-r4i`B#KdSY`'&1('e1$XIqe!Qdka%f[0BC#VD'!ZU(K"GH'4VCFEIT +qBrTaBfLM-E6ekSB[aPI'55[Vp2#@PA9kUm1B$MLHEKF$BcV+C6TmqA58br6qaY$ +3kUUEf*3IXh0(9%`3DR&c9&0'E)3J,Y[r,MU,B%ETfZXG9'Gq#GYa2L-r13TI$XU +Gc9(*3@l"E6AHm1VAmUp1N!$B0qU00miD3fFE3`%'3b-92N,K+a3HV2"I+2`r#Rp +@i6mTI,r#rkV`pa5H`l"pm2URm"+&recKcbMFV["BK6r-Z,pAH,2#0bSmAZ'E&,j +Bi8iQX4X,cl$a,SAr3q'9M%p@q%,4"ZB&6#MD+bk&fe6aZZPJCeN+(mc%JIYeK4p +JHdibe&-+IaYY#i82`IXKNhZ"V6&2iIFU[)dG*#TmVF,rV[$j#YqLm"#&pf3Yr"& +X(-h5XdF4Vh1lQFCHK8HbPDBTr+,#ma4qAH(I-N(YQ)T*#Rp"iAp6q('Q5U2#(e& +iQX*r92J*KAqRm&mbe"QQ(&C0VPU[PJfZ-%@aq3Q&[k,`2b[mNX+A+RbJ`[r&G'T +MT,q0kI3K8kK!i88XY3T,*`UMRF,2+I`YKFpN5dT-J`5&Im)+)&[K(44Z9IK1K3F +8IP6K+U2)G)Ah9hKAPQ#8jH1-lReCfUBS[*2#"l$MHjQZS2k$M$V[+[`KPSD(f4U +(@*V6&EjAiDX8[N6KD2*mV2!E#[p'iEhCBX2CraQQ5J-M$4+cR8(-1NE@U`TIc8S +,LpeLHQ$Y9kY!C!1Mi)mXNAFceLm8[P,K,c2@,BckqaMK`$TEi4d9rM98Cm86$PN +-HQ*C1FeK6"BQHK8VM`F8AUr`ja8HT[![@3)J`UE`X`SIT03p49b+YR3+Mc4G6Te +pZPIVB(2SNCN0I4Y65VUZRR'mjkjJMp29,ZIfK,QPACC22rZ*He"YfrTCqrYPM-a +kHG[LSpd[eK6DPAGc1qqBlcfhFNTPMiL"H@&V2YMAIq2`l2CE&jAh[K!5L)qEA0q +RH94CYa@[RANrE8M4eA9c6[f815+p`rBPackr@@Fe0$ATm$04m`TZI6EYK4mfh62 +QqSEIl[P,dm12GAcV$lIpr-FlLXrV[pllak"[RRlbqcIqqGrB"jCGqrUpNhppjm& +(rr24dYrrjYZlC*[M&iIqPEc`i)#[T[ll`jLl4epCqqRc[h[pS8GHHI1l2lhkpY" +aLIIpF[II0`plkSP9Illc(e[Z2h$TLiqIqe[q[BmrZh2"L5p[Q+iT6HkAD"3[5TK +iMVN)cQJ4I0QL-$%`&RA$',jX83HB(XE3`DUfH3GFYq4BkIKhTDm2SJNFdU,)X@5 +-LdC!jT!!JX6[mTJ3,2TGZV&S"&i&N!![I&G@d8&fZ@J11XJZ[cYLI)GXE'L`UNA +8`a6"C!XRKe`'ff[-"HGV6"Aje(FAMHrX4SePdN`*1H(PQY4*@LeGmb0!UDrc%i) +bD'Y342iA%3P"%@`Xa(hJQ,5G%jmrRQ'4`rKZ2MSeBQ!X0Q1-I'Ua#5E(U-(9P4S +dZQY%[KbTDXdheF[0amBZm0SN#LaZ0KDR1Bc&kp'r#40Qe&bH41MjjQ-6DEj-4&S +lBr&dSfCQYB4VN!$JIhPJE6A"-mKB@QM8$(jL`TF+RhH1TIA'8M6NPjDK$pSZG4P +hd9VIPj+P#FE5611Ze)QejFj9*$mZ+XEp+l3FPrDE5%(i'q0,*d-C3-V5q@*J,!9 +d,Hf#rT!!!Qe*RR&A432c,YE!4+F4VEh@Pp$XUicm,Eq#CNZfM9@c*5Lj*5Le*HI +%`&M5!@-AqReJHKYhlDV3M&GS&PT`+D6ekkKNRjE(a&i6PJaXfI4B81J`&Z39A&Y +3kYYN%3I'!J[18!X@R+dB'`Z13!N3DJ&D33XbM,['[e+%9M9-a&kRXH#FFGG-Khr +pEX$ME3-&,#V`dH6'U)Mp&RCd53afZL1LQY`al-"bV%TRAhQ,+b5GUj!!P"rcXk4 +J&ejT&Z$Y*p)L"XM)d%Gq@@XXk)mZ8K4j40FZEK-G,bj@D2CcJN0hIP[VUh6qLe2 +D[iEC[iECL(5MLf++l+eVErF5(5m29ThfLda#ajEdf1)A@#(qR+riLV0UUM`jRJ! +[DTZI$22`jMd[VTS-meB+-N5LT6K[+``q&,a0SZ-R3i,J!"PDk*VrUqKD63baNYQ +BealG+6"SPPjB,MTqBUaM3VVk9r![X#1fq@G6HRl!Q&qZDpq1,0#Xm1P@3+)9,Xd +DUQVj+%iVkUX99F++qQT&YE$LeFfk#brY[Ac,Y4QqrX8Y9qi`jU-1cNFacZqZDcr +L2F)DAE%ZR+!9cY"+2ZX1KX&,NcA5[kje"T2qbS6TI('Nj!XPBb&5Ha0["9D3!05 ++E-%+9DaipE2L$FN+i,EL#jF9PG5+R-S+GfVYLQ8Phq+V5Zf,,,k&520#T(RKqc$ +[iR)V[J&CJmAUAQlf)KqmDh$9dPlHi18@,aHkG29f-&@rQe5mQ9K`Y6-j)bJUJJj +2i)JXKqeMHjfa(&BQj[LI"I@D-MGEN[2a658L0YQG(e&ZbE3FXl`6Y@YR601&S+T +2*j1ZdZ*V4rA5ilr*-(4&(C[dG@PZc`VhFb[Cr@0V8"@aM[RIkX)BYXT9c8dajJB +ck*mlbf(-R9kJI32d0k@kTPP96H[QjALIPEcm#%EV[6`9XG$,9k[DM4)[$mG9MeP +HhRLIE4mjD,GaU2!d,SHG0$HFhQ[1k96*Fm`jiC95VTNE0flB*l,kU!6(f")akU, +$G`X$F&(BSpa-fe'A(FBS!-iSrjI'6M[[%cNaD*D-R$mjc9e48IbK+G0GjC!!fLS +BUP8BB3bMm5)R&fM$-"L'lfHffMIpHlU165B9m'%1rejM'$i3$%16CGK'Q(KGLmH +VIh`#6,DURCm,mck-(DC%G6T6Q1$E*e'k'YiRZJK@!)!23cdG0NMAl2dVp'[r%YY +9Aa8(1B`8I,j)J@00fD&VSC9HhYA,1kPDBJh-(*Mf-!S-h1qScidkVQV1$Pi12q9 +FlZ@A95hcUUVCKX$-8FrE-[pR`(Xq,8M8#%YjPqVk)B6iq5aq[[[%Ze`THfph1E3 +mrTR4Hlqi"&ZJpGlrK9'AiZ@$iCU0Kbmk0#p1AkdiIEA&k5`(,T9qCR5[11hZHcS +mkdCUR9%SHiS$imaMmNEA,LXkB#V`(LapZZbTNXHb(mPk02eabq(F3cPlkhFhl0R +hr2k6Tjilr8,P[mrqmmbGafmVrp24haml)8AY5%i)DYlFf,6apBah-[0E0dA%Z'2 +6YZckmF+EfclD[M0ml!a[ArcfjSf`@@hAVRCVrfaLk2@`+qKIZRcVh)!Z6hClSQ[ +(pUqmr*m1chCkT[1rE[pMRlrhr8[rhrAlkqGIp[UKaiHIr2IpIr6mHHpAZrrQmbq +MNplp4EYI6rlPc0pq%(VP&F[(LE1R6CNkrBhArQbC8EISZm9,Pbb)R$GriGcVPa0 +[A6VAjFN"6h3Fh2AP$[pjB-Mp`AH%$+fjbeT(re-DU)V$TFIGGf6$QVAV[elh4HT +R+lpDr[f+9D[IZRZVR`KMjGM+L-!eZmej2RlBTpr`@HJr2#TPq)-2MA51Z1IHmqm +0((4hI%XDr25hPM6ik@mq02KdeRZ@1H0Tm!GI'R`cDPM+`m-I'[RJL(X(hc2`lN% +YD$$*Vl$kClb)RlKf0Y'I91I[RCl)Vb9[*jmIIj%rA`(K2Mr*jeFRdGKr9EZ0#54 +,[r+[C@Tm%5$"K-UD*q'AaR)dAU0*0r'a#*L3!%bGUkJe-ET9r&aeSXaPP'3a"6$ +GbdaM+)p'8bdYSb*-rM*4!Hlf1)LlbCkQ-RU+5ZJabUC(+)XHTA4-$E23BFUP3j4 +$HkQHGP-$lD&pp$cYTj1iZq)j&2F,Q*IlEpa(p%rFQhBR(DIEU*cqK,R%[kGMQ&L +'JSUL(C4-#44%cE5C'UQ*0Y,VP%([8#EPidDl644"-H5Q@%UM,E5,IU3,p#CYSip +S1qe%UIqr#(LE,Y+hG"2cfX+SVSfZd9AU4ZhT@8UN8,S1l"AbSbr4CET&jfJ!GD% +R`I3%GD@1B(f&AUEr8!GXk8628'Ik&pe1Ik3qp(IU5hqKr[3lkNGrTFrT5qT&2e! +2qT!!2U(rd[[d$qT*2kIHp#TeTpm`KQM-[U*hk4I8MRj0NqQA0*0q5ap!MbYBj@2 +mCY-dQN*6D6Up3Dr4RfN'IS[S1eT-5fN*,D")QNIcD5(0KHDANB*Ed2SFdhF!p1e +)Jk(cbp$e2r3!$D(l+CMZS"!D5M9d&eQT6[Qr$`)UCPFib%8kaG&pG)3fd"TD5q[ +TDeT(Ae!UI8BVk5YD6Yr6#PT&UqNYfYS#"2jI")`(!GadTC'GE15Nma42`qK6qJE +B@H4(2dbM+)@'di2d%)d%d`LkKqi&khXdN!!'dGhBmP)Jm"2pl59"3$"%8ph%31" +6k2!HcF&[3K$i!hi6"i&[S1d`k2X`0"Ek2JKpl`8)h!0YliDq%`8"-YEa1e6EZ1" +e#1BD%I+@Xm"&'*h$`JFLe'D`d%i%8a`,&d3iQ#h#Bi0&b(D+N!"Z3V#NDfa3b3, +EN!!Hcm*N&L*CQ#[#idGBB-H2pfGK&JXM4,#8XU#`X*S&U`L(el$3KB83%A)6@)K +QBBN)Hc0&U1mM`Zim&Xk)d'!@i83R%D5c)U61&Z%VY[QV35)X6fGK*3XA@HM&`L) +4[LpLJ@hq[T'&8"BqBB'*@,9BK$IEXm!5pZER)QaMUQ`VCf%l#a%LI-4)q4%MbRC +'qZf-I0YCiVGhCU'(#1'-+1(e,,!##fH*$qr0!L0a1&-dbXA#C4&fG'@"UCA-$T, +$@ALCKCpBB#4)CN`**KCB)K2BKL#@l#"'QU!j,$"eJaMS01mASA'q#%fR@@$EQPJ +"0$(P0M,5EmaLJ6&YC%`EEl,!LR2MG"%bMV13!-S#8c5$J9F'BmTJK(kR@B6mSb` +`)-[hSaKSj[GNB3S,$'KDbeKJK'YPS0$+PQrGbJ)VUYDq,,$0VBb8V3aB0c%5Eh+ +c`&6Ca!LhLB(&*PDdQiD,%-'+,B+"G33VYJJ'bM%Xf6%-A')B1@)BqG`"&KKCh3b +XhDbbZ9NPG,-%ZrZa`%MM6Q'"9GTB4Y"B#`X-8'*CBQ)C5-@b5KA,LMD@U4Ml'JY +XFaSVi,3'&KLjdhD`X)Z&Fbb`5T,'b*('UQAD%"'f-+@hX+4ZB8RG`JTT5cF@'1' +fX'6[%X[`A4EKD5blQ&IB*D4UZhV*9&XS8hqBGS@b89SS&bk(F4I+mNfB$p")leX +S&`GJ+J[P-8F,j6`-PUdTP)[k&-SP(3VP3pX+jGdif0d$CN5Kh(!-"J)DZK6+HmT +K`,!(`Tp2J!(bqGYKHX,-K*N"Ne)SlbFX'T!!jF*)@3kFNZ@50&RH(5h,crHAjIh +6CIP%Q#bV4E+XC-LbhPQ@liZ$FF[b%C-XE`$$"QaFkiAT)F[VXf"@`Lb@jDq"r,U +E,(m"3DPjX[cCIKJ)HqZb,)H2N!$PU(3B#)VU,XXl,XTbFUSX"jA"()%")UK0PTX +9@Gi-38diD%9RNe@@)k"N4$2-6l)Fdai'bQlT#J2P,R5!Q5c,@HFmmZPiMr`RPdI +qIEP(2S(1LAiHfEAG)qZA2I)UJX%"e4E,P&dXbfkBGX@bTcr-L')j8!V6$qDeBYQ +m&HB#6)pLHFcXBVPf9,&Fe!&Q5,&F8&JX(ja4,$pGAbbAK"I,f9f+j8H1`d"J9Pk +aR+l!c)3CAL`rAJ*cZ9JqI!EQ)J`fjKE"P--%&mZ(X0#K(6"Bl&"RQ0l&FNiPc'U +B0TJq-"#@!`AhjX*)-0L`&iGl&aI,pFYKGX&!mISj-21,jGe3D$F@DNJTP[G%&-X +RNE#6f($bI4JXHSTJ&KA,cd'4jb$mG"N-"*q'JLqFJZPC,&Gf,jE23[&rKKE,Cm+ ++j6ZKi2%'Q%q+jG[--%MBEIYKS%5j#3BEbJFAbdHELq86dF@bj)+j#405,#Y)T() +9"X4fl)0C"i10VJ!-L1L#F&Fmc,PL1Dke@,i[V9Jq!Z@1c#f@0r3YPYGd+jEAjX# +!`'ZK`(S8f"G30K@&Q!VKRk8@bmXKr(XXrRel'""K"3jA`9"C3+C+3$V"p!c)JEL +!2#iY)*X"rHC@Q*U!2'BMc2b!R,F2*J1Q"da)3"i0aY'I"q6D!-a0Q-N"H9NYc%U +Bf3'j#-)2!(%!3N`3CKS4N!!,jJCNlfX"qH#DJ2a8DN$1kKq3!"pY#mMT8`+b"8) +1lB"*#FJ0f3(jq9+B)3(jj0'!I!UG&`B(j%S`h@N+b#S8G4b$Q4Q3!&hVB5"!,iI +T$$-b)-HY$U!b`Q$$NFL![!%E0[3,b'Yk"q6e5&!U%*rp"$-p)'q&iPZY!IR0&3% +ji8a!EXk$f3l6*i!R!+!"+k`8ZV"d(4A9dlMp,Mi1FeY`m3Dc3(NY2U+SfXUYQ,4 +CH&4-aqIMa'a0V6A5&4UCGCEbFQKF'4J,[2B8ESVMDlb*+A6BR%2,LP4E+CP2+4S +hm"8'AlVlmMa-J-iVL,mrP-+20j!!a5YGcbX$*eP-p+JLC%3bCY@@fCi1Z[KTAi` +iRmQ"6[!QcN3MEKX9Pf0fXepQ+'41J,-*R)A(VkHRkXP8UFD[Sj`eG,K-MGp+clX +T[F`aXA6kNp*Gf1NFAlARVXF(T8UI8D(Afk%l45ehd91BlCP0UjST0imH,4-cFmq +8d"i6i6Sr*11bkG#q%-FdY[FM3ec'%1QSCI5lDAIaJ`l0b2ADfrRJX1jLAaBA$fQ +*+[$G`,4YkdGe[,p@4L9HHMTEG@VPP&k#9LQP(e&Y@C6HV$V,+*hhpLGY09XfAI3 +-S@AE(F&iHK&[Sc+mmlK8*rq!LNkTcL`U`Z39cFpNZb0Bl1dNp1RL$HY%G58jP'H +LFFHU#KiRqlaK+A4[54`l5IFj@HpY5b&,56DCLr$'9Be2&aZL8V1TV)J1QY4EH96 +NT5`629p+Hdei`@T4m,hm@rbGV3)XUU$KTZJ8H$Y%rXr,j0Z4Nj5*`2Q8#@0T85B +9(1-hq*3*$kNZNa*@*L@X6,*CQC5L6$ViPNPKGCPF%@@br@CeN8aQ4C)YLX64XNJ +k#hAL[@'GrcFXNMB8LEQ4DV0TA#lZAKfrfm`Q80@#@KH90R`eiTeAd1rj+#S[8JF +FTrVP9&P%KrP9bQkJJcPd1*@jSm'LRVT%0DfTU+B31%5ehF#NH0cqeY9VRcdH9H! +l&)Ve&*lT!fpEcjqT8kh3+FUFpV-8VrfCA,8LALmTQi$+f9kH-P&mQ#J6h(YF411 +m2S99qC)Ri58*Nj`dM[hN-Nl1(U'XE#S`%HlE1e6UUUiB$,6YAYXX%[jcY2#IJQc +G[2DjS1LNq,#j0+aN0H@9d,JLRe@D[GG6U-kCK8Y&J@2#Jd$ib)*E0B0TGle#hM) +kN!!V0Ke!DIU#mPcKAjGJYPfU0h3Z`0RH$8qXmaIci"HjIDPGE)GHN3hE+@p0GH) +MKF+G[D'4C-QUT`"h9XK9VdIJ-DeCZEii,@+%BLrabHBL4VLZ@ZSVb@YkUE8Ape" +iZG$F8U4GS%"*96hYL+TX`FHI1l2TG$EYbDCFI%M+TP,F-DQ`&6"AjE*Lld[M"fd +qJeDI`A+I`A'I39De)0eC*&&a5CAA$XALKdXh8R&f93lX4efF%'9UV%E9&*`A+#h +A`L@Y+&ZeZ@K-YVm8FD&9*&PdD`UZ-cC[*J@b(9S&8VXM@$QrMfV09+a@+4@1@d! +U"MM'$A5iB8B3eqmY0`hAVjIJNfbYEdfS&Hf(+(bc+XkVcXT[)5XrR*j,bdV*Qd9 +jafPC&R1lmiA5)H+eQ&$'4kSa@XBRU'1Q#85AqUXHm#CII!NkZ''S4)ShCrNHl2I +A22M90"Uh`kH&d`C"LVhH*b8VYmECXkS45,KP3S5VSh(f'*APdU-P`VhZ+D@$Z94 +83JI09+Ek#`2N*3DZrNe$8hd!E6`1d$CY-LBGYZ$meD@IRP6kDErd-bfPRhD&@8V +3M'Y"Q`Cr"M)TrZFT0-`ChN#9CMTC3YrLJ@aQDXLL*LmeH1R34H5#G)MhT6YVkG! +15X@SK"TUk@3Y9GBkQ+ZBa939h8r%Ga6@l5QqSV$Zh!*E$6('f3@fSB-C-VV!&Q, +jPECdIp',1,'PfZhp5SbqajG`A'GbLEEe'$k,LQSCm3F*aIhql4Vmfm6)LCT`U'L +V6jd@pDj15pp(KlcUCIL4Xh5JPNS9HUb%5RPA4N,V+,pJG1H,Ve,NVje9GAHqkQb +Flp0QINij!V$"EAh33'dl6ERTp(3ZQ8VSDA19QRirYlJDN!$'3`lJC6EQdPUpZ#A +l8[d&HLbRfNRLFBV9M-6FT"qJlLTa9HhVjSZ@#SrbJG,jdA`*QD[c,("qM0Re4MY +4&50,MP,HDTmFM4eMKV@Jdl!5KBU2Jdi9f!K44mmMDcD0pdE`3,LM[UV'iZ@Pa%9 +jhJNN`T'[%F[0+j%SErQNTk%XFmfU&,QRcfNFMk[f,K0c1["bHEli21C$6P9R0+* +e%cH"6h(&4jAbP1VFC)MIkjEaAY@iB*%Uh$qAjZ0V3QC)KGV@rG,(EK2PQfMM'8T +G36q@8@S4rGe%UHYTVCILmNLYTD-QZY0,P59dXKle6e6+SlAL)+k@eYC5kMjkiaJ +&9G,'@XU[*EFIDYX"Z[U+G[0LmG9Bp2S$&5akD3$jF0'l!&5Sk*d6Aj0&Vi2iP%` +JiDcYH(mk*4bZ''9L9-j'ZPBB,hS#40m9Aj0CYhq9b%caqCR"Ejm#Cdd[RlVfreG +SlIp(S6B),AL4c2%e[5VQ%fRjbBVQhBkEZNkVfPIG9-f,@eUmc6$fqq`YCKk"&E- +K`K`66U08i+p26j!!aCd4LS4EXL5RD+f9q-&fV[m9`6PhE2-lI*Db(-BYm-VeNU) +*@UeH2hLA6S![m9j,%E[(Dk8G60@ecp#qqLUJDJFaAqBJCKBG2&H4U,B@h'USlmC +c1ZS#kX0mE'JrDA+GmdJd+Dja,mZV@bCmRcqIQT3HYq"2cQC6YSQ+cP""#BdZ3F[ +0)6KQ-6Eal5'cDL5UGlVAQ6)f3V98(l5UQ1deiB&UXTAQXUVUaDbF,UT@L[P#id* +elG3Z9F[+`"4r6%1FrV@fZZaVE99I9A[d+'D,TqMDCNcGbFd"%+jqLp(`i'b9dH6 +J*qKmiSF9EhX",cSU*Hi6aT8F%CDRXl#5KBXXp'*KN3MI&l&`PS9'"1hl8"eJbVU +BEQPDS@SVqU[LlP9Ye@)G0i*LX%pe[V@DikjCfeXpH*6$q9B`MbT8R&Z2F!0hdQk +0&Y(fjPQFfGqmL1F*[0PHf2lFK8Y!N!"XIc-%r@ejBT&Yj6UZriMPYr9KBEJ)(f@ +,`iq1BE&59IXS3p81@&Al4a#KII5ZE[pS0J4q0"I25GLZD!F!%pZcGI[f5NM&I4[ +BZ4hcRA#MSRCJXQVIIJl-fcYMkrBH3)@VYTdjB(,Z61@4D)MZl)jY1fH*E6X(krE +`HR#',pHGi3Nmh+0SiEf"R)bR*S3[iZ%""4H8a!-DSLa!49d@+#dU4,I[U)@8(4B +KCBG,aj8QePf-pFT9Hh)C0%MHKbh*,LlZDdm1eqh*D3)E*Zc,`[iNE$6%*#m@"%J +`#4%*Ch8Y`38aZDS@9+4V3HNUlLM5JZESpL#NhKj8!ffEXh4lmhjXE6l'Rh2BQQp +L#TLY1B@IF0Jflq#((3a`PXe!)q#U%0Si@GFD3E*Ph99l8aB%0*h@Y5DX8VX$ECU +EJUHT$e#pJBS$cb$`E$6VpSeG41pfp+BM+4YVZ+9@XEhH3@ai(I*'0k#eEG+G'H% +FMpc3-Tbk280XbEKG4l0FX,e6UY[I13VF1r"MSe(r-cIU@LB!0QqiDXqFJC0-3(8 +HjUAPSb'5Km,+2kVEmq0`NVm0[@E4Zk$EmPNkmRX#0dAJ4U&R"69D3@HYY9khYlV +%F+Z`Q3*R"kk[k2A8F5e,N!"h%`2k6H8mh'(IP)#c6@lG[ZPPdHZ&hZHL"dAbiX3 +P,E&F4*'1#eTL9d5D!*k)cU)NR4'IX`+0Q)rM%H)J*SXGa"aR"c(EG'G-)bDI+2B +B!B!a!+BBJ+icCUkS2(Ch!&KhZQjh!h5GlM9qE!E!fQd44eedTlZI`'VZkH"+%FK +Jh4jV"RZXKE(M[L'A29BN0MC#S12pD!&1XCm,c'Yq6$!fTjPdHeU$k"e(E`GidRD +*S90hTXd5DQTT3h6l&U(9&QLej3L!DNZi52q@-"eAYPLhYqlF-TRMPRjYb`Jam4D +Z#p$j)qB-MX-605iX"deYEa-,[85iZ%f%EfX&mEi9hJHIaP3Y-&pmY86RA6'[9"G +ICaBkY"ZieF1$)`kI8aJXTTVU0UdEPadf6&c'9[Xkh@E[,d6CK%#l6C5[$EA"0J3 +p*fVYq4)H$Yh1fh9E[("bQ0USfd)V46HdbpI1aml`1T!!-rYchID)'Gj*beUMfl) +kmcU(pQJ2A8[(cG1P'e9RlJ`q$hb(YX'j3YZF%Ph,@Bj"Ip@jem-A0LMDlU1kE6H +V,,YlS$Y#e,-'H+Z$CDUp`3eY'Z$A[AJ"ECL-c[ZUI8mjk,eRQl!hKHd%TMhYeR( +-&M9PU$EC$6)jjABm#Xm*m(63EClq`'JHh#pdi(C9+`C&$JKkPHUf3$m"DB(Aq%, +`QP0eTrN#am09R1BHr&#YSSe"VP!%ce1,ZHc,d(`TZUVDLPJe,F*%cL,N*39iF-S +bT1[J$(63Y(JDGa[9hP5eNR!mMJV)dI!9f9d%QE1Rm%-1fb2(aH!40pm0JZAK89E +3C24'6&i3VTDR@cLil1Nc!5hTc(FrAJ+-pMJq3q$"+XNS$NYIA6Ym"VZ@BkD#J!( +Ri4RF+&6XZ88J3biQMqHLYSmqKPN,`8,63eYeqb%"RiFZ##ZUcU(HZLe(P+-YCl8 +SqT`f(1Ad`D)j-aPD9$rlhPbJpdT!lpdKd([Eq'D(YRHaEUYI,K$eZi6mqRkkXhi +1Uk(eJ,Dm0-b+k#*F`@lKK(BM-mk$+fc)j2-FYSB8!+CY6`3+f,CR1&$D2P6UI8j +HPk9Sq`IVYT0Y3[,*pcPDB5H$GGXT"TqR40DU23HAr9`mj*e@EFm*2HfRiD0XTp' +'FQLR,qVDk8'U*8qe[A"+E(U"DIG#6e8EJfbh%M9V$(c3@Fc#(30Ir%r8X$&p91e +-'$VR91h1#qLJe)ihk,EMc,mHRk(EMip%%QicklEEQ"khLEa%+cITY[*3J5M[cK# +$GHe2MGL2#RZd@D#1iP1UHD4U1cCF!2+*E0efiT3Sa"0GGCXN-Ma0DN4A!,a0kLb +1T)'kTU**DZkYfT5YJN@jUYXF,1pb"9LS&fJAfLGQ3,!,MYYe6T5pD`TcL#k4GHP +i")BC8icecp(CT6VM@RPiUH+m,if(ip%G4iT%e)kJ4-`V91H'[M`FCECKN!"Z@b- +FM,B'lCbe)LZhV9h(JPXXZ4DY)60D5H[4CM(M(VS[,ZUf,eJl+*@e+9+KdMK8N!$ +2-,&p('VRmRCSl4aPVCpQ&YS,KrApI+(XLQaq##UXbPl(+m(H4a(IR-FTUXe)iC% +1,XICj*j`)lC!R0Jk6Q300R1K!"Cc+a[8#)+1fBLDLl)E-ephjS@)KT)f1Je2K8- +@'!J6G8ph,P[*Sq"aPXh'TlXb2JaYU!1eI#&3"fTdTfN%3aA-C5M[DlTf%#r$!8c +&,i@(#D"QP@'UF`#IQTp#SSUGUTD0jBUhUXj(2Z!,83'c3!X2j[BrLZGeH1"adkH +JdaP2"`)!HD$G)E5@$U&CjmN"h'F,[pL!CUIFUMVhR@85RNFE6)Cj(LkN%#lL*0a +))5$eP%"Jd[J,!+R+Qq,Y5,AGD4)5lZb!er9ieARE2TBKhZEfamQXfT8MIcGb!Ah +[SRlDITmKr1maZ!!$jA@L4K(IlG3i!"KZ#Ii*cbI!cF&KUXea6&4&ad`4A1Y&GZ' +DSY[dND)EYeUh(@(Zq%JNJ)+eDpIR#X4kY$'qaJfdMDTYAED!QR@iKASP`1)8E[9 +9YG3i"kji&MDlqpEd`qrbM"R5bJUcI-D-'aeVDQS'@81XeS&1je5VGBL`k,mKqX( +cB1mGH+-96$9@Dc"$$Vpa2Y4U23G%I,!e'-L3!2R@mAmK0Cp1F2b0rk5'R8D'##' +,3PJ-XBDdBlfPeBK[&YI82&$$9"J#&$5lIkl6'H*d$UcJ'$LPj4JElUi4SZqTUER +(EVF2U9NSJN!Ym2FBilf,lHa[F-hp6Q[0%2m5JiC#`R"RF!A6hGpZG%,!h68MX(e +`63AkrT(1i*U"6UZ6#AhB+@J98M-Yl*c914F5RIB4M#ah["CkHEJB9b&5r([mDLj +Jqrc,I#Hf$445S2c$!Rd2&!6LrZr%k#&d(kMHZ9$d[UNBcUhS$(TB-%9@,9G"V-& +h,,&H@(l68988+2Ad(ZGlK6hCmBj18Z-!kB+`jk6AAVlRKd[aPbl&5hVmTHjhX,r +h`m,#"Jbp(*Ei4qQG+lIIdr(k`%'IXb#j1mk4GSlXH-r)BF1NV5`NRqrD*5bXmp$ +Jb`1ZA4rBi9EEe@khHRHpF[f6X$#THFS28kC)b6#K$dp"q"f#G#(-kV`Ul84i-K4 +2LYhfGX4GrdIr[EeAJ(00-!2hhrkjJYbIh[$@#1b096Hk*refb'[a(`b+[p%TrMf +%UcHIX(jX[A(9DEha`lHR4PVRhPJ&i,MaSG0kmchl,2YNqc`VLMM*DPeJYFkarYV +qkH@8Fdk8Aejjl%0A*18"bGAc`b&h$lPEq[!h&Cfr*clc5[#JrSPAm9-p9kj,NhX +1NP+P'T62@P&)IadL25X&59ZlR*HZL6,i9PLEAGTLIpC1rVrE*+i@U6Q%fEcaSD( +2KSCfHq,FbqKfAIRA!BRA*BH`kd+Pe&"rq$#d9fM2a1Z[![e@k#H*Rb4+6h`TVIK +"$8M6T#6)'bGPfX+)e00Y9pU%I!!!("&"4%05!`!Zm3p9$@9&%3!aCHj$[fe[PMP +I`XX-qBD3!*1mK$R(6,,KN64(*5jC%ZFbNV&%#GambG4N%mQ50FBdjAT`-6'%D#' +'&LbA3`1PTr(j$#a3Uak"!CE$&5mhmRbXpAJj)K5NL1@fA+rBe(hqIZqlC!Q@FZr +TIIi"'kBRj8%3"%!3!+)"&qIa%Cd1,cjFb&a3L@5%!ElqCp-,,Fl'lKBqfHd02Nk +9r(UUr'*miC%lRHrprB[e%)P$@TXDHABkE&PSF[T8dqPb*"di"TiicB48I+iIR@H +MMh(aBjKB93M2%[YD&%+(lQ-&cHLm3r[`85eq*-32[km0lM(4c5-jJ)*qFMJjq%j +A&cFF*4FN+bM0S%T)T*`ih1X`$PPq&DjiQEGH1a,kli*3!6QT4Qrji*ReU9CZH5F +3@VXh4+j$hAGlHadCeir[$E6j9MU9MAYU,I1j[r[(p,Ia3[H2cqrRfrZFIhCSJe2 +pj*iV)F02!p'F3&2CP"9r999Naq@Ah,dH02HMCYQ"ld&@X1(!hGA1#ZZSdDT`1BY +HNk'`AfQ53F&N'9kYm@UmBN9q[$il%-VP[G[MJLRS1D-%KpVdLHe@LPeKE42$`ib +--J*(r3iiE+'5p6[#0Y9I[f1)UkEMHhba3%cGd+5%fheQ8hlFfrL4(1%*6d)@q'F +HS5N5eE#+@&Njr`a&SHcGTNM[AXpUGB15TLBDXSS9'0I'G'MZjK%K*C8*VIbcNE" +&65"TCG8'NEb,U5E$9M+A"#16QQ!J&8iG*-cmfKZMR0pYHJ-L"DEbZP8CRcIkc1% +HH1Z$b3TU1!DR[&bVQq@!-LFJEV9i0A&jqCGpX8PTq2piiC5HGF@6A6KRpCAlVZ5 +@V5k!QebS$qrS(jX98XIEiZf'j!kkeh+emeNI1X,bH#STp$RrT29DT'8prCjT60m ++jrF#E28jY3eTV"iNX6VVAr#Ce3hU&C2GNr$fKXhDa1R0A%$45`P)keBH'p&FGNc +,DMX5I4TVhH@pe8U8LPrfb8MFYDYl8a&pm-&Pa*`c")Sm0%NmJUmLkN@b,baH'Ui +%2VridNKa@RfT2MQ8h`BRU!TQ`X4E-P2"V,ElV-KU@Sq9Rl&5UM+TT-k@S6&!F'5 +N4jdpmNd1(&G)M5'efZZ)Md8pTS)$5`1K03@pHeIpHVK#66d[Kaa%d$Q(4e!VSKB +eGA9*eD3`8K%9`KA@lGm@&&f+"M$B9ccih)VR&6DSl0b+Uj95LpGSGHEr9GEUA@p +#rhVa-@a2aFDIHYYm9QqRlr"p&e46rF1cmT'LU8K'Y*'@N@3&%JJCA%Bae$+#9-! +AUEBAB6BDS36e!B8fSZ6LD!*@d-9c1DkYd,8$hi3V!$aK*$8F8i1"0QmTp'8T!P2 +pFipm#$)5K#5qYN)j%(RJed-9UYp-L@S1F5A4`")U%-N6j+D68Q"UCI0H8N69Iep +QFjS"190YRQU[96AEEdIH1r,8X-qN,SLhKR[$HbqhFk46eIA9JJ48Uq-b+94RD85 +DCSN"+GP!b!1Lh[Df5HN)3m93fk`X6ibj-(M86am#$k!MP")1KR6$"*HlZ*K5S(6 +%LVe'B4c*"*C!%)K43',m1`0MAp[bI$,)5#B8'X"%R3Q"+Bpheb'Cji54'$$aR[j +iNlUrerbF&JQQmQHG)jNQQmFI"R$bJQefhL3Dr"`ZP'CLqKVTr8C+69S+)rIfeCN +`C#IE6(Hr%Y([*X4"#3a*a*Y-!%VFN!"'3BS&`rrD9qIZ,akL+pr4$h%&L6fH`%m +eA8Se1KYKp'd`#NJNaZ&qKR(C4Y9IJ4cHr4)Qi&hD5GTF$2Gb*$YjX2[(!-C@E'6 +VMRjD6!H-C11@1KbY"DZbiL08V8QeJI98DR$,EeBBYaBLV65iT@k&FF[&P5jFTmI +@q%%D$[EKB2+imi-d1QK`EUPT3)Hpd,EP&AA`Jl66U0!'La&%QC!!%'6i(&+$1hd +chTYj+'`'ZQZf,H%@*+3#[#mD#eYK1)j4@UJfTSr`,!eSlYp!S0TB(dB5Uhk5&-j +RR9M)KF@p*aCbrk0JQ4TXZ@4al4pXZG(bbG11P'"a2Hd`(jR[KcViYBNcMV("PMf +@reJrf0*XHDIZME%+bhr8[6%FA2X%r4eliXk#9@q-CkAmc9fUp5Z%Bq#e!8`VQcY +BKCq4-E[(V&S""Xh'qX%CPYiZVcG4ZJLT,HHI&!JqJeYliek[PG+kf&3j1HMDe6E +%%qH(f$CA8`)4JQ(jeNje*ZVeDF5&%9USfT%C5i"pUD8Ere@Gm9R)E*4@1j24f4T +A8i219QaECVbaflQaq43U0eirHX['pqVr2hY9Li"F5mQl%e+J!d1eT(#qSXpjfhb +6MA9RY5@9brqia-5CNBjK35E3Y`H)V)QEmi+Rl"[A,1cDH1a8"bBjTPZld,+aQDE +4cRNU#P8++)-Ecq3UVJ)),A$ELZaUUl$c@qh4EIUT2phEP#4J3(`EMZMZeVBMh&3 +4*lFB9H69mS&q$'kSLTC8l)DLQ!Dhh)C!QVP@S$'B0&X+jbJBi*!!M6biYG$GRfj +*i5JC`q%Rf#4b&!rV2LQFAQ`E%e+95*ec$4aYAb,Kq5pG''jmraPLdqIFjkBKKJ) +ZSA5IT5*0M24i&dMT4[2L5AC"@ETJP!Ih5mXJ,T``mDPqN!!@`(88Neqk8[GC1!% +h64NZ!aE"CQDDDQN$UIV8I0jGHK1Mdh4)DJk!V$KP+hhFdfmJ9")5,B8k(3Q+3LH +@[aHf*"-Y*a%B8%$EJ+[-3T*I4NAq4qJSYY`@cB%4fDr6NE1$',4%NHiN4c`D,c- +1cieH*0C9`@+cZ,$&+@TfP3q2Fc*8%V"jL0,"Ihb'JD%kANfX#45Rl-l@D"0$5RZ +9km#e$j!!D!!5FR1qc3cjmPe[6rAV*@%Z8TG,M[*'G,N'`q'G8IGldM-QBEi[LZB +EJ85ZVh8A$H%G66``"025JFicf`66%PrD&NNZB'6#a)$iLrVE"A3dQB6i'%#!iq6 +qbD+60l2Y1iLIA9VHmJ)-UNSX31JZZ'-2JX@h99K)CUZ1Q5d4T3pQNFRVrPTA0hV +XB"D%[F82iLUkTlZcG8p"FE+HUN3cM%JH3qM"Tq,eBRTQ-3bck2Fd03CdIi3`()[ +lmE*iT!5UBFScqSB54KCSVpp-%,k!QVaFUP%"8&UdXLJdFrr+K"Yd0Cpk6Ek1J5[ +,IM8C9M3@4f1C*ImKfd6%e*9G4S*R#J"HJC!!LdNr,5SkmrU&Remk%+#P6BFYDBY +Yia")MDfQ,Sq5@LJYl89A1GZ9lDHP5cFYqh!bjL[c2Zl,MclkmdXHBD!QfZ26K&' +KGJjNMR3mrUNkCj9ME5Ep,FTXIZeZKpTjr0*)E&A"fYISEp&Vef6HAI#P)d2"YP# +UDbcF19$MlSp@*bXX0k2VAUiE#Lb!XklMq#@Ym![A8Uj,k3YE+4)ZFGeHQc(@[EK +lFDmYSm5NRYmIimP"jhS`fG5hI%k1(SJS%1"1U'IS&lGX2ZLKcBG+3,K'PGAT4!H +[+10F-N9m&`NZmj!!H"@hf3mK"d,6#4kbmdU%4RebIVp#%jd!dfaadR%8PRBERH& +ZTc0JkQ)SeUI9[$2AadG[F9kG6-9!AR"8'MDR9DUF%+J54*b`c,H"a$NK1TK)6FJ +iM*dA*-Da4@!h(4d`GF6$a8cmbfRJ#(lXppSiL@-frY3`'T@UhU+(5NrJcb,#Y)P +QqhQ4D(r192p#J01T!U85HNEpGZUiD5Je[U%#ql`Sj(%Bj5CR1-1@`P@CBrBY38T +ZUEYD(!$*3TXci-BJLB(4&4Kd"UJ*rER15`Pr!5R6GA*Sc#p[i(*f,DSU*YE*20@ +ZBL'3!+HH'2`l'%4ITDTF@DS5M&afKQRjZK`CB[epQ@'MFrJk9h3)CJA6aNN`%4! +S%d$@cA9I*SJE2Ze#da*-9MQ)45m4CGATiMG1D15Z)*mF9L2@I#cdIC-@ih)qf[J +kSbBCJH%GH-6T9!IkM6cdAKiRF-!Cp@F*C8+E[GQkI@!`0TNi)IJlG"%SB[hh#PM +%f$0Y!&P%ad#3!#J"33*J'FBLQdH@#"hSMr*3Uf(!)@R!jb8$2RH'r4emp(Y&hK" +0P-@fNJ)Y"!`EIjj2Tq63JaYd"dXfe$q4`SCZd0r3hp''AVh5$I9M)mIAjf*6jrc +R0K@L5&HmF%cSh3"bbSm%eeIHPIfpZRTUJcGQ[qApTe*IeA#,LiLlBL-bjT9F,q@ +hJZ%`Aj'IVUL9$IN@&b9hGEV&MQK#1[4'&MY5&4EA#$ZSF``&Ca9N#0ZbM'1UB#A +4h$F#K"ba(&i4idd'K&4+)H3`e$+0(B3+H@q(jj-S,hm9320Gpki2Vhr-6A9XbLc +l,acY`T&0A`3p"4(LrIVeJqrAbk193XCdDP50%8#lYG8#IN*IRG2TUVPeP)k0Ur6 +G406Fe6*MR+31U4VTc9H2m%+HaeqQ!+KUkG"RJf%hRdQEeLL9Xed8j2@P)plD@'R +*RiM)A6UG4bK%X&R+VP8E-JZ$pf`ffG0EdC9$*%RkBC!!`J2pB#rMFaBCVS%D#Q0 +"Nr+#FA-T*j)I$MadLMQIcbdB[H9p9aRLkfDr2HmelHHZ!J@'GlCV+(6[+fFFqP8 +"rlfrAP1U+PaaEmheT4H&2[iL*G98XN!0"GS-,MEG,S!VC3Kd3UT,jNTfi18J!R# +8ZiajR,UDjJYHIMr#6Q4qapIm'h0S8iGX9lJ4,PTqSlU!QYHIkh`F6[KGhJ93PFh +Dfj[KTRc3aJ*Y)[*khLD(iV9-j0[PXpeaMLV'XDP@ir[epqHIip'%G$LqAUD2FL3 +`bY'eHD"3DA&IbKk)S4XC([[U&5%1J6UUT-6"K!TI1Di@aRPd+'8IBXXHr-NV)Ge +"%ej34!K89CGRKmEjUL[&dhJHC3HihMM%(AQIIV1`N!!$6@[c'+T!&@`q'm6[0+L +A![AF,kTRq3p8ch+%$MP,9"1$MA0*$5A!$A-XAhm#aJGG61T)k+TG#U'83%')E6+ +p+T!!L*bA1KAbprd6IJi%dI*@a$G0mRTV&i(lMM5CQ[2Ap1SAjl)#P)89YiQ'5Nj +&V(C+%0f49XX0bdZE+5c2I,Rb%TEhl+@M"pM4LibXhJjX8TNq%kR5XkKNDY2,jfP +`EQ*0!3eIa)Er[imlA&BUV"c(N6XFYC`5&8hVcGb5CVA6%LJC2jLAahdQVab0IGr +13`-Aa+-didh*a(P5I5D)r[-B08a++55D`hRXb[GPGYcbI[0eV[-4"8EEiS$BSC% +%Y2)(h$9@ZfcRPdQeLql8Gm+)!CR9ASBHB61))p&@[KpNP(fAiM!%GZCD5M-ZBXN +L!bQ6)LNX[$)THp2K8%dL+3@RR*V1j4'cU5$ZekcZ,I$X8Xe`bHh1QTNjN!#Zr5h +f25Q-B$Q5-GHU)4D5kSLRY$EApRLVp[aF"e$Y@QrSRLZCl$-Xh&16jSJ+KU14d$f +[EAH%Jc5*ZPfGl@hVfre)4q(i41I-KU+FISrRC&(1c%blqi"l4`C,6*BE6#J%@EQ +l!BN5Z%[*fGja'qGP19!$e@H&!im(bjCp@)4(6061dqmZqh3T$`UQV9a'fM+QQSp +rk)hj!Paqi),k@60FaclE%4k)l0LV4RBiLYEjr*[fVVS`(&%VlmZFp9f-&l@Uf!i +`FRNYXeTiE&,`QD2+8-5D&48#F-qIfhYJcb-IBP+rD3XA2!*3mdR9H[S'*%EN&r$ +!aZ,(eB882%Z`J9ZH42e-U1*Rc9K1ee!GC1"m[6dAU!MhP`$Rpc,1QrBJ4KrGJTZ +j@#$`LjANJR2haa[Ai'0jfY*UK0QehY-*F,CQfD,A)hh@b&*X$XEFIGSP%J)dd#V +AZA"a`F-2RM'JR5-P`E[pZHc*MX)$4GSFC)+Y5![R6NU3!2rUrXGH,$QCRHe**c6 +&KXA#mlRm,4*1(NR3ee!J-B981l`55r[Zh0bLl*c4!c55Q0Qr@LH9CZF8j4l05Fm +e"(iVNTPI3S'mFARmX13BGA!N!TG`a8FJ58K!ZAEF"#HL*iC(@A3!p2@di,+E+l5 +jmIG30BXCGS,eBCLM*jYYU90F-NL,BC*5H%e!fVG`0aq!aCN2AA1MN[i+-H0LRSA +%!TK&XlA9l--M9PbYeE#2RH*(RlLJAD`BdcDbMh&a`,#i`#Gq6%r4U`RNS@RiYma +FZEQ!(IMC94+iL*a5#)3`pDaKk`K,B1`V+Y5$i99"L+d38NNHFj9,&rfcBZ&pZr& +bd'Xf+maQ"4-VQ&LKNa8k8IL$0-pMkAP&2HRYlN+fkbF0@b1PL`K"N4LDcbI8hR% +&bD'R`qBrh-STR$@#0M(!(9NEpdiJX$l2lpZ`i9EH&'!#V@Y[h2pkc9NV9eqrd'Y +ICBE4#Q8mS'ecCFA$H8TK*9YFbaC(X&Ki[FCAKk9GUcVK#)pNc&0C)R!rM`FQpUX +mVl+%VI*QcHXe%(@B8Y5DT[T&pN,'RHU'PhT!U0QG1E)"D,pIcH"##E*rAlUY1eh +EQh2d`-hYZ8H043bZkh[QjkErb*kHR30iV`cR'CVkdS'1556iJ+$)"h#C+E9RCbL +I%TVDbQf1l)3Dq4Xc&Y&U0I+Q3bU-cZ0Uf)*YDV+iGMML'[bd`Ua(,!k,LfhilK5 +F"@T-+UJDk50m-jqilYf5B3Tq'XRC8$,)@R@)Bk6%GZimQV&l*AI,B&Z,4d(%8%` +SRZ`PaC-p2S15e6lPKH--`U1SF16qmkbKiX224kmC,aZ,5!V+G3C&Lf`Z9V4)245 +Y$kpAZ#YB&V`a&!Zp'VS8fKGm+&,2rXBLCV`bI6+jhP6l#+k*K`Y#PTr%1"kVmIF +e5#U%jML2[%V,B02YF$Vk*I,qj8Z6P%CVA5Q$4&r$9,qSG$c5+Nd$*J*M%M)`)4C +*VYUV6KQD0i5N)Ca4%hqCad-"6$X)TVTb(jc6q+a'Bpk,`'L%2*!!q%6-K'[qiM, +PTfYq2jHQ`Z-`(Ad0[IP6rGR(402!3lmCNKN*lISNH'dPP59Amr'5bS5K-P"F@9d +bQ+[#5+4iHPc(qjBND(abGrbUB!$iE!!H"9FQp$DJfJ#1i*SI"X!I1,5HE9eST9X +hp"E%91ZaP$C6[%5`MlD'EFFL'PjUX1dd`YDm&V9Gh,*UhHhBXQTmDR3hBF[S!B5 +EU$PD#QL*P3*0-Z5FhqQ62alLN!$6J+r33p9%P3Z2r#"'!`D8RErX'*+pH@,a94@ +)H(S4$d&FLDPG*JJIm4(9lR8[Za8ZdGMCq8L*3434Vd$-BJ3beY9--eC$-*K$T6X +F5C&6P@)AbmY$hHc#rpa9e8cZb2i4K!*Q+6q1NA6RFB1)TM!4MES0*)aK%-1GF%+ +S6)b"f#@CPSF2LXjN5K)U%%ccTFjaQm1iUGLpkdK+a-`q16Zl9eYdi$R2F`H1'RT +$##IM4B8c*r82*#,fd+1aj1U%m&!ff#qTkX2ef+MYc+'pL#T'9TXF%+4%ec&9RGe +2*-&T$VQfV%G[NDhM'-,R@AGMrAB8SZCK@cM6Dm,@9q0DHqMJK5N8$p,30fp+bSc +&F$&6#K*Ra5qP$6!mKRYPCQChGP%KVT!!8c6*THkFa'Rc2,k2bqCjL$(hpTdf'(C +cHREFY0ZSAFPqj*8)8mb`qm33Hb6K)K,564pK(FSL'2dYh(,jCYl&"Ec-2)D(3FZ +JIN!IG3K0$5LI0#6F"0,,5VEL-BN)bp(XbBbL(598IbcFq'%EYCSD,#6m0IdE*R3 +FCS&-B3I!G3DSBK1lS+peCb$dLDJ,8Dm,MQDN&h4R$)p+dKmU&VNchCN`!e[j"$e +k5J0DhaY(#Ne2++apd@Eda4X&'dmBTe'3!100[ECi'$qKD2AKZ65pf08T"LBIaBK +*G$N5R[Ym2Ip!a`$!#EcVFLqh3(R-PcZj1bVJdef9U-%PI!)+mF1)b3!"HA%2)bB +EKDPi!S4-iXI+e'8e6FR-4S"hk5Z0aaSGNbimN!$TXb39``)*A6dMbF--K!aK`cd +dT-VP0&8Zah9,b!fEP)X(6Kq"3$laMd8miG[+,@HA%-,J"B5"X0SP+cc!5'P91`R +XCp(!`)'&(LM3VFCMc44mJ`SBjY9d+%f2#pd0*20EY%!bLE`QGlqKf@N3H4Nb5AL +@HeAdi[bCFYjMq6ZH91'@[q[S%F%[!-j*[MqCcRZi$Dm"hSAA&,IJ&HAQj1Fde@A +KMCQC(1)NU8Sb3BM(M+F'T$,6+6@N(aIE,dGc$X`Rp1eLJMB'3$'"IMaHKPH-dRe +-TCmIk-IQFi3KP5%prq+`VDmCDPf8$G8i3$biBF*NK"kfpi6b"$JKPd'!r"5ZepK +![kI94+!i!MF02VbIS$R`@kVSDiKZ8Nf'j[eV-c2C2`)ma)E`2"DB)6AIL9QcD)c +Q&4XMFGKN"N&40"$5!*!!IBb1DiMT8C%VBfYBi"eE1F-DBRK8j%K$lUC8P!RUUpR +(c'5j[TR8p)8cI3BcHAGT-pQENJbYCP1aQ3c25+'![aHhDQETdFQCSaNCk3GQC[l +[C-jNZhJ0GZ9CY26iC-jm!kU8AN+),LhC[G)PUR'2YDq",8&Mb[KFpY'FSUXXf5N +YUGZYCqm-DcKc@MKEY#m"-EL!Pm"M#bdY@M,LIEXAcmcN&X@I1`RZ-r'-p+9(-fE +5Pbi"%bkP(G'3!+L&Qd80*(PBlHKZ3(LE6#PGPV$E(EE,CGcY@@qp)"rQGNq)IH` +82r)m6DUp58(3S"[T8835&3m%'cbZ4Bd%jTKl+BjrH)(3-A*+Y2ab36`QTQTh+jS +9(hR@bDhm*FrYH6cDT%Cb%j*`T'Qe&&MHZFDKEEl'i3[LkE+A2+[8$MAI-!8EY%Y +kQ65H%TBqXr9#Y-9D)j+F`&!L("@0&04S,el+VT*!j8jT!CEZ,$jQbpdXl@[e0'i +l(0mF98b4iLY+,((`9m13!$mBd)ATf``&Y"r0,4)4(ZLTh8QKXJMV3L!'K6+'jJl +d)h"fc"$qC8!l0Q$313DRHBYqN!#P@,QebU*[Ue4m@UALNU'#a!Xp4QqA",%iR@- +Xq%6"Mia3`C*&3HTk0G'53aD5@-aL&ahVTlIaX&r%9C!!1qHZ%X+e%EMejC`jGfp +mfm'@&"5l'-R`@CC3Z[Lk%hG3`&bS'ih4JIl5!ErId&'`9,#VP`HVKVZb"L3%$B6 +@P-'e&-DrEP&p(8"P[lI$LiTCq3G#hJMqT3A#,T*)!22h@UN,8q)#a!i9J6f4rCb +&L,4lj)I5rM(hXTf(dD'UU)bK8M$PCjp,qDX%ETD)PjK@!k2DD+)3bA$Bh2&A&+c +Cj5BVh2%DK%1DTc,Y0fJ2Uhpjme-diXa6&lCYiH%$JQmK$bH*V!8X44*SjDBd4TE +'91&*31a@4lSS&2!XrP@'f[PNUB"&3mJ!%B#`!D@3!$GU6!%HM#m&bJEM8bL%iUe +!f8D!0C5NU4EL-BlP0`cFBH-4Gcm@4$b%hL&2#X'hL3#1"frQB9k'CUHDV%#S3TN +P"afN,'h5$8qL1`dA"SP!45J91TQ3!))Kb@@)KFH!CJJ+1"MUAX)EfDH'[ET9%`P +bd[E#+(aMhYVKHk*Z021G3hA[P)m@2V([GlE4QVURF4CcIh$)mmlS[Z2GfirE2N6 +0a'-IAE69M#CX,9QMYcjI1rVNRqlpF0@IrhEAQBXA,ajkrml4ZjFpHZbl6FmmRVr +mpcDlEH1KZMffU`mYYc8FUV0e003mrGd[0lFmGEcKMCpHf3S!!%GU384$8J-!HZ! +393eN9J%3-6AZ4IqrEFia9aNbl'+XrM+@C4'IGk'*YF6JQ#,,X'UQTBCbB+@`@D+ +b3caH$ap[ZS%mEi$Q8-**kEQjr4+DNkT8*Fpl+&p,FJc3K&)1ek3d!8S6bL%TTB4 +b#5@'LR[rrRkr2Dq'p2Cl2mrrpr-!'kfR+#H#)!L!3$62PiT(G6Uma18Y6JE3(lq +!c&@ba"F4B%P@2Ke-'%BJ+T@Naj+5rlqMq&3P29#fDHEeQ3qPY0,qNRh55@Qrc1a +4'&Pk8a@8-AA-X$QiA9If354Kq(VkdANK5G-9XdTDU'Md'Ej!($mK+$0--bq!"5D +$`f*@"V6J!K$+pCcj5a4@CSpd5*k-NmKiMTU'!T'F1U('SXbL9kmqH8+%6'HKY1Q +9LN9FXJImN@)J#G8)d!NfIkG)lKLEbX1N6#-L[$VQ6q`h*Rir2@!eq3-1$'LAVSM +3r')4ZKj+l!mfhe'N24RX@1!Vh),'-41'$GLI56GF&I(XbQIR59dZ,'&CVbcVX9a +%bhSA,SC)b$@%TRT9"I1bAS3`B82Y#GhLCp)G(5mA-8QIhC(U!P29irUakmG+FfP +3aePLG'4fThcBS03952*aB0QFXMAaJI24e,RfUr&&d#'eqj!!8+ecKIU6b53cTfd +X0+PHD'SVAGV#5TI*$&(Q6@E!B[#TN5jmI[)%@-Q9Kl#TAJ5Q,9F-PGP5%Q!aj%a +D3e&%Z#SVXihe)ae-F#A41Pe$0Y)iVqK1QThSdQZSM`0*,29Kd&iDY0Pb8*Q9+GU +DaR0$)MRi(e,A%qE+$&SFQV#S0H8'J*,!K[1$P@!"MNfH$'aU'1+*#C&U[iZh@&Y +j#+,,@4-Z%0!he9EbYRT+d[P#@-`1(*J!HVhrpm("BVXj1#JE'Ie06+L5G%c2Gq% +Lc1"e"J(`'SR0UFE"jM3,FDUS4eKZKCQr#&jkA"$&($1,lFaqE6qJeE`8LQGr$@a +X%ril4)Y))*mb+PbQZKqBBSq1#+-'dIfa1N46L!l%*%4E%IeLV!h4)85cBhC%NiL +Qad)M3*!!PKGcJiS$5!)-MUdJP#P30f*0&9DD%[["J1X$DV0+3r0I[4j+Q3jYmbb +3!"GM@jNPRrTIK#D5lS&D@@e)L"qU[fBDG$B0HQ2%#[+EP#'Mrf1Em-FF19G&Fd` +rVeJNBrk8b@Lh11!"U5%3Gar51S'Kc9PpZI%4#"(#MpH3!%Kq$aPrX*EfCql0h!Z +KTddc,VC,kjqEUL[6V!pI%@e!hIkaFD(ld-a4V5qarcY&KlCKSR`T[DY&1Ab4*HS +,ETem0*,*ELT@pB'fTMT9hh4&I6qlm[P`5Q5Q"ra2pUPk0$C6Br1,'T[41%503bp +U(*,UC""a#$X"5U`P9DHH#PLE2-l*%APbMhV+I89G'LB3-dVSJ9,5%'P'83d9j1V +F0S%#FLJ@0k%KN!"%iCeQ+$,'TA'G,[pjT`)#3-M&1l1kX6P$JFML5(p%Q*&i-fb +6r+cb"3[1ENa+,fXrFMNb6TY13pMd4&I1mF@f4N+lFL9r4Li#9V2dFXP(VT[bCfa +jd$20*i8`RCUiUr`C@ajaUN$5,%N,`(%BkMfI%X2YV2f+k"+Kc(3`elpM&*k,M!) +j)$k@"dji*lm%&"i1)2c(S1Srq%X4kY['#*DAY,iCMFNVSPdN!NP4$)k+810YUqd +H)38FH$d&9@pq[XH1p31GQ'#f6AJU%-IVi4Kh!dbTm5#,#+Y6+VEDN[5)pTL9PUi +)P4EM[%L(5$b)#q6QT!"LP3chSF$)#CpPiXqr6d4CB*%(pNfF1X`XY2"jCH+`Hk) +C%c9A4)*9-UYdM"T@RT@E*$3j9Pmb3dACaJ[#4`Y',-5$CQqa'NqZaXAL`54rJ#5 +U2$NSf4ENb3kDc+45mHRRcbI[%aG929jMDM0H0p3K[!E80V`be4Bi9X69GL$EIm6 +#8I88AL9U0Pj'9I[BIC!!DmlKeD11ia96Mq*eA6AMC9,(-+PA(F8VT6EL9DGHa'! +G+U[1HbMCVPi+JqPFV,VSmck$f@@fI9D$lHcm+,4&'hpRm&j9$I64a&'M%+9d-6l +)43IeUKIP#bM(M8&%5"R-KU,(c(6"L'V'8Tfbj-*5MGUcQlI5#q*VS%I8l6DVKc& +89XKS+JiC!fCm(!pGjmf&#KbV3d+hDVFj9%d(Y!GDL24*$&%B+M6'GqH*8+J3R`@ +Kqi,"r0`RcD&KQ@K!#0N"Jied-I88*i`mR(T1'Dj954`Hm$le,r+!kPr`q5[e'4i +`[cKdr8QcH[c*(XmP$$2X'F%VkUPR9D!083`UB[P3RS#bqNqZ+YhdaPSZUZA!9SC +XU'Ka19j"306GHh#&E[2-m"JMR,M'Ba6*9Y1CQ&8Ze[pFh-K&HMbi%!eqL-*PZK` +%@rf'+Y%-XISGkVaQ6-4%HaA%kQd!mehbX,@(G5ZBZ4NAZZ@[X"Tl#B[KZ-V'#-4 +[b3rKIIRmNlIdNZGQ,X5RjANU$rC*#)HXd-f"Xm1+b2kAYiUSY2rJGK'Y5rlM[P6 +(4K5Gq'R'%-YRRcb-$TRl-[H0V4iZ-rAK#MAS0NIDElrjhrJAL)m!ME5(69G%4b! +j0Ti2YjKf2B'1(k+V&6m1r0Ma`mh2'd9m+iVQYS!,#,)0`96$`G3kMcq"2+TdLjS +%JVJ'S[`9%Eq8RqpY%N%0-QKkr$4$F8#)f,S,`6RkbRh)bXpch8G)3E)09XfIra1 +$c8DcK!cX2"k8V[PRA,0AlJBfbU,K1$N)r-Nk5rJ")Ke!P[H*T"V(+`k8LCF)!H$ +d&*LEe4DmKLLSYe&3Ed&3(pDp3i$8+Ic13NN@@m$bR4SBV`9`k9i,kZE2%Y'BhSN +NM@&dI)f3!%'+N!""(B&dShSZmmMa)m(QMElC2Z090%5T18A0+1"fFf!V`DY@I@B +hGF#V5Ih,hkkU*EVA!f%jXB20qAXPFpmfeBMNDY5p2U14*Vb*ccUej&*c[RGp%6@ +pQHp0QA(B2K1!2*Bba@04$4bq$%AcF`[$R+%Qm!`aH(C![3Q3!),+831h"hED@Ci +2"Xed%i*'5AUJQCHPT$3!"Xld'BhmQ6+XRlTaRc*i&)0h"[hcI!FQ$HbIja`B!GK +$L(*28)hDjd"dhReFP5JE,1eq2kRL-dUI8Iid1U5"V#12C@++()Q@((XQ9qUi#3" +!m%kBVUV4!&M9QMT9bLp@%eL-[)*&hAaDM1*$dP8KNiN*GrT5"cGkdG#SQiqP4Ph +9RElelmlHKdQGZN(Ud)NJ9KcYZ&DPHbGem%hI,3DQ45KNPraqKDkifS!X)i%HT[K +SS-'E6&TXIrdAT)B(-4#433)C@Nfj`j1)i(R0533'N!!L!!K23&"IlKKkZ3J"V#f +$(DpQdfXE[d)hM#+dGk)3j"#a*$VK@U&KCj((5@V2"G%Z(QLCG+MCH5K)DEpCT9[ +a)h3'mPLN@kiNJ&dDk0ZUddRq'BdC4e)$*UX6$AMmf-l8@!X9Le$C"KabiA,T)VR +2,$I'J`Q1-*UC4m%-U'Z4-6kb(THE1JTa!d%la-8pf"1,1'JlVXh$*aINcQ!DQPQ +["Y0N`3&L3eMC,)VdJ1)8!V%S9#pfpkJeb)6[MCVkIUSfXX-1rkH!B+A&Smj&ZV4 +3YECV#l8AJ5X4-Z)9SH+T*P6!`5TdPB09k$iZe%,9H$dF+JcAKDkLLa9Ldm@qED& +,,"E2D%4'1r4#b5#f-rN*k&ZCq%%r%m@G"1SlR!4'268XiNB3I*[RE*!!"KE&,cM +`64TBXJdX64SiTJ`X64TB`X$D&`dETf&[d+$0YN'E*`dkT!cDr1*"#HQ(J3J@"9L +`EU0%Y@IR0,qMX-C+(i4l&*&rM-5"+0!$b1DjP,qA#hFUePZPZY#`XfJf0PY18Bm +c1SQ`JbT!1PB!6DXDX`+9pC,M$BSIrRLjL)%#52Ic&S&LE$SAfBDVDK`Lir4q),@ +Q"N3rKk$IaTPU"VS9ThJSA,)YCXeTe(dHD0k0+@S[&qd1L-iFF)6Z9T`8R$S`L+G +$A'lRi,#l"pPH()#-Fk0Z1SDb`fd0'HGBXUNp1qIqY**dZ3KALZeKABi5p(Sd(J[ +@hfCQ1R!fGU)B!@B$&I%JeR$J(!X%NZRJpY!PS0X9M-*$KB&Q"5N-I4dC"@-ESiU +JJ%Ke&8R%$L2,q8-qhNPB"2(Pc'5a*HTj%2jiS-4jJ'Td(U$qjB818%[F"kJPcJ2 +8id#`fXN(6#""Mb8"R+`*RBZ&,$#kb$'$ABkJN!#f0MD+m)J1l*UkTSjqIe-m1fI +CPT4"DN"#)4-TCeMllZ6XDR3$CeF[3NN19UA`S%!6c5mATFbi1'p!r`e'Pb'JNMP +`4LCK*M32V2*,"fA&bq9J%"GqQkji9ZV)2i22[@Jm*i0mk%K3rAe4,)m"#6pcl)d +35@i'`SKS%(%JmK3L583HeYf%J"I-2mBJL'%fm`Hc9['c&3[[5Ehc"m@Tfhi-p"i +)rUD"IcM$-kbl"QH)$bfc0SK!4GY`'KX10h8dkH@&jFNa3GNFUb,QfT[dc(jHQM- +QMUHr+&!,GE-,'@ZJTrIqq)9[VX-Jcb"S*X"!D@Hb3LcY("-)NXm3q$0$T48&lcC +E%E`$aDH%b)D[TrIld6dVZh*jQUC,,NkaT5-!r#2-(%dCQ&%eeT@9(M-M5"bjGB1 +lJ$@PiP+*r$2-m&YH20B9LbT$(@PDMD8GBeh1L4L+Kbm'ZlB[&U-LfK8i6i@Sbr+ +Sb%mk+V,@Sk`[H"5fMZhjN!!JQIJC`)m"2ceJSfLNrFcBVFh3CB**fB!1Fm'J0)" +Tf#B08&1@EJ"0GU@TK`MEb"(G!(i-q-PN-MITZjLj3##miPi#i!L+e2dckjJ"LF( +UL1a@8[r[`iF%m3d+,1N)#Z3'QRT"QAS"T*%3*&U"A(`F')"SpA,`)%3@CXD&*@U +4@@@X9-$eV-aSEDS6ejfX#hK#CJ%PQLNMFjN!5iVCZBQA9[4NTPXb[SMK`'J+V$& +QGJ"&f-4q"$'S-p6)5"#[k)L'"pKke#5BK8PS25Q,R(Ij)J"4b@m*T!%$,kK`mib +0%8UIL-CeI'hZ,Z,p!Uc&GL3Th$[e1`a&GrPi`mDNh'`aH",#`C!!,0l*JPf*pdl +IA9j&L'+NF"3rfIJa'Lp0ZXk"B1)Z(frJPfr6"V489!d3`Vh+)[0G2Z245CdD5di +DkbBYYJ3P6,91@[B(Qqrb54j,YLbcL#k1Uf25biQ(K%1MCK`NYPTBMXB@AA!*ad5 +'%XK[0rUe(fRh@YF%NQ&(`2qD2l$-i6$iKN)'lc@c4Sfif93GlNj!U`kjBmDaJ$f +-cPCdRKF+E+A1DjbGkj`XTKRXC$ZLqhTkjccpqA!A2-AK#!l81)-U*F$0L*!!qdC +%(m$bR'"bK[''##6l1akq4fmde[@c!)!#$%NfBr#*,[qDHr6R%3JYPK%dp)-YBee +b)i1Zd`9A9q6-H"2LPE2HdlJlf'h$ZQQ-L)kbBJ$,4Y%acpC8K+E5Sf$8GhaL@I5 +3!'"H,,M3+Z2-Y"qCD9CH54l+2PITLT!!J@l8&GdmbF8D,VJm1qIZ8XlB4!abeLC +QPjRa4lY`S!'&qA6G#VQ3!$[+fD)aqm+-Pl1H3S&a-c9`@E9rjG,!,rj6k0(8DXY +D0M-6lNR+6%,)p,-53+h$6b0q,J,%KK4PN!$$f"*X3p@!*,hX4MXk1CbI*'B0+9P +V2`ImM[0F*,#+3jqC1J&(liAMAHc-c`NQCi$6(Kd6F[,Cqh3kC01%ZP2Z)*eik`Z +ad'8ikhA2CJIhM0[P!Djb3309D&MKm5N3M4!cR@J`dR@VA-TiV!$"V&A+H$)6&4i ++X*P`8$m2f5%X&3Lpk!`kj[QUEb!6fDS`jZ-(DQb-q36q0q0r'c,,c@"(KN5VN5- +GL-6P"GH2JCU!k,B2J8ACHMcG'(CG"D2PUZ")'hkXq'Q&BU%66ZcIIH&Q4+*33M( +U5'6RE+YZ'[rLrY[r*Qq40iKLT!iE6$Qh*hAK`+L8!4%[`5K%4'FdmK'LMRQ2VUX +U9aSCGehkIliaJ8`*$#)*VMLPZSFD!+$KRaA-X3J2JZiTr#5)d,mUljX`"+2c(J` +K@3k"VJRZbPdq+rqhkJPGfVJ!Q$!jaC00(3%rN[-Iqq2GXb(UI$Ne31bIk`!AKk( +`A6Z$c0IZ0CQr!GC%@&afj2NCI)bYQJlYSEBI#J%QVUD3!&QjhlUPZ,"2&9!4*VP +5#"$5"R`JciDKQ#9Ma@!&*R0Q1J$rdE%ViJ!bG!FL9m4j0"l!NGIjZ0!lr"PmAfE +A3)"H!BEjG5cNJPPcRCJe#*T1CNeSke%ZLU)3ARBZ3-G!mLKP"08YYS#N49BXJi* +5&J@Pii*CVb8))YFjL(al`,$Gk%`36PBP+&lNi)L-BFBP4j%AE$`M+VABXGRc((c +i"m6HM'S8BEQK+'eL3m!HUK0r&5ScEibGdN$Q%AF!NGN6#$3$*EcF'@aqX&MBk6! +*QG"aKAf48#)T911cPrL3!1eTT+)X!H'k%CmAk60&"9Z##lDr1iGK0R@MdMd#&`Q +)3`2MS`5#@5I[X$`XH3F'`mp&BT&Q"*J0h-U!$k9AI2IlQS5f6`CqVXV`TUp`k`e +mD!q0G@MkT15%DcGV$U@5[#J2#+@8rAVm+,0%%UM@*#1V&NC@*(ci@GdL*l2+VV* +YPTQR(INPk6)D9i5dDBU3!!Cf#P5f8)&VcS"9p5HhH&0fbLRHM'`L)5!,b,-A2kj +[X%*p(--K5"U'bdjaF3'4X!kAJ#"%!T!!,!MCdAc18K"kqT)X#%e8q4PqDfI('kT +idAIrZpAX-$YUP6SbMN&"`ma(I`)k&8Fi'RV,'r*5*C!!KeZ%i9dTY--R9`Tj(Dl +[FSGBrQMZ`$d1M89"TcNU9rTVKMURj4qQj`P6ESc9h8*GMNf`b2-HEq&'&j3[V#" +r$ddc3*LK3()H52acSHDQ8)&Qm(rpZ"G&9T&Qr)2+lrE#VDQ)P3h5q+h2*!Q9Q+C +r8"RG5`VYXd&(%C-q6aSI+Cc3H$5S8Y1B0(lT&i@@63PR98!8Np0[hSclG$S"I'8 +rKZU9iPBmjf4e+0A4j*%G*ELJ[0%PkE1JH$-G#S4fRT6df*+k`&HpbE5(QD+YF+@ +)Q9*qCaGfV!MSRHVZL9d3PGa6j5NB@LQ3!'qJ3"B,6I&!-f@5TJ&m1JIrPG`T(L) +QqQ&h"PcS8IaV`F$3`(eSqEb6erh)NLVXM4Y3(6Be0-RLb3S8QXRC3&JBBJNM501 +KQ"r*-RA#3C*bd)9rQ'jdS$-$q"!bBjZTbL1bU@ZI$LB`-S$)9#0a&@"r6`Cf63G +8$dkf`%DR3a#baZcbjIMQZMpqiDMRJF-2p&e@Xh2Zb3,`SHJfp3fh)Z[,i#"#+$L +cFljUKXJh&0eENSi#32mhVHi"aj!!`L,4KaYe$i6miQI'PXQ1!f%`XRL5eDGT0a3 +"c$EQqlL#4b1FdHrq9ddIZbZLF"QLUQKPAFJmI[9F#`F@[DN$bP*rM+Ye0R!'3VF +i1fI6h*5K**dAR)N+S(eEXXIdc"VCp18)0pXR0"Xa8"X',feU3'8!1"Bmc99(NAQ +PbU!3eYL&U5R1U)3ZX3[1bK`iYXZGi%3`%aNaU"jd@q(3JJZ*,I9`rY"ji4jN!"R +ZZ5`J,ZkJcMXJKLiK9Y!p3%CfCJ@a#m%mbP,%T-YU23Kl+``(c"e5Vd0M&[1(Q0M +D2GUHHAf&I-J13P`lX*N`Q$iGJ9Lp51a(jEdPk+Ja$F85'V$2'B&HmdRU`@e#K8J +4QY&S,40&q2&Tql*k))aM`!8p`rQ8I1FeIC%N-p5rj*-6%&Q#6!SB2G,qU)NC6Q$ +2-8TPFEi0+N8jf91fMSC*(I95Vp)46Jc)4#DC(IHP!NiBI+"SrY*a1&rNI(AA"(B +81D+"&H0i@hachCMrMeqJJMF033%9jMBp`*93)C!!TjPkKP[VRB#AbB#hFDS&i"e +PC0RLF(3SS'G(9)LIFCE1f$NCq(LCTh%R1)`L+HUBJE*9kVLE+KNKSji@B1"Bj[S +a+ZiK!lMa!A4+Br"M)02d-!%f'YB#G!Xd24*PIk,lCc51)*&-2EI-R$Je)X2(#95 +R[ZQV6L(V@456l#6QaF*)-&D*Ue,mjV%-+-4G,4NpfMj+X,jjIF0&$,Tb"CEe@pB +#bLkSrC5!X2ie9[[aJX@%D"XfmI+8`*KpZ"d9JJ+0"-,fINBJB#JmIId'"kcQ@"X +)V51Lc0AjAXRMbA!D*(+!%A!beMUjSmP-(9%Pc*K*4$2*9CbC3%d0&N'RADRH,!F +HG(jfGPeAS"@$pP*b1irefSjpHj5"Qj2l!$UACZGXf$J*h%a3qTMBq4!!Gj3!98q +!HT1UF(,AL+BR4D#kiFZ61YXTL8b5Ki%9B)A+4B`S0XaPiXU!Zf'q'h!hI-+!qk8 +DMGp5()$,(&8kZba3K"DVlbZ&k"!*(bMF(c#0%[--bPNrd-U5e&AeIB",-j+p3f4 +GPjGhBDQ1TiZG2!JbILe`)NNqD9$IPj0`Y%XC)1HbQUI#+B@G6$3TCKB8T1U%dAK +!*M5*'*l*!XB[KdCP4NX[#bDBF*8'F-KALfQi!`68,$"J2JDVS('T89BN3X4'"MA +YRIbUT9qjbfIULF8A&)19Z""4#8FG9bi5KJ"mh03"d69-QpL%`0L-BNJ[iD#C&b$ +H[Xp%XeZiZh@1bSj"R"e-+0P(&%eAK+[TLZKTDQ$aPM2TR(@%3((DPR'FcJ9jLbh +Vq(,k`3)%DppJ&`e6-3S")0CSlp'C!j%2@L)'YbQ"&jJq-2-*E-H+JY1"UZ2AX)( ++jdFI-A!L@'CUh-jkZSA1*,I-r0lS)X(2"E,dJ2Nf,M`@eeq!)Q!Qh1NrIH@UF1Q ++JG6Qeei92ETT%!)@"PI1-,UcaDFSJm6E8bV'@e`kG3*J`S8YX6j4p0XDQfU,PR6 +2)P#eSN&1PNJV*b!bkpf9FMBFQDJiEmM)frVQa%YCA%Jr`pMI`9Zf6h"2*)BH*fq +qbBc!`fU`hP6YP1T)lC6J&Hf8kLY3Nd`*bU)&%%11Z'Jb(`G)A1P$Bmq8)%aY&%k +TKV,Y4M#%V,8H$APSm,(MJidT[kc*`d-S8aebp3-@hGI%`2aB"PG09PH913GEYB* +4#IpJ5JpB+iXA!(%!U&[TJTdQ"2"!fjA#+H96F['URl,h#SDC8Sl$kph9ZX'`iST +SV$iHb2c)BCdITQV8mEIqG(Ya8)fFF,-eQ3MZ#ki+)LX!NMLQ5l96bYqkKPIp@m9 +#C[HLB98QX6@*()j2q9SfYZBf'Sb&0$BYX*RC--4S9*@P-MN5QSr)0[R$X`c*Xid +,#$K@SBT[X'0'BcrF`j3ZAqB!lMk!Um)bk`h"c+T-+@#RF$Rl33ZcP8-',!ij8Sr ++U)G`%)CV-6SF3r0rU"'FDCr+BNJICFP48-irGRZAaH&4KrpiZV[+Uqaq&dB'$'$ +JBe@rB"FX2a6GUU4qd-Q#Gi!9A804Nkc)j&IIFR+qY-XGCM3Dk[dF'*RPR'392ec +Rp)b'RqKKT(9PIf8@a0UZ#Bl2M9aT6,!l+9"CUif"#H9B9U#CNS@DRZJmcSkQ@4- +6&Sb$!Mi`XCHM3+9$fC83a,42j381A3#RQ+0rrDpC(d()4R4fcUBdC-d3G9c-'K& +@A-VKcVV*3%[9CT)6Mf%"RBGqILm$CdRkV55K()J[NXQ@I-5'C*!!K$V+2Jjb"2Y +6@C(9pakCbZVpH*hilGlVILfF4U51hqk9XKkm+E0*![A5BHdCM9rE%meDI91%l6h +#($Yq@G3,Z0S8*E)ibjML,12&d4CfeN+LA"apSMamGrGT(bdrrVZp2LpAlS",rF9 +`10HA1Pfb6hZST!H'2"bhhf&'Tj3&0JSc61ce3#m+HfD[K5!hhjQ"N!#dYCQk&AL +"%3%&AVqNVA(Fqr%kAff[EMiU,)hUhUbfDq)`fc(+`UT46arer)(+%P`Cm$8%Xb- +FN!$59J"P,XS6#!!,N!!K+'8",+9P8Y"fIQMEcJmYY[0$fhELf-i2H6YJ!T9+TdZ +UG+@SUV+ST"IAD0BYZ[dD0VC!dXSE8apPG4L,RCRT%5dTJY*53RV8RT5ce15J8ID +i,e`5'C*k*-eiFXGHbkBDGBd[r%cGN!"dL"YGCS0CEPlM+cMA1#3GjQ@hd3BXr`@ +A55["JEL1AjGfHim&-H'1[bV-"58%&hXjl*C%`1TF2Gp3BK!h3YT$KPrcCdP*L4J +2CI8DhZ22JT)#F64dkV$KFrkX,i([8UJ%VR)`'i+&U596XA$16&QY-TJ'%U[R*d[ +#@$`Z,jCD,TkA&aHl&c0GGLJ'#S9Za2@`"-3GAUCFG5k52FcAC*!!Eh5NB#DL,S* +-*%bS5*jHAp(CU'I1XG1qfZGd@qrm8Galap92kKr`5ZheMfmIM,6rpFKHhiD6NKm +6MdApFdjLiUp!M0)lZi8rlYhqqHp2EI*+m8[@RB24H,QG%cKem)jT8J-kR)`fc-Q +P$NRG0(4)aVd*+ILPM9kT)fr9eX'DM[)eGeFGm@hD*m8a24I6cp*dZbiIdqeallY +[E&jaPeIbA0C['kccP,IGAER(Ya%+f9jIY+()'qe31MKdQp$"%IIq1@p9a3D[j"p +jr0l"P2q[qmlklMSfBBX`PUAEMXR@Z2I`QIIUlRKADRMEZQ+`X3&AVrMBpm"*UCd +ffUjX0)aU4pdL(2F1DRTAddCAd8EA+"[ph,E4-p5K99H%$Uealp,HIe"TShVDD*[ +&4XrB0LVTeQ'k&2IqbMGl!fq851iKNTpPNY-frFVdK'i$TLILhRdpceG`!K(4ff@ +LSi*rfAV&N!!!E4J4KIJ4h5jdM-5p1YeIhU)YVk)YVk%YFkGf)Rrl((a3PaVG-R5 +TLAXr1Rl(1laY5S#iNJ"R1!'+f""$Kl*YM@iZ1QMLh[YZVSQZ03(1f",J8Ge86(i +8**VpckrqAENbE384H614JqZR52CH9,*"8YL9T"M9E8((dEMhdhrVqjLf[iUfldb ++GC`8MB)6)f'IFjSkMHYfS00ih2[bDmQReT)F$GLfRFQ,LN5PFHqLcLF28$)m`FR +`5cNCiT4JZ64TFGaEC(lG[2jGbAlT0cMHAVk5MimHr2Xd"B4A+X-YLhY6jmmp4q3 +H)R)h%lNrSQ5&SlI8AT6Vml)630chd`@I&frbJFaf)V09)I0+)Ya+*Kb'h"lhhYA +Nq(FLla0-hPr+j*8"eX0*J@QliYj3McAMlqp++qQ++q8V%NNl#&6YbS!liYi0(pc +V*9)1%5QEPFfXib4M*bpTCG&*ZZ5QZ1qhIrrDe)dqN!$36L5d%JNriQ5LlGL,cY, +8$A(I8lrlVhYCS6Q"M#X*+&FUK0`5pdljA[YGN`P*L--#&@"UIYblq$Xr1--E)N+ +Z9!Lj6`iH&S4F&rFG1QHpIbf%E&!#REcaUA&[pcrpY12rJT!!dq,HXVpqYj36N!# +Zf'",DLFKR3P6&2F'ESA@-b(cKN!F*U4-()p#R,K#aVPahrIV"[B`'H[Y)!k6m5Y +b8(m$8prbbXQX@r)Y&b'p9NCk2rdq0J(AaIrKLmCTbVUipm`r,r*5%ZqQ*'j3L2G +VUH%2[ULITJ%!#rrrAd3jm()aeaJh((BG*X+e4aYHpd8lD"S5BZRGShBLaNSQ4[P +[lTi&FTb422m#mY)N")a2hYR@`m'R[T@[r91P32Lp,pT18cE&[IXIq2qkL9LlL9J +0YQ#a%KIhd$33DY%IpKZC8(bPQRC$VkZA#"@2VRcGHA%!m$[r-MG)"&K*52mh6U4 +[)a+5-2,r[[dHAEZ9Vre6"G(m`8QNVA([YJmH@8*JXj[!TX'*hRr[h$a!DmYI0FH +F*)V'$3GG"qRDRdXVrm9jE34jrpkrG4$b@%QJraXPHH9Vbb6B%2HZhj,r,8)H6#6 +26ip-5YLjFHqpArVQh46FGP0`Dh!APEE%4D$XQT&AbKHRC&Xj+GPN)J%iThhPe'e +#c#X*e(rM"RAI-H95)-,LKk)p4+B@*Y2p0N$hR95)J%6TUp2pNC+ZMC*1EiNZS[E +6#-L[8lAiZ'r@`JXrIJ!"lY)DfX#U#HKL*DEDDHVfZ+rXeCRI)Q643#6El8B@[V0 +ZJYcqbc06L'3Y6,,lEBM#PkZ3!!0*p+rfGGF)6E34QY"ESSPS!`ledk'lS(Vikq, +riqp&52!eP1#Vh'M#GmB0bXGbrre")P`$%@lh@JL(!(CVm1hdRdJi*&4DcEdl*K2 +1L4k)($,K&XGpheAlV%bi[$@%(PDjdB10(!$Tl15D$bL3!$83DYLYS!C,JL#J2Cr +apQN+(#dF11kAN81FVQm,q'rF@2iBJp")'kkr%PHE44[`@f`!)&4hajerB&)3`H) ++`8lbp8%`Ma1XIhRflcpL8P"5qT@N221PQemG&2jl"NAbMN&KKk"C1XP")cNLJUX +JmJpYpmi"keEEKma"d90H[h#dA&T9j(h+pkM3pYRl)+aZU"HA8Am%iVA+$Qc-K,f +dkTV[6ZrG(afkImUkllaVe$2$Pck+T0@lpPjDpDMI-#F9bMapl[3d,`qFd05)ZrI +NqK+RF@M$R5IRq'V8U+C9l2SSi6PqHTT2QH$phCjMek+H8lK5Sc+KA,rPT(Z#`H9 +bmC4-6)NFG!kKY4JL'2jGmE&r$2CI@P@q%PfpdG8rrHMdr"SaajI`APU9m'6K5P& +$p1&Ui@cih8FRVf&k-df(I9CR!b-EENTiH"[4KpICQR")pmPV@FH3!,AV34B4iRc +D,SY-"l&6j!bXD*&C+fTFB4[J3qbeG#&5-Zb2+eNJ9!H5I1i&UK"ddlf!+N%@Rpl +ClSp[Uq-DTH20b9H3!0DiXe51)QQ01p[&Rmi-'MiHGbpr@af8)adq0f1MLeNU8-G +1@CGDRDG'2H9GZlVRR+haE$Tla!XA"2pP0HV(dV%krmCMHla[3rfkI5q#@bX(0qR +aYh+$r8@j"qqI2T!!dYK&X$rUhr(4(0r"qkF1R*hI+U*qed($39ji6eNS$f-`,%b +MK8K(p2(AFhQ!,f$"FS!r64VJFf9"l[jVZAZmTU21rrYMfX2f`j5*LdNG1rG'1mU +l#1Qp+mAa'DF2lm!p5EFcRee5YKaj'5iG[ZL'epIGAQ,"&TXd39T[18&AM`UVa-a +J-h8!SRS`4UEAjUNA$J9dTE9j(mhkVlm53ir!Uk`6TK0+Ic1XHeDSH#d4)Ebq*Ma +iP3NrANY&"ejT)SkA6V52X!1ehKK*l)F6JGeKC@A2@bfZ9JVmb@Urb4VE"SBS'la ++MB"KJB8YF'I-9bi5,3(EUP9KdHJ@X4P$VY*)94X99Kr8IISQ2a5PCdfN(JRSZpJ +)mN@`q1(!S"P+#DMpNeaP(DV)Lh#I#-P!!bC'QYdX'U%QUK20[+J+'-"6*ZMB08m +m"ZA[k&`4`N%K1Q5B"Km&Ha6ZX(Cf*%Z,18beXjD!L6`r!a%d$+,K#63NAI)#M!2 +"@`j94K'"Zf6XR2[!3(C3I""0XA2T%RECD4V21P55KFd[k9iU`F9"Ym6YJT6UXTq +8(Fj6XX0j4YrpXll'UT%RqQBYBAG3B`f1k0+Ph8VBDi9ZeT,VE9TF!3%6Vi2hceU +bTSV9DFBiNkelDK1c3Id'fE9iND'`1+[lqr5+Z,5Z,)@)IPH6Z+JBFb`(Qr48fL, +$F&VCB$Qcm3BrJb++U`Q*q6MLHUF@8DSfa)`JX@DZq'pKDlkpdqRNJ3'@i-ILb-% +2q0@%Dd'Pd+fT,6jP+-VbpD1bIA'*SHJEL!kqLNZ+`9`fHBR)%5Mkc3m@BQ)pP2S +(D*!!'IKiDK"++&c[-lTZ(##c&84P*Zkb`A*8F8kN6M#LP"8ahIXiJ3cel%S+XeM +Y)(*j`Y#%EF&e@LB0-hQhXQ'"lZr,LrfXEUjpicSYXR%jX$,I+'!LG[q)#c!PQ80 +)jRZCj)3!Z8U5J,ZB[[XN@2eGV(JEr%bHaXU%PiX5*e*+B%aEl'6NYp9@r&`Q0Ic +!#bZjZR@%(&RFVZZRS8lpN!!E64(eeB!,%lkZ+&A(j#i``6V#894eUHpENEBB,0[ +KY-@mC#K3&fERr(DU6+kJQXQU@5dhZBH*Y8*4BfILK0Keq[,aG'8kP'HK&,NaJ*J +aKf5#1iK`EY-)-`(IZfDSAmQU!6CXNQIb3FPK0ARBp-$h-Yf$U$Z9aA&@l6$)%,- +C!-09MDPljG1pcZ[+`he05djT+APEkN)q'ZkPM3$%j+5T%CK#FQre(9D*a+CqHi5 +jGckjVMPiD3d#J[TU24[-U#0LU$)aX0"L)hlBJ[Kf*e'0E&rmfbDTf2+65$TQGT0 +dDCdP54p,XaMNTV+ilB9)kJBP0MVcfaCjdk*H*NS6QcT@j5jXE2Qhj`LPYJ8kD6" +-4R@TKF%i6*9ENXCKfjCUZ5h("#-6&NBET%P''c``US'!(Y!m)lZj$KP6LPSQL3' +[!6MEaM$&ZFL'IArl'V'B,Bcq`JM5Z(fMjV#8r+!6CM,1X@+aD6ccXp[PV(lVRTR +U5JdJ+28P-NI8M-1&)&C`&E0B3E)N1i"[paRpMTDALjLT932eTF2$5T8fJ@T2N4H +H1PZd6A010BlC1m5URc4pJqAdT+2MK1#PM-293PGqCD!b+!d!U!rLqZ8F$Ce'Y2k +P20&3QAH&M9AV+YqQKQYS1-e4cpm42F[4$LZLHc$j"j8Imq3'AH90DNLJB5&(ilF +4RFh4pNm4I4q6QbYRmZ69ZXSCe,!!$Cpb02NmSX8FeBmL@N@AH&1ja'[8B%$$2)i +fI)6SA)lDTb0D4*1R+C2IXkab)$RCj+Ua@FX9!KeVhJ)X##eA2&pc-F3ZKEIZY94 +S4NM)6@i(JMI!LDUf-T9GZDM890[G*k[VAB99TiaC-)54-ZAH'NMjZB$8+3@N6RI +&9"@ldPGe&9H5ULkp9&Jj[HUmUl*+#c99E@AF8&M9#lA1-Kk+!m2+(T1!dfrm1e0 +QRaaqVEqfkK3@0E`BB(-SdbFB6)'cE&3aTTa39(L55h*%VFLJVhR,Qr+b%HCSM8$ +@02U3!%#fl*'$8!@Y5Dcq$em#)ZKETk0JR-1PlR4![h121-hB`4MDZ3FZrIl8LFL +*bDBN&''rFDh+UQC@8ke05F9%E!rc*D'NFP`@jB)&ikap2)aVd"r(6qL5L1k2HL9 +9klX!J`q5QX@4T+5HiSKG8NXiiT!!e(-FX8VUFBk%*4J-4D5elkG#b[6D[BbS#ZI +Pm@"VN!#BMjD)I1m@AqJdLbR4ef[%)piDS6f@FiBGbNXqdTkeRk8ZGmV1*!*QGX) +lh*GHaB3P81',*fVmS8L02`i(eVh'4ZeTHGJkC-Ff(!Y4"E`DcB"ikKKqcYC!Q-m +rbdBd1H[fqZ05HmBC1&C1ImMP$ch8iir$[A+Cmb#!3T%E"4%U,a$Rb!$r16MLSCN +qXNdFeI1%+`A#@&A%LG&8LmijiJBA%e"%kib4&*Ci1dd4YCNR)m)+IZQ+ZDSSNb[ +hkcJUHG`SLee88l)KFE[4JFN'L*(2`Q#%$SMm3ll#'lQ"q),+@AZUGhkGLM)f)N, +UA+TUG9IPV)q9D9c"(qMP4rL!8T59X,@981bZDb'h(`GGdH8H4&CqXfN56(,PRma +-*c0@IP6INJHd0ZQ9JS'R5$a`C[T%%ca1-@9%`*AKP1@@fDJ+#H3jZKDC3$"iF0e +G!5hL0-FLX8QAL9h*5-Q-Zma8b1HJHL9A9H-"%R"Y(Z0#e#aL)@hILlZLN!$B-pQ +NdCKFD6$*,Kka1P0KeG5!!`&l+Kr6H2SPFp9lap1a2!e"U,Ei@kLDb5*Hqq!MTXS ++Dm!+Ca'3!")GhT-++kcC0q'J&G*iq[(!!S83*'!+`Bj8`Ylp'kR,l[ZXr(U-c6h +e+`%AfbP(4lm'#qJk40hdG%')TDPK150$arI59FbFBAR1&a[P,!*938BP!jk!406 +$jEiGSR"NmT)VJ'Y1khiEk(!D,Zm)X"-k$U$#8Yk!3pj!8(5CfF8KGF)TcN2eMSX +'8K"(pA!3kk4VF#85')d4H[I!E0UUSX(C$49KC!GVkc2mD!IhjXqCDLXD!Z11fUT +YA-`CI'2#K58L,6Y1,&'%kZ83U,QU6f(9YZlcU*bTYhfHi)G&00N)Q,E&dB9,0e* +'T0&'HSGXrTkhb0eFMeLifVHCDUZQ"fJ!0%l(pZhC0ih06N3U,p!`5@a&Uf3TN`L +-GRU3!-0!qQ%LF*)0qfbr,4[i@ID,IY%p-h'#0p$Y5'PK(L)%0diBL5"(6La$J"S +b&$dD3I@E13Yp#le`mGl,reIXc6qpdiI-jJaf%fXSCT0G%"#dlNrZMNF(1!c[SVX +9hEd,I4'YaSS$8)6`!C1(!e04Lb&R[S6UJ&A6m)T@6Ed#mjm99V`L&3kU11MJl@2 +,U#`6H3!"a1m#B6Jj%0Q@R90RT'e#,'@Rbqi6#JRRA$P4B8HQaQHa1&9aMZF(Z(c +52llp0T*V*LD9ibF2J#)3U@B"8,4hEfZUVE"EGTCkB%Lq@1U$8Ek[%'$"Y3TA'S# +3!2N*VZ@L`C3$-&!3%dleMbrl"6lU-D3(3hUD110e2$[RNHR+%%B-SFF3TpJYerf +S!D"ecYS&%!"EbD8rE(2VYa@MDADEd`NKA'51Rm@cJA)J+iX!6,)!42!!$!,iarN +ekeQH-U(DC,dkB*UR$J4kU$*%R"J-F@)`T,"J9E,f,Ibi*BAYeXL2(*'chFJB02p +(UCSCL#Hd%*cR6N5XXMNk2*UMXU,PGKfZ9B-Jp4aAjj%E,YAQHkqB+eU-cFkPicj +HF$kfT-PM-86Rl3)JSr'[r3XlG$*T"SeYAE&4")%EH#c+C5N6MKmKX(J+4"`!$$G +1'%**U`jcKAa%bkUEi4iIeff[43IGYK%9)LeRTI'JQar!IA$#"6SY(,9N!f`bF@% +Hc1J#1iH,dK[C13pG"M,faI`1Ml&'dpH%`$YV#BSH28GXQA)'T'1FN9$)lcQHlK` +qE3Hl*6S0pDINLK&$9"'cC9)"akj0j$S2&c1ZD"TqdB3@H3*!D5iCB"U6A8L(JM" +a9eZ4B)&UqAbZkSNUZ$#q`PAN191d*S[GQ2eT9#NN3K11XJ%bb`+*-fK1)a42Q#X +5cSaLE1*3HKS+4V0hRiACJBdXf-DSdM*!(U`JVMD),-`[,T@$5"&0&jN*r6+*T"- +'FXbKJDU*%%+Ni3T`NcE8FbEcqDNm,,+qRFk"%6"$5%D)dNp(P8(aq#'UaPVpNVQ +ipmV9d2@+mhJC+miek9d"DVU[AmL'"H5)jk351DBd9#2bK5)BZQVLSXh$&FJpZi* +QAN)3l3c%Vece[&eaMX%#$Y!0#-iTQ1GbS3$Q6GZTmLHZY(`MUMV8&T[QA`d9"'T +SHXVTRUb!aQP-mi&iLlJVR"IM-TJdGI"QfIPhp3&+F+'fd3"iG*P-%$TUE@4SPFQ +`Y%FQJhT1*S1UC6+Sf8`'"KPUI%EHX2SAK3#RP8LZdR!1M`3M83G2ArQHQaLK$DK +BBdQ-baAR!'VcU&UchTP8F'HG3+$I4*'9lV")a,83#JEYIL+K(*XR%JV(ZSJ8)M4 ++JE4&Z@6PmYQFT@C5P0h)B[C''3H"4FY-3RERKCRr6f%FS4J9C+DaHkc6-CC-3c5 +#BE'3!,-$6P-U)D!5h9`JV`Ziq+1)2"PSK,0Z(99aH5F34H(cA##DE!4fR"YS#3f +RkD!1((jV"p54r(V('*FA%E3ZiUF4#AAHa1Dc*%3()JBNhMcm[)EVXi0l#EfB1@6 +&-Cf+@E)fZYa4jA*CcX[9APAEG*[`DY(Yi#akMIJk)h$2A*LMi`GkCHFNf$M0*VN +D4b+-MafCkEaaTr-Y(6!@1)TYC!EUH*Zaa#XpD6YUqp*fJT9d,b15TkkL+)cJ%i- +mp6i,iK"#R-6q4+iH%fM$81d`U0$X"%aXie&0Pf*QS4jXi3JjjNFBKE#jNjZ$F"i +AXS$rTl!Xi-Fb`5L1"%bBIK4*j#)QD3f1q6)UJb,6U)Z3!&Q#rEUMr!'A[`&brSm +S"JSbXEAMf&T0-$,$50-[b!J4,+EDG9q8h6+cFqb2)YMYc8)3ZbYcSPR8,JQSH!K +9e9TKU,)6U*Qc"P(*3iAIXN!5!NUif!`"T,$Bl#UX5,PUL`0"Hp(*Q*dQJ3H!i2V +S5iFV5j`,U$Cd')X*QAfQ[LS,Nq1#+b!jMBSKdC+)C$+$hG5$`JCQ"-"U3@Am0Ul +5E'-(GRR3R*30Q%#B)d-TKXaqCLM99Tah&JSJaK%'(k0TmQ!mT5X#YQ+"qJrrFi0 +4`%cLX5G!!6rSPCPF91@jim#BVFScXYRihmJr,afU5#&Bpr,$VB"!9L(Ek2K4CF9 +jc5%Tb4(M%%eaIM*ESX6LJ6!ER48'f6!`NU"jK*mid[9c2jb4ZlKU%aGCR9XS'Zp +(*BU@)J+J)93,q4$ZTaZeqfc6UV4p9%$M850F3"0,F'0pjfcc$EqQ!qTC-B6!m5D ++Z9[q[q(",c4K"i"S"jMqME#Je1KFe2TiZ@pC8Z$KBc6-M%ClRqHhp0LZ'PjiX*% +H#1Lm9!eG5Sr(Qj36ial"Te-+)ZLl+m!Y06K9c#`'0,*,mD3#1'A1iia(JKfB`H! +YF,*5BBUP+kf!c9qL-JZLFK(4!40!D38`(6'#K#T6N!!Y$+4%J#JB65`e1*(FdUf +@#'lTBLH+K"#3!'68YR44c2C`Vk@rC,3A3j@STEmF%4C6QjA--#!p%"T4rpDhp&@ +)9N01C,9dSI-3[PC61jN3Ma)M9Kr3bfJFaEf@8%Bl6`+CJNLQaV'ZJpJXh'pP4(e +i)U*Qe,l)5%`ZiEFHa'BQ)fd6VKU)dlAM9*hd(5bp'Z$*#eq%4!pE9%AJSH2bd*i +F"AR",-l5-NCH5m[@KVbQ(9H3!&H@#4-$fDkUY#'Jd$C'AQP#39iA*A4Rj#9[,'f +)&fScdb4'B%[,C!5@PUJpR+E"&#%M-(5j`#cL2jFV9iS!&"kqJF*j-UXL*8M-Ij, +"J#UUTaRY6NB-2TG0B-,F1i%*8r!#6*J#Q3R6k('cBA)@mNDC5)YhbPF+IEKfCNc +1J[`c2jNCNl03CXC-CS#N#-#H&a-Q&p"J1I&26)H)e'cNe-bQ"Gh-Q%BR-kBaia# +f98jQQh0DZ%S$&(bk)%#-6F"mI!5"L3-8+`-J'QbfRe'-#"@BpJAB2'cF+HUbdXX +'JJ"-hE4AmS$-*S$KdaYP3UJI-i#L'QNTJa1-f'qU(9jUN!!,jC45+#q`&FUY0pf +&FQZZA#L[&Bb4h)'i')BKMlN[$-!["RC,F(jk9,kLf)VU20&AHTCq8RYikDF-KJL +Ja8%c9heJKXE56b#Qj8&TA9N4#BacJ3rb@@m)9,XpK)S$iI'1jhVKQ*qmTFrX@p" +EZ-3)jY@#3i9,j+Q2el[3NF'6MB09e!6DF03!MXV'K"S-2i"*"j!!5EkHF@J#q&A +,i#I9c[SB*[QU1GRNj-,MGdVG#4RH$N"""E$3m-3%A6l2)N%M*!D+T9B,"a-m8U* +9BHma3iV0#BV05*!!%IaF`UF@%HN%Ub#22)G+R`#*)QEEi('06`bfDET'@299*F& +!fe[h9pa!3Xr!KQi-IZCNDXP+6hlSSPdrST+`kE1BALj2"qMZSD'Z4eJP6kaH0[$ +'PIlYIY%)4DYI2)%12BSkZlD#JP2h[r1$2H(ZX%+hH1C,84mhZ!,GrbkM6KS5,$T +8!U1U2Gde0lUi5)ZJdQF-9CqjSIX90NF2S@UaSUU"Z5YQdXJA&&ZB@3@&'mcfa5i +L`6qY,4bFcYRN`FhdQ,)bCI$Yh8qk#YmB`%qf!C(")#CVM9P"$cV#a(R,-#Tdk@9 +RRX&rTSHSPLVQEjCe9fZki*UJCe099,NCM4$Y#j4PZlaPTdMrH"Qf0FjNNZJaN4N +)d&!Zj!BLV2*'P6@qH+Y-9M6!j,Sl#I4l13NFE(M)9M9)b5!R&DD*`m+e3XR8JL9 +RY6%$diMC1ZlClQ5IpA[i`Eb"LiTUh@1K@+pp`bJVbeNC$NDZ4BIMkE(0PU`3C$j +V+rS4-'iJke"CBFBMUj'8h9p(S$(cCVUYL0k3!,H)kNT*C0re9)N1$+r(Kb`'kJ$ +$Bq`TJ,0BL-H6,Na%a2Z[H@208B2dN!#B#E0VX`(Heek$m3ZHk"S8Rh!NDVK3)"D ++pr'D,@E#!02Xep"8@'!D&!Y[2BU+%`XP9'$@,B2`fKB0lI!1M)ICS-D[TBiG[J& +c@$814821aB&$@)#UK48PiYHhiY&aQSTM(MiSTV2bC5!#be3,"r+5e!'2mIkNVQX +Y'jMp[q-'H#)Bi-N(#m60Y5aHXpJS,e9@'*!!h)CE3$Nm6DUY-$`i+'rp685UrAL +`q@cDi[mfa!#J'ZUk*P8mD`CEB*lEI"FV*6Q!mP"MifVAK`ALBa6NeI,deChFB)r +!H(XeLkp3[51+l'GkJ)hCHELCTlX#6H1RNlSGJrr"PC(K1UMLXEi$%+S+ef82(KR +YiQ*%RXSZ020KN!$J`aiM%5XM)USR0`rIbafGLpNj1mFc`BUc-#&QZc)Q$-KA(@, +(S#32%!HU)X+BaFH6ZV"k$deFE%0SDj3CqC-kQ5b""4UHf6C92e!a(XB-TU3T)SC +MMB3-GJ0SN!!e`dF2+Z85XS1M$9i3jeh1"qjf#FXQ,Q+3!!3jS8Y`Ri5CQ4!cJ8p +CS*T#'G%lMG`4+T,SN3$SMUdDJ)cpabPVUPak(83Z2L#+"$j&d3X[*KE8M1X#`e" ++Ikmi#bppm5QmA-8PH$eBI!j&49Da9AD+8NLl@9j`ZNG4i)',9(k"Q)j$Ti*GG8T +aJ#Tmiebap5@i44@IBc@mXm&SHZ(M*MYIdG*heh+)20Rf!!-f'J@#aCf1H9#KePB +-`'46NXfrfTM3-*4b1bCr3V%`)*-"Kir5G3i@Pr"4,a@)UF@RJJem("me*KCJ+G$ +iF*qB+KQ)B1b@Z+6iFAQ,mP9Xa)a6SpA0JXE3Il2BEUhYQ)q9EA`Afhd)lQZ[1S& +h-(GL3L&SC@"J5Jch0Te$fiC6KRmT6hh)1654,S,!@h4*RqrYjm,d)GY"eC-2`J! +V,DiDYPh9C(&9Um99*HF3l!VCZTEVbN2DKP''a4A$PPFFMBKVKBq1qB&QEYl`Q!i +94T6XrL,1lLZE-&PX`NS1H)X'Fbd-m5f4A4!S%p92#0IKLSJ"r&6M4hSBJVm`d1X +D8$&FL3&+0`e&3)N,DANk)fMmc-62q`qcN6F6[6l'Ud&-"EXTB5r8kGiBL'8#')e +3Kp8@AfGe'&GL5lY$8QdU-Hp1hd[Q0l,G+M9-23pe@Qha!9DRAHVHiKh)Li6Bf0` +@hdZZ0`CSB#eBX4$-hXKm#5mN!`3eJ1%hmN%QJ'%*"i#i@Af)3C)$2d5rBKBh!-J +p42+,p2"e6#Iea52f`RC4I,c3(qaJPD%3HMa-Rd3J2)Upq"#kh6"U[[dZhDZjLic +Xj'5@8BZ-9Q684%52L-'(mciI&C[TP8qN[C1$K)bQIM$Ma@K+38CkX&128c$#),& +4J-S2#4J2%hVBa-#MrUhih$1%e!K*N!#!43pY`UXl#eFd'aRT`S"&p`N&4!FjLf% +I4VDPe6Qi8h4cATK&1"LX1`2!XJrZX9@T,V2F,Y65%1N)Z*jMe@A&FicbFB#M1c) +4-6[CATa"'LIffr-Em*-2GU-"$Tl2ALQX(+S-mHXVD@!b6JIEE"-l$VN+Zl2`XpP +9f9f0RhXY@@m"+1(r`NE8Dll1,lJ5Kpj1JF9R,a6qbK)fHbXE3kRc5"dIG(,eGi$ +(qcZ2`HL9q&PTp6BmlUHjET`rf&!,-K#q5%I1b9ZKL-G3f2d1e*PNPY@cr0$phHp +NlXRF3hrk3-iZBG)1PrE$805ZHC3"0AkBLmFaP4#l2""S$D+D@d#[!3X9MhEBDi5 +ihd4QUMI-c8aRGkEqpLBbqqK(&[QIAL-(Taar&E2i6#GPNAm)"2R'ZchUbqr#B$S +Hc`e6-$"qS4E"HCM0cmaM"kUIP4BQjFXE3h8HCCJ#ZRJ(,PjELDYk4Mmm*NrQi3Z +6%D8$El"b(6U-SN-2EE5f%J$K5AkBLdY*TQ2F!F*GNA2Vf(*CIfhhCM428c,GRp# +Q%l6T6QckQ,,T$YTd"l'3!(#*1pkcEEY$ZGCf8bk6mTB4`rGB$!pfb$r&D2MH5B1 +rQ+"di6ZZmZ#9kiLNmKD1F%DC-N%LED0-&Sp@hUl("(#r$-!p"m!VJ6*Z'#"q#S) +C@*U'`QH0q)&Ca'Fcm9-#JcV,aPJ!JA[CRjIc4"2BMB&aJ*qKe`aNBi"E[#p@BkQ +!0[,M"286e$YRh3T5r1N!PFr[3,&[+$CC'!NVC3-2cNI2!i'G(bEA)K9(9D3-4IP +BBQBd`091*!"iJ`L%L(j@bYA-%rZJ8#K6f&!aUID0A"6RTGA(D`[Ib0@96A4*)JG +e'&)1@+(JA3q9!4K`[eXFe((QANbIj0b8`j9p`EJSII!D'`AL!fl&DGM5#F1@XK' +'j6Y'RDb`*%pR"PKL(dIj)I![X"NFF(-[6+SKNK*r4,1drm%TF#Kc42I#R#!ECLm +E(S)"Q[8`53ZQbHpB!DU$*SZ"`djCH!6#lm3JcQ%M6er2cRNHMiRJLJKZ3aDi+"J +@AdQ$UDA#Vd!NV"`#-1$44'PRLE&T*kFV1dr69PEb)j8FEPG9*@%8pI8#5KbqTY( +XiYH0YC*B,a-MGVQ*rMb&jCZGC!@c1[BKYS6(`CDj@CC[j!l2)c#h!Xa2a[b5ajJ +NiRMbpkD%DjD`IimIp4@'@FiDr-%EdL0p)J%d%&+'m2m4,aK'fXJN@(i!$&ll4!+ +3!2-D((6Z'5$R6)rXV'[KR1P(GBmSh&'5h3pFkH[Hb8kBhGZJ#R*dhmA)"0II2JD +L-UMF-cdVhF+"J-3+Cr"9(Ti&BI1H6r"RB*b`I-3D'`'Qifh1`T-ZF$&PiSIAQ$+ +'bmEUK!1Q2[(RH#!M,6h*Qdr!S+`NDKlMajb&LB'kAEN3&+#@Mf&$B451Y4"i@)Q +ScBT,#B6$[m2&VBQ(D#''b*!!M6KXrPhPMP!26AGh5*['"G-)XI1EqS6X1%%GZ4+ +mX#-$I#VS!%KVjFFGfJ6TXYYK'@hmRh-CE5JLY4C'fUCh&Fjk9Q()**@JckDEq)p +0X(-J(PX0Nq5P6&EA3MR)9CbrCB4EahPGUE(%#@lpUpf!KU#Fl1m6'J6ADc,!,6[ +["MJdjZR@SlQF3A4X8*M(!+E1B-h+UHm82EM3aKKA8%IKKja9TB#YAh[!TL!j""9 +E-`I,Vll@hb-Z!S8dba-UcMqi%%XDbmSS3J$%QV[cAf*!fi)2IIF+&1SE$k*iBAD +c-`PI21dP#%S[RYMN)B1*5A+K'arqcqTU-YM&Ih,'H2,*`EDa,Sh(%P39)k-`@8P +GQ!AUjfNa-MUNUf)3RfJ`e0R*G#f@$2*$0Ih1l+Q&3I8hj8#!a*Z,Rk,J1)"K'U* +616Q0jD6JRDXBMl`aq+p3P4MY+*&kY,SYX92fULmHl-[3EBJ0N!"VhbK0Ia06[dG +6)r+#-X3Id2!+06JJ$2`"jX@["8-`&HBhkK-i(SmJ+K*m`6Ej8%`IjHP3cq9TaTF +16Jb3!1aHc)3,&[cLjh"(H%3chP&,j'K*C)"%9PZMRKT9QD#@3Dh*!fIQ*0`3qI' +0B9X(,[kiLq!Z4Z@aL`UamXN814Y`T-Sk#'+ME-J1%3eAdN%%5RK@)+4*AE)6iKC +m[%pSZShqe"ejkAUBPA0$dJrUkPIkk8mqb8F5TYMd,+laf6"RrEH`HaMpU5`+1-4 +kZ6NfI2d5A[mCj'T"@pRSN[a(Q@M''k`d6C+[YR3G!`3lL-T!a3%Z'"Um--B20S! +KE5kB)&c1CQEcc)Gik&p8rqScrQabd1+69%&MPqhi'#A,iUEa@[b6Qq)1DKU3!)Q +`p"`GH95Hb)4JC)PNG-M-@GH20H-rq)fF5$+CPNDSLedQhY)@rU6$krKKX%!'qB` +Ldl+NMRHr$rFG[R+F*Pb3!!FSfbjh,GXKAk&XJlcjXRb0Kp93PRp+LG-BP'ci&dS +b3Z*2hp$BR+4PXlp0XP'XCYRjq@QcaKB%Jf+#H6#UjKJGF#TjP2mhl9E4GFXIKKS +m-Z%4SM-[@$aSNajJ!$#0-`+!'[GMSiZG@q@+Gh@HJEc-$Q3JHqYlBIB!TM0R*Q5 +MId#9l+$F&Z`Gk%$*SRf`U#qI(S,3LdGF6@#VNk0`FS)"m&kh`X8YV09,VJc1B-T +'#X@EBh-*E2%(b$!,(5Uca@aULFNm'*6r2"Fm0(UaVT6r2"Mqif$J[VFi(mDYi5" +DKXFh`p3e9h4m*VhiSF3*E2!m!8-T'91+FZ)-&X0TGTc4&`$M"m8eq'a82PI4Ti6 +(%4H)0LN6D&lL*PH!'f)K9mD#RZV3U)F*9Ab&Kir0)#1#LTL`G"-fNNhZe9m-F", +IK)YPb(JH+Yj0A*d*J!4MKdXh-I0*[B+NEH02EXl1qDpm1"q#P8N'HVFKH'r&$mb +VT@hL"qAMSj5$2*4fQfDHCq"aJG&(RdiNLMm@3dJQ%@YM&dKbpPV@rFm1Z2["m8B +%YLR69K!j9J4e6FcQq"BM0aim'1,L9bB96m$2mdj8#DH&jph'ReS&6,JPFI4LL-j +fX@[QFrc`J0"*r[0E)Kjkb!-rN!!U,Nkb(G10U&`r)3LJ1+#+83ALI4$BNG9(5T5 +AX`EkfDPm*LAC%#PM1%(`U16P#rL2jjPBU*!!d94rprq!3(!Gf@3Sc2R9j"KmMV) +42hG1(-a%4TSqKF8r!!!aL8&%3e)$!&JL$e80CNB4%#(MlQ(rEEq@U[6QllUqZCl +QmEQZUhUUYRT"md4f8MF'l-S#[@iQXl2)RmI@mT!!MZZEZB83`KAYjjFGF-U-L%k +21"F1%fZ5m6cVC"kh%&l2`RU%F(S$)i6P@BI4J)%Qh56[I$-HkqrIhrrhG4dJ[lX +Nlb8[2`!9GeiNmb!b)K)Km3!4)JCIH9dQBc(mb,jQ!D5B(-!Q)BKQX`H"NmbLmmf +F!l-8X95#lmhlmli*)rMlcS+-ph$eYPU'2+,4)ke$(aPkZk&&6Y`1&bTLXGrpJK8 +2JVPf0GVmR"(XErGEI&m[NNB3i@YB-C!!1Ye!&S@"H'%JK6-)T!Ymk3NQFEkFfSU +!X,5r4CELL15B1&a'hV%qjhLMIm!r!,$pBAmF2jI9VFea+)[+D&"DI'-`dFVL[`C +m&ZB$X@3%V1"bQ($TC")QE-*dpm0X%&AMCGlX+IjV@i5,C@L98J-b1$eae%FYm6% +Z2U)Dm8Fr-Z0!'LfqeU-ZCG%[*EF#)+i6Pd-J+Lp+e64#[qr-+FHA@acG+BBpJl- +Ae9eAa!2DlcXcbJ1GqJ2DG-P4PqN4Pr&a-U,+NbTSRl6)RJdG[QCe`Y"X,E)C`A3 +c31333FGe#,(UI"PMrP'E`fmNLl@T*4Re2qaT9QZTq+1fTEZf!6PZ'EI"F+Z-8(m +A!))`,d-3jk2P)4,)3mE'`@i[S-D-J"TCV+K!I`H@fV-p$%B-ImS'rk(&8f)%93) +T8pE"TD@,'B8Nm&+%FAD%F&ERqF,bVGf638jG)2cq,(Gh[q8*Tl%F5V$9Q9GlM'4 +E1d$MjFSM&j9(SPJDf(Yr00MICB3F&X#kjfk(e*f2IU4U"Hhjqj0*CB&I,$LlbdJ ++@*m-Y)B0P-2)3NjU-%1lVEfahAH&64B*4+dSXZZ,lNL$CF&Rj+6CGS+++5IYE5F ++qH%F"a2Cb+6%0*@B*X9dFVN,3-*N!*IQX-2+S-NB$2E2lj1UZfAN+`J5AFc)m)V +6dk(8k9M-Pc5SX!%YRN!UU`F-kF2'aYfXQQUm1@RGHD+`j&fqdf)X%E$'m*Dfd`, +ST1kL[+`"8V,ba6pV890,,mAUr&QA"2RTAYDp81[@QVTC@%MGD0iiLLKXL'lQa5C +5cQXb$!-+1,TjSCQ9+!I&"2Hcq0*"`p+ML`Zjb[3#%`A%'m685Y1kEE"q9SQ6%8c +0a(4#6#HPAPMVAP3+UbU(B[SXUdmQ`edNH2()`iVJTEa1KH4M!IRXSk(GAmc'SHl +Pm$`A`qX@G4Y9)ZT64d1m`5b5([6!Tq)"YrRl08L%N!$!YXhc9TV1EEGJdkdXAKK +HYj(2Q4i[AiD!mCYc14N@S1#8*QAE#GkBIpiR#[-KeCr*5F160&*Y(5aZ056J3Ll +i59bm$jANiTiddD9CGBCjLP35"2F-$!GJ%U#9c3G33@qDL9B"PMbkd1pbP6)SmVd +R%J9Hp5FUCR5'bLYFc%UKmSFa8DJH[5SA%j9fMbkrd3+Maq@QVVN#8KXX"'pJ+S* +Lf+3)Z4,9Em84U(iKVf*a)Ip,UlimVH+8e[M+6UAULqN3YCiBB*MR&9B8+!U)NU( +RfJaYGqC1Rjq6TP#p1qF#iarYEUIJKjQKHaNN(*6!TmTB3JT)iqlLlr"SIL6Da!& +Bq,TABqE*Z63AhaENi[+ImpJ[4Gjlf*1j&-92aD8JIPcUYDXSQ'Ff6SC)V8"FXDp +KdrD-9(Z2I99p@RQemYKAP5Z89mDaVllU9Pk&D'Z21ZkN1RL,[R!$!UPrN6'[S3e +9`k5m'!UcFf%,JmMQC1QiVE&MZV5JlEj[6!(SXQhY,0c,[4ZV'RXh9ZR[3[9[T5Q +E$b!dQ2)VmiX3iI"'&LiVF`+-F`3H$l"DpBbS49GCD0TNJ-J5Lc1&UYlPE4HNqYV +"AUpl4AQG2pMVVfj5ARZ2H3d)G[1#mM*%l-DMc&LN9pi8L6j(`98BP@CALl622!X +#SKa13LKRFMR)MR#5MJLI!EB$6%`3qS'2$f'5C9BjC9YLN!$H%jEYd'TiL3RS[4( +88hL$lK+8cR)9A-Dlk!$h!91KBaK6IH16i8Nlb2@lX[98`pFI&aY)1%ZX!1%dBG* +fBATBV"9&dCec-0PPaMbkdBVXZj,$IaXU%HE+))3'I#@Y#L%a-p,I!@!`bKh+X+K +)U0#d(6rQVqp"4@K[)6drpEGKUa,mf5PaAF0*0ZIC3F+lY$QkRJ2lTFf4$c'TqX- +"*,9J$T%cIcMJXp1a9MUfe@Kh5lc`SC29!&#Y0FlhML2!YLr)5&DS1*&Q%Th-DSj +hL"3&*i!FilmpF&ZBfRr&)9laUMJ!FbSYeXM!f,4@NTQ0NmRGKI(je,1#'6ULT"j +HCXDkm[rH4l'aSZMZp5)%-F`Iih1U4A+ZXR)K02G5V&SGa`H62p`1c9A'eUQ,HP( +-&V3@0KKaH(&bEhdS[eh1fF#J9NIc`9JSAijE95HkB'@D'&lR)VBBbjXih1##YK# +a*9BTdLVr&rm[mMri,hV-Id(P2`hr"I#IIP$@JK55*EM2X'b'mpA$q%233Sh#LL4 +B8"LdaSEm$iF83kljKd-(0H3GR0TP3ri[,$SCZ6(FUL6TkP)iI,ZFVZ$*$f-,frl +K%"ki1)aMjL+TGLR,jE6"Nlq0,9K$PPJX)iZ6cpHhYBH``-PGSDjhLSe'@J"aD4F +MUSY[`j*ZSqT-5TJ*h`E"RJ!d9fieYC!!DY'NFKY3VDQ@[iDPaHS@Y)XK0ANabQQ +#f,TBA88!,%b)!YVlaS$SKR)lQpdM0RBHm6LTFkfNcZ@LcZ@McR@C1TH8&d$Z'X( +BraY[%lVYrr@I0mj6q&eA3kR4rpm[PA3c+iqmD9V`U(JNd9fmiT&(12Aq`Yf'f#@ +8YE6YUDfU*&H3!-RP-)aNp!hd@%kXKVQc%f(MBTQJ!M'TF1*UXh`$mCK8*hJ5BF@ +2593@2T-@m(!5eV5hb)rCJ50k,b3CJV##E(##NQq'qF9541*B2Ma*KdI9U#-ZAY' +552((HpIlNRB#CZ*il58&ETj$qY3kQ2)P-K&'-*HkP2VC`f9rqEdP6ZT5"BlCqKF +Zaf)bUL,aq)8m*L&hK#GclmVS)JT``i$(Uk6M!6jm&f%YN[Pib8c1PR1FS[jZASE +!lTNq$[XUMf$+Yi+!d(EHCcEMM%4!'Bbpcf3[bqQJ2lc&S2%+&)VGL"2XX3`ZR#! +q-9[K*VY5H&+FP'1h6R`mJ-2ri*24DML`r!(Nc'$b"T*Q"i&+mR'UM1i&UGXa'Ac +q2S!CQh(['B9&q#FQiK0M%UkG'`(q2ac(%9`8J$chE#-QGbS5P[Daf#0FS'hRLL+ +Na-Xi`-+4Im#Ipl2f9"lK&61dj,6#cM$EJMqEBB%i,&IP-b%PY%i0Kk*,Ld*3brH +Z*iI"p96JSe6JemKii1K((8c+[G6GC+591Km!#!!0lUbpq)mDPd!HI9PlElkifVB +%JYifJi-C!V`BII9ca+$H0qjp&q(iX*h"13"jB@-'(l4&"M*b1'5#$[&QlBjmFF4 +bX%1UKKa50I33@D*[4,kB[T(Lb*!!3qU'(&*hc#&Vp)h)'qNE+Bi11D4fb#'e3`j +4Kqf$T"8[mR#pd[J3&SPRCY(#bHEGDhIF"ibC)F1%fmYl#%AF8Ia%931'Tm&!V%0 +0Tr)jhA4BC$BKXSQpkch@QD@#h0+qpElchY0,XHTK1hiUqr1,PY3B'c"#k[GJ1L9 +`)Vd*dbKRGdrmfBFrU`%,lZ2d&c14XAeJh`jaQ!5`C3lUDKq-DMY-H4pZY[qBNf4 +`Vd5i@`rfB4R#jY8'ZQYXaHihHmme-4aS8j1T@kc!I2Nc%R$I#MA(#U5A3j8pc+c +eMB0FP6%*kjhLcYjh(TrYlK5jJjCJ-bXfi1KT@EPIfISe"(p'FGjfc[FD,VkLN9r +hkYf"$iFVAe6[%030`)#Y4((Vh8#"'k+T!D8c*)H$qjC3G"Te!J6AAfhQ6S!LEVe ++#G20$5-2"MXFZViP(3B5UALZ!J#[NjGPBDV[[(2+j9GlFERA*d1&d22hbG5[$hE +RL3RZcKN*d1!QP-*r*cJ1(3"&q0R[JV3#YVAMa8PINJ#XNfqG4TVf0"*%AFCmBpI +#0rJP1YSB&Te!%66KaS[#1Z&Scb!j$#"X'ppHM,ckT6Xi-MZFPDpZ'Kl1bmBPC#3 +)HRIj9mBCjRHGcmj[Xmae`mch!'`i8CKbRFI0JF8+'4X&E+)f&`,2hqH0c@@cFX2 +!V,BB(!0%dS$,,NcS,rhZV24Y08)Sm(Ta5G$A!AC[bQcF[3Q%ZS3*03(ij3`Dm`1 +iHA&dSeT4#&b*(2k55%JJ53Iha%+!2Y6a"bMQ-)-IZ-`0l%"bJS'+b@,+rZk'VJ@ +E8X!eh2hJ%-8AU+&(@Q)[5ZRS@SDY6XYBGP"NeGYe1*D9pIIbe@9&mUele5@M`E( +JC6Nc9Pe&j08X$YTJa0@eq&2$!CCarT%5b3Tp`$Yqj,!dBD)Z%K$%$B-ZCc,3TjZ +fEX4PI10L-bq"HKq!k+BmXb!ZKJF'(bYIHUQkdQdD2rcMIA"AKXPaN!#$m#q*cZF +539bX(+!!`kUY1HNTm!*f4AIpUG[dEZGP4JJ%J4GEKCYN9@VN!8aaLSA$j'&VNdK +pSYTRUrG-"Tk4N`5L,Vr14JLXC+ak,jXfUPNZ3NR$"F$!DKqV,Q0L-KA*D`#%Y#f +Gk2`$LM2Eq2I1aXl(mQ$Yaq&##D2ff!PQL[Ji*%bjimCc[$NN"-H93&U%03iL)#0 +%1(a%4Ya%2#i5kEK5[*%)bJf%RqFmaF8IikHS1%NIZiUAmdI9c89HA39@m+G59YH +TMbFq41R$51+$4KqQ%Kr#p+%Lm5&#(h*M!68$NfkT,P'0XB!lbL*AQc'0d$59B`E +XGf)CUZf[,R0dQc!5Aa&5['8&"iMmidCJ5bH-c[AVqe)UbR3(&hl"G1I*P#d8lXj +rf$%CC+D[V@05SQN"9($E5B#Nm9-06mfbQXe*Al-4jr5fNjR$(6pQ9jVY4pk!'Zd +L0GTm@HV-"YaV`V`4MebhL6BNC5e%dFV+dC1NEIm0ZR+j#0'&8#(X-KEfP-aVEZX +,L690E!-NYR%5fe3D1pe,BZXMXGdPX4@6d"`NY,XN0*9%eUXk%X)kP4$63%*!+a1 +Lb5D%8S"3[)T3HK*#-40##3QK1+QE2@U$!hZQ%1K[hh!,MRhGRPD$LXLlFFYI(Rm +TeR[mQkCXHZ0)2BTKhQRaGrNQ8VIB'ACD(2-hq#6P@Q1M`m,G(JedY#Y5G'@eP+& +c8YiAZ"-*#!fUJGR&X+0MaDhE,e+J%kNZZ6fK3#k!+,j5ihU!)k`!r63QFX+P'`i +jF&YMPI0m*`23f1*BGFhTFlCcPTEU@UFPDSR9aQ+iUA0D3'lb1VRK,DP@8KRaJhA +rSF!dZ4#63aJV03S1l(##Vf-RH1pfCTF8a4G'Gf2KMT&``b6@'I8b(1@4@L#(GA* +Di!UpG#Tc9B(J4Scc$1iN(NJ*4N4f+T!!AF94$`$#NMI&Dq83km%Zm[*qr5+Hq(I +`QBV1rZZcX5T8(m33S#SAXCd"VCFYVJF%!!Q!m,F%"kDP9N`LapcPr%K*H)DrcH* +)ZA6i&F`!#3X3dq5mf$"J+rjS0AT204@ZUY'LK`KQ'`6-1)K#8b-d-5NPk-bd-6c +f*FPaE5N&(4ITGC%H,-9'&0M@J$*@dq%Tr)c*6,%&,%c4*0,$'pILdYY10Aaqa28 +!#N"UZk"5lR*ATKqVac8@91F+'lIFeaRQJSRdBhB@#541k!)-(R#fAiamdXdZ+(+ +EiI*R)QYmdIi,MPYSN!$NA08qr6-4q#2"KJpSl[-3`,&&1&Fp221fZ2KMI6"0AXa +UB!40)kl*98E5-i%()-$(9VVB4ApKjQfS["'BG6%q&ZMME6`b'QR"KfEk-)[L'H@ +%QSp0)m2,UfhF(@)MGrE,KkK"cd0p$rLP`BGPC1QTKPI2mZ9M)fcU[(R2')l0b*j +6$BXfmFTl6IBBri3(N!"U`NrbefGP6MEM*bX4r2(a2q#Ej!ri"4j#"p-rfk822f& +jeJqMpddN0TK`mBppkmlqb"U3!'efp"Ya*iPXVkDE#EVCPq'EjZq,"q,dm8#"EdS +ISBp,*A)92VE4!mAd!+[r%5,lfhP+E'ij2H#M"rD)KC%@`5,JK9H`[(46S*XDjD% +2&@HM%IG0d8L+EXl5$H$qD*M%@LUBPXEf"6XCQbNJJMiB#&,+6Lbbq8h2!"L+eF` +'ShMf'I(LI0Xj*N!'J22BJEB,Z,'IDYLrA5&'-V,2X$-FDpK"*Yl2-&&krmFA`"C +rLm5lR)r$RcBFHBdG$4%ZV-AL(PVXKZN[`i@him,1`RbdRF%&"Si!$YKj%T@HP!! +Q"0#!KmXT'E5(MLileA#iP-&Hp1)Z8Kh&A(8dR[#bdVSpbr![LS`GPrBCVL`l"p9 +N,5$%eq#!Y--G9e5NU(SV0kSbl1Jd+q!%mAj6aj%Q$L#8LKeekC)e3bip3)D$0,e +RjCA)9BdA'+DdJ(**&&TLSA#"hPb%aFdjqEf"f$)ki,Fq$6FU8Ji!'@,,2,h+TLC +))GJ"iU`idX4*b0KU*eFTrZ-QUP6m5U5NrR!pYXS2aRN5fi0(kT4(UX4(L&Y-6%8 +eQ,L8A,GIA"a6AM6L(dAA5L%j--TGkqQe)p5eP+kHJP!AZ(XqIAhN!@jZ$hEeTkr +3TeR4dCqq#IEb@D%fRRjYj!%69&4+pB5*R2j@E9CB&DUF[mNRb1a18QK*8N3`9f` +ra%SSc6NV+jVAM1pZ*MGr*,SQLSaPlE2$6$)EZhbMSr(RZKVDTk-hfJZ",IFjR)) +#L)1B"Cl[j#$[ZbJ)fHRi3))FD0I5'M1BLT[d"$GBif3$@+F+Yp&JQCh,c'r[,M* +@i0MAfjRB8a#4NChXY1kcLQCRa#5ab`T5e16SB4%0dF*T$Bj-SiL5[mlf(pbM$B6 +6AY)'S)T6IrmPU6hbKM&IC$6LNRrr"Ji*$kBhVGE-S)0)R"*!%mpS5&`Tl%0XQ"P +f0+aMe6AV2qNE4VHVSS6,ib"I*MXbrI3-2e53!,l#c2b2d"K"4[!$B!`rkf43jA5 +MaPeFFUSc@C!!rRDIGA,qf%Y9Ff*dJNQJeAU-Jd#iBSb6r*aQGIBLi@3[q0fYMpM +1)$R8Eq%%r@K`lep4`6f&iUi&!pTC#1bqcd"%0YjiHX(15F['dp-THUJ@$cfPcL) +%$"lq%K@qfAMkGUQamA!p&cRI,TK'3$PD2RGVleq"&!iqRZ($CYN0U8CC3TqQ*m! +mhN*6KaTDS[&P),5RI$*f#C0Dck`4f+d,PF'kZUL&@hpjNP%&F&E[CN1F*2F'GUF +eB(RGiZb&5fFGQ34-VQ!b5Bkfdf+6!rLSK3qJTMAfY`"*rUim9NA&9BF+Tf*I0lJ +KL%MR9k8aEJ6MjpL4(f`Ha1p%8@H+!1GNB'`bLiic*R186UpK&apQ#ePB)!#9F$K +VGNF1jHrqC#!`hMhq%a3jNh[6J550F0dLGl*+[9N33B#YB*-RrZ-bS26DJZLfbB+ +H"$j"Pr`D'aHcD+*KKmcTl0UTKYhA+@dZI5ScZ@#qHiajlYKHXr%FR)@Br,5#l!# +5lVr!&6ebNVB2D"YG2UFDKVhAdYLa`!3UepXLF`MDDhY2UVSc9G,a"S-F#0PAmPC +m"G9-('NqhmR(+KG1$9jiYT`B0YeCB!qEkaJ+%`@CZib#a)-C3a3QTqC[S5Mhd'H +R`3j0+%jUF-cXFRLT4,-cQBA+EfD9RqiD"&$5UaF[03FSXdS'[VFSbABdhVR($L! +h,P!M,B,kB'6B1#I8#[RX[)"JiH`8BX8eLJEa2LFj-GP*),X3XZbk'&@8D5'RLk8 +K6Xe!6(DI1qTB9#&6L&2eYR%cBD84a4id*fAPH*rGF%ieE0QTN!$ealR$(,Q!JN! +L)C0AR93mCPYhikhE3Shr3KhRMcpX8VA&(rkQ'jZX8JUpP3V06!JmP4"11m50Pii +Qm8KMLda0bqSG3`+81N@0&'EZ,6)c2*TYR`PL-QDfI`pK-P$'X*j'B!FZM`19EHD +%#!0N`m*a0Y,@cN'Vl#RN6BE`Sh"m%kR9hb'*AqA(4irim#JqP1#K)!49PjfR#eV +d&!JjPCD5bM$C@F[I6Jh8i@6'lP89RrUD&p(-ARU0qrjHcb9&F)qV$RB'1iHZLZ* +1RC'P8R8jcrHHArQT'FGPrPfB!a[$*lIB"$CBI)A&EZ@J1jkF1-L6-NGPK#TZ8Dd +cJ'A9Z*)!ZJmM330ZZ"r@qhYp"4LK5@b(h4eGY0""e)"-G&V&658ka$QTAM&qEXL +BJ6,*ATCN@L[)i(-'U3q3!2e@N!$p9S1ERm'9[YJmmKF`qRSM$iD6JDe0DT)#b(V +mfD5i$9QK3"Uap4j8p6eXVBFF#$4h&PY3mI%I85ME82MXUZE%`Hqc!U2ZT66R*mA +9)a3A'&FIb-q-EV$+`!2Pj,3`&YZ%2r9kdKrXacqL#8XMKi6SH[DVTZ))1jU$b`4 +!LjVBH`![Ym0&G8qX(!kkZf*Pl+BE+m(,Pf-eB)H5#L-Q)e@'h@&T[$8lJ10IaTr +pq,1,Kcci*CFZ'A,T4Eid+VLG5-[,cHK1eV(BHaXdhi3r#$-kX!'I-9NpFmH[HD` +E0)pp11#i)jSZJ$eGpYePF&D5-+8Dcc$r0'+j*`1!1a+VB6FUS"0[38(`C'`EPJS +R@PS+f"1J@pRHF@jXUc*6@pi,d$0V([a"Z)LA`CLfdm@mbX9HpPJ2YU%C!C`Zie# +&Qilb*5#qA#'Z0d',Xi!A"`2hf2Z6bdN*P4-6$+$bpfIed%%bHed(0E0F+#PeJ-c +24-1'-Y%J%bV#Q9!i+Vr@,`4Qf"bXfTcY0k+*AjP[2cE8#M9N*6*M*&53!!%9C!J +9&+X#3H%`UK,0HfSF*`[f$EHQjES2KbLLpET,PI'%E-f`m`U(1HZ*9+qKlV+T5(5 +AGP+1lF2[#UG#2&!['#88dr['P0*G9KbN1bbMlL#$hi"5b5TGSP'9`3qTd8h,C8N +Xd'S'hYQm621+Y%V&C34"LDlf8)ce3ZA&9K6bFDJh*3(D)aUb%Ra6)'KZP%#j9p3 +q1[S6#(5eHRFQ#0Ak#IkX9[fkQJbH8P4q&lS#50PdUHkD%Yafc#XfmGAL3$@K9S2 +-mRrLS5lKk)*S@Rl2"YRbPfGM,F,YN!!,5P'p2m($Um&kYFiF"a&VdBNB3Q!`8%K +FA$IJ`!kQ0irA[e#D!qb$ijcjL!hT@`d0&[CY'&KSK803U(&JfMi+f!D0"'S2YF6 +@Ff+J`6,B@$pfb#ppQVrIpc1`bA$,@FR&&@R)Hd,ZD%2HpaSRH@"m38T0(D#2B+e +L"jlRa1d"Q%'+Ym*T+r(j5!Z"!VDX5@SE+F3cdD`J1NX`m6Er04!E+IHGdCMYiQ6 +cP5"5c@&Zr-j06I8MR3bTlL-(5e4*Z&KZX6aUBkJA6&mHLd,r-4*Vmi9IDB9EKNe +P0R8CR!"qJNVYj!D(F0FV9lFjThUR9VB5UIPj'UN453mQ0Z&A!R6!0S@FR-J`40m +'0G!'Gre5G49Y2i$YahPcD$l8FLD+6Xm`K-erh&IJTJ)H1cjYiNpRSX6%rMDf4Nh +4p#&-C55PU)@0#D8`Si2H8!108*aC8JXf8JZf8`frke2F@GI!X4d+NN$Y#k*MF$T +4CYA6LRVBQ+BFa%9r`4H9Vj1#f#M8!`X&bX(')Er-JSR-CLfr1Bi+l&)8K+'EFEr +PK45&c2b1$bU"Z[K!(D@NKHM@HkJc$fAmbM!XKe8(D2KSkKbbNP1LDiBfREGD5A@ +BT$T5#YMh@B"p2J,l2LG#jjqk'F)%1@VJG+CRJ-,M!B,lAXN%9@G"8q!qhV!1q$N +9TY)+pUrGdF(J(N,A(3F(pb)qGT)YLYMD2H%NJG652JM1m9!a[*'2-3!3!hp)EMd +"GYPP#(G(+kN92m(l&d9bAfjL9AAeAIQTiT+A8J"[1a0+$(,K*%J)V$iE`#55R0r +--+(-F&1!PMr,`VUmXV$S6lk-'Gardl"`$!YIqE-Yr%UYXP"a0b8B1Jh!b"`F`0! +%J''eTJ-BJ-+8TPidq-JSUC-f,N))fmi1QZ-[bA"X$`M$jBbI"pDi,$PNcJ6l1p3 +a",c(EdpN![dGSpTcABjZ"+mp5)EH9a+MdFEMXmfjJ+1,Aqrp+rh9XSlT6ic!i8j +feml10ajIN!$"kpc4'ip2bk#P`!S6L3!dN!#BB)8*05'$0eQGdZ",Tk$Jba9&KD& +Le$JTqh*ec2m%KK(,X"UQ3fZ9)dZ8!qZ8!qY`i!le%"4@15S9eipLpSJZ3USbqVV +SZVTlq@i,91YfX)!@5TpS8(eJ'1EiSH!HbdSC[B-fZm(S!&U2"C3Q3cK8"$h+4T2 +qISq-VZ80BN[8S%cC8K@fY*IG4aX(&Tl$*!QbXI1BM5NU2+S3A+MPm0#Y4AE4eS+ +d04Xe*J)$6-+V"'Qa3E4Qfr9#rU,-"IHq-d4mSIk1R&EHlHMDq`l%&cTm2`&93(b +F8ZIAHpr4Ac9!I)A3&BdK$3**)-$))B**)-#)VFp[a'q'`6l[`,CFJimb,+C8DBG +5[(&4LDN+mKK-S5UmU*@U%U@UV"jDb"A"k'NCmpraX@%Rd3IXkKKAGJl9fh!('jR +"4Z+0Gl#445%+36l&S#CBB2AIBVFIA[6SrliS-rkq+G@DCSbR&m*N1+GR`ijZ)pl +B[E#AIq!B8-*!h-dNTemB,PF[mBG%K8,TjM+N3X+a-),UV%aXp6JhfD@YSXMN1k) +ia&EeaEaKYee!miT,hD2Uih#5D(-(0PM!)'J`'fl!ZahTY6LRbY3+(L!X'fF`EXk +#X#Ik)cL8B4,%*)K*!"-0Nc!Q!8`qrK'lN!#K)38Q'aNSa&!YiP,P3d-dFPLh+LQ +U&*S,D'"UY*apE(lC,Fm%9$2FX)a9'2VTPXqjSTXq!GSc0[&J8,jiJ3%r'#bfRA6 +(0PJ'KfkbTX&*D$c3-0(!J*'4clMFj[GY9q!DB$,B93AQX@$Nehq(Q@@R#`PUIka +5KcrJARGC*"N+IR@4(8AP$S)L'B!mlH*K[9U9T$'j"lrDbB0XZ2FFX4PK2&c[6Me +L!fN#qGV+MpcM!IT5(4""B(S&(%'EpB4Kp@Bqc'GR&3M63!L(&$8!9Jah9Cjq1cd +1-939(-GIP4I!f,hLMX`a@&rV(5p+rI`MGaB$mL%FmBlh)5(+0h!@a'XM+&iBh60 +j`i&Nl39ZL)%K[h$BqP%MPGDiSSi,Dk9SL$9a44ST,P!-qAF($@[@RQViSed-hXd +&H&LS`qG3C4Hc#6Xl#dYJlj1qak%QNlk[NG+XFMi"JJmShBJ2@(jXF9M!TP@C$1d +`+&2j$+FE)HM*H3a#pjj`rmN'aQf(,E49&iIJECf&r,0i@+B3rZ'ipAk''6cLjMY +)H%iiF%'$2d'K)@fK$9C&0!9JTm`R9Q,MBmim$m'&iahkdEaCMpD2(pUfRDS`!GB +Q*@$Ij1Dq"fP0&LYek"TG1!k'L"PXGM0"UJ#"X%5&!#4AVa*!XUq(#5fp'U2+0Z2 +P@['5SEP`@N2)`8'Z'&4+2aiheTYa9$!$pj4+,Ql$c&M8RNQqD+Yb0*,&eH2+C5m +UPp9I)V&4R90H[MC*fdQm4%1%DP0j1B01"8&mVbpc03&d9Pab&lZjUfeNpbm6Ml9 +5fMR%!N*hJ@Ja1'#Ge(l!5HN`!Bi*9e@4)%k[6++)I(d2dJUPVqp")N9md#+QK9c +*XF4#VTD4Z1@+a(RlV6F+9j9YBaLeMBGF$`B,'QNT"Sh$D",+$'&+E5EBac@6IcS +[V6-!F6MBK3Jq`qa,h`1pFB5jD!L6im@#Q66"62E#2"jRGH*R0FP+ECAbDUAEqAI +H`VLah*IkcB0A9N50ZD[M(b'"cUN&+CmdqSePc2BLS3Y@UqG*5M1(MIZCINipmb" +#25p5iVK5*1RC&HE604M3%3bSE`D"5+ha(2rrCAB0qI52P5%I2r8E9bHP2J$NThI +jGZCY(&BP"MhNK@q0SpVD6)jB3E#9Qd[k-%5KNI3*S2P&YGG)#PA$(D5TFqSb*r1 +Nm4efcI"lTq"LNB)D!3Z(6fK5)aS36D*aLlZ9*j`X)rG,T&[BS3&LZGl(U6'Zk'N +NaX"i)j'['HIAIjj&Te3hKl4EN!!,6lJA'*pa2G!6Am)BLZ5cpb)IiXm0Yh`f(rR +cQAFMDhq*B,F*`9,+Zj6%#dF%h"64i%heB1rp5%mra"embpfq"`F4HaQ,R8N4YRZ +Xi2HFDJKIiNEG4`Rq%fVBrXRIH62M4ZTJ`Spd',dNr,8NmK-NF!c!DAf*"&iPZZ# +A9bM#RMA1kd-eHVFE[Im%J8I@N!$!8@aIrPT#i(cVd`Aqj6!*[!DJHBdlrhGHEqr +Raq%S%$jk3h!4Ch2XRB&l!B$3AMJ4p,#SURE5i+*Ph1"D-3`T$h%Bl-bM8eh496k +DUL4-K*G([S%+`DbX"MNSP(Pllaf1[%FQJeX3Va3fNiqX-NbHb%0`YDB8%RhqB1C +CCbq6AEK%V*T-JQ49BRR,j-ILaPhmFaYZ),,0ECa),NLB&5lfSeSf+pmS%Qmh)bh +S@Q$BdJ29r`1RT'mr%-d+!92Zk"0'#**Q6*%49JN4r+Mqi%C)#NR!BXXpF@Fr%61 +(BA)cN!#0Rr0S43qTf9-0S9N3dK6B!!FRcelY0(S&JH''4$cijqBRBA6pkcr2L5T +Z"-m'TeqS,qe#c!$KS(LKPjhN84eaSE9dS9F`Q'`PGeGF#"@0I!-AFKac)4XkG$m +PY82'6GQ$SB4lqE+C&lJXJkQ5"QNKGcK+8)$B2k4#j35DB!##@9[&c0VJ!+1YL5' +fQ)%+V4C$fIT#a"VY%N25mJqkS"8LV50'LZ((1RG11(&NqYhA[Qp6K`G$HMa`$a[ +SaJ!$&0!cNfDBK`8V9DZ`8YF6E&608$EU5N40B@MLESr*E*fMJ`a"EHbBhDp2Tr- +mU#Xa68eJQZB8TUPNN!"03NFE[#Na"!2@S6",63PQUICJc")A4K%+3mX`Di4Z`-2 +FpJJPMXmEQ-982Q[dHCd)a@0e8*'E!([!I0)kfmj8pk@chrSA!26G6-SmB6@&jTF +TqTP33d@Fr'V"-!6bTK8#0!'Z#AM&3NFmJYG0@8eKSkS'f5JdrNc5S!T6a1bF*KD +YqL!X@VAc2,X3JP'VpM46Jm8`h'qKQL)63VRVV"LkRT2B,pj'NKN`X4'$KPSfFX* +K$80QYhZXUACNJ4p#5MMP5H%ii5)hkRUJ%!)8KGe*6K8SR&J9ETZj5kB9030*B1' +MUeN0"4GS-0ZNTjL+%STphD`S5)r+j$TP8BV3SK5KRiT3ib,d$ca4-DFTV##85eY +6)Fp"mc(-S$94B'N-SGc2$'(VN!!K#cJFiUk0!@P29Pc&&Yp"0m@fP%$VG0Z&60i +eKF'%8qb-l2kM$a`VVlTM!&UKNYrmaH,9F3Dm1jm*[2QkrX%h3Q!8$l9LmQ$4"3Y +haS`3Eclaf"b8LRpbrXd,r!P$L8IIM1(6$`T5U(Tk+)iQ#a$G6kXBA)2DBc88@jE +hD-q%hRbpi63QJ6G[T"fJ$DD-G4FrraXBC$H-TD2imkF*9XhNJ4liJ@pM10IB1Pc +NaF*9%$PfjeN(4UIk0aLQeL)R+kD[A$Slmb`HZSJrPpfbr[-Bh*EF5#LjF!*TUBZ +a$`'kh*MK!4Xr#fIjP9!C&j!!ZVU-"0Gbcjae(J1fR2Ik!B@M3F,k-Ai-$)ePE3U +*($5)qp@eaaGLkq(%fM*ppRC4E)f2)ASD'YQ$VXk$@DR1a'0QiV%32`DR",S3KKK ++(1VC5BY"B-`,lNF&8d(Eh%B2cl(,ED`9Mfq$1M03,4#A#%aM6Sjrj!'lE)lSkPB +-NkZV@lbD%8-*Bm%*8ZBK*LHXB"0$"I0,Gq)P%Y[1cb3@pG',X#!d4beEUErq06[ +hD@N,ME5&iD-@4SFX6,ZJ,%PEQ$TfS6`dC'(+Q@J54kmh$APYTKel)HeBqe((AKU +bd$ji,!rG[Rbpm4Pq%D8ZU(mb-[L3!"KmK-PC!5PSq(c1&f&3h'`mPBr!bF(PGl4 +[k*LZhG!aUaR*p-&(H'"SX)E[%62-i%%cXBU0#%cba!+q+iUEKS*@i)6`iT@B-Qb +a'$k9S2RBBcb!E'6VE`66!4E(9$VpiY9R00(&H8"a*K3!(8*ABRLm(Q5JK)B2`9$ +``mXL@8%X*VB,%N)$mGk8jJJD2i)CU[,qFGqI#MF@lJb+!SA+R#L$bS65#9jlH`J +,bKINlBZ,SSXZ-ZZdlL4F6M'*P"1l*eieZl2%#-lb38RcEDmBaZf&MT+l"2ZjlNb +I`SJ'V`dH*eHjA84BA@$h8X3F'fm2#Bb11[#%'%!8l")Ul1e(`(&kl4L'PHp(8di +S,hD'jB-dXEAD&pcDR!L$eK&l6q#)bfYajfNV'J+9jH6#JqT(DcL`K@KZc169(!F +Qc%4AlY)V*#q)BT+[iDMB#PDFH*L(*iDL001$9Q&fEK00B5V*"EDbB+Sp4&65#-M +Q$rSHp,F6Z@Rhl8d2BYJ)LG(XGf+3!(LSDMm2!bmfp085JL(N,hRimiQ(RdarQ"Q +8dN9bDFEP8edLf#biH1MhrjcqeH`c&G+Lr(-%!-%%59TjP9fQ)QF&qd#$H(-U06N +U)%,mi`B8GP5GqZ+6bh*AMG$ETCPa)3CHkY%(A"UMm!D'Q6+&)I1"AT-(fF"`'e0 +'+0ei8jQ4"i864Fl[If5NlPUZ90Sk-RQiMQ[Z2Kj@qkl&eZ(-C`$lYTei0LqD+0' +8rQN3QTSFPY,86N!d6kfBfQRDLUQ9TJDQV64eBQV30)1TNkBj6$-dc@+DSqNf6,- +dAF4d'ddV-&fND4l6#TS1B*URk6LQ!c5G`R5FTLj-TfMDLkQ,TRfBpY*d"-jRhNb +!QJ[*Ip8bJB'1C`HNL6pfr,(L6b[q'%CJ#(P1NKKpaEm5BR4q4Q(NVl04i"mVZ+# +V'ef*9Pp+$'R%c85iZabBA+kE4j!!NdbT!YJ%-1Ak#aLr9T[q3LIVUbp0Ab'b[KC +reM"Cjp$58icE0Yk3!$Z#iH'qq-eQhJ5r3[IZdKIrblGZrqVSaEjChP)e0rKV3rH +1JZ5ZMBA)05"&!q)DD1T4krjiVFU%eMH(M`B5SGX1YX`G1rJb+2-J3[81T,L+R(R +Kb[qaQ`b8)C)fVk2BqI1rL$-)2UKJDqQaVK'##USYI)RUkfJ5p`ic&p905c3-CR8 +AAkkDNm(0rh'fqRTXK#lr'Vp'',q!3q[&S@[("+[)`q$$D6e")%M")'QZ%`UPf'k +FNFjHT3&eh@JF!aSYpV(cCkA1B,SX4$bQeMX(3hb3!#-)Lj89Q-X,81S-S@VBc%J +K-&@4jG&06QmpkEdR9#`8SX+54bV%F$qqU11@mTR9j%Z$Rj(H5"Up$S4%I)P"CR, +&D8qF,TK+)h)(4+%icR)a99mLjNT@lf9AJU%TiU[@-6&NFe`-'i*%E[2KqaRleSl +#29DAaN#1K`0V4LU&RC8a4!fPXmjbi1(SjNFDZUE,'VTQf4fjaqK@I8B[$r#cV-1 +h1+UjMHFXR"TdQaLbEXS)kN@PE,1553B+kBl8+!9e8Pbd!1EVfH05q`)ZJiDXh+! +Pb3!8K6Np4KFAJd&ZcqPTKU[NY-TGmp+efH)d"FY!)4aSB5!I-PPFlaG3@`%-"&` +N1UDe$4fha30ZHQ!S)ipr"Q45'@*FbbQ*m[(%%5Ba#BkYAm,)3Hr+fFCf1!$lMH$ +KcZ*VEHIdkLS(aF&DhC1c1YJB+LEcVp293'L"2[`l(`k#CYF*'N0U-%-93IRe6*i +$H!VfA+2XPP5*a*I*JDFa$`JH)Q,)F1EHBrGN'(q3!*4j$-8'Cj!!X#G$EP*X@#B +'GkVJ-)f61qXf-kb6NBpKi(kB@SI[&#fD`+,N8BXBhZ9&Rk3YQX#LRL,cNBp!3NJ +01ZT4'"[lEc&M%EYj93`BL3S(9P'BqHqLZS('%5,eEhiZIIJN-6LT,XMr(#V)%Pf +3!0%E$"@3!#",&%''dJ8C[832(#2)k'XN5)"1d9NKb1K8iJKl3T!!R0"+kB*mYE2 +B2&D3!0&Q%Q4+"a'e$iB+8VZ4%'5*!X@)P&C03TMK9i8`cD1%DBFC0MRC"+B+cr( +rC'SC!Rj650cf3$MQ6"irF4+8I3i'i"NG+UMr[25[[f*"9CDQ#FS13H%IkU*PcA` +XPXB2XT6-iUYPD8ZEDDP'5kh+8[Y45d%1DHN(D8ZY[&3HSU8pbY,QJbbp68[GD8Y +lD'N6,@e9PPU208JX&GZG5e[DLU9hD@(T#brmRh6*cG9T#dZaX"4`HS[i*dB5aKc +@MEPD0fBfS5I6M6PD4XCF-Y5Ba3!P"B,VM'"LQ%F"l@e9$@%1J(4kYPZqh3kfp1[ +B!JG")I()d-&(VLibk2GN*d%YSm`D2hPG#C0D`Ha'2Fd!K(J!UV#j$*U-S(83h$a +rQN'Br13T!VYDhBB)8M`XQ#!&(4SGCqfM)%DH*"DrN[ma,9N2H0I[1Mm@[mcKh,` +5cTe(-rCEdlA,E[PHJb1#YZ'@cc8Dl1f'JJm8"AIAZba$1Nb4XrF(82!mC#)l+EM +1jcDUmCPlFqeIZ-IZJmaXdT(Gdr[a8+GiD!l"Q1-#T4me-AJ+E@i0`TL`aq38de0 +a"!B$r%%243M3#G0,T+X`R&`&%`R2+(FY``8RBhZ#CGFrQHQIm$-P@2QR8LJ-6B& +YUh3JJ3FC`mX3KFN!!TNjH5UN#%(+2bFa52NKJ#abc)-"Amr!FB8+fh+US6C$5qf +mm*X$R!`4PkXGaI%0rlb6AUIdcrpF6Tml4&"1LbcdkC@d6c-iTRG)eAU(9'Z+3@J +ZBKVZ6#3(Nq)IBJ*8)q&XlerrhcK%S1&6HG&h+18@0Z*L+$1'Bp,JK5$"eYCQ2-5 +$[3))(X1r+X%T1KbkIR4`3$CqX2LRYR2&2FrAmi!jdA2X[h,*h2+Q"F-L5j-rS(N +aA"q4PK3Z5kP"B*crm50ZZ)+2ad$Q88X`*Q@abIrFbF&HXj88pacp'Pe4mMq(amh +qBM%fNTHrcU%q!k%CC6'D*NQ[PVBeL&pDMcQ'KdP0LDi,D!!*-R)c-G&)"!f!#Dk +BJ$Qh)ph%M4p,"KX$T`r$"3!!)aY"4%05!`"AiJp9$@C%!K!KiZj8lm&*6VcD+lQ +B+m2S*cN[&i)F6DhM8UU!aT`R2DjJ+H1km46Z6ScmrKD3!&,(cC`",@2GVKShihB +b@6HE54-E$','d&[V@Z0N(%2YDDcM@*YK(1V39!de"b@Lm2IrIZrhhAI!iCRdf@H +IHAi!(@Bq*"%3,a!!%"!!%&%[PBQrD'V#(r'M9bL3!0*K&3jFPbcXNEc'ej5X-@8 +h[KC*$(V54"f)TX`aXq@6j5q9@AX"R,-M4Cr0RaJ4lDC09S35'aG(%NGk`!*"@Z" +R&cTX(PMCZ'ZJ6!5Rl""PVqP["PBf,DD"fkE'cFL8cVKSklipKL*LVqiNKAhiY!, +6TN-)KeT&apFM&#cU019qpKU3!!NJh`$#EMV4GLj5p-8N(QLrAAPqdUAV`SmaEJS +9[C0Q0T[Ua(PdF"P0QMec$)&E&$Y#cfD12AIeR66@U82TT&FkH5+*5#NkpD#6B@" +H@p$NrNB6HhUMl1PfpHRFGp)kAK'GT!cVlAI5)SPpEh-4k-,3HjJbJb[U2Ia-al, +&fJr($!9GTq2R4#6aB*le6AaLiTm&k3-r81+LGP`#SV4a-`EfB1*46'cM%rIJChF +NdEk$2ZJ5HPEl86G#`Gdj`K0C+RASA-QR*UC@XbZ6kRclqjZD'$V%&R4j'PZJQeE +'&MM3b@PXJ@0k$l)&EH*9YU$Y84(dJIKPX(LXXH"N[h$&)hbaK"5XQh#UT@2k+$j +Sf$fQ#qk('U`he'2E)dY2MA8!19j8H6jTU"Krc&eT-q*YDE6G-LLl,V622$28M!+ +0K"Cc![b*QE)R*YaMdY%i!q@c"EEeqeAXb-5Z2f!)X25h,qcIjeZ#,ALC'%'5&k8 +NCr6e4H[5SdR*U)X@,IT@5M6e%qGDL-j,f@PR$qCND"Rb5NY,56kE(&dNpRi"$r9 +HXIC+3@EG5HX`MVA(d')Fekk!#Ef%a&!!c1Qc$[2&GK`b'%)9Q'@RJ5qfC)jT)F- +CiaPR+-iaSB6LL2f`f5f4K0MN"V[5P*J(l&m8kc)+IZ'mM5jFk8M["QZ[K"2PQ-P +0JADJBQl1i#+L-$J#aKAmbT3Mr0K`4(4V)D#'%@+bd`&5NP0cXR9DHPBf2JqN*fH +PpQRCfM%YpfcGQC5F%e&48bPmi'#@,LIp6$3e05Y9'BTQkj)[+Q15ULMSUi4jC@S +E0F,jS&h4"5HI0cY)KE&K+ebeT"ch@"@UDP8Z-5a"CE"B@!M``)h6N84"YPBShF) +GHAAm-J*!GRc%MDDj9i@&&",h5XpeI*hq*c8T,'Vc%!JA"`HH4,KmGk9`J%bH$RF +'C5TP5,qK"9Yc,+dd8LM)3mH`$J2Y!2)N30B9L)R$1N5JP'IG"(A$J)Fr2bSG,'E +3aV9D8qi[&LV$TU3M!TpEL@(L)h)@URRJq%b!TYah2X8%V`&UJa#SUJELSLPh6LN +q$N5+jUaPLLJ1hAk(9k0QX-il*dbj-4-qEZ++L0,PMq"`NMUKmbcHm3'`f3Ef9)G +0aeR8%Bqqe03dcdd2NkYiB(PJFAI,Le#FX1#2!aPq5@8"K3'#e-h38M1VR5,K9B2 +6HJ,)T-CEqFK5B[[Bff$l3Xlf&8!d5fc[keABAZTqVCN#PCG@NMX8cSJJQ(r8b+k +54-KmLJQ&2553!'84ke03GPP)3*!!1r6Mhhh"h+@&iN)dSf,K3UiIecaFb$he#lQ +ePkk3!$)N([U(KmfG9N[(ecR,e#dJS$P%ciRCk,`k2YVa2KYBM`mkeN&L!4-AmPL +U`L68@3XT,S[,Ce-JGT,3p[@G68U+CQGS59NT@YD"C#h,V+@HcGC&r4CCc$U6C6l +$CbNLQq46XSZ%YjYF-PmV[TE4KD8(TJZU3$Fe5YP*94dbSK%"8)F-B-QBN`-FKjU +j-@3Z$fL6`B!%d*5-jH$X@Je`9U"Q,!R+Tj4"jZ!#BSYHZ,PTm%0$#`rjd1)"IYe +@D@%8'jXcac+k0Y4ZE)l1Jk*T'!948flJZdka-h'aJcJfFh"qRaj$1,XHP8Y!6Z0 +D(0'dm5KJ*-&2'rdr!C!!#D*!FFZ-F0B2FS@#BCfXhhD(UfLGNrAE3UU+H2GVY33 +13DLeMYL*3!&J5M51M$S8G91'A1k8PPa-GV1*pe!ihqe@-k0YP$qe`jNCEIh9RVS +AD*i55XC!L'Cba-[Ek-$#&j3$6D0*"CCA&'!*dXf$DDZYAI`53@a2iUD#6"9JFK& +43@HSQ6VSfX%'AM$"&4X!5N4"Vh6!lU%9pklG*8*8ZQVC4p3Y8dK6T#A2IJ0BiRA +R44Fj5aK[+YAllI'Q8L)eG1hFT+*Hm6Im&-$LKhci5PL`IA!["aZZGV"AUQeeZ1C +@FI4m*q+L`X`h%@i*+38-@cC1M5BG2*XHV3NjRM6SU2m"ZEJm-8)#i14P9UAp*Qb +9YX[2+Qf9Ae@D#q+i"Z!0"MiRY``XAlDDUVFA6F*,3(!4`[B1P,KNL`[+BP#)%#e +3X0$B4bIlL,#2FICKB"pkQ2U-0C@BkLc)[LpHBdp094ZBS'S&V,3'c,@E$Jj`HBL +,+)`#b[1arA1dN!!+"V(c$(bH)JCN*$4e(#35LC-m$*Jc&XL0jQDPrN6,bGB'8P1 +Lf6RTcUJ1L-+qHNCVCQP08PQTmMY)K6!mmi,3-q$jDIM3XimTpM&"(adkUK4rRdr +%!99qp4))Qf&dTPBL*d65mAaAEPH50pq9G3(Efq98N!$2U#JS0NfQS(91"INkE48 +8dr$X9KJ3DVVaT12Eq-AET)Xhb5kfm)Y,-''3!&eFJTp+QH)EC4HMifFlk1,ma8, +,%Z*QG6@%!-UcXY0mAri''+(#1N6C$R8Ce%rpk0#DHi`"0XXBB#1V,K1I+3`3ii9 +%jd%fb3j#(3FP"J%$h%!P9dFUc@&PSZcSMlA,"l252p$#N!$q0KQX6)[@jD3N8bd +SQe[e92pB,LFl*eRXPFNDlmZFc4k!hkH*p$G))3'2p6PaNKKUp*Kl$-Ccac"`$-A +(qe$3TU1qlZH%pPG,-+MKT`m&@MH+Xjf4T5-#@G`(%bU4Y,pll6GhS*!!m3d4i55 +MhP6Ae%5'6Bdl)8`HqU$3a*dlV'"+`k[4YEeM"Md@56bAQ6Q'LQ(hYKQA`850@f4 +-Y*BbVa&-ppAC8ZBeJMNEBc,QA12-20k4+S1YdX@hYh*#e5JYTdU0`M[5*%+e'-c +6JZ-cY!q%rQ[0GM&CDkk)(f,G%NB"XN#d6a`4hKYUYhYfDD,M%b"rpP&`F926j#e +-,2c,3de#QMSk(BH@(ME`KdA6"$XB+61K[APU6$A&mV80@@jd[@NrhR[&mk@CAh" +mEILTi$1V(r6qSIf21[pbk`*Y8IH,KVR'pr82M6ihGA[%1['V4hjqjrFRrqc)IqV +lEIqhMqdI(1MBGqL6#qqD,S@ZpR`R-ZEqj[MNZ@rPr5Mccmrr[e2rppNcmE1Adc1 +LCYh&R--I(-c0cNVklkNTb3I5IPchNa0rFI5r[Ih(VVZ[eMEIZrRpPMqjpG2Vrq@ +(rq2DdZR2crLI$rccY2rkJhrpm1rHqrrcrmqRrr[MIhcYkkqmYIJEEa3YHDGiBF' +XPrpKiq[jhdhmKfhIfrbI0reQedHlrrka[pRaepXIV[cGUPm%PUeiBGh20[cYfRp +EmmXp[hlmRdVrjIjIYAjZjlqAIIRTVkaI[[,4LUpZq5a@A[M&NTIQ0FbHdpJNb8& +@'QU`!pPDaJ&H`,B*0qbGVChQ1D05B084'K9h`0!h11K)Y,rY(NX6j+Mf#9i-5PJ +6#QZ5Q'p*e4m@KUNESA[%YLLqVQfhe!P[jq60"5#A'+XMh$5q'*A4U"M[1BbE,S6 +ZRKScHlM6"N)c8H!H'`&5Hj1M3k'lCXIYGcQJLe'(A`fkaa!L[C%2!mmdAcal["E +'6kjFm`R4MSHd'j2hB'b5GaS2GVM(M26JN!$X`Ah1"bF#)'RiYHE&D5*ddbbDTTb +!lD[cf3,+'0NYNI"+Q,TK2NalMML,+`f"51)2#$bYL%[KPSC@U,32`#1SK"`jX8G +&qREU6L)q5X8f$`)**j%&*c'F$mCI5`X)H6ZkGXSQ1j!!98$44%1AH`c6qM$3KfN +[BeSPZYYT`!Pb[+,QB$X0@Q`(8im(lKTKKZ5`T!i8hbAAMRNeC8*U#KR8*KhIb#Z +XMEc#D[K8"Q`@%l"TU)`NPPq6J%e$*AlHN!!"Qm91B--lHMQ`34&9$I3j)N[IAGR +3qZjA,(Ep994'QE,$H50,*edrfR4)2$-SlR!6C1I%B'3T3PGN+L-IaK3p"B8XXN& +X%FmDE#m1S6#KQd(X$F3iMVFTNRKd1Rd3@i`Nf+&Tq%-+!Dqq6pR+,X$M8+0QUdD +Mi*PH&$2c3-#)MY3eAeDYEZ2UfKC*V,r-e,802ar,UY8G-R@KieHHjZVLl2$3+BD +Jc(k-,BKG9V!&f-dlNbh!LJm'+B`1GZ8QApPCbGTCY8V8&,!4c8#--M9k0RG[`'2 +Iq$iYr@)drB18!lPDENj+lYRNp)Zr*6Sr#G9ZaYRNXeT1LXBUEcp)1"$+DaMTrHp +K5Hmb2dR[Q&qNph`!`%VVN!#4L[JmN!"142L9#b!K#iJ8lQlKT2Bqi@$NXce8kai +c%iQfUJCTK'VckIG-Z3dYM25$FIqAYV*-A'G,qMeYT%`%!4D6b#j'GS13!1"N9kA +XmYd+qIGdKicm#mJBC)mYqIIPlC5i3#'lFHJJ$kqBAV`)5f%2,53Mi424e#`Y+a@ +NQ1jXFNjD9,Ym`'b1TR+ULLLP$Vk1CPc+4RC1FSk3!-GZUmc35f2bh+e"K09cGep +I2D1R3rEV+G--,4!-bZS@LEJrrLNMlR[V)qkj16!RlP&411khS%S)ER4G(ZiqM+( +$80E3Tb0c$j2Dp%"4Tf[09J'8R3I2%%CQJZiJ38pUiL,Zd9RqGV%)+N%Gjb&$'$B +2Fi1rQl3JpeK58c`iL38pK`V,ih")*Y,b)hCU,%MMU"1b5cTNPf3J!9)`8CYKe)D +ZhE051-h$LrJf4p5,"c#&MXK$EAb$U9VahDMPdj(i6&5J[Gh(KpG1ZXccZJH`"Fm +rSr[D@RUXFB0Qb364CA'DIqF@#dP8Llm86P5,CrSRUXAYISRUM[T%eIl)`2)9TLF +MUMYMYU*k2*Q*d`CE8Geje'p4I8`4eCh6`SKUUDfSlY6NSLSA8@`NH2UL1XBKEcf +bq[N39[RY6QQ9$jqQZ+i`94IAVP[qL5[%dF'&Y9QRebcADUh%kRCEGSIJ1T!!e)L +,Vcc)bSr"QDGT#DNB5@FXcJUm(T'eFh&l&8G4K"31)4,DQJFMjY6cJk9VI&S2Gma +iE)p'4&[m#,NSH5F%C1+MhBGja[XKN[+03(L-6!ar(PB-lrJTKS0qL@%&a,#%%Rm +B@H$B@&XR$&FlB,BGDYDGebb`-!9&M8"[5C)2)Gi5)RJJ5%@a9PkBkb@$NIXYVl[ +LAG)R18ki1"6&(ZGG,+p,*Z!Ppeh1Dm`**"UE,5bCYmDE2Fhd41je6UD"l)ACpe9 +b5RQmFRI#)UM6BP%cP,X6$(U,4@XVEB(TZqI5Er4YXjVEQJRFkLGk,!ZE&afb@23 +,e#P)eUCREJPb#aQQ,"CXX9[Vb@aar1(5TZkfKAIElY*dZV*lSP2-FKR%C,2jrN- +GG*(qM)cG',Mk3M%G`h54L2rBda!"4Q63*m`F$!biF0([d%[K[aS1V3[8hD"13X! +QL!+E9mFCGIMTc$%NA3Va4a*$5b6"qN)U%kckA@#0eL%+*5-EQU5$2[8KUM1I8Tf +KJZQP"!05e@48945#)1JkmFH"S,S0@(k+QrT3FL3CUrB`9[hcX+akhNp@0I[$UJf +DVI*RhT%T[f*Jq3Z$L[*I'24Eq6h8hD"18T8rNaFX'"#4Cd&[RT3&AkUS+JZ%8e% +m)e4&VTBc%3AcH4KI@K4b9`A[1,a5eP'@%F-EC"Q3!-Sbi)r$CS$,c`bilPF'e$P +9aad4B2JAGKPDjR*hV4E+((0ZAeA`9UQ6T$6"PACUV(k9932H(KR`CNUSeX94(Ec +cBi%9eJAhILcU*"h,hPc9X4E8I2K*(%eb@kmE$1qfjS3K"m+Bi"RPa#'Q65(TYai +"LhZSJ'5K%$f)8h*9kRUID6iLaQXhhSZ@kSFdLc2T$fH4DBa&rM%XLlcQ*iX8q-8 +L1f5C`4bdXI2BH!%jFYhKXU+!C894l0cH')36ZNXAj3L,X+$BEp'1kpV'PbTJ$`B +VMC+Jq"4(mhfiHBFNjJ!iR"FT+MIbC,%0j23UEqF"&imZ+8f!)#b8"UAYP6mb$J@ +E,b!ieF(Gli3--Z4-G3KN)a*C&T@hK3541EUC6VFGABe(lh-6TL'G4jN8Qhf+'5[ +a!fPDk05BFB&-19@BZT3ImFI84G#4TTb-jH#-CFTp(8'&mTY'lX!XC`BZj5FfZYa +M'9l*M+!mQ3eR'j!!%"RNpM%!X*QbS$KrX2`LZ[Ab#CIjK)6SVRN"N8AN426BC8F +j8Xp4mZJ)8CM9D%2M,UXdk'BZA&U%$#BbRS#V9b2hE[NK-T,"BBDj+CNL&Yb3!%` +#THA($#fCYNBY-!QKbPp$C[0,m[3#BJAhI[T*-UhKcr!Ykc5qa5SH'5GcJ1f8K9S +2+J8%MGD-dT*IFee@,AKBe[3iNi`5kdX-D@3#8Rk+ZqIej'LA"VU(TP2QF-GhqAZ +CNPP%3QcJC1D8Fe+'CY1PU(`DZA$l"HmqN`iKCbY5[Tk"&`S*`m!%i$%HiFGqEqR +$Q[fqUl5&rPrI%QKTG4Q*G&Z0ihV84iJddh2$akY,YeHIX230!VGbT9Xj@#6(#X6 +@XE!5a1qec*E-2ePBD5l8,ZR29$F#eM2!Kq-&!ID%,mDh9@`8#6JB,[G58EJBCPX +Cc-$!YiFAceUG"JDqRA)$Jr,&e26(LRY)($Ll!!UlR#FTE'PP[C[9%!k`I+k&JJ( +,0ZRYfL&6dLQ3!*N8&23p4TGb-0bVIhkm0[-k!'lK,h'BZ2"&EQ0+8`c"EMZC"X2 +CAc%eV28JL80-ElrIA(UGrPprI@e,Dh-)TX(QYU1qE5#)-lVfh0aimr)mQ2KdmB0 +p6!eV-)GpN!#+2pUlTU3HBAd6aI8#p3")CU(Gq+C,2jKN6lL`[+PC!V9dk%A2H`3 +*8+$CZ6aRXmbc@@ED,-rE,%rC,*q9,Gfe'kp(VmGRbTrPeFp+&0mXqE8C"Je+*$* +I8L3TN6E5,da*GKL$cbRMeFVh3@!0@prN'jr13q1m-'#iUB6Gdk,FQ""Z2*K3*Y[ +D!M`48`#VKi-"*e0f[DL")HFj'C*AR*YCaIP`f)UcdXq+FkeI&@GCG9,KCre9N`T +HP95JSJ`QGD-SXj9!@VTh`50NVLPcQ`"JR4U,PXN,9,,0YV,0IMAXCVIiZGP'[cC +ESKMl)CQZ*aAZL0#VkHhBmVP!FDFBCd@`hPm*Red8[aVG@Bh%Nm"QSMaYB2QD"!L +(aGb8di%IHhJ5JhIPa&jj4P8NKLPhBDqNMS82KP2(3UprkPKSm%FGXldb-K)9D8@ +b3NkD,PS`8'iB@2j,Ye58X6KSi@jK5hZp"CSMe'QZfKQIGUR`3YI&CNZ%9[R'UJX +[6U,AiR%bdJ+e'&,K8Kq@`RG$YXH1l3c9FN!fc-)PdV5M8U8N8rF%8rHh`kVlQ*r +U$[QPlNak'+Ujj3``SJS(34@,1lG!!DcbEG+KaEPkeAb(,M'dF#)Ja+FNhM5V5b5 +0@H'Y@XA598M`F*K2IMYcE,r!!TAYPT+*"5V#c"!`Gp[51+&@jidV&6)#5$Vq,55 +a&@b"BL5-$p!)"SViiY-49*&SqJ5ZGK#E@pDGA("Z6)F`Cq0+@CMc['*+X!aNrTa +TqiHB-3'FS5pkZ6NFK6V2fCS6,+0N29[hMc61N`lEYCd([mMNY&FK20,2CT0(+JZ +'TTSjjb!2E9l!"dc!-(BD3Fc[R%fh$@T##BqIVK+JJ#eSUSF[V2hlmCrd"iMe*aG +`YC6+e*+[U#A`SBeDN!#%[lY09FY'@l8%Z!%3*@4KDLq8e-k[Ilc'p3JC"ikTejG +`JiM%SSr9keq@ABr1[pM&P&iS+Id'N65*1FAe+$dGmG[ND$@e5k0242(KXr5*Adk +'#l*-a3BY*hN!-9N4#%XH#348ZZEN!MDN$qh,j#a0aYbUHRX8Tm#U8N@p2#L*K"( +D"9@p%9[(`+S-8LqV6Mc9&AS`+i@f5hl3DMXRe"2Fq(TPidM'k8#`G&4iVZ%J4N( +0HacNbA&"2-l15P08-G6$331jbRQ4CdXTQ-cYfGIdEe`CkfA+F#Y1M0qY8j9"ESb +9NF5#2P8CKf`G'Er,*'933(FC$N)ILN+3!-mC%LAQe!%0IVj8`)13!$#Ejf()Sj* +#P'fhj9AEpNj*Y'`f2+jXZ,+eqSDhKX*YZ2+LI-2FeD#b`)p6Fb"+dTkP$I1K*lE +K,@TPNr#jZ9(k"FkJp4KR9RE+(&X`9PRj)A-q(E0Pi)FrjTZ3!"T+mXK0mf`jGZr +QHG@2bb[V2&CCTiHYV$2mV+b6r+UXkj5JMlC%UTTV9--c`j2)'QmqU[KD(Sa+C!4 +(#kVdB@)L9Vf[PNp!XejYbX!%QITXiXqlC"FF0HA1MT1E3VUXk9Nh1ci'VK-5*P5 +j#p&dAG-K'HT$D4S#`EN,Ab%(N3cj"N1fBB('*jSm#K+UQ'#UD(&ZQep6jk1`FTY +#$)Y0!m[h6,'N%X(k5@$U`)+`Mqf&"0l'-[U[`fEdGMmcHS0I'6h0KVchmQ422(N +'L)S!MMkG"A1pYNP"UQe`ZV,"0j[hXX(lE)12KYeJKCmER1hA"Pp4$dX'TRBbbmB +(JRc-DGNQ'fk$fd%#$*dSpTIa*'N5bU+LMJ#e5SDbUkKc3,dX3cP89"*32q"X*U% +d&A8G+*F-0DLL`+U0CSRK1-UPST!!L,5aKiZB$`fcPM,hI#YcY*64"a3`[jkX3QX +e+TP-er5T5hTZ5Ph5XEDU5cUq3eh50Y[8*G3a*kBZSEBj1hN`MJLM2B`)RkMA5ED +&ZB4(4CRCJLUr9AAjH-RPib(R@1pPi601r,DY+p+!*,JD@M2)&*I&8I'!+"D9BLG +5mkj1DN+$PU8)""fD5ddaSY&9IUA`hH'*`lD6!Dp2cj&Y+Y,,N8XidT2NBeHdSCV +VG"lLR)X3h!#i$+JMXZ-j8DZ!1ZG%ZCfSPi&+FU*5(B'l+R)DN!$AC8K044i&kK8 +CDP"&A3CUYa2943T5RUYHH4e6+UqrMmX-jfA'bF*Y@hRYTX$39LPcP'SVj5HjPl- +1KV(`rXkj#pr*bSJHl1[64Id`p(B'AMN3e$KKk8(3UT@bAKY#iV4485S2Q")EKm$ +@cmUV%'B@`$1p0Fhh$$9*A!B$J9,Z`[DCZq$8Eidlq,,0E0H'!Li3&+dEZ0(0R1[ +1VRKqKp40YkN$6!%cK&CE!b0'$J&KTUTXX5K9QPHd#H[Q&YJPJ&E`6$L!9V$D2i" +@d1dA30Y8)fQZRa8b+R,()Zk@1jfTUN(Am+3VeIF[EmdGN!"#2M"J(YBXNmd`UZL +8Q@-J8"'ShH#58##V@ZI#J%LZ@TRU4TMUIKY@GIeqUXlNPqV+H+)J[QP8@AX8*bA +q"+NKA6*[SB3mD0l1mlN@Uf#*0a6$T$8eL&`)cLi4*Z&1h&E!IY1L*0a4`4a8jA5 +2eM!51Jm,TE(8M'JU%c2EJG-a$0SUECBC"NfMV-kX`X9(MAcfk!&F(+KF2($bfE[ +*XHUE[)ZXpR5AS6M#&qDBdf&'i4cY)H%*[#8F,f+D"PF0UA'J!J(XKi4Mf69#&lm +PJZNM(@q"Y%H(lSI8DpZeTp!FCS[4a5rj9hk&p-K1TdZ0KlSmSGTFAJeZI%9BFP@ +"P$(91FC8Cm-be@8rQ5VE(kDDBj*#@VrZGBDdkR-prlUhUS#bkMj2G-e$jaiL*X- +jcJR0M,YDUb+e1(P69,k1%3hN4YSK2ekiKG2jU9EV0(NAUpD,bPG9DIT53XB@9+K +M"pMTTNDF5eLKNBE@U0QPQ'88P6HU634`3Sf'TC!!3Q%IDpUE&L2Z-ED%q91KRJU +H%SUHB8Y#@EJcf+XcFDFc$A8L!ae1`H-*,FSBdV'ALcV0q@VL"'crP*SabR%9&E0 +M2LXlFUE0NFGP6jAB2$9BimJp94cj`PiZXMhb,YQ4ej0c@h&Gm+3Ej1"GcbqTN!# +-aXUT%IAeK#LmSeiHBiJ5D9(Bb`iXa')fe+fj&ki!`$r"%V(0CP2S@+[Ce0RUe+" +ZLJdS%c[$G[DBer(%"e,Mk$&bJlBp*MY-KR3BmeBfX,V'36e)E(*HhQ5(SSE3md3 +5XfX94F4NLUL3!#QL3VBYfb0kGG4XfQae#cc4Y1N$#S8@(UlChEbLihR$eFaEFd0 +`ZGfUlf$mfD16C+iR(H&9"+)UR%Ql4@D0C2CaaI8U*GTQckI"E!$9fe`hJ4GHj%% +SZc"Tr(Qq)-'Q"Kiej4!(N4E`mqhdSqCNKHTJ0ZAq1Lie`&#BEcT),Q[*!9"BB!a +Pr[4p024Kr#P9TH6f,Rb$+hk2P#'&Va&VNpN`Q4Ic$[0jKl9-[DmK8FY@Y[L"iT3 +[R-''IXM-3C6-D+%%lqC!R"F&jUbh5H`Y'4#(C2p-3U150GM!+9l`Tfc*GcDI)(K +33E[+YV2CQF(D95NXB$a6,lKPaLE8a!92kXmCQKSJS5'@5DAB@T`bdZTJ@EKE0N& +L+iH1A*)10LJai48T(&piH(*kM3PHFm$f#IN48IfGB"ATpm0@T#eq9U3cr+T)NeK +&QVDALM60[iTd9p[!mXH(+FNbL0@m-0ATU0)*a&'H-rRb4ee9'8dhV9%5%2!Q-#a +mbT4481*J*!-qUPa'aLeCf5GmAblL4180'8QC4mX0VRS)bj!!3PLqrNSB`M,6PV" +mI8)K,1QIG%$L1jDN)&`Lh3YR8j+I6%*GU6&!fRBD*GHBkLMZ9ciXl-212McX`m% +qJZc$bcikhE@H@Qj`[$'0Qlc#M++5b-9[ZRMclIEL*G6dXLM!"$eF5%MZ5P2(Lce +#(I,9''UV-648BmK5BqK'MD'Z'N0[+N-`[N$cEe(4G$%HV(NiZ2Pam1K1$%adA%[ +c8G2!SU4T28c)*UL6p[2qfB(LrYR[SqP[[6*iTepJ8$cNkVHJF-S(Z`pT[qUh"%L +aKaDjqZfM#Z)6)1`"8[3R3(LQ&-3&)$`"8[`&)"`M#Z*G)"`"bSKhJ3M#6'B#VJe +#JA@!$!BSFbi"kHA)%SBX!G)ES!`MC#IIp[TF0%FEhmSlaPM('$Vb,I'18!$,eM8 +X@kHF5Y+6QLCJNTrA2H%4,pCfmS(aiKj&EHX`N!#RNI%41Ta!8hIm#MF-+LNaD3F +5NhC,L80Mdj8%Tq8VR%P'Bf6%-N`2DMI'lq%K`e2&4j!!6S'Z08lJF-hjp%`a*CT +ANT9b-$HIJEQLX'"ZLCpJ,Z%AQ,YQ#kDqG`SJD*FIB'TA66#e1AkkB'VccEf$UB" +,$UB#VUV"e+`frm"8`Dh6!e16"l0qr'6!9%2VraS`eG$k(cHBDQJp26$982DR!8` +eP*dHQ%*bk!T5K&&LNiRhNr$[`9MBTjdR@+42$drD4jm1i@#I3Cl!N!!q[F,,2MY +&jlYIJAJT6hc-'1F4bJCUY)'5HZ[4K%0$K49JMMFI9S4rG`F$6P")`#+kLMHDCZ% +G!ND3!)1XFf#8$#,C42f3!2%'`*U$b%[cic6P+#@-KRR%SpR5dc"V0E(Nq!4#+HR +mHJ)%&G0`*6+!2E'GAmXI!+$Z'Vq*!aZS@3Re5-%S+e$bkieDPl1j#!C)(f1!p)@ +`J(5GRi#de#p!QPr6*'eCem$bIdSfY2aHDVBZV$%DGC*!D+#NbJ!+)mePcCDY0Sj +c)h)d&-FEQj)eA&Di4fViEGP+iE%PTU9Vd&`F1fM"YJ9+NK*j8h&,E0f(["%p*3Q +F4hG#D6S5CV6YV1Q[@Pimj!e5lE9i@'IEm*GHd%E)L06+cC8,p!XN-c*f*0Cm&@q +HN`T#P[$0e`&#(cLB6'R50GBBTDceb5I@D&6"HXC@,i9PUhRqXG@XVUVC+R4leS0 +Q"cT59YiRa+`(-mFBX`8!)KrFGfKIcLII'rMC`%F$haVF02#eI4m1TJeqIr$eI4X +'l`eQ$5CeA"cmZi(4I4phT(4m2("5X2m!N!-V'd&%3e)$!'Ql%&8,C*N!@@f6lpC +ZP&U@CJc6@iDmM&VUR0Z3!-8BMX$E6DA@XC9Zb%*)@VHehA6Adl2V8`L(9AFp$+q +2cAN-'!iaKSJBe!9e6L,5L$F4m3I$'""L3!4"L(TlFR-m1f,Xmrhrlp[VfkDE3-k +jIrFe(9Bf*!m4%"!!%"!!%"!KlYr9+e'2"hm8e44bT)39fD8Lhi5,h&+PE0V(A'3 +3rM285kiC%aQQcC*J)MBTa)44dI,SF"$1`C[dpBF8CheXm%ia)DA023S%a$6cG$9 +``KacpkPdYecbH1TY+5XmRVZQXC[r'+C"MKBbC[Q(mU3iam,k'X@AXN*42U0EVqR +@b@lG%!f%fV3B`Ll1*#P1G!-`2!$qMGeHPQ1hIhAkk[5FXRfPDHRfr#2TfVhCA,b +XVjpE(k1Ml!)6*6*BSecYRU$BC#I@VB*bqNr2HiIJX"fR9)Eci,E@i9Bm'1GTM4j +@c(`j9c!UQT2L9!*#KDh4c*8RkmR&4SGUJe$GkNDRTBN3UHU&p@Ef%SSp1a$(MlR +HHXaG1aA4%D0Y"2laX"Y,DI*ZT5f[deM@L4mcIQcimH+R(cmqr$4&l%%l(IAPdSc +5#SiD`&PPakE*A51'I[)heFdk)%Qd!@8R0%dk10b94JNG"3bm-N)LcEX1+%l&58J +9jkU'3XdF`&`KA#[XpL2TTR8El#'YTLFY0b0(@aE)5C@q2r3RZldiVI")XGCHQKQ +f2b52[rUd2D%d3iA[A3fdl`he2&km*F$8aqSYlS06Rp@NK#f(K+RR`ShiFcPiF1U +j%&5je`A(2%Gd*(V)2I@Nk'kBIXhi`HP6ZbmZQGSGc9cZLckR+%H15FUAG6F30T9 +%M4G-Pf[FR1PicR3FQ)i2MGCEM"K1%0hHkGFm#BD6`(!5'%D)i5p@qc&F6Jb$YdF +)dIm'hfF$3kLh`Ae`lA1DbQMQfQ+DpYa`02-aHRb"P%`h,B"0,LZEYFp40F'8[r) +TAjUQ2)r(,491q5ZE8R)V65NaQkDXaq2CLUD8h#T0+H46MY18`kXB@59P01A2EaP +-+C5QI-1R2'ZD!V*+p"91qBC0@ANh69RCBTS#XPBf964PjGem-qlJmSE3p180EKH +fI$X[,PPH4k$LDKqMDHpZ`FHR#"M@MfFV,bjC%k2MqRpF[YR`SaU61c1Aepd49HV +B`jSB2BLi8Fr'PN*d1`Pa#f*e495#lMUA0'8c$F-b!3+4P@ArBR`F3d#`IM`crZ+ +5Y8%kT[r(0I--2kSa'53%'$RdX$E)b&NEl)SF2Q8H$31i!Z4XKa246*Am6EZpN!" +%bp9qSU9Z"`61hQa606*e#BX6!'D%3V1JcNpaJ6)P#M$)YmXhXeX5rhLX%lrY,&I +-RD83U"h5akIi4kIaac@aSKqAEcEqL%&Mk2MI"bMA"ZAE0I2BVF3Q8(5j0@1+XPi +EV)#%HFBI!D3SG6hqh3k[SJ5`XUS"$%)qSR&fE(&XGpFS)kUc$)%eG@iP+Bkr1)9 +1D36LQ(FKMNIFf#"8dBXmL2k)[+"VAf&a@VV@*2[qJ29+#qfDdQ*YIUl'[Pq@JA@ +&j8G5l6QT4dTcd[(CcVT"*J)*iC&b*E)'lL99#b2N5$jE-1aKQe$5FRp1IbkMF+a +@kqVSemY([hZ$hp'[Ii9(,kb3!*V#aqISNef0"c2eY%@%jD,P5T1I'@"Nl2#&SU@ +CqEQQBp8pa&C+cdR9(XQF2*6PlR)lkqa3[G23PHHkVNhAjY$8XH!Cf&qXF2-[er8 +(B`$8KNQfc1,kp2+drCP(-TiE@cj)([%3Spb--QfUTMKYreJb!N)@8KG+MZ$kZDM +D!94XA8S(!U@&0X(MJ4VQEFGLMPMNJ'+1rbNfGGSE,,*)G0fFq`S@P`m4cMp5H%" +cT,4iE"MY0c'k0Lell''arp9@cUlV`9JVCpFm!iA&Y9'YbGE4F&89Db*LK6EFLLS +@fr+LV6S5F0NHKid8+`6&`[C8ZeKeeDV#)DUJ@&fc+C82`B)m[U9q92&e2)*0NLL +fmFaCF")8jkQAHVBkR1UPf2EeTP8L01M[h#Q1L-j8-@ZheMQTfY'#MF*Bji[Y#a* +FQX@GkKX4XYbiq59-4SMP6GYlYJPXqhrbL1)VDkIE%!B%Spj4J10GapNAP$1@qX6 +kQ!6!I5NG3583&rD8Z&5f"$!)p4'EM#p&TacSZDirR"l1cFNB+cAU)6eLarBC(pZ +'BjXRHfacj`M5F,SqpQBFh'`kYJ#QCKcD9YC#Nh&S-cq`eh685MTU%MYUHh!NG1( +XU0'"pIc!22A!GHhKG*9f,!r-U`fU(p)VN!##1)eA3jJSfJ2KY25aiFKHr&P$mdX +0$CppD@&Y4QCDQEESSJGSd660@0ApBS0erNc-bNT6*l0m9iSYQZF0dlqP`lh$Xea +895Y!Gi58(%Pa0QaI3N#US1bpVU$b0LRf"i4L(TB3QJHh@jAE5lIaA,NE4VHrkqL +rfA+,Rf*[9ck2Xr9i2(k+[ESfLMfCVVYRrf38ZmV(0Z2BFmNeB$hfMIUE*-8f(IY +kNh,ED")1EGjZS0VESGVmX&$Yq![EM99l8fe8Hf,'5Ue9ZfZ1MjpUGlhSf+Pf+hF +)!-'U6ZV)!m0*`j4ifcP-L!qF5cV(((AU*I2+qCm![8DiCkB(dr#[1SHj3F`rG@a +!SZr0p)'1a9l!8*!!M'4P+dca1TJ)VHa$aJ*ki-(Gbm%SmLY&8`IBP0*a9Z&K&"q +#`@0Zl9(f%8[DA$"eIZ95T1PRB*FbS%e1S09DI031C2GGjRqbV5#l,r[9"*QLr+( +'!'5mZ[L$l%qe"YPN+NUYeG)!C+FBb)`"CU"JQb4`1HQK)R"CJI9rS9CTMjGDrC) +f0(5N!NK2Jc"G&"V@Q3HpG"Xr$'Ia"EL2eiX*35p5dR6+D8hj`A+Pc[-8rh2#MDd +k96Xf$*j#8J)P+h$R"9`,#C9HF5qI%1-T[BXFLR,9`EfH#H,HHmZ9djiIK*&5ePl +YqF%HeleUcaY)mh`$$#B3Jk0E2ir$m#aX(Bd6HrM`5G,`5AciC3brM1(MM)E[%42 +%!&a&Tk[0p`Bm9ql0m&ca2)PdQbFTbGQYD-k+(q2&Mm+0R0'2pVJ1IZc*m1i@%`i +'X+8Ei-YF`,3,RQIJ"Tq$$eGlTQ%lT0Vc$*mbEC-,'a(H`@IS(`ma`Y59!*8&c2f +0lCe95U-B$m"%2#r`2m-!cc$5jRm*d2ih`(Jr!2@#C`fPCPK9!KeC(cHdqf"Sah0 +JrEGM4)bR`p5BaBXJHla%pRL3!(h4N`UbicQ"bd(HFNV"3`Tf4D6e5Sjj,!mhei* +)r,e(FF`T%VXTHebhUTA6h,&aKVpkQEpiHBp,G02b-#4rkGf09eGlhZ)$IX`"mKB +IpQ-1%!!HLT*2*UGkbEYlX"QmY419DGe5GNXE#NR$Y)%HcE`rMp$empi3("@5LlS +0Yc`pR4iAHfN3Hm6!68RF*BVEF3$E9XmBFTXHH!X$i'5mAc3GY1PJJLHESh'fK-D +A314,UBRkh8MK'FAK4c8e)'6fYH9+JqGeE2'p2X5GL0M8DKH2B5Z08QQb6BSl)Qp +3ZICTLR26blZUKa-,eUXNHL4"[G3UHZjEqXT&ckXYRY-H4r(-dU#c'fd@T4%Zf,i +G5cfY54HJ9+fN9!Jj+eRK$L)mHN$4QFbcrT31(p)NSC)@(+%IB8alJN[9JTqm"*l +`L5fal4I"#-RV-"$,1V'e&r'HLEULHP)rZ1K1K&cBkU+YXaDNIfc9AN9%U2SS09i +bl'l1c8J[,pANM+@lcT0&5N!S*fG&p+L"Sb,,kUL`)M&jRJQ*18"kT49TY1Q)SlE +cbI1XNf'm9[Th-8PXJ5h@3HKQEM%KHDqI3k6UKbVL$Q&EUkFi#R&-'k8PZRqU4&6 +HX)q%K1),0T+Bd0M#RSL,YJ3KU-IVJ&38IQ!%qe)kG$,"4SkEX&Fr#U(@k6i%9fZ +6ZkrBai)BbGdD-c%mMT4)L$k%hSHBilA-khD4q&0C"jd1QcQl8q*1fNUi%aA0G'X +fhGS'X9J%T[fZ[BU6&B)"X1`'TRM9`99P3ea1'M%#SpF35-%+J&4MiF!fZlY9A[G +SKM'3!1qh9D0`5,r'LCF4$X46lY(L-hj!0*k`KJ5ldSq+%k1IVedUdG&j'%8b$MI +LaGP8-qpLcSJ(%)Mp86'r1HaS16cNX))i&Hb(AP$UR@*L*aIccShebQ43-QM%YJT +SN9RPVkP@)Nm6Lk3iNjJZ03KFUSkLX3YE*XRT(hbMqrU$4p(4EpEN`I'Z$$e&(EP +Ldr4,0b4FR%MmYZ&P2VB0EP(Td0PX*R(!4"!kr`@mmer!4C((0,`1M#XpP"$bN98 +0-(bMT!L6M#T,)aKXT%5qHc18lhMQmkNE-%L2Rk[`mhImV**ZjN--%4%E*,DfP!j +dNqrKjbEHZGp%hB'N##4)c5KmJD-e[Jl6D,lRll5p35R-4F3S"d$M8icmaZa"Z!f +ah*H$Gb,Y`%)LR!EIl1-NhX@0R%HKT2K$kDNJIJ&%rPdK-K9QNG%3,&GXR6[reP[ +j)Y)dU!YB9*pA2jF1"1*RiHBZIT!!4,pMr*F2MP@[Nik!lZ!5b)qAMZ&c&%Z#P#F +kr&YVf-10aSpJ50i&%K[P9pqGaY-jVJF4LcSqU6B2hPRrU8cqT8hmC5F4L24I9iK +F%,r$%#T%jMH)(3dTiG[*0F%,6f+!$SGb9(-3pKF"B(m&"&D(+-e[0KRH-#GY5)H +#BIUhhKA[DEld(djJrpaD*Il9d,eHp6S"AbVIBSUN)E@T(Nj!')HUQ13SFHE$BF# +hPR)6aT(c!#kr2(VT(D8(9PK5Y,!KVNY&R,UeSJ09lEKFe@KMM9Hd0UCSPSdQedd +lZ56T%DMAHHKP#DpSk'MNF-41D8`Im@Vf8C+NUTBf-(4k0NZZ*5H3!(3"2cH%@c$ +XJUB5J0r-$GGRBAaZpT3!p#Aiq'`iKQ,"52T2Y4$V4#GBhm#0jBCG*-$FEbreh)$ +(Kc"eQ)SFSiMTX'*$jAREmak4qIX-chXH$kpUli'-'+qX%bM`mD[Q9dR92-P)h&G +lVN*9(d!U`*!![-R)MlD"(ff$I,5K%Lchrcfc11YaB"+@L[NqJ*mFk@D@*!E'5FY +kH39k#6mrim6pV')a-23CQ-rb2-#"TcF#AKpqVZ2!kq2!dh2J63,`p*la!0jiI*` +N!Hmk)q"GC`#mkb6JZ56JZEMcMm$fJ!5f"b"HeZ%)afAeAlb2#m#V!R(&Hkf!#5U +NNJ$+fBSUIZ2*fbeqe6iVB5$Fq#9e8l'-,lPi@XBVm6+)TSdQd66(ZS!1#a4d[F$ +T*ZIYHIj,b'*0Yj-%fm%GRYpa&#f5#N(-i8+0&lcar+lH*L&SN4q#rZX8#EK23@E +0el*Jde8Sf*lPa9$CdP-330i9L'-(JP#ka0'hbJKpcq0R)dIImaapUcMkaJ"pUj! +!3NeTadM1PG#hd3Kp'`h3Ye&#hf%*IBG0k,Y,3YpGQ(E#8(Kj6KJ*VhfjBbHjXZ@ +8-@C`NmKJ'rC3A,lYXC,%"3VPHGpe02P[AM"986P*U"PYDedUXV&@@r2r#CNFpC* +CJjeZ*#PhN46(!GP%!8qYdr'HX)S),,1C"CN8eYh'%`3Pajk1hqL3!09-j!"TFX" +Tm-&Xm)(#,L5N+QC6D()2#dfN!A*iFSp"H$,I5KDaK1*A(+*XpKriHi3TaQNmVTk ++`Y'*`em+4rpNhlYMj+,brd5S16&h`eL%QUlMTP$cR9Fee(brLU&Q,C*#[LHKjSK +aU#QP0$eHSHC)V8209f(,jh%)0ApR%'U1')HD%K#0*f`U%QT@1aS3DQlh#c9eFUM +T[qAhTZYl'RL1[+,!mpAH,T[L&hL1F)0iNmC-+68`c8lD-M`HK*aRT"ZcL"F3293 +-RB@8B4M'lkZUdB9XBKpPi85''$FLVk0!MM0d5T-ZF50P25DYpc03Hb8PQ@)3K[C +#X,CG#pAbh-#REX'Je8CKk*Fm"%@"@FR!fH)A`2d92rrNKX)r$3a3*0LcJcD1J`R +kMmN%SK*!'[H`)c5q))@L"BDK+#GcF3@Kk!hS%KE(9cd8A6c4824k(1'iG*3cMJa +r!iJ)jNCElq-FM0B9#8BEZJK'ceC)BYIKD)("K&U'Sj02pC,$dHe&`p%BNFE#cDp +K9['0HKk3!$D-dS1T%P$M!9825bG,Md&B1L+&TC,D14Y-JDNhAJT-'h5HKAKePPF +r#%#rX(3pVhMVNdb+DeR+cI00XRPH*1AK!RFCX6"e1a##M8SJ03['qLE2'UK2$!Y +NmD+rP2a!4B`@'*RX#hKDZG9XaqYHE2DmVCHfHib#9K4pqXMc$KhKS3c21jk&f$K +j"`5Qm)Vp"*Ci`NmNc+m`C*d[KD`4[j!!G3XrpKEVXBGD8DdrmGc(Q8mc#PTR58% +VhG`R#BeTIN(4Er#cJJZ0&8@%4V[%IJaHhaGe)9&b&JI[kLl"fiHIG9)J5q"GcF% +l"H"GlAPG!Zm8+YaT!Zmk)r#Z+`,HGAlJ03KV(k*JQJ!l#i*U839"lA`%YG%+JPT +Ia5+NmGR*K,8&"Q'Y9Fa9&0CfY84JV!,EaE81E-miUVX3NamCKlCH,dIVBU2`YSk +Mq-XZ8I`mG9p5X%XSrT+Mq'@Jq%[2Qa++AmE2QbB8paUKZ,F)LR[p8'`3qJ,&Lcd +,Vk8r*`b&C#h#hSQQ`aZ&[5-ml'AGH)dTm(8f')5pfa85N46fNZKXU%hB1l&3a#M +XIH"l%[BqX'%LBHr)+`PlHCM%`Yjh(VH`prfUKld6hB3e$RXA`UKB+"rPfQ,1[L% +Aa3md4`Ue1A)4Z-+Fjm*DiQ'hdiF+`bmr9YFrb`SA',)#8E"A#l0c%)BMUDGVMN9 +BhV*eBLch6jbP5`jZd$5M$@NAam),5e`SPAdC`ZiH5N+J&!8Uf+pHmQ%q06l)%a5 +@FAIA(2@5qhmCpS4FETpQ-DVkbb'A3C,#(*DN`'iT33(6H%-D2CJUQVdhDT!!![( +K&,i!&UcKKFmq6ke24,U#bj5Zi)13!2'biR48@$k)3MK)$*Q0*!DA,J(T)Ll9kE" +&2pTT1EllT'ZE@N&cDYX%U'LPiZ4'AJ&[lN0Qd,B0kXU6EG$`(JqYU2'T#rA84-q +&HKi5P@e(BX`SQV5%N!"qGrVp1rFT*-3Jc'29lpCrbJS#'DH13%(AXE34L0X(hG1 +RMP1eK2"(MF*q1M-CUYBM4++Fr&jHL+S%M4pN49!X%!I!Rmk$8bI4)G$)%3VJ64d +[ZT'Sc`[!fTGa%`0(fd9(Uj'10SdkGp24qL"+E@)lIrAQ`FbT%p!03kKlAZH0,L$ +dJ2"pXkXNCRl%#!KD`dbK#JkjLKe5&`[fQF4`SA&je$rp`C6,J&+CAAZET1qRMa5 +6,ZDNTA)Ae0I&KE+1qVmc&@ePc@la*YK#3Dr1FMX9KNYN4E-@#b8$e'fAG3C$3B6 +#0hf!T'XJ9daXkd1!Df(KG4N[SLihQq@+3eX%T5pSAl8$Q%K&FKLUUA[kbLa0,$4 +pjCj$Q5[hV-`+(PbC*4i,"L)l48X@4$b5iLdcKa'iQb0K-aUUS5CNV8@1)kc)X9H +pj*pR)Va,8#qCf43C&Sr9H)-AG4F0fGH!I@@LQ*Me8m@T29ZG'(SDc*6k6kAL[RV +H%HHa"Gr@9jZ4+2@a,S#L`F'%*a5RaLQ11)BkYJ5MZTdSrY[1#JT,SKK&i6k2`lB +4'VS9ch'LMiN"+Q)Aq4F3lMDT`ekl[EDL8JBQ"(Kj'NTjTD,8EK%`&KJGY!"J,*J +)',1+J0%'0a4hiBedSRN4+`Mp@!1%"Ir()(br+!LVf%98$%P$8+ib1[!UJ(,9f)0 +bj`eqS24M$9#ZqTm-b[eM#FVD&b1IQ@3Y4Vlbk#X[4Mlc&pCLj#ZcUe#-2)XDAkB +Q%&#BqKR08GQ"2IM@a58VTmQZE6)LJflH#4JiX,%-6b2-'%-LP*ET`ZPYj0$QaE' +I8@-"8l-&KF9(dNQff[e!,4HDE#A!'RH5rUU@SNG4ljK-q[Y"0"h8bP+hCqE,"NJ +33MkD160IQR+'ZJVMia8KZe-Zm2R[Q8F1D1eG8bJh28T9+#Je*JH6U6r58h+K6(G +,Hch[S[FQLHk1$cV0mekMIdYIfcJmDrIhA6iPrYcDpCr(D4I`*%QfFE'p,!hCfhC +$#GP$46RSIqE8I+L"[H'PLM12T"m`)S8em0#13lDXh&!B1Dci3"K)X6&5cP*`D0( +hZ9(X4*-(%Ml4cZ*93pSi!3(TK8Fb+UDLLq8CF@0(K+SS%ImU%j'4PP0l+RJ6YPr +(`FPe*TLQR&Vl59P`ArYfTqeBSk*e0PJF[0Kl,iUl,bZq2XZX0(brcX9*Z%(F'4r +('kc0GA@#K*bdh(!B&E`#A,#9UVV3dSNYK1K`FJY"[-&KTdY6[*eT+&5d[LcQp89 +GTr8r@DpG*)lSb!eh"aMY,bh6CP5S1BAdrhl&AeeT`i,8&BC32j!!GAEYqM,IlCC +EcX$jci4T(8)XrGVeJ6MYE#-&hB@P-SkNTPS$fL*+@KJSj'LiAB'6XFR@dkL8pF[ +!Q&2Fd'"@D-Z!LPA$c$5(%DJTD%Dq`S%@HH"ar6(&Te3i+-pi8*0b4[(QIBYEFX1 +f1k1lShqTaPB@0AA2&[)QdUY+4BpQ2-0$dNHR2%AIMFr1bC!!**T)rkc#!9kMSc9 +-KT&J00!KNA&*Q9,&+B,4`,2q!hP6c#jTD!a-A@``EqBC0fmbDDCjVJ)%NT*!bCa +N9RB1hj'QY0$$l*2m`DbBhi8LSV$ANiSC$Dm[Q9P'`IlJ0R6A1k!DTih$E)PV)49 +"kk,#jRpGE0"`a'PD,$)-ekj0CB-EM4NA,b-JLkRbQ+RE9B-,rShmQ&E2PT`jU$L +ST$j88YhCpZKSp!-T`FT$eG4V85rjBc'f24Z3!-EHf1m+869G)1lN$S6*#B0#dRQ +UA99GjT'*,914+2"EjY-',+($8R83#T%1Z'MpZa9mEX$R5M+E)Sh2+kYhPcQIEi` +N"UFUBQ5U8TQUZ2H!8hI0d&F$BI-D9b&5rH1E1d1KNqh680MLFAJ)l(jf3$['d@, +m-E6lf6hDTGim((iH$Rme$Tq@Dm+IS5R@XcG8bN4,L2j#[S3N%I1T&q#)3'8EF(! +4"frU011f%VHk'[1m+r4[kC8EKQF09#FDJ+1TFkULNm!aaJ3146NR*S5Db4%UIKA +IJ@E3([G($U"c$UrrC`kL133L-i(S0*N&'C1(%1P)L)[k!##ehlKb84+$&1+-358 +lLN$4(BKM9HI(a[A@N!$eA[p+DX4SRRV*SjHV`+M3bSJ+q`0CC[(h@@h&H94F%ZQ +j[!'!jNbFVY4UFTILI`04C+D(4kN)$!NERI&UTkqfIkc0d+E#3UZ!r!VB4+V)TY! +B#04-(@Xq#kN'j(Ke`P@c&CGr#)@TFHllBD)kq6E,BDRK,&H5h!543aI&C5kFc)d +5C-eXc@A0E"Qi8@C,4CqXM@[Ypa1VVhlM@S%ZhXP"$B)$FJ(59LJDpC[,h#PL3S5 +fFGdL&5E'LkiF4q*1hRLBC1Ll[U+H4jAakVK8S1U%'HlkP,S3pf#El"b(ZIqj99h +MUJ&FK#Xc(9)$&cc8A+a)aA9m8Z-ZSTm1'i*%9S3jXSQVBmd9HQepYb#@J[!BVTT +MG2BLDf!L@LEZ'%A)iql"0(qR+"+NlT&FSQLHD[CUUdX8$HY9k[Uf(8-Bl*`jE!d +lYlPKPMXMa3Mf8641CBid*je,'0@dQSblIFB1Zk[VXV@&"1e!6lB*09BFd'H#5DJ +(YpB!'0Y*f(b3!%+a+"kkSmraa[fN-"5"*QfDpQ[bH##i!"pZP"jZa--0dX-0H2L +(p2!22-bA(ZEMiHr5`praF*AdF"8HVT%HVX($21PK(KlZNalZ`m-Xk@%@(Kk3!"i +HU&h3rTM2+'MA[r+JrE'lMB,fp4-*fR0TXj!!`+Zp4'aAhLprq'TG)#iPGq")IPT +UMU,!jA+rCVYlHX(XY$-*q#-H,*Jp%`AM9Xi@iEa"3iciQ2%J6r#Ci*kqBKQ5!$* +A,%YT'm4$I6ec+iH#5@$CTceF#SjJZ@)1-9Xa4cbiBJia+jJM-eXa*`11l4AhF$E +hF$Eh2(P25Qkhh5j0Pm`M,e,Jqm-@ebJFeECGf,lDeaTd"mi(cT-3V)q&CrH1`Kh +,RE(aBASNKhDi98mEAFqDYj)`STF*'94-N4P1E`a#)`p!C'G!M13@jY"LTrBK@") +Vkj8)*MqKf#)jjUe"0ea@jSiY2$dX0l)cZr@GjKU,,V'NZb`5J5-F(dl@@!T``4L +GCHdR'KZUMfPi5EGf[QKTkdi03-cCN!#Z`XQ)AiAQ52J#fd!Jb)Zam$Bq4TdLQhU +CNCHHQmr['#KZ"RNq'#j04%6iZhpT&RHqr8%N'VlV,ffld1#b426)2r@r1PITGXp +3l40$GjD6q8d1XGYf+VBl3q6NaUdjFKl,YY1bAmG(KNd2$j,+S0QLmhGL%(jXi9B +aT'm,+PP2+1C#jlBHfKcl(1!la`JX,XeJa#PRj$!cYA964hKSGdIBZIXR5,lK4!9 +(EY,rkRcPcZAADCc"*aAEmVpTc)20Jf#+aS14UR0E+5F6Ih"V)eGk%TVPZF!@bFf +3!*EKCN!p%0[SQST*Z1#DZ0Xp9I'LU5hRlMEFpUYX@,S0MeNq**[FYYZh05AhC)) +%4'0FFqFPQB$9pBVZK9EGZa[k`N2k2MQB#bV21pFh4hEqmkrKKASi'h(C)S[m8UG +!eI,3P-HRXX+KL3XdlB%YJDIaLU%ic"XXeDR1S[&,'fXficB)d9d%9MGYA(1(BZj +P%h(Ti@**i9[1!)a08%)al04hD2*VYL%P0K(Nd5AFGJ!diC6Fi)lIE!TrqTIQF#Z +"Hq1H6Dl4CJaTeX31YflT@,$RcVlS9R&[CH#,pq$dK0&K"E)1Yb)%q@dMG,%EaNj +Qff`L*e1EUY,DdD4b0N-Z318&J[Z"cZD)J[3#IH81,$K$%f)%-',dZhFc-Tah![6 +meJcPA1kMj$IREY`%ieH#*0e2S3,V0%1$*lT'[L%a'GV$1F`NJm"S4FTJjSV@cME +aUpYf+-ilm!"P`"raY8-l9V3kB[5Rml8lGT!!LGJRU3me[K)NG`LD)qdF@I'*CUM +j[C9,9V4UR$4FI&&PlQaQ$!H"mX&QF8I36Lk5ET-#8MF&3@6,'e88lrH(4MfHCBT +Y&#Q!5PNH,[(35"GK)[4V9U(MM9&5$Cc020N*'d9F-8*Pl1CiUXMGSZceC9S!4pa +[clG@pJBUp!-%IfIMk#CAX$%F+('9$@8(q2(ck,#1'&[Zq,+NZ'!8c[Dj6%b4F#Z +")C2[-bhELkB$jJEJ-$[NaX3'L#hR@MVk!TQ&P@$'`(JUh2%l!m2Xa@qNEK`1m05 +d6(XfV+e`@PTa1LHC+P6r9qGCPF'&%da#PiPUh8kSa!NN%l3c`8`AMi2k0$rVNT[ +-TA4Z#8!6f)eQ)aH)@2UP-ZeN&Mp&LiX)cL*h)XL&-Y3VPG6920EdYMi5[6-!mk8 +pD94R`BZk6LG,)UP8DK3S09*H455k`!Kc2ImIm`I%a!3A,T5cZl!FJ[3$hAQB2Nk +Gqp@j$I39G'ZR19U-@BIkD-N#PrB4hANL1pA'NQI95eCXI4Z&Gf"m"3$1U8S$kaK +1lLdpA*%impfXJmXX@lQ)3cZF56"##NlQYiS@IiE"D0+`,ZTZdab2([l1&(Vel@I +'b2mFVN9FBXrpUq(+U"l*G1*aA$,,l1"GUDIe+aI5NZlTaFBRNSGX8**hC9GkdR$ +`($H(ih8`SkPK-Y'G0-`B[Z521%hTB@fC&A@FF0'3!("dq8fr1QG)[JlN9dCh!5# +9jl#KBpD)`AK5I&8r05iXN@+M6cM3R-%6Jc-B#Emf9"ir)RLP0Q[bU,,Lq-G+A2N +f9M&qG3lE$P)eqrBc9$--k-lN[#4R-6PZi'+kRJ%Yb)#@i!qdS++cF,BYp4+4R`d +'L,&%F*,NdZh6T'STIB)U$X"4fA#T8Dr(`HC%9G*Jab-J`ShU1i,dlKD9e*M8C`Y +"jTQK!`Y[362,"b#&R#!T"PGBLiT%f3M-Pc8mN!$+2BmSKEGiL6-`FFB"Elb8ekm +*bk&X$bd(&[2P`S4J`YTLi%a))&-i(['+3`Pl8)%lfhp[De3HeZ5eVd*5E!`2-Bd +6$`q(AQ0$0&GaPaZd&lQS13`I%(d3JGVd,KR'1-1(1F1(1F1B-F2rY$,-560L4`E +$E@L58)RJMiJN**hLddq$N`F*5IMNJk-kpiUGqVQ`(3Np'QfUNF%*e$*JI)j'1V, +JpU&LIEZ1%L-i'+-mIDj'DDUR"ZJZTF"%#Jq98))IQS0('+Q$@MU$Z('2UZ5L6,P +)X0#Kb5mI,KCV84)eATN*AbB%Se"K!kp3r(LNc)JSRmP&L18L5+GVdTQ$#-C8S9d +pLUj#KN2Bh$)N9#"#aEP%TJ&j2LYjTQ-VXQTHPT%Z8d3NL33Q1LT8l@'0cDT%k23 +pZ"JA*L*9!UlB4qDL!M3@S*K1H*mH+5B2QUQC&%dl6jjrQ&M)%m+@%PIQGLp0-LF +SIc6MQSVcKQU8faAcERbNea`&$3#[j9XA(++RcEmA'pPN0P#Kbr#D@9$!Ml%Zb*0 +X0(P)aY0TDR!C1jI'CPhDi@86q5HE-6%*K%3!'e[#%EKJ[Hcc1EXGVB[CbFh!$3) +!`4`pM)ES@AFefifNl8abfdB)R-3%5YaLc%LZq$pIR%6ZVp`"$6J@-T!!3K4k1D, +TiJAkG`LF1ddJGVT(VD!PCG2`T#,Y+3B`K)a$UIXf%B"IT!)iUTYK2SkU6L(-'j, +"B5U'`5rAk`Ff%5ik#I&*F6)+9"8K+Bq3!$M,r,A#$NE+L$4V8G-T,r2cFJ*$4C1 +0JHVYNeQG9F#X`@e4jB9M"DkU-1)251Sh)39Yh2NKa9BK8UU0N!$5Eb*NUM)Ac1U +9Z3idjB)3PRFjpT'!K"l`,V3U2)@#-KPq+Lm"9"DIf$DQ#RFXT3hA[6a+SRR`*+U +T%`h1a2%0LLCCG!1Y6P4NUE&JaUCE`q@d8FSp&ZD%r@)e%m-996Vf5UjN#3U4a6i +bK0T`69HYcELLX"GI+daNQG$H`JE*drQP0+5&i*b6'Vc*Am1,*`eP+j0$''2"'%* +8q4MUf1GZ$CFUG-a%FZkHaR%fP@+C(A@0YL%8bXZ$Z"p#eGfQ2)c!lSj$`KH9B8m +01Z(qE5!9U"#h+6lkJ1!Kd[%B(22EP,U0`jKXdH)bHfH'[Kii15!fdT!!EVXQ4dX +pPL)l+I+Mj+3BN!#qQd3XM#JV@!(%2!)e4*Hd2"1)-UJd1S2$qi`1lcH&#ajF5P! +#AP5Rh-Ll&+V)UM)CDGmUUL6'h%H9)XrQ9#bD[6!,I8LMmCA&F2',ZS+TLUr3c%$ +UD+#AEAe304Lk50-MXH0V`a#kf)3aUKejl&%5&XGJ-1e$&d90)%54i!$M'3k!CLi +H[&dI!dR0YPhSK'4%XXm!,T@D8L46bJB3Hf%FeV1,EH4[B)%1!CZ0UfH$E(*P+rX +F(69[#T,-+fdQ'[6PAF`T-JIkQ9PlYPkj1bc#6)DV0'bTHI(B`!CACD,+p[+!Z#2 +dQRFdB8#c#*hC@G%5&3D&6NZ1EqD6D$V,FYq`DhHhUmEjb"8-Va0h*,f'"-`Ur`( +Ep5rF[U([ITSH-heF&,CXFD(5aU6&qc5,X%&kQ)XLj!BA)f60a"(8P#Dci&!8lM( +U3Z%&,8fc``Be1EEfFDF@9#-c,jaAiNVMSS@#(8Sr8LrjSZ&Y24Q9ZN"N*0bi3Um +D'Q`10kl9Bq'BTS@V&"FmI%T-%k20!(,R`4PX56R*ZQpk13"h1%N6-[GJbNcr)SV +Q#4S**@jkU'EG##jb3meBfGa#I"aYE`2a88Fl(H+lHKcL(R)DIK(0EL4$%#C+BEP +@LN(5+1HALef1F1d%''9BJ+SiABL"#F6kGU#lRbqKLlK3k13NljDP#a6c)0KZ4d0 +9C9DHA6$PV2KRj44MaB[cQKLpBEI[6bf&T@rL4!dm[b'E[UE2U$V1(jhL"QhkFqP +fbDSRNh(+l4b9p&NbbHPc"%%#&`hPA1!kL@fi!GkJa0PQAY#P!6mk4k9l6eV,N!" +1q9"*4#!U+SN1VhY2XFhdbDXNGJijmP*"F+T(E+4U3GNA9Y-AK0PkA9eZLf$ckHR +p8,$#m(1'Np!S!&i2dqY-&245q(mAK*la9`d,Aehjch1V"i42CLhif3*Kbk2dRpT +peee#U[SfGFUalkX2UE15,b3[&q,a-qCTp8qAcTSKT!SRe8kejE(NV#YUYr#'F%h +b-rVH,ci8-S5r#cPcNYF+2@T&(YLZrR4fmY6,kTm,8i4Pb5mRIr2K0am*BH'2dNK +KfG2#V16,b41%%qZ5[jNRV%bq,2`[IPB,jG1%hiiANXF,*CbfMhr`i2QRaielHR$ +,PF'iJ5[G!d*!+"-qI[VA9li4IVdJZ82S@l$$)q"5FFT$kKp-%pjrp&(KIappp10 +lCJLM-i6RC`L6(K1@RKMS&YkB)DaA&rBX5liY1Ap`[c"EII6B`H6[*(meq+EDeLb +F'ha`f[+p%pU%[d`VkE%,FG-%fV3D,cJ!%RZhZSba&GjrDp'L,r!Mr$YH(,P3X1* +#`A*ebQ#Em&YeR[$5&@&!2I1Tep9VVJJR9jd3cR8)(38r9"p0GL5r*4`@rQATB'* +[FNjbmf"CpcI#bp+)EhkScNRqCI+E`Qq&e+@$04mQ&bB2U$Gbb[)ac[($*iAT`K* +eSr"$i4VKq0-R9`JAKF'HeDqV[a@q&+B12rR0CD(R`XqkKGFAU9qmdLGmI-f%"li +CdbImj!I#aI(GilYRR"mRG#qI0N8SA$RMp4NRKB[cKBprrH-6,`NAAa1qIHBh3RD +(m-b[qhjdVR[-H3#3!aJ!!#5)!!"AZ!#3!`J!N!-J!!!r2!!(UI!!N!-+@-!!AF! +!!&h!!*!%,N&9Fc)!N!8$8f9R-JGcC@GYC@jd8f9R-`GcC@GYC@jd8f9R0!GcC@G +YC@jd!!!DEJ#3!`&f!%ja5S0Q)N(Y!#!J2$mm!!!L2+R`!!&+3@B%5N"R#NK!5%% +JJ#&"!!4#Td(krml3r!%!,`J[2!!!'@i[!f%!!Ua8MfG!3MJ+AN+R,ca%394"2c` +%eDJIF!%4`!TH5TpR'%ja-$bTF+G'3rS!+L+)3IS!)$!mUA#Q4dU$C`4`!8je6Zd +!)Nja5S0Q!URdF!"1G@!'!*!&!8ja(cVrpNSICK*)jq$J3IVrkP$36VS&VNcI"`F +[1[rH6R9JFN&-384%3de3!!-!N$43FN&Y51GJm(43Rm)[5!!J)%mL9$&T!"3!'#& +!!#3aI!!"!#c5N5&"!#kJ!Yr#60m2"Nje5MJ+AQF-)#S!#'F-)%!J%'F',cVrK%j +e51FI"N(krjj`$#)U!!6#Z!-DBD4Q!!%q5(VrMNkk"fjB6l"kreTQ!!%1S4SZ#!J +U!%!!"'F')(J#TU!E,#S!"#SU!!JB+J!%Pp59e#!kreDK(Mmi!L"Q!!$X9%mX5#! +krd3L"X+i!aTB3@%!rd`J1[mm`,J$'N(krcJJJ%U&CJ5K)Q!%)%@J*fB!!,3U5#! +18)""q[m)))!J1[m+8B""q[m!))"#CdKk!,`[&8Kkr`)[1[lL,cVqiLmkrXS[1[l ++,cVqbQ%!$8i`(fFJ2`"+K@F))%fJ+U!VB!3J6D!M)%kJ(b"(S"Xah`)JB'!J6U! +I)%HJ'h)!%J6R#H-Cj"%!!3!J!J%!i#"0S'N#!!!IJ!%J6D"UeG6Ae%(krRC+N!" +R#(!"S*K`!k#B)%dP5!!)F!"-hf$i6R9-hf$iB!$q[Mm!)%kJ(b"(S"Xah`)JeG6 +Ae$!i!L!a`!TJNFJP5!!)60pJq%je6PB!!%MR!$JSEJ!-4rVq+NAkrLSJ&,#5E33 +J%LL!5S"[%L"6)Qi!#+)Z)"64Nj'5F!"J"$!mrpP-ha`!6Pj1G8j@rmK)jaii*Li +!##JZ!!`SEJ!33IVpZLe)rp4#,[r)S4SY52r-98qS($!I1J!-43!!Eea)E[rX-!9 +646m!U!p96bmZrqbS$6!I2!!-4J!!Epa#*kQE@8m[,[rX-!C64Mm!U!iJ(be!rr" +b!4m"UCXJE[r`5T!!Ca"96bm)UDB`(dM!FJ6!J@I%,blrm+QMB,`3,J!8C`TC6bk +i!UBJAk!E2cbJr%kk")C86be!rp"+J'F!!Ci[!%kk!pCB6dS!C`T`!4e!!"C1qJ) +B5'lrj%KZrq")E[rB6VS&DNr[!!`J,[rJS4iY52rF)!KR!!&N)#lrj+%H,8Mrk#! +)C`!"9#mZrq3[#%kk"EK36b!$CJ!!TPP2,ca$6d4&3QHS(b!I,8$rm%U!C`!!ML" +!)P"b'02",`P1ZJ5d@%pb!l""CRBJ$5"!F#M4`#e)rr3LE[r`*&&`'0A!,8Vrq#m ++6VS%ZPK2,8$rr#"Zrr#J+9"+*Qlre#G+!#KC6bmZrr"1ZKA-)"pbk0#"8B!R3!! +X98p)H[ib,blrp%KZrr`[$#m%,blrh#mZrq![,[rS6VS+aP42,blrm+QM*'lre#9 +Zrp!!$#9Zrp`!%#9Zrq!!	ZrqJ!'$mmSCK1ZJ0@9%mQ3$mmU*p1ZJ0+9%mL!#! +,X)&Q"(!!B!*`!5!!*8!!(#9%!#!P6!!N5(Vlc$mmS2`r2+$m6VS#q&42(`"1ZK9 +52cbKQ%kk!`a86dU!C`4`!D#B)(`!!!&D-"")`1#!FJD`J@B-3IS!VL*m!!!$2#+ +)(A`!!Ir))'lrc+!E98qS($!I1J!-43!!Eh4)E[rX-!9646m!U!p96bmZrqbS$6! +I2!!-4J!!Epa#*kQE@8m[,[rX-!C64Mm!U!iJ(be!rr"b!4m"UCY96bmZrr#TTM! +I5-"b"-#"C`J[,[r`UD*J`L4Zrr"+NQF398m[#UQQ-"p)`()%`)&RULm+UD0JT"! +ZrmJG3!!@60mFH%jH)&p2l`!16Y"19[rm51F!-%)Zrr`r2+$m6VS#,&42*%"+J'G +F,`"1ZJ'!@%p+!'G3)!SQ3#"!,bJ!$$mmS2`r2+$m6VS"hP42(`"1ZK3i)%XJD!! +3S"mJ5b"S!"LJ(b"m!!!"@M!35-$JJ()'X)&Q#R!!)(`!!!-m))!GI!!"rr`3,[r +m60m-!%jH6R919[rS51FI1&P2UA8J(bS!5'lrk+Kd)!dJ3#!3FSE3J5e!rr`J3&a +)3qlrl#,B)YKC6bmm4%&836mm"0@TS#!I+%!J3#43-LS!#**U!!3m!63U!!D8DJ! +#2J)f,[rb5--i,[rZ5-5@K$J"5-5@K'S#8S2LJce$rrBf,[r`5--i,[rX5-5@K$J +#5-5@K'S#8S2LJce$rr3f,[rfeN%p3rrk-Llrp0*#28(rq&P23UG)E[rd5(S!CR) +"(`&b!6m"F[m[!8)R3UHT%b!I*N![!+Kc"S8!N!0i,``J5h!3dF![#+Mf@8qTG5! +IX)9N!Q$d98qTG"!ICJ*JpR$r2`"#Cb!IS$)[#kN8,`bTSbmZrqLSFdcI(2K1ANj +e!!)!!%j@!!")j`!`*'i!##!+*N!J3#)S!!)-J8&-384Q&L)S!!B-J84$69"Q#M! +S!!Tb!l""C`4`!'!#F!&-h``!6Pj1G5m+@8mr2+KZF!%I!%kk%RJJAb4)@8mr2+T +ZF!%I!%kk%QBLAb"+XFPQ"M!m!J"J"$!m"!!NAdje6PB!!#m$0Li!#$!$5-!#J!! +!#!"+J'm%F!&J!R!!*Kp1ANje6PErr%MR(!!f,J!)2`01Z[r-9%mG32rmFJ'`!@B +3!N-(rdkkri#`3fi%F!"J+&P22cbSRh!"(`"1ZK(`)"mU!&P22`-I,[rm6VS4i#! +I+!#`K@B#F!"-h`!i6Pj1G8j@!!")jaJ`1#i!##4Z!!SJ5L!3*N!J3$)3$%&"4'B +S-LJ!!Ja"3e*Q(MB%F[qf3@FD)#J!"()BiUJ#J!#3!rmb!dM"X)&R"(!!B!*`!4e +!!!j-h``B6PiJAea26Y"19J!!98p)EJ!)F2mr!%kkrj)3(fF5)'i!##!S!!4b'1+ +S!N!!rf!#F2p1ANje6PB!!&925'i!#($r2`"1Z[pN%"pR%#"Z!!JJ+!!%!S!!rj! +$B!*`rdjH6R919J!!51FB1#CZ!!JSEJ!-)%X`[!-"F!!N6#5!*M`!!!%Nej)'NJ! +!!NJ'NJ#3!b!S2!#3!i$CNYQ5+$`!!!53!0Q5ej,CNJD5!*!$I!D5!!#!!(!!*'i +!%#5!"T)!N!-N"T)!N!-J"T)!N!0)"T)!N!-q3N"-ha`B6Pj1G8j@rq4)jami*Qi +!##SZ!!`J#bK!,8$rk(!NfF!Y62rXF#$C`#e-rr"`50R!,8crp(!qfF!J$*!!Ll# +&B`C`C8lk!,*#3$i!3N!p32rN0JG`*,C!C%K`",C!C!4`!'!-F!!`!eQ!DJ*@J15 +!H!!i!be%rrMBV[rS*%38J#!ZrrM3J0#Zrr!J3$#Zrq4`!435FJ!5!Z0Jd@lrj&* +(B,"#3$i!F!%m!$B(F"qf3'4%F!'f3'3%F!"J$(!!-!06J'S#8S$LJ(J!1!-Y42r +mf+lrl#4%&)!J,[rmd)$3V[rd)%!`KR!"&"*b!")#if$F3&*(B,4#3%cI(2K1ANj +e6PErm%MR(cJNEJ!)*Qi!$$SZ!"!SEJ!53N!m!$)&F!!`!G#!0!Cb!$)#X)&[&%* +!0!Cb!$)#dS(5M#""-)"54Q$D3N!m!(!#28$rmMB'YN9N!!#i3N!q!%*!28$rm(! +!-!2PJ0#+)%!J%#e!rr3b"R!!-!(3Lb"!'""f!"B%YNGM!!##-#lrpR)"`%(4E[r +`F!!`!e1!0!Gb!$)#X)&[2MJZrr"f!$B%,82rr0D$eS`J3dT3CK)J,[rmd)$3M#" +!-+lrmP4Zrr)b,[r`F!!`!G#!d)`J3$!328$rm'!@-!A330"'0#lrm()!-J,5JG+ +-)%%`J&*()#lrp1+),8$rp'!!rfa54Q!!rd4-haci6Pj1G8j@rra)ja``*'i!#$B +Z!!`QEJ!1-J0`!$!"jS!i!$!$FJI!36S!F!!Y32rm0!4b!$)#dSSJ34)3F!!3!63 +&FJ!b!Z+JFJ(!JG'Zrr`L,[rmiiR5Lb""-K"`!$!",8$rr&*&-!9b#,""CJC#3$S +!8N3b,J!5F!!`!G#!X+lrr'-#B+S3,[rr%Li!%p)"N!!"60m-1%jH6R919[rm51F +I)#4Z!!Ji,J!-1Li!$M)%F!!`!HD!2!!b"(3(`N)q!AB!0J$@LL"$%""d!"3!,8, +rr(!!-!%d"A)!-J,3JHD!FJ+`J@F-FJ'`J@FJ5S"R0'!b0!Cb!$)#9)(5LL""%K" +`!"!"FK$MU)'Zrr`d"R)!-J*5JG++)%%5%(!!%!(KL)'Zrr`J,[rm0!Gb!$)#iUJ +Y32rmF2pb)$B&G!!d!j+#iUM!E[rq60m%q%jH6R919[rB51FI1#CZ!!JSEJ!1)$` +!!!%NdDi!%L!m!!!#50'Z!")J,J!5,8$rl()Jdki!%L)Z!")Y3Ir`*$`!N!1!eDi +!%L3Z!")Y3[rd*%XB%RB!&J3Y3rrijS0k"mC&8N-p3rrF*Llrq1+$HJ2'494$282 +rjRB"1LlrjZYM282rk(j!b!Gm!"`%28EriRJ"kf464$e%rq!U,[riIJ(+KfF)HJ! +k"&1&B!*krce&rpji#$e%rq4+4QG',bi!%Lm!2`055Lm+6VVr1Nr[!!lR30&Zrq3 +[,J!5,blrm$m$,blrl%kk#`K2l`!1,blrp$m$,blrl#mZrr"1Z[bX6qm!$N*!28$ +rf$!ZrpL`EJ!-C!!"1M!Zrq*R1L4!2blrk#mZrr3r,[rN,`Y1Z[f16qm!$")!)!T +`!"!"28$rfR3!0!$8V[rX)%)3%()!%J$6E[rNB"`r,[rQ2blrj#m,6VVpm&"228$ +rfM!ZrqE4E[rN-#lrfV"ZrpjQ&M)ZrpK5E[rBF!!`!G#-)%"#%'!!rhS`,[rDX'l +ri'B!!*3`,[rLCcSN3$mZrqJ[,[rd2blrj#m,6VVp"Nr[!!`5!#!+F!!3!6e!rpT +d!$3!e+lrl#"#%""b!")!dflrj'!F2blrjMmZrq3[#dkkr@K36ce!rpS`,[rQd@l +rj&CZrpS`,[rD8flrfNT!C`$r!$JZrpKf!$B%,82rr&1$eS`J3a!3)Llrr0+-)%% +3J&*ZrpKJcK!Zrph3,[rE0#lrf&*ZrpKb!$)#dS`J34#!B!$q[M)Zrq4`!$!"AS$ +QJ%cI(2K1ANje6PErM%MR(cJQEJ!)+Li!$#KZ!"!X,J!8,8[rb(!Nem!Y5rrJF#$ +A`#e,rma`50I!,8[rj#e-rj3Q2!!!!56AV[q8)$`!!!*)dDlrP(!JdDlrP#Jm!*! +$J0QZrj6CV[q8,@lrP2qd+$`!!!53!0QZrj3YE[q8rlMAV[q8,@lrP2qmfDlrP#e +Zrj6re("mdDlrP#eZrj6rT#!m!!#!!0'Zrj3J,[q8N!#-X)9M#R"P28!!+%lk"RT +`!#i!3N!p32q-*'lrT0Am!!#!!#e+rkJYE[qNrj!!,A`!!)!!rqK)E[rS,blrT#" +Z!#41N!"36b!ZrqKQ#R"R28!!+%lk"M3NE[q3!&*+YHlrU'0S)'lrN!"55*(ZrkJ +Y52rd)'lrN!#4l[qN,8Mrm#"ZrkL4l[q3!#e)rq`J#'F1)'lrN!!LE[qN)#lrl+) +Z*'lrT0AZrq`Y5[q3!%KZrr![,[qN)'i!*%k3!&"2)#lrm,#Zrr4N#R"R28!!+%l +k"F!JE[q3!&+Zrj!!%"!G32qJFJ!5!0*"8d%p3Ir3-#lrd0"!28$rdL"Z!"`J%0# +Z!#!Y32q`*%![$#mZrlJr2!%N,blrN!"1Z[[b6qm!$M)!)!T`!$!"dDlrN!![$#m +Zrl3r2!%N,blrZ%kk"lT2l`!1,blr[$mm!53[,[qi,blrY%kkq9a2l`!1*%![$#m +ZrlJr,[r3,blrN!"1Z[ZJ6qm!$M)!)!T`!$!"dDlrN!![$#mZrl3r,[r3,blrZ%k +k"fK2l`!1,blre$mZrp![,[qi,blrY%kkq3T2l`!1F!!Z!%*!28$rM#eZ!#$rV#" +Zrkbal[q`C!!%U%*!28$rQ!aZ!NMrQ'3!!-)`,[q-CJ!!M#4Zrj!!8NUel[qSBfJ +JE[q3!&*)NHlrU#e)rr3JE[q3!*(Zrk3Y52r`)'lrU*(Zrj!!,8Mrl#!)C`iJE[q +3!#*Zrk3J,[rXSLiNE[qNeHlrl#e+rj!!5'lrm#mZrk3JEJ!N6T!!8%mJ,[r`X+l +rp'3+F'Fp3!!S6[S%3L"Zrj!!8UlrN!!5%(!!%!%Z!(!)28$rM$!(FJ(!3G&ZrjJ +b,[qBF!!`!G#!d+lr[#"!-"!p32qB)!ILL#i!8flrM'!!rcJ%EJ*)rjJ-EJ%!rjK +N%#"Zrka5V[qX%+lrQ@!!r`J%EJ%!rjJi,[qBGJ!f"#e$rrM@JpDZrm`J3c!328$ +rQL)ZrrM5V[r))%%5%(!!%!%p32qF5N"R!!$#$'i!'2q-BJ!!Q#4Zrj!!8NUel[q +SBfJJE[q3!&*)NHlrU#e)rr3JE[q3!*(Zrk3Y52r`)'lrU*(Zrj!!,8Mrl#!)C`i +JE[q3!#*Zrk3J,[rXSLiNE[qNeHlrl#e+rj!!5'lrm#mZrk3JEJ!N6T!!8%mJ,[r +`X+lrp'3+F'Fp3!!S6[S$+#"Zrj!!8UlrN!!5%(!!%!%d,[q-FJ!b!Z1SMS"3E[q +-B!$rBR$rFL!i,[qFGJ!f"*+$iUM!4p&ZrjSJ"qDS,J#CE[q-3N!p32qB-#lrQ," +Zrp*N!!$#-#lrM'B!!)`NE[q3!&*+YHlrU'0S)'lrN!"55*(ZrkJY52rd)'lrN!# +4l[qN,8Mrm#"ZrkL4l[q3!#e)rq`J#'F1)'lrN!!LE[qN)#lrl+)Z*'lrT0AZrq` +Y5[q3!%KZrr![,[qN)'i!*%k3!&"2)#lrm,#Zrr4N#R"R28!!+%lk!PJJE[q3!&+ +Zrj!!%K"`!"!",J"`#$e!ri``"h)"`%(4E[qB-LlrQ(!!-!(3J0#Zrp3J3$!328$ +rQ#!(iSJZ!&0ZriaJ!2mf-#lrdT&ZrjJi,[qBGJ!f"#e$rrc@JpDZrq3J3c!328$ +rRL)Zrrc5V[rJ)%%5%(!!%!%p32qF5N"R!!$#$'i!'2q-BJ!!Q#4Zrj!!8NUel[q +SBfJJE[q3!&*)NHlrU#e)rr3JE[q3!*(Zrk3Y52r`)'lrU*(Zrj!!,8Mrl#!)C`i +JE[q3!#*Zrk3J,[rXSLiNE[qNeHlrl#e+rj!!5'lrm#mZrk3JEJ!N6T!!8%mJ,[r +`X+lrp'3+F'Fp3!!S6[S"@L"Zrj!!8UlrN!!5%(!!%!%d,[q-FJ!b!Z1SMS"3E[q +-B!$rBR$rFL!i,[qFGJ!f"*+$iUM!4p&ZrjiJ"qDS,J#CE[q-)'lrV$)Zrjj`!$! +"NF!Y52q8XHi!)'9J)'lrP&+Zrj33%#"Zrka5V[qX%)!JE[q88UlrP"!3)'lrV&+ +Zrk`3J#"Zrj45V[q8%"!JE[qX8UlrV"#!-#lrQP0ZrjT+3'F!qpiJE[q88UlrP"! +3)'lrV&+Zrk`3J'$F9QlrQL"Z!"M4aM)Zrjj`!$!")QlrV*2Z!##3!)Q4`#e)rj3 +`,[qDCbBJEJ!BdFDal[q8BaSJE[q88UlrP"!3)'lrV&+Zrk`3J&0ZrjTJe#eZ!#$ +rP$!ZrjT6E[qD5N"R!2YQ)'lrP&+Zrj33%#"Zrka5V[qX%)"Jh#"Zrkbal[q`C`K +`Cce!!#KJ&#"Zrkb4lJ!J)Qi!(#+)3N!p3!!S60mFq%jH)&p2l`!J6Y!!F$`!2L! +!!(JJ2M!J*LBJH#!m26-b!!!k3fpYF(*PFh0TEfik4'9MEfe`FQ9cFfP[EM!c-$% +ZB`!!2!!q)!!!H#!q-#!Q*L"i)$`p-c)!!$T$Efe`FQ9cFfP[EMT%C@0[EA"bCA0 +cD@pZ-$-`-5jM!!"19[rS51FI1$iZ!!JSEJ!-0Li!#R!!-!-i"h)!-J53!)&b!E# +"E`!"Y$e%rqJp3rrU8Qlrk$!ZrqL`EJ!+C"ab!$)!dS`J34!30!Gb!$)#dS`J34) +3X!&N!Q$@8flrkM!ZrqU`4f-FFJ!b!0+-)%%3%$3(FJ!b!Y+-)%%5%,!"B`*Jf$! +ZrqL`E[rUC3*JFMJZrqKf!$B%,82rm0D-*%-5%R!!%!%p32rX1LlrkRJ!1!8Y42r +df)`Q4"!6&)!@V[rY)#lrm0#!d+i!%#"!-"!p32rX)Llrp0+"dUi!%#""-K!N,[r +`e),8VJ!3)%)`J5)Zrr65JG+Z!"!J36#!B!$r-M!ZrqU`4fB'8NGJ!2m%1!Gf!$B +%,82rq0D-*%-5%R!!%!%p32rX2#lrkRS!1JBY4IrmfS`Q44!6&)!@V[rY)#lrq0# +!d+i!%#"!-"!p32rX)Llrr0+"dUi!%#""-K!N,[rie),8VJ!3)%)`J5)Zrrc5JG+ +Z!"!J36#!)#lrr#)ZrrL3!)%d,J!+FJ!b!L3Zrra5JT+#X)&X(LmZ!"![$$m'2`4 +1Z[jF6qm!$$!ZrqT53$i!B!$qA#mZ!"![$$mZ!!S`,[rU8N!r!%kkrMC2l`!-2@l +rkJ!+B!$q1%cI(2K1ANje6PErj%MR(cJNEJ!)1Li!$#CZ!!iSEJ!5,8crm#!m!!! +"*0R!,8crp%*!2!!f"VC&C#ai!$J$,86rq0L+)%33%#)ZrrM5V[r`)%%3J#!ZrrM +3J0#Zrr3J3$#$8NCJcLmZrr3[,[r`2`9#CdkkrE*2l`!-3N!m!$B'YN9N%R!!-!2 +3V[r`)%"+%'B%8NCJk(!!,8$rj$B'YN9N!!#S5N0R-L!Zrq4i!$J$,86rr0LZrr! +J4"33FJ!5!LBZrra6JpDZrr!J3aB3G!!8!j+#ikJY32rN0!Cb!$)#dUlrm#""%K" +`!"!"2J!YE[rNrqa`!#e!rqJ`"e0(5N"R)#!ZrqMML#)Zrqad!F+#J)%Y32rS)#l +rl1+),8$rl'$B0!Cb!$)#dS(5V[rd)%%b%(!!-!(PJ0#,)%!JV[rS8NC5V[rNB!$ +r9%cI(2K1ANje)PmJAk!P,S"U!N+A6Y%LAa)I-"p+!@F%TdCJ!U0',SK1d5*I%Km +`(b"I5J&R"+C(B!+L4dl4!*!$#J!iS!%!"3#3"J%!!!'253!"MNN!!!4X8dp59!, +U!)!!(!25!"4"6&*8!!S!UN&9Fc)!!!%Z3Nj%6!!"!6T$6d4&!!F"8N4"9%%!!!' +b4%P86!!0!Ej%6%p(!!)#CNC548B!"!++4Q9KG!!!!XC*3diM!!3#dNP$6di!!!- +18%P$9!!!!aT3Ff9d!!!$*P0*@N8!!!-b8e45)!!"!cj69&)M!!!$9Q&eFh3!!30 +LBfPMEJ!!!hTTBf`i!!!$KQYTEQ3!!!15GQ9bF`!"!ji!J2rr)!!%X`#3"B(rrb! +!"--!N!@#rrmJ!!4c!*!&KIrr*!!%J`cb!)J!K[rr*!!%S`c[mBJ!Krrr)!!%N`# +3"BMrrb!!"0-!N!3#!2rr)!!%j3#3"!)"rrmJ!!6e!*!%"!(rrb!!"'-!N!3%Vrr +r!!!8(!#3"d!!!"R2!*!&J2rr!!!CP`#3"!%!rrm!!"Ph!*!'rrmS!A0Y!*!&!3" +H(!!H9JcaX(J!!J"S(!#3!"m-mJ#3!`-!FK`!V$3-mE"J!!3!I"`!mk)-lr&X!!8 +!KK`"*5m-mJ!i!!B!N!!F!8K1$2)!#!!(rrm!!A2*!*!'rrmS!'!B!*!&J2rr!!! +"T`#3"B,rr`!!!RF!N!@&rrmN!!#!$1e0Q!#'rrmN!!%Q$1e0`!#(rrm!N!2@!*! +&L2rr!!!$!3#3"EArrb!!!J8!N!3""`!d)!!6EJ#3"!)!rrm!!!2C!*!%!J(rr`! +!""F!N!3$k2rr)!!#e3#3"!3"rrmJ!*!("%X!+!3!%Z!-mE"d"+rrr`!!%c!!N!3 +""`!F)!!4)`#3"!2SrrmJ!!PB!*!%"%X!%!3!%3S-mJ#S!)$rr`!!'8!!N!@"rrm +!!"P,!*!&J[rr!!!C9J#3"B2rr`!!'@%!N!@%rrm!!"PX!*!'rrm!!Bil!*!&J2r +r!!!8,!#3"B(rr`!!&6!!N!@#rrm!!"Bd!*!&Jrrr!!!A1!#3"B6rr`!!'$`!N!3 +%5rrr"!!5C3cb!*3$k2rr!!!*Y!#3"B$rr`!!"5%!N!6rN!3!!A1*!*!%!J#3!b! +!"38!N!3#!3!()!!&&3#3"B$rr`!!#A3!N!G2!!!Cp`#3"B6rr`!!'I-!N!3%5rr +r"!!42`cb!!`!K2rr!!!D8J#3"B$rr`!"FjF!N!8"rrmJ!"$i!*!&![rr)!!3fJ# +3"!C`FQpYF(3)a#"cG@CQDAJ,5@jcCA*d)%4TFfX,4AKTFh4TEQFJ8&F,5@jcCA* +d)%4TFfX,4AKTFh4TEQFJ8&F16hGZCA)JFQ9cEh9bBf816hGZCA)JFQ9cEh9bBf8 +*8f9RE@9ZG#!a#90PCfePER3J-JP6C@GYC@jd)$-*8f9RE@9ZG#!e#90PCfePER3 +J0JP6C@GYC@jd)$B(V`: diff --git a/macosx/Makefile b/macosx/Makefile new file mode 100644 index 0000000..7195e77 --- /dev/null +++ b/macosx/Makefile @@ -0,0 +1,196 @@ +######################################################################################################## +# +# Makefile wrapper to build tcl on Mac OS X in a way compatible with the tk/macosx Xcode buildsystem +# uses the standard unix build system in tcl/unix (which can be used directly instead of this +# if you are not using the tk/macosx projects). +# +# RCS: @(#) $Id: Makefile,v 1.22 2005/06/03 08:52:16 das Exp $ +# +######################################################################################################## + +#------------------------------------------------------------------------------------------------------- +# customizable settings + +DESTDIR ?= +INSTALL_ROOT ?= ${DESTDIR} + +BUILD_DIR ?= ${CURDIR}/../../build +SYMROOT ?= ${BUILD_DIR}/${PROJECT} +OBJROOT ?= ${SYMROOT} + +EXTRA_CONFIGURE_ARGS ?= +EXTRA_MAKE_ARGS ?= + +INSTALL_PATH ?= /Library/Frameworks +PREFIX ?= /usr/local +BINDIR ?= ${PREFIX}/bin +LIBDIR ?= ${INSTALL_PATH} +MANDIR ?= ${PREFIX}/man + +# set to non-empty value to install manpages in addition to html help: +INSTALL_MANPAGES ?= + +#------------------------------------------------------------------------------------------------------- +# meta targets + +meta := all install embedded install-embedded clean distclean test + +styles := develop deploy + +all := ${styles} +all : ${all} + +install := ${styles:%=install-%} +install : ${install} +install-%: action := install- + +embedded := ${styles:%=embedded-%} +embedded : embedded-deploy +install-embedded := ${embedded:%=install-%} +install-embedded : install-embedded-deploy + +clean := ${styles:%=clean-%} +clean : ${clean} +clean-%: action := clean- +distclean := ${styles:%=distclean-%} +distclean : ${distclean} +distclean-%: action := distclean- + +test := ${styles:%=test-%} +test : ${test} +test-%: action := test- + +targets := $(foreach v,${meta},${$v}) + +#------------------------------------------------------------------------------------------------------- +# build styles + +BUILD_STYLE = +CONFIGURE_ARGS = +OBJ_DIR = ${OBJROOT}/${BUILD_STYLE} + +develop_make_args := BUILD_STYLE=Development CONFIGURE_ARGS=--enable-symbols +deploy_make_args := BUILD_STYLE=Deployment INSTALL_TARGET=install-strip \ + GENERIC_FLAGS=-DNDEBUG +embedded_make_args := EMBEDDED_BUILD=1 +install_make_args := INSTALL_BUILD=1 + +${targets}: + ${MAKE} ${action}${PROJECT} \ + $(foreach s,${styles} embedded install,$(if $(findstring $s,$@),${${s}_make_args})) + +#------------------------------------------------------------------------------------------------------- +# project specific settings + +PROJECT := tcl +PRODUCT_NAME := Tcl + +UNIX_DIR := ${CURDIR}/../unix +VERSION := $(shell awk -F= '/^TCL_VERSION/ {print $$2; nextfile}' ${UNIX_DIR}/configure.in) +TCLSH := tclsh${VERSION} + +BUILD_TARGET := tclsh tcltest +INSTALL_TARGET := install + +override GENERIC_FLAGS := ${GENERIC_FLAGS} -DTCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING +export CPPROG := cp -p + +INSTALL_TARGETS = install-binaries install-libraries +ifeq (${EMBEDDED_BUILD},) +INSTALL_TARGETS += install-private-headers +endif +ifeq (${INSTALL_BUILD}_${EMBEDDED_BUILD}_${BUILD_STYLE},1__Deployment) +INSTALL_TARGETS += html-tcl +ifneq (${INSTALL_MANPAGES},) +INSTALL_TARGETS += install-doc +endif +endif + +MAKE_VARS := INSTALL_ROOT INSTALL_TARGETS VERSION GENERIC_FLAGS +MAKE_ARGS_V = $(foreach v,${MAKE_VARS},$v='${$v}') + +build-${PROJECT}: target = ${TARGET} +install-${PROJECT}: target = ${INSTALL_TARGET} +clean-${PROJECT} distclean-${PROJECT} test-${PROJECT}: \ + target = $* + +DO_MAKE = +${MAKE} -C ${OBJ_DIR} ${target} ${MAKE_ARGS_V} ${MAKE_ARGS} ${EXTRA_MAKE_ARGS} + +#------------------------------------------------------------------------------------------------------- +# build rules + +${PROJECT}: + ${MAKE} install-${PROJECT} INSTALL_ROOT=${OBJ_DIR}/ + +${OBJ_DIR}/Makefile: ${UNIX_DIR}/Makefile.in ${UNIX_DIR}/configure + mkdir -p ${OBJ_DIR} && cd ${OBJ_DIR} && ${UNIX_DIR}/configure -C \ + --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} \ + --mandir=${MANDIR} --enable-threads --enable-framework \ + ${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS} + +build-${PROJECT}: ${OBJ_DIR}/Makefile + ${DO_MAKE} +# symolic link hackery to trick +# 'make install INSTALL_ROOT=${OBJ_DIR}' +# into building Tcl.framework and tclsh in ${SYMROOT} + @cd ${OBJ_DIR} && mkdir -p $(dir ./${LIBDIR}) $(dir ./${BINDIR}) ${SYMROOT} && \ + rm -f ./${LIBDIR} ./${BINDIR} && ln -fs ${SYMROOT} ./${LIBDIR} && \ + ln -fs ${SYMROOT} ./${BINDIR} && ln -fs ${OBJ_DIR}/tcltest ${SYMROOT} + +install-${PROJECT}: build-${PROJECT} +ifeq (${EMBEDDED_BUILD}_${INSTALL_ROOT},1_) + @echo "Cannot install-embedded with empty INSTALL_ROOT !" && false +endif +ifeq (${EMBEDDED_BUILD},1) + @rm -rf "${INSTALL_ROOT}/${LIBDIR}/Tcl.framework" +endif + ${DO_MAKE} +ifeq (${INSTALL_BUILD},1) +ifeq (${EMBEDDED_BUILD},1) +# if we are embedding frameworks, don't install tclsh + @rm -f "${INSTALL_ROOT}${BINDIR}/${TCLSH}" && \ + rmdir -p "${INSTALL_ROOT}${BINDIR}" 2>&- || true +else +# redo prebinding + @cd ${INSTALL_ROOT}/ && \ + if [ ! -d usr/lib ]; then mkdir -p usr && ln -fs /usr/lib usr/ && RM_USRLIB=1; fi; \ + if [ ! -d System ]; then ln -fs /System . && RM_SYSTEM=1; fi; \ + redo_prebinding -r . "./${LIBDIR}/${PRODUCT_NAME}.framework/Versions/${VERSION}/${PRODUCT_NAME}"; \ + redo_prebinding -r . "./${BINDIR}/${TCLSH}"; \ + if [ -n "$${RM_USRLIB:-}" ]; then rm -f usr/lib; rmdir -p usr 2>&-; fi; \ + if [ -n "$${RM_SYSTEM:-}" ]; then rm -f System; fi +# install tclsh symbolic link + @ln -fs ${TCLSH} ${INSTALL_ROOT}${BINDIR}/tclsh +endif +endif +ifeq (${BUILD_STYLE}_${EMBEDDED_BUILD},Development_) +# keep copy of debug library around, so that +# Deployment build can be installed on top +# of Development build without overwriting +# the debug library + @cd ${INSTALL_ROOT}${LIBDIR}/${PRODUCT_NAME}.framework/Versions/${VERSION} && \ + ln -f "${PRODUCT_NAME}" "${PRODUCT_NAME}_debug" +endif + +clean-${PROJECT}: %-${PROJECT}: + ${DO_MAKE} + rm -rf ${SYMROOT}/{${PRODUCT_NAME}.framework,${TCLSH},tcltest} + rm -f ${OBJ_DIR}{${LIBDIR},${BINDIR}} && \ + rmdir -p ${OBJ_DIR}$(dir ${LIBDIR}) 2>&- || true && \ + rmdir -p ${OBJ_DIR}$(dir ${BINDIR}) 2>&- || true + +distclean-${PROJECT}: %-${PROJECT}: clean-${PROJECT} + ${DO_MAKE} + rm -rf ${OBJ_DIR} + +test-${PROJECT}: %-${PROJECT}: build-${PROJECT} + ${DO_MAKE} + +#------------------------------------------------------------------------------------------------------- + +.PHONY: ${meta} ${targets} ${PROJECT} build-${PROJECT} install-${PROJECT} \ + clean-${PROJECT} distclean-${PROJECT} + +.NOTPARALLEL: + +#------------------------------------------------------------------------------------------------------- diff --git a/macosx/Tcl.pbproj/default.pbxuser b/macosx/Tcl.pbproj/default.pbxuser new file mode 100644 index 0000000..2ac716d --- /dev/null +++ b/macosx/Tcl.pbproj/default.pbxuser @@ -0,0 +1,173 @@ +// !$*UTF8*$! +{ + 00E2F845016E82EB0ACA28DC = { + activeBuildStyle = 00E2F847016E82EB0ACA28DC; + activeExecutable = F594E5F1030774B1016F146B; + activeTarget = 00E2F84C016E8B780ACA28DC; + addToTargets = ( + ); + codeSenseManager = F9D167E40610239A0027C147; + executables = ( + F53ACC52031D9AFE016F146B, + F594E5F1030774B1016F146B, + ); + sourceControlManager = F9D167E30610239A0027C147; + userBuildSettings = { + SYMROOT = "${SRCROOT}/../../build/tcl"; + }; + }; + 00E2F84C016E8B780ACA28DC = { + activeExec = 0; + }; + F53ACC52031D9AFE016F146B = { + activeArgIndex = 2147483647; + activeArgIndices = ( + NO, + NO, + ); + argumentStrings = ( + "${SRCROOT}/../../tcl/tests/all.tcl", + "-verbose \"\"", + ); + configStateDict = { + "PBXLSLaunchAction-0" = { + PBXLSLaunchAction = 0; + PBXLSLaunchStartAction = 1; + PBXLSLaunchStdioStyle = 2; + PBXLSLaunchStyle = 0; + class = PBXLSRunLaunchConfig; + displayName = "Executable Runner"; + identifier = com.apple.Xcode.launch.runConfig; + remoteHostInfo = ""; + startActionInfo = ""; + }; + "PBXLSLaunchAction-1" = { + PBXLSLaunchAction = 1; + PBXLSLaunchStartAction = 1; + PBXLSLaunchStdioStyle = 2; + PBXLSLaunchStyle = 0; + class = PBXGDB_LaunchConfig; + displayName = GDB; + identifier = com.apple.Xcode.launch.GDBMI_Config; + remoteHostInfo = ""; + startActionInfo = ""; + }; + }; + cppStopOnCatchEnabled = 0; + cppStopOnThrowEnabled = 0; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = _debug; + enableDebugStr = 0; + environmentEntries = ( + { + active = YES; + name = TCL_LIBRARY; + value = "${SRCROOT}/../../tcl/library"; + }, + { + active = NO; + name = DYLD_PRINT_LIBRARIES; + }, + ); + isa = PBXExecutable; + launchableReference = F5C37CF303D5BEDF016F146B; + libgmallocEnabled = 0; + name = tcltest; + shlibInfoDictList = ( + ); + sourceDirectories = ( + ); + startupPath = "<<ProductDirectory>>"; + }; + F594E5F1030774B1016F146B = { + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + configStateDict = { + "PBXLSLaunchAction-0" = { + PBXLSLaunchAction = 0; + PBXLSLaunchStartAction = 1; + PBXLSLaunchStdioStyle = 2; + PBXLSLaunchStyle = 0; + class = PBXLSRunLaunchConfig; + displayName = "Executable Runner"; + identifier = com.apple.Xcode.launch.runConfig; + remoteHostInfo = ""; + startActionInfo = ""; + }; + "PBXLSLaunchAction-1" = { + PBXLSLaunchAction = 1; + PBXLSLaunchStartAction = 1; + PBXLSLaunchStdioStyle = 2; + PBXLSLaunchStyle = 0; + class = PBXGDB_LaunchConfig; + displayName = GDB; + identifier = com.apple.Xcode.launch.GDBMI_Config; + remoteHostInfo = ""; + startActionInfo = ""; + }; + }; + cppStopOnCatchEnabled = 0; + cppStopOnThrowEnabled = 0; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = _debug; + enableDebugStr = 0; + environmentEntries = ( + { + active = NO; + name = DYLD_PRINT_LIBRARIES; + }, + ); + isa = PBXExecutable; + launchableReference = F98F02E608E7EF9A00D0320A; + libgmallocEnabled = 0; + name = tclsh; + shlibInfoDictList = ( + ); + sourceDirectories = ( + ); + startupPath = "<<ProductDirectory>>"; + }; + F5C37CF303D5BEDF016F146B = { + isa = PBXFileReference; + lastKnownFileType = "compiled.mach-o.executable"; + path = tcltest; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F98F02E608E7EF9A00D0320A = { + isa = PBXFileReference; + lastKnownFileType = "compiled.mach-o.executable"; + path = tclsh8.6; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F9D167E30610239A0027C147 = { + fallbackIsa = XCSourceControlManager; + isSCMEnabled = 0; + isa = PBXSourceControlManager; + scmConfiguration = { + }; + scmType = scm.cvs; + }; + F9D167E40610239A0027C147 = { + indexTemplatePath = ""; + isa = PBXCodeSenseManager; + usesDefaults = 1; + wantsCodeCompletion = 1; + wantsCodeCompletionAutoSuggestions = 1; + wantsCodeCompletionCaseSensitivity = 1; + wantsCodeCompletionListAlways = 1; + wantsCodeCompletionOnlyMatchingItems = 1; + wantsCodeCompletionParametersIncluded = 1; + wantsCodeCompletionPlaceholdersInserted = 1; + wantsCodeCompletionTabCompletes = 1; + wantsIndex = 1; + }; +} diff --git a/macosx/Tcl.pbproj/jingham.pbxuser b/macosx/Tcl.pbproj/jingham.pbxuser new file mode 100644 index 0000000..2472114 --- /dev/null +++ b/macosx/Tcl.pbproj/jingham.pbxuser @@ -0,0 +1,173 @@ +// !$*UTF8*$! +{ + 00E2F845016E82EB0ACA28DC = { + activeBuildStyle = 00E2F847016E82EB0ACA28DC; + activeExecutable = F594E5F1030774B1016F146B; + activeTarget = 00E2F84C016E8B780ACA28DC; + addToTargets = ( + ); + codeSenseManager = F9D167E40610239A0027C147; + executables = ( + F53ACC52031D9AFE016F146B, + F594E5F1030774B1016F146B, + ); + sourceControlManager = F9D167E30610239A0027C147; + userBuildSettings = { + SYMROOT = "${SRCROOT}/../../build/tcl"; + }; + }; + 00E2F84C016E8B780ACA28DC = { + activeExec = 0; + }; + F53ACC52031D9AFE016F146B = { + activeArgIndex = 2147483647; + activeArgIndices = ( + NO, + NO, + ); + argumentStrings = ( + "${SRCROOT}/../../tcl/tests/all.tcl", + "-verbose \"\"", + ); + configStateDict = { + "PBXLSLaunchAction-0" = { + PBXLSLaunchAction = 0; + PBXLSLaunchStartAction = 1; + PBXLSLaunchStdioStyle = 2; + PBXLSLaunchStyle = 0; + class = PBXLSRunLaunchConfig; + displayName = "Executable Runner"; + identifier = com.apple.Xcode.launch.runConfig; + remoteHostInfo = ""; + startActionInfo = ""; + }; + "PBXLSLaunchAction-1" = { + PBXLSLaunchAction = 1; + PBXLSLaunchStartAction = 1; + PBXLSLaunchStdioStyle = 2; + PBXLSLaunchStyle = 0; + class = PBXGDB_LaunchConfig; + displayName = GDB; + identifier = com.apple.Xcode.launch.GDBMI_Config; + remoteHostInfo = ""; + startActionInfo = ""; + }; + }; + cppStopOnCatchEnabled = 0; + cppStopOnThrowEnabled = 0; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = _debug; + enableDebugStr = 0; + environmentEntries = ( + { + active = YES; + name = TCL_LIBRARY; + value = "${SRCROOT}/../../tcl/library"; + }, + { + active = NO; + name = DYLD_PRINT_LIBRARIES; + }, + ); + isa = PBXExecutable; + launchableReference = F5C37CF303D5BEDF016F146B; + libgmallocEnabled = 0; + name = tcltest; + shlibInfoDictList = ( + ); + sourceDirectories = ( + ); + startupPath = "<<ProductDirectory>>"; + }; + F594E5F1030774B1016F146B = { + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + configStateDict = { + "PBXLSLaunchAction-0" = { + PBXLSLaunchAction = 0; + PBXLSLaunchStartAction = 1; + PBXLSLaunchStdioStyle = 2; + PBXLSLaunchStyle = 0; + class = PBXLSRunLaunchConfig; + displayName = "Executable Runner"; + identifier = com.apple.Xcode.launch.runConfig; + remoteHostInfo = ""; + startActionInfo = ""; + }; + "PBXLSLaunchAction-1" = { + PBXLSLaunchAction = 1; + PBXLSLaunchStartAction = 1; + PBXLSLaunchStdioStyle = 2; + PBXLSLaunchStyle = 0; + class = PBXGDB_LaunchConfig; + displayName = GDB; + identifier = com.apple.Xcode.launch.GDBMI_Config; + remoteHostInfo = ""; + startActionInfo = ""; + }; + }; + cppStopOnCatchEnabled = 0; + cppStopOnThrowEnabled = 0; + customDataFormattersEnabled = 1; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = _debug; + enableDebugStr = 0; + environmentEntries = ( + { + active = NO; + name = DYLD_PRINT_LIBRARIES; + }, + ); + isa = PBXExecutable; + launchableReference = F98F02E608E7EF9A00D0320A; + libgmallocEnabled = 0; + name = tclsh; + shlibInfoDictList = ( + ); + sourceDirectories = ( + ); + startupPath = "<<ProductDirectory>>"; + }; + F5C37CF303D5BEDF016F146B = { + isa = PBXFileReference; + lastKnownFileType = "compiled.mach-o.executable"; + path = tcltest; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F98F02E608E7EF9A00D0320A = { + isa = PBXFileReference; + lastKnownFileType = "compiled.mach-o.executable"; + path = tclsh8.5; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F9D167E30610239A0027C147 = { + fallbackIsa = XCSourceControlManager; + isSCMEnabled = 0; + isa = PBXSourceControlManager; + scmConfiguration = { + }; + scmType = scm.cvs; + }; + F9D167E40610239A0027C147 = { + indexTemplatePath = ""; + isa = PBXCodeSenseManager; + usesDefaults = 1; + wantsCodeCompletion = 1; + wantsCodeCompletionAutoSuggestions = 1; + wantsCodeCompletionCaseSensitivity = 1; + wantsCodeCompletionListAlways = 1; + wantsCodeCompletionOnlyMatchingItems = 1; + wantsCodeCompletionParametersIncluded = 1; + wantsCodeCompletionPlaceholdersInserted = 1; + wantsCodeCompletionTabCompletes = 1; + wantsIndex = 1; + }; +} diff --git a/macosx/Tcl.pbproj/project.pbxproj b/macosx/Tcl.pbproj/project.pbxproj new file mode 100644 index 0000000..e284063 --- /dev/null +++ b/macosx/Tcl.pbproj/project.pbxproj @@ -0,0 +1,1539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 39; + objects = { + 00E2F845016E82EB0ACA28DC = { + buildSettings = { + }; + buildStyles = ( + 00E2F847016E82EB0ACA28DC, + 00E2F848016E82EB0ACA28DC, + ); + hasScannedForEncodings = 1; + isa = PBXProject; + mainGroup = 00E2F846016E82EB0ACA28DC; + productRefGroup = 00E2F84A016E8A830ACA28DC; + projectDirPath = ""; + targets = ( + 00E2F84C016E8B780ACA28DC, + ); + }; + 00E2F846016E82EB0ACA28DC = { + children = ( + F5306CA003CAC9AE016F146B, + F5306C9F03CAC979016F146B, + F5C88655017D604601DC9062, + F5F24FEE016ED0DF01DC9062, + 00E2F855016E922C0ACA28DC, + 00E2F857016E92B00ACA28DC, + 00E2F85A016E92B00ACA28DC, + 00E2F84A016E8A830ACA28DC, + ); + isa = PBXGroup; + refType = 4; + sourceTree = "<group>"; + }; + 00E2F847016E82EB0ACA28DC = { + buildSettings = { + MAKE_TARGET = develop; + }; + isa = PBXBuildStyle; + name = Development; + }; + 00E2F848016E82EB0ACA28DC = { + buildSettings = { + MAKE_TARGET = deploy; + }; + isa = PBXBuildStyle; + name = Deployment; + }; + 00E2F84A016E8A830ACA28DC = { + children = ( + F53ACC73031DA405016F146B, + F53ACC5C031D9D11016F146B, + F9A61C9D04C2B4E3006F5A0B, + ); + isa = PBXGroup; + name = Products; + refType = 4; + sourceTree = "<group>"; + }; + 00E2F84C016E8B780ACA28DC = { + buildArgumentsString = "-c \"cd \\\"${TCL_SRCROOT}/macosx\\\" && ACTION=${ACTION} && CFLAGS=\\\"${CFLAGS}\\\" gnumake \\${ACTION:+\\${ACTION/clean/distclean}-}${MAKE_TARGET} INSTALL_ROOT=\\\"${DSTROOT}\\\" INSTALL_PATH=\\\"${INSTALL_PATH}\\\" PREFIX=\\\"${PREFIX}\\\" BINDIR=\\\"${BINDIR}\\\" MANDIR=\\\"${MANDIR}\\\" \\${EXTRA_MAKE_FLAGS} ${ALL_SETTINGS}\""; + buildPhases = ( + ); + buildSettings = { + BINDIR = "${PREFIX}/bin"; + CFLAGS = ""; + INSTALL_PATH = /Library/Frameworks; + MANDIR = "${PREFIX}/man"; + PREFIX = /usr/local; + PRODUCT_NAME = Tcl; + TCL_SRCROOT = "${SRCROOT}/../../tcl"; + TEMP_DIR = "${PROJECT_TEMP_DIR}"; + }; + buildToolPath = /bin/bash; + buildWorkingDirectory = "${SRCROOT}"; + dependencies = ( + ); + isa = PBXLegacyTarget; + name = Tcl; + passBuildSettingsInEnvironment = 0; + productName = Tcl; + }; + 00E2F854016E922C0ACA28DC = { + children = ( + F5F24F87016ECAFC01DC9062, + F5F24F88016ECAFC01DC9062, + F5F24F89016ECAFC01DC9062, + F5F24F8A016ECAFC01DC9062, + F5F24F8B016ECAFC01DC9062, + F5F24F8C016ECAFC01DC9062, + F5F24F8D016ECAFC01DC9062, + F5F24F8E016ECAFC01DC9062, + F5F24F8F016ECAFC01DC9062, + F5F24F90016ECAFC01DC9062, + F5F24F91016ECAFC01DC9062, + F5F24F92016ECAFC01DC9062, + F5F24F93016ECAFC01DC9062, + F5F24F94016ECAFC01DC9062, + F5F24F95016ECAFC01DC9062, + F5F24F96016ECAFC01DC9062, + F5F24F97016ECAFC01DC9062, + F5F24F98016ECAFC01DC9062, + F5F24F99016ECAFC01DC9062, + F5F24F9A016ECAFC01DC9062, + F5F24F9B016ECAFC01DC9062, + F5F24F9C016ECAFC01DC9062, + F5F24F9D016ECAFC01DC9062, + F5F24F9E016ECAFC01DC9062, + F5F24F9F016ECAFC01DC9062, + F5F24FA0016ECAFC01DC9062, + F5F24FA1016ECAFC01DC9062, + F5F24FA2016ECAFC01DC9062, + F5F24FA3016ECAFC01DC9062, + F5F24FA4016ECAFC01DC9062, + F5F24FA5016ECAFC01DC9062, + F5F24FA6016ECAFC01DC9062, + F5F24FA7016ECAFC01DC9062, + F5F24FA8016ECAFC01DC9062, + F5F24FA9016ECAFC01DC9062, + F5F24FAA016ECAFC01DC9062, + F5F24FAB016ECAFC01DC9062, + F5F24FAC016ECAFC01DC9062, + F5F24FAD016ECAFC01DC9062, + F5F24FAE016ECAFC01DC9062, + F5F24FAF016ECAFC01DC9062, + F5F24FB0016ECAFC01DC9062, + F5F24FB1016ECAFC01DC9062, + F5F24FB2016ECAFC01DC9062, + F5F24FB3016ECAFC01DC9062, + F5F24FB4016ECAFC01DC9062, + F5F24FB5016ECAFC01DC9062, + F5F24FB6016ECAFC01DC9062, + F5F24FB7016ECAFC01DC9062, + F5F24FB8016ECAFC01DC9062, + F5F24FB9016ECAFC01DC9062, + F5F24FBA016ECAFC01DC9062, + F9FED5C7047C7D1B006F146B, + F5F24FBB016ECAFC01DC9062, + F5F24FD3016ECB4901DC9062, + F5F24FBC016ECAFC01DC9062, + F5F24FBD016ECAFC01DC9062, + F5F24FBE016ECAFC01DC9062, + F5F24FBF016ECAFC01DC9062, + F5F24FC0016ECAFC01DC9062, + F5F24FC1016ECAFC01DC9062, + F5F24FC2016ECAFC01DC9062, + F5F24FC3016ECAFC01DC9062, + F5F24FC4016ECAFC01DC9062, + F5F24FC5016ECAFC01DC9062, + F5F24FC6016ECAFC01DC9062, + F5F24FC7016ECAFC01DC9062, + F5F24FC8016ECAFC01DC9062, + F5F24FC9016ECAFC01DC9062, + F5F24FCA016ECAFC01DC9062, + F5F24FCB016ECAFC01DC9062, + F5F24FCC016ECAFC01DC9062, + F5F24FCD016ECAFC01DC9062, + F5F24FCE016ECAFC01DC9062, + F5F24FCF016ECAFC01DC9062, + F5F24FD0016ECAFC01DC9062, + ); + isa = PBXGroup; + name = Sources; + path = ""; + refType = 4; + sourceTree = "<group>"; + }; + 00E2F855016E922C0ACA28DC = { + children = ( + 00E2F856016E92B00ACA28DC, + 00E2F854016E922C0ACA28DC, + ); + isa = PBXGroup; + name = generic; + refType = 4; + sourceTree = "<group>"; + }; + 00E2F856016E92B00ACA28DC = { + children = ( + F5F24F6B016ECAA401DC9062, + F5F24F6C016ECAA401DC9062, + F5F24F6D016ECAA401DC9062, + F5F24F6E016ECAA401DC9062, + F5F24F6F016ECAA401DC9062, + F5F24F70016ECAA401DC9062, + F5F24F72016ECAA401DC9062, + F5F24F73016ECAA401DC9062, + F5F24F74016ECAA401DC9062, + F5F24F75016ECAA401DC9062, + F5F24F77016ECAA401DC9062, + F5F24F78016ECAA401DC9062, + F5F24FD1016ECB1E01DC9062, + F5F24FD2016ECB1E01DC9062, + ); + isa = PBXGroup; + name = Headers; + refType = 4; + sourceTree = "<group>"; + }; + 00E2F857016E92B00ACA28DC = { + children = ( + 00E2F858016E92B00ACA28DC, + 00E2F859016E92B00ACA28DC, + ); + isa = PBXGroup; + name = macosx; + refType = 4; + sourceTree = "<group>"; + }; + 00E2F858016E92B00ACA28DC = { + children = ( + ); + isa = PBXGroup; + name = Headers; + refType = 4; + sourceTree = "<group>"; + }; + 00E2F859016E92B00ACA28DC = { + children = ( + F5A1836F018242A501DC9062, + F9FED5C6047C7CEC006F146B, + ); + isa = PBXGroup; + name = Sources; + refType = 4; + sourceTree = "<group>"; + }; + 00E2F85A016E92B00ACA28DC = { + children = ( + 00E2F85B016E92B00ACA28DC, + 00E2F85C016E92B00ACA28DC, + ); + isa = PBXGroup; + name = unix; + refType = 4; + sourceTree = "<group>"; + }; + 00E2F85B016E92B00ACA28DC = { + children = ( + F5F24FD6016ECC0F01DC9062, + F5F24FD7016ECC0F01DC9062, + ); + isa = PBXGroup; + name = Headers; + refType = 4; + sourceTree = "<group>"; + }; + 00E2F85C016E92B00ACA28DC = { + children = ( + F5F24FD8016ECC0F01DC9062, + F5F24FD9016ECC0F01DC9062, + F5F24FDB016ECC0F01DC9062, + F5F24FDC016ECC0F01DC9062, + F5F24FDD016ECC0F01DC9062, + F5F24FDE016ECC0F01DC9062, + F5F24FDF016ECC0F01DC9062, + F5F24FE0016ECC0F01DC9062, + F5F24FE1016ECC0F01DC9062, + F5F24FE2016ECC0F01DC9062, + F5F24FE3016ECC0F01DC9062, + F5F24FE4016ECC0F01DC9062, + F5F24FE5016ECC0F01DC9062, + F5F24FE6016ECC0F01DC9062, + F5F24FE7016ECC0F01DC9062, + ); + isa = PBXGroup; + name = Sources; + refType = 4; + sourceTree = "<group>"; + }; +//000 +//001 +//002 +//003 +//004 +//F50 +//F51 +//F52 +//F53 +//F54 + F5306C9F03CAC979016F146B = { + children = ( + F5306CA303CAC9DE016F146B, + F5306CA103CAC9DE016F146B, + F5306CA203CAC9DE016F146B, + ); + isa = PBXGroup; + name = "Build System"; + refType = 4; + sourceTree = "<group>"; + }; + F5306CA003CAC9AE016F146B = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = text; + name = ChangeLog; + path = ../ChangeLog; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5306CA103CAC9DE016F146B = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = text.script.sh; + name = configure.in; + path = ../unix/configure.in; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5306CA203CAC9DE016F146B = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = text; + name = Makefile.in; + path = ../unix/Makefile.in; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5306CA303CAC9DE016F146B = { + isa = PBXFileReference; + lastKnownFileType = text; + name = tcl.m4; + path = ../unix/tcl.m4; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F53ACC5C031D9D11016F146B = { + isa = PBXFileReference; + lastKnownFileType = "compiled.mach-o.executable"; + path = tclsh8.6; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F53ACC73031DA405016F146B = { + isa = PBXFileReference; + lastKnownFileType = "compiled.mach-o.executable"; + path = tcltest; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F5A1836F018242A501DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = tclMacOSXBundle.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5C88655017D604601DC9062 = { + children = ( + F5C88656017D604601DC9062, + F5C88657017D60C901DC9062, + F5C88658017D60C901DC9062, + ); + isa = PBXGroup; + name = "Header Tools"; + refType = 4; + sourceTree = "<group>"; + }; + F5C88656017D604601DC9062 = { + isa = PBXFileReference; + lastKnownFileType = text; + name = genStubs.tcl; + path = ../tools/genStubs.tcl; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5C88657017D60C901DC9062 = { + isa = PBXFileReference; + lastKnownFileType = text; + name = tcl.decls; + path = ../generic/tcl.decls; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5C88658017D60C901DC9062 = { + isa = PBXFileReference; + lastKnownFileType = text; + name = tclInt.decls; + path = ../generic/tclInt.decls; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F6B016ECAA401DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = regcustom.h; + path = ../generic/regcustom.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F6C016ECAA401DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = regerrs.h; + path = ../generic/regerrs.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F6D016ECAA401DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = regguts.h; + path = ../generic/regguts.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F6E016ECAA401DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tcl.h; + path = ../generic/tcl.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F6F016ECAA401DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tclCompile.h; + path = ../generic/tclCompile.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F70016ECAA401DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tclDecls.h; + path = ../generic/tclDecls.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F72016ECAA401DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tclInt.h; + path = ../generic/tclInt.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F73016ECAA401DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tclIntDecls.h; + path = ../generic/tclIntDecls.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F74016ECAA401DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tclIntPlatDecls.h; + path = ../generic/tclIntPlatDecls.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F75016ECAA401DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tclIO.h; + path = ../generic/tclIO.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F77016ECAA401DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tclPlatDecls.h; + path = ../generic/tclPlatDecls.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F78016ECAA401DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tclRegexp.h; + path = ../generic/tclRegexp.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F87016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = regc_color.c; + path = ../generic/regc_color.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F88016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = regc_cvec.c; + path = ../generic/regc_cvec.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F89016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = regc_lex.c; + path = ../generic/regc_lex.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F8A016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = regc_locale.c; + path = ../generic/regc_locale.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F8B016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = regc_nfa.c; + path = ../generic/regc_nfa.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F8C016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = regcomp.c; + path = ../generic/regcomp.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F8D016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = rege_dfa.c; + path = ../generic/rege_dfa.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F8E016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = regerror.c; + path = ../generic/regerror.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F8F016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = regexec.c; + path = ../generic/regexec.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F90016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = regfree.c; + path = ../generic/regfree.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F91016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = regfronts.c; + path = ../generic/regfronts.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F92016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclAlloc.c; + path = ../generic/tclAlloc.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F93016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclAsync.c; + path = ../generic/tclAsync.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F94016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclBasic.c; + path = ../generic/tclBasic.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F95016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclBinary.c; + path = ../generic/tclBinary.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F96016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclCkalloc.c; + path = ../generic/tclCkalloc.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F97016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclClock.c; + path = ../generic/tclClock.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F98016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclCmdAH.c; + path = ../generic/tclCmdAH.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F99016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclCmdIL.c; + path = ../generic/tclCmdIL.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F9A016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclCmdMZ.c; + path = ../generic/tclCmdMZ.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F9B016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclCompCmds.c; + path = ../generic/tclCompCmds.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F9C016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclCompExpr.c; + path = ../generic/tclCompExpr.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F9D016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclCompile.c; + path = ../generic/tclCompile.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F9E016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclDate.c; + path = ../generic/tclDate.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24F9F016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclEncoding.c; + path = ../generic/tclEncoding.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FA0016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclEnv.c; + path = ../generic/tclEnv.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FA1016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclEvent.c; + path = ../generic/tclEvent.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FA2016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclExecute.c; + path = ../generic/tclExecute.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FA3016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclFCmd.c; + path = ../generic/tclFCmd.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FA4016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclFileName.c; + path = ../generic/tclFileName.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FA5016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclGet.c; + path = ../generic/tclGet.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FA6016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclHash.c; + path = ../generic/tclHash.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FA7016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclHistory.c; + path = ../generic/tclHistory.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FA8016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclIndexObj.c; + path = ../generic/tclIndexObj.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FA9016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclInterp.c; + path = ../generic/tclInterp.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FAA016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclIO.c; + path = ../generic/tclIO.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FAB016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclIOCmd.c; + path = ../generic/tclIOCmd.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FAC016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclIOGT.c; + path = ../generic/tclIOGT.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FAD016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclIOSock.c; + path = ../generic/tclIOSock.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FAE016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclIOUtil.c; + path = ../generic/tclIOUtil.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FAF016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclLink.c; + path = ../generic/tclLink.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FB0016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclListObj.c; + path = ../generic/tclListObj.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FB1016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclLiteral.c; + path = ../generic/tclLiteral.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FB2016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclLoad.c; + path = ../generic/tclLoad.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FB3016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclLoadNone.c; + path = ../generic/tclLoadNone.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FB4016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclMain.c; + path = ../generic/tclMain.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FB5016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclNamesp.c; + path = ../generic/tclNamesp.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FB6016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclNotify.c; + path = ../generic/tclNotify.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FB7016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclObj.c; + path = ../generic/tclObj.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FB8016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclPanic.c; + path = ../generic/tclPanic.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FB9016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclParse.c; + path = ../generic/tclParse.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FBA016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclParseExpr.c; + path = ../generic/tclParseExpr.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FBB016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclPipe.c; + path = ../generic/tclPipe.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FBC016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclPosixStr.c; + path = ../generic/tclPosixStr.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FBD016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclPreserve.c; + path = ../generic/tclPreserve.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FBE016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclProc.c; + path = ../generic/tclProc.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FBF016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclRegexp.c; + path = ../generic/tclRegexp.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FC0016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclResolve.c; + path = ../generic/tclResolve.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FC1016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclResult.c; + path = ../generic/tclResult.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FC2016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclScan.c; + path = ../generic/tclScan.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FC3016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclStringObj.c; + path = ../generic/tclStringObj.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FC4016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclStubInit.c; + path = ../generic/tclStubInit.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FC5016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclStubLib.c; + path = ../generic/tclStubLib.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FC6016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclTest.c; + path = ../generic/tclTest.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FC7016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclTestObj.c; + path = ../generic/tclTestObj.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FC8016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclTestProcBodyObj.c; + path = ../generic/tclTestProcBodyObj.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FC9016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclThread.c; + path = ../generic/tclThread.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FCA016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclThreadJoin.c; + path = ../generic/tclThreadJoin.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FCB016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclThreadTest.c; + path = ../generic/tclThreadTest.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FCC016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclTimer.c; + path = ../generic/tclTimer.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FCD016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclUniData.c; + path = ../generic/tclUniData.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FCE016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclUtf.c; + path = ../generic/tclUtf.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FCF016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclUtil.c; + path = ../generic/tclUtil.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FD0016ECAFC01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclVar.c; + path = ../generic/tclVar.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FD1016ECB1E01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = regex.h; + path = ../generic/regex.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FD2016ECB1E01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tclPort.h; + path = ../generic/tclPort.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FD3016ECB4901DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclPkg.c; + path = ../generic/tclPkg.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FD6016ECC0F01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tclUnixPort.h; + path = ../unix/tclUnixPort.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FD7016ECC0F01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = tclUnixThrd.h; + path = ../unix/tclUnixThrd.h; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FD8016ECC0F01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclAppInit.c; + path = ../unix/tclAppInit.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FD9016ECC0F01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclLoadDyld.c; + path = ../unix/tclLoadDyld.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FDB016ECC0F01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclUnixChan.c; + path = ../unix/tclUnixChan.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FDC016ECC0F01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclUnixEvent.c; + path = ../unix/tclUnixEvent.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FDD016ECC0F01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclUnixFCmd.c; + path = ../unix/tclUnixFCmd.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FDE016ECC0F01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclUnixFile.c; + path = ../unix/tclUnixFile.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FDF016ECC0F01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclUnixInit.c; + path = ../unix/tclUnixInit.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FE0016ECC0F01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclUnixNotfy.c; + path = ../unix/tclUnixNotfy.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FE1016ECC0F01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclUnixPipe.c; + path = ../unix/tclUnixPipe.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FE2016ECC0F01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclUnixSock.c; + path = ../unix/tclUnixSock.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FE3016ECC0F01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclUnixTest.c; + path = ../unix/tclUnixTest.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FE4016ECC0F01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclUnixThrd.c; + path = ../unix/tclUnixThrd.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FE5016ECC0F01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclUnixTime.c; + path = ../unix/tclUnixTime.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FE6016ECC0F01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclXtNotify.c; + path = ../unix/tclXtNotify.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FE7016ECC0F01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclXtTest.c; + path = ../unix/tclXtTest.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FEE016ED0DF01DC9062 = { + children = ( + F5F24FEF016ED0DF01DC9062, + F5F24FF0016ED0DF01DC9062, + F5F24FF3016ED0DF01DC9062, + F5F24FF4016ED0DF01DC9062, + F5F24FF5016ED0DF01DC9062, + F5F24FF6016ED0DF01DC9062, + F5F24FFA016ED0DF01DC9062, + F5F24FFC016ED0DF01DC9062, + F5F24FFE016ED0DF01DC9062, + F5F25001016ED0DF01DC9062, + F5F25002016ED0DF01DC9062, + F5F25003016ED0DF01DC9062, + F5F25005016ED0DF01DC9062, + F5F25007016ED0DF01DC9062, + F5F25008016ED0DF01DC9062, + F5F2500A016ED0DF01DC9062, + ); + isa = PBXGroup; + name = Scripts; + refType = 4; + sourceTree = "<group>"; + }; + F5F24FEF016ED0DF01DC9062 = { + isa = PBXFileReference; + lastKnownFileType = text; + name = auto.tcl; + path = ../library/auto.tcl; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FF0016ED0DF01DC9062 = { + includeInIndex = 0; + isa = PBXFileReference; + lastKnownFileType = folder; + name = dde; + path = ../library/dde; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FF3016ED0DF01DC9062 = { + includeInIndex = 0; + isa = PBXFileReference; + lastKnownFileType = folder; + name = encoding; + path = ../library/encoding; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FF4016ED0DF01DC9062 = { + isa = PBXFileReference; + lastKnownFileType = text; + name = history.tcl; + path = ../library/history.tcl; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FF5016ED0DF01DC9062 = { + includeInIndex = 0; + isa = PBXFileReference; + lastKnownFileType = folder; + name = http; + path = ../library/http; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FF6016ED0DF01DC9062 = { + includeInIndex = 0; + isa = PBXFileReference; + lastKnownFileType = folder; + name = http1.0; + path = ../library/http1.0; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FFA016ED0DF01DC9062 = { + isa = PBXFileReference; + lastKnownFileType = text; + name = init.tcl; + path = ../library/init.tcl; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FFC016ED0DF01DC9062 = { + includeInIndex = 0; + isa = PBXFileReference; + lastKnownFileType = folder; + name = msgcat; + path = ../library/msgcat; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F24FFE016ED0DF01DC9062 = { + includeInIndex = 0; + isa = PBXFileReference; + lastKnownFileType = folder; + name = opt; + path = ../library/opt; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F25001016ED0DF01DC9062 = { + isa = PBXFileReference; + lastKnownFileType = text; + name = package.tcl; + path = ../library/package.tcl; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F25002016ED0DF01DC9062 = { + isa = PBXFileReference; + lastKnownFileType = text; + name = parray.tcl; + path = ../library/parray.tcl; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F25003016ED0DF01DC9062 = { + includeInIndex = 0; + isa = PBXFileReference; + lastKnownFileType = folder; + name = reg; + path = ../library/reg; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F25005016ED0DF01DC9062 = { + isa = PBXFileReference; + lastKnownFileType = text; + name = safe.tcl; + path = ../library/safe.tcl; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F25007016ED0DF01DC9062 = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = text; + name = tclIndex; + path = ../library/tclIndex; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F25008016ED0DF01DC9062 = { + includeInIndex = 0; + isa = PBXFileReference; + lastKnownFileType = folder; + name = tcltest; + path = ../library/tcltest; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + F5F2500A016ED0DF01DC9062 = { + isa = PBXFileReference; + lastKnownFileType = text; + name = word.tcl; + path = ../library/word.tcl; + refType = 2; + sourceTree = SOURCE_ROOT; + }; +//F50 +//F51 +//F52 +//F53 +//F54 +//F90 +//F91 +//F92 +//F93 +//F94 + F9A61C9D04C2B4E3006F5A0B = { + explicitFileType = wrapper.framework; + isa = PBXFileReference; + path = Tcl.framework; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F9FED5C6047C7CEC006F146B = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = tclMacOSXFCmd.c; + refType = 4; + sourceTree = "<group>"; + }; + F9FED5C7047C7D1B006F146B = { + fileEncoding = 5; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = tclPathObj.c; + path = ../generic/tclPathObj.c; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + }; + rootObject = 00E2F845016E82EB0ACA28DC; +} diff --git a/tests/NRE.test b/tests/NRE.test new file mode 100644 index 0000000..4a279bc --- /dev/null +++ b/tests/NRE.test @@ -0,0 +1,476 @@ +# Commands covered: proc, apply, [interp alias], [namespce import], tailcall +# +# This file contains a collection of tests for the non-recursive executor that +# avoids recursive calls to TEBC. +# +# Copyright (c) 2008 by Miguel Sofer. +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# +# RCS: @(#) $Id: NRE.test,v 1.10 2008/08/01 00:44:05 msofer Exp $ + +if {[lsearch [namespace children] ::tcltest] == -1} { + package require tcltest + namespace import -force ::tcltest::* +} + +testConstraint tailcall [llength [info commands ::tcl::unsupported::tailcall]] +testConstraint testnrelevels [llength [info commands testnrelevels]] + +# +# The tests that risked blowing the C stack on failure have been removed: we +# can now actually measure using testnrelevels. +# + +if {[testConstraint testnrelevels]} { + namespace eval testnre { + # + # [testnrelevels] returns a 6-list with: C-stack depth, iPtr->numlevels, + # cmdFrame level, callFrame level, tosPtr and callback depth + # + variable last [testnrelevels] + proc depthDiff {} { + variable last + set depth [testnrelevels] + set res {} + foreach t $depth l $last { + lappend res [expr {$t-$l}] + } + set last $depth + return $res + } + proc setabs {} { + uplevel 1 variable abs -[lindex [testnrelevels] 0] + } + + variable body0 { + set x [depthDiff] + if {[incr i] > 10} { + variable abs + incr abs [lindex [testnrelevels] 0] + return [list [lrange $x 0 3] $abs] + } + } + proc makebody txt { + variable body0 + return "$body0; $txt" + } + namespace export * + } + namespace import testnre::* +} + +test NRE-1.1 {self-recursive procs} -setup { + proc a i [makebody {a $i}] +} -body { + setabs + a 0 +} -cleanup { + rename a {} + unset abs +} -result {{0 1 1 1} 0} + +test NRE-1.2 {self-recursive lambdas} -setup { + set a [list i [makebody {apply $::a $i}]] +} -body { + setabs + apply $a 0 +} -cleanup { + unset a abs +} -result {{0 1 1 1} 0} + +test NRE-1.3 {mutually recursive procs and lambdas} -setup { + proc a i { + apply $::b [incr i] + } + set b [list i [makebody {a $i}]] +} -body { + setabs + a 0 +} -cleanup { + rename a {} + unset b abs +} -result {{0 2 2 2} 0} + +# +# Test that aliases are non-recursive +# + +test NRE-2.1 {alias is not recursive} -setup { + proc a i [makebody {b $i}] + interp alias {} b {} a +} -body { + setabs + a 0 +} -cleanup { + rename a {} + rename b {} + unset abs +} -result {{0 2 1 1} 0} + +# +# Test that imports are non-recursive +# + +test NRE-3.1 {imports are not recursive} -setup { + namespace eval foo { + setabs + namespace export a + } + proc foo::a i [makebody {::a $i}] + namespace import foo::a +} -body { + a 0 +} -cleanup { + rename a {} + namespace delete ::foo +} -result {{0 2 1 1} 0} + +test NRE-4.1 {ensembles are not recursive} -setup { + proc a i [makebody {b foo $i}] + namespace ensemble create \ + -command b \ + -map [list foo a] +} -body { + setabs + a 0 +} -cleanup { + rename a {} + rename b {} + unset abs +} -result {{0 2 1 1} 0} + +test NRE-5.1 {[namespace eval] is not recursive} -setup { + namespace eval ::foo { + setabs + } + proc foo::a i [makebody {namespace eval ::foo [list a $i]}] +} -body { + ::foo::a 0 +} -cleanup { + namespace delete ::foo +} -result {{0 2 2 2} 0} + +test NRE-5.2 {[namespace eval] is not recursive} -setup { + namespace eval ::foo { + setabs + } + proc foo::a i [makebody {namespace eval ::foo "set x $i; a $i"}] +} -body { + foo::a 0 +} -cleanup { + namespace delete ::foo +} -result {{0 2 2 2} 0} + +test NRE-6.1 {[uplevel] is not recursive} -setup { + proc a i [makebody {uplevel 1 [list a $i]}] +} -body { + setabs + a 0 +} -cleanup { + rename a {} + unset abs +} -result {{0 2 2 0} 0} + +test NRE-6.2 {[uplevel] is not recursive} -setup { + setabs + proc a i [makebody {uplevel 1 "set x $i; a $i"}] +} -body { + a 0 +} -cleanup { + rename a {} + unset abs +} -result {{0 2 2 0} 0} + +test NRE-7.1 {[catch] is not recursive} -setup { + setabs + proc a i [makebody {uplevel 1 "catch {a $i} msg; set msg"}] +} -body { + a 0 +} -cleanup { + rename a {} + unset x abs +} -result {{0 3 3 0} 0} + +# +# Basic TclOO tests +# + +test NRE-oo.1 {really deep calls in oo - direct} -setup { + oo::object create foo + oo::objdefine foo method bar i [makebody {foo bar $i}] +} -body { + setabs + foo bar 0 +} -cleanup { + foo destroy + unset abs +} -result {{0 1 1 1} 0} + +test NRE-oo.2 {really deep calls in oo - call via [self]} -setup { + oo::object create foo + oo::objdefine foo method bar i [makebody {[self] bar $i}] +} -body { + setabs + foo bar 0 +} -cleanup { + foo destroy + unset abs +} -result {{0 1 1 1} 0} + +test NRE-oo.3 {really deep calls in oo - private calls} -setup { + oo::object create foo + oo::objdefine foo method bar i [makebody {my bar $i}] +} -body { + setabs + foo bar 0 +} -cleanup { + foo destroy + unset abs +} -result {{0 1 1 1} 0} + +test NRE-oo.4 {really deep calls in oo - overriding} -setup { + oo::class create foo { + method bar i [makebody {my bar $i}] + } + oo::class create boo { + superclass foo + method bar i [makebody {next $i}] + } +} -body { + setabs + [boo new] bar 0 +} -cleanup { + foo destroy + unset abs +} -result {{0 1 1 1} 0} + +test NRE-oo.5 {really deep calls in oo - forwards} -setup { + oo::object create foo + set body [makebody {my boo $i}] + oo::objdefine foo " + method bar i {$body} + forward boo ::foo bar + " +} -body { + setabs + foo bar 0 +} -cleanup { + foo destroy + unset abs +} -result {{0 2 1 1} 0} + + +# +# NASTY BUG found by tcllib's interp package +# + +test NRE-X.1 {eval in wrong interp} { + set i [interp create] + set res [$i eval { + set x {namespace children ::} + set y [list namespace children ::] + namespace delete {*}[{*}$y] + set j [interp create] + $j eval {namespace delete {*}[namespace children ::]} + namespace eval foo {} + set res [list [eval $x] [eval $y] [$j eval $x] [$j eval $y]] + interp delete $j + set res + }] + interp delete $i + set res +} {::foo ::foo {} {}} + +# +# Test tailcalls +# + +if {[testConstraint tailcall]} { + namespace eval tcl::unsupported namespace export tailcall + namespace import tcl::unsupported::tailcall +} + +test NRE-T.0 {tailcall is constant space} -constraints {tailcall} -setup { + proc a i { + if {[incr i] > 10} { + return [depthDiff] + } + depthDiff + tailcall a $i + } +} -body { + a 0 +} -cleanup { + rename a {} +} -result {0 0 0 0 0 0} + +test NRE-T.1 {tailcall} -constraints {tailcall} -body { + namespace eval a { + variable x *::a + proc xset {} { + set tmp {} + set ns {[namespace current]} + set level [info level] + for {set i 0} {$i <= [info level]} {incr i} { + uplevel #$i "set x $i$ns" + lappend tmp "$i [info level $i]" + } + lrange $tmp 1 end + } + proc foo {} {tailcall xset; set x noreach} + } + namespace eval b { + variable x *::b + proc xset args {error b::xset} + proc moo {} {set x 0; variable y [::a::foo]; set x} + } + variable x *:: + proc xset args {error ::xset} + list [::b::moo] | $x $a::x $b::x | $::b::y +} -cleanup { + unset x + rename xset {} + namespace delete a b +} -result {1::b | 0:: *::a *::b | {{1 ::b::moo} {2 xset}}} + + +test NRE-T.2 {tailcall in non-proc} -constraints {tailcall} -body { + list [catch {namespace eval a [list tailcall set x 1]} msg] $msg +} -result {1 {tailcall can only be called from a proc or lambda}} + +test NRE-T.3 {tailcall falls off tebc} -constraints {tailcall} -body { + unset -nocomplain x + proc foo {} {tailcall set x 1} + list [catch foo msg] $msg [set x] +} -cleanup { + rename foo {} + unset x +} -result {0 1 1} + +test NRE-T.4 {tailcall falls off tebc} -constraints {tailcall} -body { + set x 2 + proc foo {} {tailcall set x 1} + foo + set x +} -cleanup { + rename foo {} + unset x +} -result 1 + +test NRE-T.5 {tailcall falls off tebc} -constraints {tailcall} -body { + set x 2 + namespace eval bar { + variable x 3 + proc foo {} {tailcall set x 1} + } + bar::foo + list $x $bar::x +} -cleanup { + unset x + namespace delete bar +} -result {1 3} + +test NRE-T.6 {tailcall does remove callframes} -constraints {tailcall} -body { + proc foo {} {info level} + proc moo {} {tailcall foo} + proc boo {} {expr {[moo] - [info level]}} + boo +} -cleanup { + rename foo {} + rename moo {} + rename boo {} +} -result 1 + +test NRE-T.7 {tailcall does return} -constraints {tailcall} -setup { + namespace eval ::foo { + variable res {} + proc a {} { + variable res + append res a + tailcall set x 1 + append res a + } + proc b {} { + variable res + append res b + a + append res b + } + proc c {} { + variable res + append res c + b + append res c + } + } +} -body { + namespace eval ::foo c +} -cleanup { + namespace delete ::foo +} -result cbabc + +test NRE-T.8 {tailcall tailcall} -constraints {tailcall} -setup { + namespace eval ::foo { + variable res {} + proc a {} { + variable res + append res a + tailcall tailcall set x 1 + append res a + } + proc b {} { + variable res + append res b + a + append res b + } + proc c {} { + variable res + append res c + b + append res c + } + } +} -body { + namespace eval ::foo c +} -cleanup { + namespace delete ::foo +} -match glob -result *tailcall* -returnCodes error + +test NRE-T.9 {tailcall factorial} -constraints {tailcall} -setup { + proc fact {n {b 1}} { + if {$n == 1} { + return $b + } + tailcall fact [expr {$n-1}] [expr {$n*$b}] + } +} -body { + list [fact 1] [fact 5] [fact 10] [fact 15] +} -cleanup { + rename fact {} +} -result {1 120 3628800 1307674368000} + + +namespace forget tcl::unsupported::tailcall + +# +# Test that ensembles are non-recursive +# + + + +# cleanup +::tcltest::cleanupTests + +if {[testConstraint testnrelevels]} { + namespace forget testnre::* + namespace delete testnre +} + +if {[testConstraint tailcall]} { + namespace forget tcl::unsupported::tailcall +} + +return diff --git a/tests/eofchar.data b/tests/eofchar.data new file mode 100644 index 0000000..4aa3d70 --- /dev/null +++ b/tests/eofchar.data @@ -0,0 +1,846 @@ +Ho hum +Ho hum +Ho hum +Ho hum +Ho hum +Ho hum +Ho hum +Ho hum +Ho hum +Ho hum +Ho hum += +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla +Ge gla Ge gla Ge gla Ge gla diff --git a/tests/ioUtil.test b/tests/ioUtil.test new file mode 100644 index 0000000..0f0d2fc --- /dev/null +++ b/tests/ioUtil.test @@ -0,0 +1,333 @@ +# This file (ioUtil.test) tests the hookable TclStat(), TclAccess(), +# and Tcl_OpenFileChannel, routines in the file generic/tclIOUtils.c. +# Sourcing this file into Tcl runs the tests and generates output for +# errors. No output means no errors were found. +# +# Copyright (c) 1998-1999 by Scriptics Corporation. +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# +# RCS: @(#) $Id: ioUtil.test,v 1.19 2007/12/13 15:26:06 dgp Exp $ + +if {[lsearch [namespace children] ::tcltest] == -1} { + package require tcltest 2 + namespace import -force ::tcltest::* +} + +testConstraint testopenfilechannelproc \ + [llength [info commands testopenfilechannelproc]] +testConstraint testaccessproc [llength [info commands testaccessproc]] +testConstraint teststatproc [llength [info commands teststatproc]] + +set unsetScript { + catch {unset testStat1(size)} + catch {unset testStat2(size)} + catch {unset testStat3(size)} +} + +test ioUtil-1.1 {TclStat: Check that none of the test procs are there.} {} { + catch {file stat testStat1%.fil testStat1} err1 + catch {file stat testStat2%.fil testStat2} err2 + catch {file stat testStat3%.fil testStat3} err3 + list $err1 $err2 $err3 +} {{could not read "testStat1%.fil": no such file or directory} {could not read "testStat2%.fil": no such file or directory} {could not read "testStat3%.fil": no such file or directory}} + +test ioUtil-1.2 {TclStatInsertProc: Insert the 3 test TclStat_ procedures.} {teststatproc} { + catch {teststatproc insert TclpStat} err1 + teststatproc insert TestStatProc1 + teststatproc insert TestStatProc2 + teststatproc insert TestStatProc3 + set err1 +} {bad arg "insert": must be TestStatProc1, TestStatProc2, or TestStatProc3} + +test ioUtil-1.3 {TclStat: Use "file stat ?" to invoke each procedure.} {teststatproc} { + file stat testStat2%.fil testStat2 + file stat testStat1%.fil testStat1 + file stat testStat3%.fil testStat3 + + list $testStat2(size) $testStat1(size) $testStat3(size) +} {2345 1234 3456} + +eval $unsetScript + +test ioUtil-1.4 {TclStatDeleteProc: "TclpStat" function should not be deletable.} {teststatproc} { + catch {teststatproc delete TclpStat} err2 + set err2 +} {"TclpStat": could not be deleteed} + +test ioUtil-1.5 {TclStatDeleteProc: Delete the 2nd TclStat procedure.} {teststatproc} { + # Delete the 2nd procedure and test that it longer exists but that + # the others do actually return a result. + + teststatproc delete TestStatProc2 + file stat testStat1%.fil testStat1 + catch {file stat testStat2%.fil testStat2} err3 + file stat testStat3%.fil testStat3 + + list $testStat1(size) $err3 $testStat3(size) +} {1234 {could not read "testStat2%.fil": no such file or directory} 3456} + +eval $unsetScript + +test ioUtil-1.6 {TclStatDeleteProc: Delete the 1st TclStat procedure.} {teststatproc} { + # Next delete the 1st procedure and test that only the 3rd procedure + # is the only one that exists. + + teststatproc delete TestStatProc1 + catch {file stat testStat1%.fil testStat1} err4 + catch {file stat testStat2%.fil testStat2} err5 + file stat testStat3%.fil testStat3 + + list $err4 $err5 $testStat3(size) +} {{could not read "testStat1%.fil": no such file or directory} {could not read "testStat2%.fil": no such file or directory} 3456} + +eval $unsetScript + +test ioUtil-1.7 {TclStatDeleteProc: Delete the 3rd procedure & verify all are gone.} {teststatproc} { + # Finally delete the 3rd procedure and check that none of the + # procedures exist. + + teststatproc delete TestStatProc3 + catch {file stat testStat1%.fil testStat1} err6 + catch {file stat testStat2%.fil testStat2} err7 + catch {file stat testStat3%.fil testStat3} err8 + + list $err6 $err7 $err8 +} {{could not read "testStat1%.fil": no such file or directory} {could not read "testStat2%.fil": no such file or directory} {could not read "testStat3%.fil": no such file or directory}} + +eval $unsetScript + +test ioUtil-1.8 {TclStatDeleteProc: Verify that all procs have been deleted.} {teststatproc} { + # Attempt to delete all the Stat procs. again to ensure they no longer + # exist and an error is returned. + + catch {teststatproc delete TestStatProc1} err9 + catch {teststatproc delete TestStatProc2} err10 + catch {teststatproc delete TestStatProc3} err11 + + list $err9 $err10 $err11 +} {{"TestStatProc1": could not be deleteed} {"TestStatProc2": could not be deleteed} {"TestStatProc3": could not be deleteed}} + +eval $unsetScript + +test ioUtil-1.9 {TclAccess: Check that none of the test procs are there.} { + catch {file exists testAccess1%.fil} err1 + catch {file exists testAccess2%.fil} err2 + catch {file exists testAccess3%.fil} err3 + list $err1 $err2 $err3 +} {0 0 0} + +test ioUtil-1.10 {TclAccessInsertProc: Insert the 3 test TclAccess_ procedures.} {testaccessproc} { + catch {testaccessproc insert TclpAccess} err1 + testaccessproc insert TestAccessProc1 + testaccessproc insert TestAccessProc2 + testaccessproc insert TestAccessProc3 + set err1 +} {bad arg "insert": must be TestAccessProc1, TestAccessProc2, or TestAccessProc3} + +test ioUtil-2.3 {TclAccess: Use "file access ?" to invoke each procedure.} {testaccessproc} { + list [file exists testAccess2%.fil] \ + [file exists testAccess1%.fil] \ + [file exists testAccess3%.fil] +} {1 1 1} + +test ioUtil-2.4 {TclAccessDeleteProc: "TclpAccess" function should not be deletable.} {testaccessproc} { + catch {testaccessproc delete TclpAccess} err2 + set err2 +} {"TclpAccess": could not be deleteed} + +test ioUtil-2.5 {TclAccessDeleteProc: Delete the 2nd TclAccess procedure.} {testaccessproc} { + # Delete the 2nd procedure and test that it longer exists but that + # the others do actually return a result. + + testaccessproc delete TestAccessProc2 + set res1 [file exists testAccess1%.fil] + catch {file exists testAccess2%.fil} err3 + set res2 [file exists testAccess3%.fil] + + list $res1 $err3 $res2 +} {1 0 1} + +test ioUtil-2.6 {TclAccessDeleteProc: Delete the 1st TclAccess procedure.} {testaccessproc} { + # Next delete the 1st procedure and test that only the 3rd procedure + # is the only one that exists. + + testaccessproc delete TestAccessProc1 + catch {file exists testAccess1%.fil} err4 + catch {file exists testAccess2%.fil} err5 + set res3 [file exists testAccess3%.fil] + + list $err4 $err5 $res3 +} {0 0 1} + +test ioUtil-2.7 {TclAccessDeleteProc: Delete the 3rd procedure & verify all are gone.} {testaccessproc} { + # Finally delete the 3rd procedure and check that none of the + # procedures exist. + + testaccessproc delete TestAccessProc3 + catch {file exists testAccess1%.fil} err6 + catch {file exists testAccess2%.fil} err7 + catch {file exists testAccess3%.fil} err8 + + list $err6 $err7 $err8 +} {0 0 0} + +test ioUtil-2.8 {TclAccessDeleteProc: Verify that all procs have been deleted.} {testaccessproc} { + # Attempt to delete all the Access procs. again to ensure they no longer + # exist and an error is returned. + + catch {testaccessproc delete TestAccessProc1} err9 + catch {testaccessproc delete TestAccessProc2} err10 + catch {testaccessproc delete TestAccessProc3} err11 + + list $err9 $err10 $err11 +} {{"TestAccessProc1": could not be deleteed} {"TestAccessProc2": could not be deleteed} {"TestAccessProc3": could not be deleteed}} + +# Some of the following tests require a writable current directory +set oldpwd [pwd] +cd [temporaryDirectory] + +test ioUtil-3.1 {TclOpenFileChannel: Check that none of the test procs are there.} {testopenfilechannelproc} { + catch {file delete -force {*}[glob *testOpenFileChannel*]} + catch {file exists testOpenFileChannel1%.fil} err1 + catch {file exists testOpenFileChannel2%.fil} err2 + catch {file exists testOpenFileChannel3%.fil} err3 + catch {file exists __testOpenFileChannel1%__.fil} err4 + catch {file exists __testOpenFileChannel2%__.fil} err5 + catch {file exists __testOpenFileChannel3%__.fil} err6 + list $err1 $err2 $err3 $err4 $err5 $err6 +} {0 0 0 0 0 0} + +test ioUtil-3.2 {TclOpenFileChannelInsertProc: Insert the 3 test TclOpenFileChannel_ procedures.} {testopenfilechannelproc} { + catch {testopenfilechannelproc insert TclpOpenFileChannel} err1 + testopenfilechannelproc insert TestOpenFileChannelProc1 + testopenfilechannelproc insert TestOpenFileChannelProc2 + testopenfilechannelproc insert TestOpenFileChannelProc3 + set err1 +} {bad arg "insert": must be TestOpenFileChannelProc1, TestOpenFileChannelProc2, or TestOpenFileChannelProc3} + +test ioUtil-3.3 {TclOpenFileChannel: Use "file openfilechannel ?" to invoke each procedure.} {testopenfilechannelproc} { + close [open __testOpenFileChannel1%__.fil w] + close [open __testOpenFileChannel2%__.fil w] + close [open __testOpenFileChannel3%__.fil w] + + catch { + close [open testOpenFileChannel1%.fil r] + close [open testOpenFileChannel2%.fil r] + close [open testOpenFileChannel3%.fil r] + } err + + file delete __testOpenFileChannel1%__.fil + file delete __testOpenFileChannel2%__.fil + file delete __testOpenFileChannel3%__.fil + + set err +} {} + +test ioUtil-3.4 {TclOpenFileChannelDeleteProc: "TclpOpenFileChannel" function should not be deletable.} {testopenfilechannelproc} { + catch {testopenfilechannelproc delete TclpOpenFileChannel} err2 + set err2 +} {"TclpOpenFileChannel": could not be deleteed} + +test ioUtil-3.5 {TclOpenFileChannelDeleteProc: Delete the 2nd TclOpenFileChannel procedure.} {testopenfilechannelproc} { + # Delete the 2nd procedure and test that it longer exists but that + # the others do actually return a result. + + testopenfilechannelproc delete TestOpenFileChannelProc2 + + close [open __testOpenFileChannel1%__.fil w] + close [open __testOpenFileChannel3%__.fil w] + + catch { + close [open testOpenFileChannel1%.fil r] + catch {close [open testOpenFileChannel2%.fil r]} msg1 + close [open testOpenFileChannel3%.fil r] + } err3 + + file delete __testOpenFileChannel1%__.fil + file delete __testOpenFileChannel3%__.fil + + list $err3 $msg1 +} {{} {couldn't open "testOpenFileChannel2%.fil": no such file or directory}} + +test ioUtil-3.6 {TclOpenFileChannelDeleteProc: Delete the 1st TclOpenFileChannel procedure.} {testopenfilechannelproc} { + # Next delete the 1st procedure and test that only the 3rd procedure + # is the only one that exists. + + testopenfilechannelproc delete TestOpenFileChannelProc1 + + close [open __testOpenFileChannel3%__.fil w] + + catch { + catch {close [open testOpenFileChannel1%.fil r]} msg2 + catch {close [open testOpenFileChannel2%.fil r]} msg3 + close [open testOpenFileChannel3%.fil r] + } err4 + + file delete __testOpenFileChannel3%__.fil + + list $err4 $msg2 $msg3 +} [list {} \ + {couldn't open "testOpenFileChannel1%.fil": no such file or directory}\ + {couldn't open "testOpenFileChannel2%.fil": no such file or directory}] + +test ioUtil-3.7 {TclOpenFileChannelDeleteProc: Delete the 3rd procedure & verify all are gone.} {testopenfilechannelproc} { + # Finally delete the 3rd procedure and check that none of the + # procedures exist. + + testopenfilechannelproc delete TestOpenFileChannelProc3 + catch { + catch {close [open testOpenFileChannel1%.fil r]} msg4 + catch {close [open testOpenFileChannel2%.fil r]} msg5 + catch {close [open testOpenFileChannel3%.fil r]} msg6 + } err5 + + list $err5 $msg4 $msg5 $msg6 +} [list 1 \ + {couldn't open "testOpenFileChannel1%.fil": no such file or directory}\ + {couldn't open "testOpenFileChannel2%.fil": no such file or directory}\ + {couldn't open "testOpenFileChannel3%.fil": no such file or directory}] + +test ioUtil-3.8 {TclOpenFileChannelDeleteProc: Verify that all procs have been deleted.} {testopenfilechannelproc} { + + # Attempt to delete all the OpenFileChannel procs. again to ensure they no + # longer exist and an error is returned. + + catch {testopenfilechannelproc delete TestOpenFileChannelProc1} err9 + catch {testopenfilechannelproc delete TestOpenFileChannelProc2} err10 + catch {testopenfilechannelproc delete TestOpenFileChannelProc3} err11 + + list $err9 $err10 $err11 +} {{"TestOpenFileChannelProc1": could not be deleteed} {"TestOpenFileChannelProc2": could not be deleteed} {"TestOpenFileChannelProc3": could not be deleteed}} + +test ioUtil-4.1 {open ... a+ must not use O_APPEND: Bug 1773127} -setup { + set f [tcltest::makeFile {} ioutil41.tmp] + set fid [open $f wb] + puts -nonewline $fid 123 + close $fid +} -body { + set fid [open $f ab+] + puts -nonewline $fid 456 + seek $fid 2 + set d [read $fid 2] + seek $fid 4 + puts -nonewline $fid x + close $fid + set fid [open $f rb] + append d [read $fid] + close $fid + return $d +} -cleanup { + tcltest::removeFile $f +} -result 341234x6 + +cd $oldpwd + +# cleanup +::tcltest::cleanupTests +return + +# Local Variables: +# mode: tcl +# End: diff --git a/tests/macFCmd.test b/tests/macFCmd.test new file mode 100644 index 0000000..f50e7b9 --- /dev/null +++ b/tests/macFCmd.test @@ -0,0 +1,204 @@ +# This file tests the tclfCmd.c file. +# +# This file contains a collection of tests for one or more of the Tcl +# built-in commands. Sourcing this file into Tcl runs the tests and +# generates output for errors. No output means no errors were found. +# +# Copyright (c) 1997 Sun Microsystems, Inc. +# Copyright (c) 1998-1999 by Scriptics Corporation. +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# +# RCS: @(#) $Id: macFCmd.test,v 1.11 2003/05/14 19:21:24 das Exp $ +# + +if {[lsearch [namespace children] ::tcltest] == -1} { + package require tcltest + namespace import -force ::tcltest::* +} + +# These tests really need to be run from a writable directory, which +# it is assumed [temporaryDirectory] is. +set oldcwd [pwd] +cd [temporaryDirectory] + +catch {file delete -force foo.dir} +file mkdir foo.dir +if {[catch {file attributes foo.dir -readonly 1}]} { + set ::tcltest::testConstraints(fileSharing) 0 + set ::tcltest::testConstraints(notFileSharing) 1 +} else { + set ::tcltest::testConstraints(fileSharing) 1 + set ::tcltest::testConstraints(notFileSharing) 0 + file attributes foo.dir -readonly 0 +} +file delete -force foo.dir + +test macFCmd-1.1 {GetFileFinderAttributes - no file} {macOnly} { + catch {file delete -force foo.file} + list [catch {file attributes foo.file -creator} msg] $msg +} {1 {could not read "foo.file": no such file or directory}} +test macFCmd-1.2 {GetFileFinderAttributes - creator} {macOnly} { + catch {file delete -force foo.file} + catch {close [open foo.file w]} + list [catch {file attributes foo.file -creator} msg] \ + [regexp {MPW |CWIE} $msg] [file delete -force foo.file] +} {0 1 {}} +test macFCmd-1.3 {GetFileFinderAttributes - type} {macOnly} { + catch {file delete -force foo.file} + catch {close [open foo.file w]} + list [catch {file attributes foo.file -type} msg] $msg \ + [file delete -force foo.file] +} {0 TEXT {}} +test macFCmd-1.4 {GetFileFinderAttributes - not hidden} {macOnly} { + catch {file delete -force foo.file} + catch {close [open foo.file w]} + list [catch {file attributes foo.file -hidden} msg] $msg \ + [file delete -force foo.file] +} {0 0 {}} +test macFCmd-1.5 {GetFileFinderAttributes - hidden} {macOnly} { + catch {file delete -force foo.file} + catch {close [open foo.file w]} + file attributes foo.file -hidden 1 + list [catch {file attributes foo.file -hidden} msg] $msg \ + [file delete -force foo.file] +} {0 1 {}} +test macFCmd-1.6 {GetFileFinderAttributes - folder creator} {macOnly} { + catch {file delete -force foo.dir} + file mkdir foo.dir + list [catch {file attributes foo.dir -creator} msg] $msg \ + [file delete -force foo.dir] +} {0 Fldr {}} +test macFCmd-1.7 {GetFileFinderAttributes - folder type} {macOnly} { + catch {file delete -force foo.dir} + file mkdir foo.dir + list [catch {file attributes foo.dir -type} msg] $msg \ + [file delete -force foo.dir] +} {0 Fldr {}} +test macFCmd-1.8 {GetFileFinderAttributes - folder hidden} {macOnly} { + catch {file delete -force foo.dir} + file mkdir foo.dir + list [catch {file attributes foo.dir -hidden} msg] $msg \ + [file delete -force foo.dir] +} {0 0 {}} + +test macFCmd-2.1 {GetFileReadOnly - bad file} {macOnly} { + catch {file delete -force foo.file} + list [catch {file attributes foo.file -readonly} msg] $msg +} {1 {could not read "foo.file": no such file or directory}} +test macFCmd-2.2 {GetFileReadOnly - file not read only} {macOnly} { + catch {file delete -force foo.file} + close [open foo.file w] + list [catch {file attributes foo.file -readonly} msg] $msg \ + [file delete -force foo.file] +} {0 0 {}} +test macFCmd-2.3 {GetFileReadOnly - file read only} {macOnly} { + catch {file delete -force foo.file} + close [open foo.file w] + file attributes foo.file -readonly 1 + list [catch {file attributes foo.file -readonly} msg] $msg \ + [file delete -force foo.file] +} {0 1 {}} +test macFCmd-2.4 {GetFileReadOnly - directory not read only} {macOnly} { + catch {file delete -force foo.dir} + file mkdir foo.dir + list [catch {file attributes foo.dir -readonly} msg] $msg \ + [file delete -force foo.dir] +} {0 0 {}} +test macFCmd-2.5 {GetFileReadOnly - directory read only} {macOnly fileSharing} { + catch {file delete -force foo.dir} + file mkdir foo.dir + file attributes foo.dir -readonly 1 + list [catch {file attributes foo.dir -readonly} msg] $msg \ + [file delete -force foo.dir] +} {0 1 {}} + +test macFCmd-3.1 {SetFileFinderAttributes - bad file} {macOnly} { + catch {file delete -force foo.file} + list [catch {file attributes foo.file -creator FOOO} msg] $msg +} {1 {could not read "foo.file": no such file or directory}} +test macFCmd-3.2 {SetFileFinderAttributes - creator} {macOnly} { + catch {file delete -force foo.file} + close [open foo.file w] + list [catch {file attributes foo.file -creator FOOO} msg] $msg \ + [file attributes foo.file -creator] [file delete -force foo.file] +} {0 {} FOOO {}} +test macFCmd-3.3 {SetFileFinderAttributes - bad creator} {macOnly} { + catch {file delete -force foo.file} + close [open foo.file w] + list [catch {file attributes foo.file -creator 0} msg] $msg \ + [file delete -force foo.file] +} {1 {expected Macintosh OS type but got "0"} {}} +test macFCmd-3.4 {SetFileFinderAttributes - hidden} {macOnly} { + catch {file delete -force foo.file} + close [open foo.file w] + list [catch {file attributes foo.file -hidden 1} msg] $msg \ + [file attributes foo.file -hidden] [file delete -force foo.file] +} {0 {} 1 {}} +test macFCmd-3.5 {SetFileFinderAttributes - type} {macOnly} { + catch {file delete -force foo.file} + close [open foo.file w] + list [catch {file attributes foo.file -type FOOO} msg] $msg \ + [file attributes foo.file -type] [file delete -force foo.file] +} {0 {} FOOO {}} +test macFCmd-3.6 {SetFileFinderAttributes - bad type} {macOnly} { + catch {file delete -force foo.file} + close [open foo.file w] + list [catch {file attributes foo.file -type 0} msg] $msg \ + [file delete -force foo.file] +} {1 {expected Macintosh OS type but got "0"} {}} +test macFCmd-3.7 {SetFileFinderAttributes - directory} {macOnly} { + catch {file delete -force foo.dir} + file mkdir foo.dir + list [catch {file attributes foo.dir -creator FOOO} msg] \ + $msg [file delete -force foo.dir] +} {1 {cannot set -creator: "foo.dir" is a directory} {}} + +test macFCmd-4.1 {SetFileReadOnly - bad file} {macOnly} { + catch {file delete -force foo.file} + list [catch {file attributes foo.file -readonly 1} msg] $msg +} {1 {could not read "foo.file": no such file or directory}} +test macFCmd-4.2 {SetFileReadOnly - file not readonly} {macOnly} { + catch {file delete -force foo.file} + close [open foo.file w] + list [catch {file attributes foo.file -readonly 0} msg] \ + $msg [file attributes foo.file -readonly] [file delete -force foo.file] +} {0 {} 0 {}} +test macFCmd-4.3 {SetFileReadOnly - file readonly} {macOnly} { + catch {file delete -force foo.file} + close [open foo.file w] + list [catch {file attributes foo.file -readonly 1} msg] \ + $msg [file attributes foo.file -readonly] [file delete -force foo.file] +} {0 {} 1 {}} +test macFCmd-4.4 {SetFileReadOnly - directory not readonly} \ + {macOnly fileSharing} { + catch {file delete -force foo.dir} + file mkdir foo.dir + list [catch {file attributes foo.dir -readonly 0} msg] \ + $msg [file attributes foo.dir -readonly] [file delete -force foo.dir] +} {0 {} 0 {}} +test macFCmd-4.5 {SetFileReadOnly - directory not readonly} \ + {macOnly notFileSharing} { + catch {file delete -force foo.dir} + file mkdir foo.dir + list [catch {file attributes foo.dir -readonly 0} msg] $msg \ + [file delete -force foo.dir] +} {1 {cannot set a directory to read-only when File Sharing is turned off} {}} +test macFCmd-4.6 {SetFileReadOnly - directory readonly} {macOnly fileSharing} { + catch {file delete -force foo.dir} + file mkdir foo.dir + list [catch {file attributes foo.dir -readonly 1} msg] $msg \ + [file attributes foo.dir -readonly] [file delete -force foo.dir] +} {0 {} 1 {}} +test macFCmd-4.7 {SetFileReadOnly - directory readonly} {macOnly notFileSharing} { + catch {file delete -force foo.dir} + file mkdir foo.dir + list [catch {file attributes foo.dir -readonly 1} msg] $msg \ + [file delete -force foo.dir] +} {1 {cannot set a directory to read-only when File Sharing is turned off} {}} + +# cleanup +cd $oldcwd +::tcltest::cleanupTests +return diff --git a/tests/osa.test b/tests/osa.test new file mode 100644 index 0000000..7a16ef1 --- /dev/null +++ b/tests/osa.test @@ -0,0 +1,48 @@ +# Commands covered: AppleScript +# +# This file contains a collection of tests for one or more of the Tcl +# built-in commands. Sourcing this file into Tcl runs the tests and +# generates output for errors. No output means no errors were found. +# +# Copyright (c) 1997 Sun Microsystems, Inc. +# Copyright (c) 1998-1999 by Scriptics Corporation. +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# +# RCS: @(#) $Id: osa.test,v 1.6 2000/04/10 17:19:02 ericm Exp $ + +if {[lsearch [namespace children] ::tcltest] == -1} { + package require tcltest + namespace import -force ::tcltest::* +} + +# Only run the test if we can load the AppleScript command +set ::tcltest::testConstraints(appleScript) [expr {[info commands AppleScript] != ""}] + +test osa-1.1 {Tcl_OSAComponentCmd} {macOnly appleScript} { + list [catch AppleScript msg] $msg +} {1 {wrong # args: should be "AppleScript option ?arg ...?"}} +test osa-1.2 {Tcl_OSAComponentCmd} {macOnly appleScript} { + list [catch {AppleScript x} msg] $msg +} {1 {bad option "x": should be compile, decompile, delete, execute, info, load, run or store}} + +test osa-1.3 {TclOSACompileCmd} {macOnly appleScript} { + list [catch {AppleScript compile} msg] $msg +} {1 {wrong # args: should be "AppleScript compile ?options? code"}} + +# cleanup +::tcltest::cleanupTests +return + + + + + + + + + + + + diff --git a/tests/pkg.test b/tests/pkg.test new file mode 100644 index 0000000..4f92d4c --- /dev/null +++ b/tests/pkg.test @@ -0,0 +1,1222 @@ +# -*- tcl -*- +# Commands covered: pkg +# +# This file contains a collection of tests for one or more of the Tcl +# built-in commands. Sourcing this file into Tcl runs the tests and +# generates output for errors. No output means no errors were found. +# +# Copyright (c) 1995-1996 Sun Microsystems, Inc. +# Copyright (c) 1998-1999 by Scriptics Corporation. +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# +# RCS: @(#) $Id: pkg.test,v 1.31 2008/07/19 22:50:39 nijtmans Exp $ + +if {[lsearch [namespace children] ::tcltest] == -1} { + package require tcltest 2 + namespace import -force ::tcltest::* +} + +# Do all this in a slave interp to avoid garbaging the +# package list +set i [interp create] +interp eval $i [list set argv $argv] +interp eval $i [list package require tcltest 2] +interp eval $i [list namespace import -force ::tcltest::*] +interp eval $i { + +package forget {*}[package names] +set oldPkgUnknown [package unknown] +package unknown {} +set oldPath $auto_path +set auto_path "" + +test pkg-1.1 {Tcl_PkgProvide procedure} { + package forget t + package provide t 2.3 +} {} +test pkg-1.2 {Tcl_PkgProvide procedure} { + package forget t + package provide t 2.3 + list [catch {package provide t 2.2} msg] $msg +} {1 {conflicting versions provided for package "t": 2.3, then 2.2}} +test pkg-1.3 {Tcl_PkgProvide procedure} { + package forget t + package provide t 2.3 + list [catch {package provide t 2.4} msg] $msg +} {1 {conflicting versions provided for package "t": 2.3, then 2.4}} +test pkg-1.4 {Tcl_PkgProvide procedure} { + package forget t + package provide t 2.3 + list [catch {package provide t 3.3} msg] $msg +} {1 {conflicting versions provided for package "t": 2.3, then 3.3}} +test pkg-1.5 {Tcl_PkgProvide procedure} { + package forget t + package provide t 2.3 + package provide t 2.3 +} {} + +test pkg-1.6 {Tcl_PkgProvide procedure} { + package forget t + package provide t 2.3a1 +} {} + +set n 0 +foreach v { + 2.3k1 2a3a2 2ab3 2.a4 2.b4 2b.4 2a.4 2ba4 2a4b1 + 2b4a1 2b3b2 +} { + test pkg-1.7.$n {Tcl_PkgProvide procedure} { + package forget t + list [catch {package provide t $v} msg] $msg + } [list 1 "expected version number but got \"$v\""] + incr n +} + +test pkg-2.1 {Tcl_PkgRequire procedure, picking best version} { + package forget t + foreach i {1.4 3.4 2.3 2.4 2.2} { + package ifneeded t $i "set x $i; package provide t $i" + } + set x xxx + package require t + set x +} {3.4} +test pkg-2.2 {Tcl_PkgRequire procedure, picking best version} { + package forget t + foreach i {1.4 3.4 2.3 2.4 2.2 3.5 3.2} { + package ifneeded t $i "set x $i; package provide t $i" + } + set x xxx + package require t + set x +} {3.5} +test pkg-2.3 {Tcl_PkgRequire procedure, picking best version} { + package forget t + foreach i {3.5 2.1 2.3} { + package ifneeded t $i "set x $i; package provide t $i" + } + set x xxx + package require t 2.2 + set x +} {2.3} +test pkg-2.4 {Tcl_PkgRequire procedure, picking best version} { + package forget t + foreach i {1.4 3.4 2.3 2.4 2.2} { + package ifneeded t $i "set x $i; package provide t $i" + } + set x xxx + package require -exact t 2.3 + set x +} {2.3} +test pkg-2.5 {Tcl_PkgRequire procedure, picking best version} { + package forget t + foreach i {1.4 3.4 2.3 2.4 2.2} { + package ifneeded t $i "set x $i; package provide t $i" + } + set x xxx + package require t 2.1 + set x +} {2.4} +test pkg-2.6 {Tcl_PkgRequire procedure, can't find suitable version} { + package forget t + package unknown {} + foreach i {1.4 3.4 2.3 2.4 2.2} { + package ifneeded t $i "set x $i" + } + list [catch {package require t 2.5} msg] $msg +} {1 {can't find package t 2.5}} +test pkg-2.7 {Tcl_PkgRequire procedure, can't find suitable version} { + package forget t + package unknown {} + foreach i {1.4 3.4 2.3 2.4 2.2} { + package ifneeded t $i "set x $i" + } + list [catch {package require t 4.1} msg] $msg +} {1 {can't find package t 4.1}} +test pkg-2.8 {Tcl_PkgRequire procedure, can't find suitable version} { + package forget t + package unknown {} + foreach i {1.4 3.4 2.3 2.4 2.2} { + package ifneeded t $i "set x $i" + } + list [catch {package require -exact t 1.3} msg] $msg +} {1 {can't find package t exactly 1.3}} +test pkg-2.9 {Tcl_PkgRequire procedure, can't find suitable version} { + package forget t + package unknown {} + list [catch {package require t} msg] $msg +} {1 {can't find package t}} +test pkg-2.10 {Tcl_PkgRequire procedure, error in ifneeded script} -body { + package forget t + package ifneeded t 2.1 {package provide t 2.1; error "ifneeded test"} + list [catch {package require t 2.1} msg] $msg $::errorInfo +} -match glob -result {1 {ifneeded test} {ifneeded test + while executing +"error "ifneeded test"" + ("package ifneeded*" script) + invoked from within +"package require t 2.1"}} +test pkg-2.11 {Tcl_PkgRequire procedure, ifneeded script doesn't provide package} -body { + package forget t + package ifneeded t 2.1 "set x invoked" + set x xxx + list [catch {package require t 2.1} msg] $msg $x +} -match glob -result {1 * invoked} +test pkg-2.12 {Tcl_PkgRequire procedure, self-deleting script} { + package forget t + package ifneeded t 1.2 "package forget t; set x 1.2; package provide t 1.2" + set x xxx + package require t 1.2 + set x +} {1.2} +test pkg-2.13 {Tcl_PkgRequire procedure, "package unknown" support} { + proc pkgUnknown args { + # args = name requirement + # requirement = v-v (for exact version) + global x + set x $args + package provide [lindex $args 0] [lindex [split [lindex $args 1] -] 0] + } + package forget t + foreach i {1.4 3.4 2.3 2.4 2.2} { + package ifneeded t $i "set x $i" + } + package unknown pkgUnknown + set x xxx + package require -exact t 1.5 + package unknown {} + set x +} {t 1.5-1.5} +test pkg-2.14 {Tcl_PkgRequire procedure, "package unknown" support} { + proc pkgUnknown args { + package ifneeded t 1.2 "set x loaded; package provide t 1.2" + } + package forget t + package unknown pkgUnknown + set x xxx + set result [list [package require t] $x] + package unknown {} + set result +} {1.2 loaded} +test pkg-2.15 {Tcl_PkgRequire procedure, "package unknown" support} { + proc pkgUnknown args { + global x + set x $args + package provide [lindex $args 0] 2.0 + } + package forget {a b} + package unknown pkgUnknown + set x xxx + package require {a b} + package unknown {} + set x +} {{a b} 0-} +test pkg-2.16 {Tcl_PkgRequire procedure, "package unknown" error} { + proc pkgUnknown args { + error "testing package unknown" + } + package forget t + package unknown pkgUnknown + set result [list [catch {package require t} msg] $msg $::errorInfo] + package unknown {} + set result +} {1 {testing package unknown} {testing package unknown + while executing +"error "testing package unknown"" + (procedure "pkgUnknown" line 2) + invoked from within +"pkgUnknown t 0-" + ("package unknown" script) + invoked from within +"package require t"}} +test pkg-2.17 {Tcl_PkgRequire procedure, "package unknown" doesn't load package} { + proc pkgUnknown args { + global x + set x $args + } + package forget t + foreach i {1.4 3.4 2.3 2.4 2.2} { + package ifneeded t $i "set x $i" + } + package unknown pkgUnknown + set x xxx + set result [list [catch {package require -exact t 1.5} msg] $msg $x] + package unknown {} + set result +} {1 {can't find package t exactly 1.5} {t 1.5-1.5}} +test pkg-2.18 {Tcl_PkgRequire procedure, version checks} { + package forget t + package provide t 2.3 + package require t +} {2.3} +test pkg-2.19 {Tcl_PkgRequire procedure, version checks} { + package forget t + package provide t 2.3 + package require t 2.1 +} {2.3} +test pkg-2.20 {Tcl_PkgRequire procedure, version checks} { + package forget t + package provide t 2.3 + package require t 2.3 +} {2.3} +test pkg-2.21 {Tcl_PkgRequire procedure, version checks} { + package forget t + package provide t 2.3 + list [catch {package require t 2.4} msg] $msg +} {1 {version conflict for package "t": have 2.3, need 2.4}} +test pkg-2.22 {Tcl_PkgRequire procedure, version checks} { + package forget t + package provide t 2.3 + list [catch {package require t 1.2} msg] $msg +} {1 {version conflict for package "t": have 2.3, need 1.2}} +test pkg-2.23 {Tcl_PkgRequire procedure, version checks} { + package forget t + package provide t 2.3 + package require -exact t 2.3 +} {2.3} +test pkg-2.24 {Tcl_PkgRequire procedure, version checks} { + package forget t + package provide t 2.3 + list [catch {package require -exact t 2.2} msg] $msg +} {1 {version conflict for package "t": have 2.3, need exactly 2.2}} +test pkg-2.25 {Tcl_PkgRequire procedure, error in ifneeded script} -body { + package forget t + package ifneeded t 2.1 {package provide t 2.1; error "ifneeded test" EI} + list [catch {package require t 2.1} msg] $msg $::errorInfo +} -match glob -result {1 {ifneeded test} {EI + ("package ifneeded*" script) + invoked from within +"package require t 2.1"}} +test pkg-2.26 {Tcl_PkgRequire procedure, error in ifneeded script} -body { + package forget t + package ifneeded t 2.1 {package provide t 2.1; foreach x 1 {error "ifneeded test" EI}} + list [catch {package require t 2.1} msg] $msg $::errorInfo +} -match glob -result {1 {ifneeded test} {EI + ("foreach" body line 1) + invoked from within +"foreach x 1 {error "ifneeded test" EI}" + ("package ifneeded*" script) + invoked from within +"package require t 2.1"}} +test pkg-2.27 {Tcl_PkgRequire: circular dependency} -setup { + package forget foo +} -body { + package ifneeded foo 1 {package require foo 1} + package require foo 1 +} -cleanup { + package forget foo +} -returnCodes error -match glob -result {circular package dependency:*} +test pkg-2.28 {Tcl_PkgRequire: circular dependency} -setup { + package forget foo +} -body { + package ifneeded foo 1 {package require foo 2} + package require foo 1 +} -cleanup { + package forget foo +} -returnCodes error -match glob -result {circular package dependency:*} +test pkg-2.29 {Tcl_PkgRequire: circular dependency} -setup { + package forget foo + package forget bar +} -body { + package ifneeded foo 1 {package require bar 1; package provide foo 1} + package ifneeded bar 1 {package require foo 1; package provide bar 1} + package require foo 1 +} -cleanup { + package forget foo + package forget bar +} -returnCodes error -match glob -result {circular package dependency:*} +test pkg-2.30 {Tcl_PkgRequire: circular dependency} -setup { + package forget foo + package forget bar +} -body { + package ifneeded foo 1 {package require bar 1; package provide foo 1} + package ifneeded foo 2 {package provide foo 2} + package ifneeded bar 1 {package require foo 2; package provide bar 1} + package require foo 1 +} -cleanup { + package forget foo + package forget bar +} -returnCodes error -match glob -result {circular package dependency:*} +test pkg-2.31 {Tcl_PkgRequire: consistent return values (1162286)} -setup { + package forget foo +} -body { + package ifneeded foo 1 {package provide foo 1; error foo} + package require foo 1 +} -cleanup { + package forget foo +} -returnCodes error -match glob -result foo +test pkg-2.32 {Tcl_PkgRequire: consistent return values (1162286)} -setup { + package forget foo +} -body { + package ifneeded foo 1 {package provide foo 1; error foo} + catch {package require foo 1} + package provide foo +} -cleanup { + package forget foo +} -result {} +test pkg-2.33 {Tcl_PkgRequire: consistent return values (1162286)} -setup { + package forget foo +} -body { + package ifneeded foo 1 {package provide foo 2} + package require foo 1 +} -cleanup { + package forget foo +} -returnCodes error -match glob -result {attempt to provide package * failed:*} +test pkg-2.34 {Tcl_PkgRequire: consistent return values (1162286)} -setup { + package forget foo +} -body { + package ifneeded foo 1 {package provide foo 1.1} + package require foo 1 +} -cleanup { + package forget foo +} -returnCodes error -match glob -result {attempt to provide package * failed:*} +test pkg-2.34.1 {Tcl_PkgRequire: consistent return values (1162286)} -setup { + package forget foo +} -body { + package ifneeded foo 1.1 {package provide foo 1} + package require foo 1 +} -cleanup { + package forget foo +} -returnCodes error -match glob -result {attempt to provide package * failed:*} +test pkg-2.34.2 {Tcl_PkgRequire: consistent return values (1162286)} -setup { + package forget foo +} -body { + package ifneeded foo 1.1 {package provide foo 1} + package require foo 1.1 +} -cleanup { + package forget foo +} -returnCodes error -match glob -result {attempt to provide package * failed:*} +test pkg-2.35 {Tcl_PkgRequire: consistent return values (1162286)} -setup { + package forget foo +} -body { + package ifneeded foo 1 {} + package require foo 1 +} -cleanup { + package forget foo +} -returnCodes error -match glob -result {attempt to provide package * failed:*} +test pkg-2.35.1 {Tcl_PkgRequire: consistent return values (1162286)} -setup { + package forget foo +} -body { + package ifneeded foo 1 {break} + package require foo 1 +} -cleanup { + package forget foo +} -returnCodes error -match glob \ +-result {attempt to provide package * failed: bad return code:*} +test pkg-2.36 {Tcl_PkgRequire: consistent return values (1162286)} -setup { + package forget foo +} -body { + package ifneeded foo 1 {continue} + package require foo 1 +} -cleanup { + package forget foo +} -returnCodes error -match glob \ +-result {attempt to provide package * failed: bad return code:*} +test pkg-2.37 {Tcl_PkgRequire: consistent return values (1162286)} -setup { + package forget foo +} -body { + package ifneeded foo 1 {return} + package require foo 1 +} -cleanup { + package forget foo +} -returnCodes error -match glob \ +-result {attempt to provide package * failed: bad return code:*} +test pkg-2.38 {Tcl_PkgRequire: consistent return values (1162286)} -setup { + package forget foo +} -body { + package ifneeded foo 1 {return -level 0 -code 10} + package require foo 1 +} -cleanup { + package forget foo +} -returnCodes error -match glob \ +-result {attempt to provide package * failed: bad return code:*} +test pkg-2.39 {Tcl_PkgRequire: consistent return values (1162286)} -setup { + package forget foo + set saveUnknown [package unknown] + package unknown {package provide foo 2 ;#} +} -body { + package require foo 1 +} -cleanup { + package forget foo + package unknown $saveUnknown +} -returnCodes error -match glob -result * +test pkg-2.40 {Tcl_PkgRequire: consistent return values (1162286)} -setup { + package forget foo + set saveUnknown [package unknown] + package unknown {break ;#} +} -body { + package require foo 1 +} -cleanup { + package forget foo + package unknown $saveUnknown +} -returnCodes error -match glob -result {bad return code:*} +test pkg-2.41 {Tcl_PkgRequire: consistent return values (1162286)} -setup { + package forget foo + set saveUnknown [package unknown] + package unknown {continue ;#} +} -body { + package require foo 1 +} -cleanup { + package forget foo + package unknown $saveUnknown +} -returnCodes error -match glob -result {bad return code:*} +test pkg-2.42 {Tcl_PkgRequire: consistent return values (1162286)} -setup { + package forget foo + set saveUnknown [package unknown] + package unknown {return ;#} +} -body { + package require foo 1 +} -cleanup { + package forget foo + package unknown $saveUnknown +} -returnCodes error -match glob -result {bad return code:*} +test pkg-2.43 {Tcl_PkgRequire: consistent return values (1162286)} -setup { + package forget foo + set saveUnknown [package unknown] + package unknown {return -level 0 -code 10 ;#} +} -body { + package require foo 1 +} -cleanup { + package forget foo + package unknown $saveUnknown +} -returnCodes error -match glob -result {bad return code:*} +test pkg-2.44 {Tcl_PkgRequire: exact version matching (1578344)} -setup { + package provide demo 1.2.3 +} -body { + package require -exact demo 1.2 +} -cleanup { + package forget demo +} -returnCodes error -result {version conflict for package "demo": have 1.2.3, need exactly 1.2} + + +test pkg-2.50 {Tcl_PkgRequire procedure, picking best stable version} { + package forget t + foreach i {1.4 3.4 4.0a1 2.3 2.4 2.2} { + package ifneeded t $i "set x $i; package provide t $i" + } + set x xxx + package require t + set x +} {3.4} + +test pkg-2.51 {Tcl_PkgRequire procedure, picking best stable version} { + package forget t + foreach i {1.2b1 1.2 1.3a2 1.3} { + package ifneeded t $i "set x $i; package provide t $i" + } + set x xxx + package require t + set x +} {1.3} + +test pkg-2.52 {Tcl_PkgRequire procedure, picking best stable version} { + package forget t + foreach i {1.2b1 1.2 1.3 1.3a2} { + package ifneeded t $i "set x $i; package provide t $i" + } + set x xxx + package require t + set x +} {1.3} + + + +test pkg-3.1 {Tcl_PackageCmd procedure} { + list [catch {package} msg] $msg +} {1 {wrong # args: should be "package option ?arg ...?"}} +test pkg-3.2 {Tcl_PackageCmd procedure, "forget" option} { + foreach i [package names] { + package forget $i + } + package names +} {} +test pkg-3.3 {Tcl_PackageCmd procedure, "forget" option} { + foreach i [package names] { + package forget $i + } + package forget foo +} {} +test pkg-3.4 {Tcl_PackageCmd procedure, "forget" option} { + foreach i [package names] { + package forget $i + } + package ifneeded t 1.1 {first script} + package ifneeded t 2.3 {second script} + package ifneeded x 1.4 {x's script} + set result {} + lappend result [lsort [package names]] [package versions t] + package forget t + lappend result [lsort [package names]] [package versions t] +} {{t x} {1.1 2.3} x {}} +test pkg-3.5 {Tcl_PackageCmd procedure, "forget" option} { + foreach i [package names] { + package forget $i + } + package ifneeded a 1.1 {first script} + package ifneeded b 2.3 {second script} + package ifneeded c 1.4 {third script} + package forget + set result [list [lsort [package names]]] + package forget a c + lappend result [lsort [package names]] +} {{a b c} b} +test pkg-3.5.1 {Tcl_PackageCmd procedure, "forget" option} { + # Test for Bug 415273 + package ifneeded a 1 "I should have been forgotten" + package forget no-such-package a + set x [package ifneeded a 1] + package forget a + set x +} {} +test pkg-3.6 {Tcl_PackageCmd procedure, "ifneeded" option} { + list [catch {package ifneeded a} msg] $msg +} {1 {wrong # args: should be "package ifneeded package version ?script?"}} +test pkg-3.7 {Tcl_PackageCmd procedure, "ifneeded" option} { + list [catch {package ifneeded a b c d} msg] $msg +} {1 {wrong # args: should be "package ifneeded package version ?script?"}} +test pkg-3.8 {Tcl_PackageCmd procedure, "ifneeded" option} { + list [catch {package ifneeded t xyz} msg] $msg +} {1 {expected version number but got "xyz"}} +test pkg-3.9 {Tcl_PackageCmd procedure, "ifneeded" option} { + foreach i [package names] { + package forget $i + } + list [package ifneeded foo 1.1] [package names] +} {{} {}} +test pkg-3.10 {Tcl_PackageCmd procedure, "ifneeded" option} { + package forget t + package ifneeded t 1.4 "script for t 1.4" + list [package names] [package ifneeded t 1.4] [package versions t] +} {t {script for t 1.4} 1.4} +test pkg-3.11 {Tcl_PackageCmd procedure, "ifneeded" option} { + package forget t + package ifneeded t 1.4 "script for t 1.4" + list [package ifneeded t 1.5] [package names] [package versions t] +} {{} t 1.4} +test pkg-3.12 {Tcl_PackageCmd procedure, "ifneeded" option} { + package forget t + package ifneeded t 1.4 "script for t 1.4" + package ifneeded t 1.4 "second script for t 1.4" + list [package ifneeded t 1.4] [package names] [package versions t] +} {{second script for t 1.4} t 1.4} +test pkg-3.13 {Tcl_PackageCmd procedure, "ifneeded" option} { + package forget t + package ifneeded t 1.4 "script for t 1.4" + package ifneeded t 1.2 "second script" + package ifneeded t 3.1 "last script" + list [package ifneeded t 1.2] [package versions t] +} {{second script} {1.4 1.2 3.1}} +test pkg-3.14 {Tcl_PackageCmd procedure, "names" option} { + list [catch {package names a} msg] $msg +} {1 {wrong # args: should be "package names"}} +test pkg-3.15 {Tcl_PackageCmd procedure, "names" option} { + foreach i [package names] { + package forget $i + } + package names +} {} +test pkg-3.16 {Tcl_PackageCmd procedure, "names" option} { + foreach i [package names] { + package forget $i + } + package ifneeded x 1.2 {dummy} + package provide x 1.3 + package provide y 2.4 + catch {package require z 47.16} + lsort [package names] +} {x y} +test pkg-3.17 {Tcl_PackageCmd procedure, "provide" option} { + list [catch {package provide} msg] $msg +} {1 {wrong # args: should be "package provide package ?version?"}} +test pkg-3.18 {Tcl_PackageCmd procedure, "provide" option} { + list [catch {package provide a b c} msg] $msg +} {1 {wrong # args: should be "package provide package ?version?"}} +test pkg-3.19 {Tcl_PackageCmd procedure, "provide" option} { + package forget t + package provide t +} {} +test pkg-3.20 {Tcl_PackageCmd procedure, "provide" option} { + package forget t + package provide t 2.3 + package provide t +} {2.3} +test pkg-3.21 {Tcl_PackageCmd procedure, "provide" option} { + package forget t + list [catch {package provide t a.b} msg] $msg +} {1 {expected version number but got "a.b"}} +test pkg-3.22 {Tcl_PackageCmd procedure, "require" option} { + list [catch {package require} msg] $msg +} {1 {wrong # args: should be "package require ?-exact? package ?requirement ...?"}} + +test pkg-3.24 {Tcl_PackageCmd procedure, "require" option} { + list [catch {package require -exact a b c} msg] $msg + # Exact syntax: -exact name version + # name ?requirement ...? +} {1 {wrong # args: should be "package require ?-exact? package ?requirement ...?"}} + +test pkg-3.26 {Tcl_PackageCmd procedure, "require" option} { + list [catch {package require x a.b} msg] $msg +} {1 {expected version number but got "a.b"}} +test pkg-3.27 {Tcl_PackageCmd procedure, "require" option} { + list [catch {package require -exact x a.b} msg] $msg +} {1 {expected version number but got "a.b"}} +test pkg-3.28 {Tcl_PackageCmd procedure, "require" option} { + list [catch {package require -exact x} msg] $msg +} {1 {wrong # args: should be "package require ?-exact? package ?requirement ...?"}} +test pkg-3.29 {Tcl_PackageCmd procedure, "require" option} { + list [catch {package require -exact} msg] $msg +} {1 {wrong # args: should be "package require ?-exact? package ?requirement ...?"}} +test pkg-3.30 {Tcl_PackageCmd procedure, "require" option} { + package forget t + package provide t 2.3 + package require t 2.1 +} {2.3} +test pkg-3.31 {Tcl_PackageCmd procedure, "require" option} { + package forget t + list [catch {package require t} msg] $msg +} {1 {can't find package t}} +test pkg-3.32 {Tcl_PackageCmd procedure, "require" option} { + package forget t + package ifneeded t 2.3 "error {synthetic error}" + list [catch {package require t 2.3} msg] $msg +} {1 {synthetic error}} +test pkg-3.33 {Tcl_PackageCmd procedure, "unknown" option} { + list [catch {package unknown a b} msg] $msg +} {1 {wrong # args: should be "package unknown ?command?"}} +test pkg-3.34 {Tcl_PackageCmd procedure, "unknown" option} { + package unknown "test script" + package unknown +} {test script} +test pkg-3.35 {Tcl_PackageCmd procedure, "unknown" option} { + package unknown "test script" + package unknown {} + package unknown +} {} +test pkg-3.36 {Tcl_PackageCmd procedure, "vcompare" option} { + list [catch {package vcompare a} msg] $msg +} {1 {wrong # args: should be "package vcompare version1 version2"}} +test pkg-3.37 {Tcl_PackageCmd procedure, "vcompare" option} { + list [catch {package vcompare a b c} msg] $msg +} {1 {wrong # args: should be "package vcompare version1 version2"}} +test pkg-3.38 {Tcl_PackageCmd procedure, "vcompare" option} { + list [catch {package vcompare x.y 3.4} msg] $msg +} {1 {expected version number but got "x.y"}} +test pkg-3.39 {Tcl_PackageCmd procedure, "vcompare" option} { + list [catch {package vcompare 2.1 a.b} msg] $msg +} {1 {expected version number but got "a.b"}} +test pkg-3.40 {Tcl_PackageCmd procedure, "vcompare" option} { + package vc 2.1 2.3 +} {-1} +test pkg-3.41 {Tcl_PackageCmd procedure, "vcompare" option} { + package vc 2.2.4 2.2.4 +} {0} +test pkg-3.42 {Tcl_PackageCmd procedure, "versions" option} { + list [catch {package versions} msg] $msg +} {1 {wrong # args: should be "package versions package"}} +test pkg-3.43 {Tcl_PackageCmd procedure, "versions" option} { + list [catch {package versions a b} msg] $msg +} {1 {wrong # args: should be "package versions package"}} +test pkg-3.44 {Tcl_PackageCmd procedure, "versions" option} { + package forget t + package versions t +} {} +test pkg-3.45 {Tcl_PackageCmd procedure, "versions" option} { + package forget t + package provide t 2.3 + package versions t +} {} +test pkg-3.46 {Tcl_PackageCmd procedure, "versions" option} { + package forget t + package ifneeded t 2.3 x + package ifneeded t 2.4 y + package versions t +} {2.3 2.4} +test pkg-3.47 {Tcl_PackageCmd procedure, "vsatisfies" option} { + list [catch {package vsatisfies a} msg] $msg +} {1 {wrong # args: should be "package vsatisfies version ?requirement ...?"}} + +test pkg-3.49 {Tcl_PackageCmd procedure, "vsatisfies" option} { + list [catch {package vsatisfies x.y 3.4} msg] $msg +} {1 {expected version number but got "x.y"}} +test pkg-3.50 {Tcl_PackageCmd procedure, "vsatisfies" option} { + list [catch {package vcompare 2.1 a.b} msg] $msg +} {1 {expected version number but got "a.b"}} +test pkg-3.51 {Tcl_PackageCmd procedure, "vsatisfies" option} { + package vs 2.3 2.1 +} {1} +test pkg-3.52 {Tcl_PackageCmd procedure, "vsatisfies" option} { + package vs 2.3 1.2 +} {0} +test pkg-3.53 {Tcl_PackageCmd procedure, "versions" option} { + list [catch {package foo} msg] $msg +} {1 {bad option "foo": must be forget, ifneeded, names, prefer, present, provide, require, unknown, vcompare, versions, or vsatisfies}} + +test pkg-3.54 {Tcl_PackageCmd procedure, "vsatisfies" option} { + list [catch {package vsatisfies 2.1 2.1-3.2-4.5} msg] $msg +} {1 {expected versionMin-versionMax but got "2.1-3.2-4.5"}} + +test pkg-3.55 {Tcl_PackageCmd procedure, "vsatisfies" option} { + list [catch {package vsatisfies 2.1 3.2-x.y} msg] $msg +} {1 {expected version number but got "x.y"}} + +test pkg-3.56 {Tcl_PackageCmd procedure, "vsatisfies" option} { + list [catch {package vsatisfies 2.1 x.y-3.2} msg] $msg +} {1 {expected version number but got "x.y"}} + + +# No tests for FindPackage; can't think up anything detectable +# errors. + +test pkg-4.1 {TclFreePackageInfo procedure} { + interp create foo + foo eval { + package ifneeded t 2.3 x + package ifneeded t 2.4 y + package ifneeded x 3.1 z + package provide q 4.3 + package unknown "will this get freed?" + } + interp delete foo +} {} +test pkg-4.2 {TclFreePackageInfo procedure} -body { + interp create foo + foo eval { + package ifneeded t 2.3 x + package ifneeded t 2.4 y + package ifneeded x 3.1 z + package provide q 4.3 + } + foo alias z kill + proc kill {} { + interp delete foo + } + foo eval package require x 3.1 +} -returnCodes error -match glob -result * + +test pkg-5.1 {CheckVersion procedure} { + list [catch {package vcompare 1 2.1} msg] $msg +} {0 -1} +test pkg-5.2 {CheckVersion procedure} { + list [catch {package vcompare .1 2.1} msg] $msg +} {1 {expected version number but got ".1"}} +test pkg-5.3 {CheckVersion procedure} { + list [catch {package vcompare 111.2a.3 2.1} msg] $msg +} {1 {expected version number but got "111.2a.3"}} +test pkg-5.4 {CheckVersion procedure} { + list [catch {package vcompare 1.2.3. 2.1} msg] $msg +} {1 {expected version number but got "1.2.3."}} +test pkg-5.5 {CheckVersion procedure} { + list [catch {package vcompare 1.2..3 2.1} msg] $msg +} {1 {expected version number but got "1.2..3"}} + +test pkg-6.1 {ComparePkgVersions procedure} { + package vcompare 1.23 1.22 +} {1} +test pkg-6.2 {ComparePkgVersions procedure} { + package vcompare 1.22.1.2.3 1.22.1.2.3 +} {0} +test pkg-6.3 {ComparePkgVersions procedure} { + package vcompare 1.21 1.22 +} {-1} +test pkg-6.4 {ComparePkgVersions procedure} { + package vcompare 1.21 1.21.2 +} {-1} +test pkg-6.5 {ComparePkgVersions procedure} { + package vcompare 1.21.1 1.21 +} {1} +test pkg-6.6 {ComparePkgVersions procedure} { + package vsatisfies 1.21.1 1.21 +} {1} +test pkg-6.7 {ComparePkgVersions procedure} { + package vsatisfies 2.22.3 1.21 +} {0} +test pkg-6.8 {ComparePkgVersions procedure} { + package vsatisfies 1 1 +} {1} +test pkg-6.9 {ComparePkgVersions procedure} { + package vsatisfies 2 1 +} {0} + +test pkg-7.1 {Tcl_PkgPresent procedure, any version} { + package forget t + package provide t 2.4 + package present t +} {2.4} +test pkg-7.2 {Tcl_PkgPresent procedure, correct version} { + package forget t + package provide t 2.4 + package present t 2.4 +} {2.4} +test pkg-7.3 {Tcl_PkgPresent procedure, satisfying version} { + package forget t + package provide t 2.4 + package present t 2.0 +} {2.4} +test pkg-7.4 {Tcl_PkgPresent procedure, not satisfying version} { + package forget t + package provide t 2.4 + list [catch {package present t 2.6} msg] $msg +} {1 {version conflict for package "t": have 2.4, need 2.6}} +test pkg-7.5 {Tcl_PkgPresent procedure, not satisfying version} { + package forget t + package provide t 2.4 + list [catch {package present t 1.0} msg] $msg +} {1 {version conflict for package "t": have 2.4, need 1.0}} +test pkg-7.6 {Tcl_PkgPresent procedure, exact version} { + package forget t + package provide t 2.4 + package present -exact t 2.4 +} {2.4} +test pkg-7.7 {Tcl_PkgPresent procedure, not exact version} { + package forget t + package provide t 2.4 + list [catch {package present -exact t 2.3} msg] $msg +} {1 {version conflict for package "t": have 2.4, need exactly 2.3}} +test pkg-7.8 {Tcl_PkgPresent procedure, unknown package} { + package forget t + list [catch {package present t} msg] $msg +} {1 {package t is not present}} +test pkg-7.9 {Tcl_PkgPresent procedure, unknown package} { + package forget t + list [catch {package present t 2.4} msg] $msg +} {1 {package t 2.4 is not present}} +test pkg-7.10 {Tcl_PkgPresent procedure, unknown package} { + package forget t + list [catch {package present -exact t 2.4} msg] $msg +} {1 {package t 2.4 is not present}} +test pkg-7.11 {Tcl_PackageCmd procedure, "present" option} { + list [catch {package present} msg] $msg +} {1 {wrong # args: should be "package present ?-exact? package ?requirement ...?"}} +test pkg-7.12 {Tcl_PackageCmd procedure, "present" option} { + list [catch {package present a b c} msg] $msg +} {1 {expected version number but got "b"}} +test pkg-7.13 {Tcl_PackageCmd procedure, "present" option} { + list [catch {package present -exact a b c} msg] $msg +} {1 {wrong # args: should be "package present ?-exact? package ?requirement ...?"}} +test pkg-7.14 {Tcl_PackageCmd procedure, "present" option} { + list [catch {package present -bs a b} msg] $msg +} {1 {expected version number but got "a"}} +test pkg-7.15 {Tcl_PackageCmd procedure, "present" option} { + list [catch {package present x a.b} msg] $msg +} {1 {expected version number but got "a.b"}} +test pkg-7.16 {Tcl_PackageCmd procedure, "present" option} { + list [catch {package present -exact x a.b} msg] $msg +} {1 {expected version number but got "a.b"}} +test pkg-7.17 {Tcl_PackageCmd procedure, "present" option} { + list [catch {package present -exact x} msg] $msg +} {1 {wrong # args: should be "package present ?-exact? package ?requirement ...?"}} +test pkg-7.18 {Tcl_PackageCmd procedure, "present" option} { + list [catch {package present -exact} msg] $msg +} {1 {wrong # args: should be "package present ?-exact? package ?requirement ...?"}} + + + + +set n 0 +foreach {r p vs vc} { + 8.5a0 8.5a5 1 -1 + 8.5a0 8.5b1 1 -1 + 8.5a0 8.5.1 1 -1 + 8.5a0 8.6a0 1 -1 + 8.5a0 8.6b0 1 -1 + 8.5a0 8.6.0 1 -1 + 8.5a6 8.5a5 0 1 + 8.5a6 8.5b1 1 -1 + 8.5a6 8.5.1 1 -1 + 8.5a6 8.6a0 1 -1 + 8.5a6 8.6b0 1 -1 + 8.5a6 8.6.0 1 -1 + 8.5b0 8.5a5 0 1 + 8.5b0 8.5b1 1 -1 + 8.5b0 8.5.1 1 -1 + 8.5b0 8.6a0 1 -1 + 8.5b0 8.6b0 1 -1 + 8.5b0 8.6.0 1 -1 + 8.5b2 8.5a5 0 1 + 8.5b2 8.5b1 0 1 + 8.5b2 8.5.1 1 -1 + 8.5b2 8.6a0 1 -1 + 8.5b2 8.6b0 1 -1 + 8.5b2 8.6.0 1 -1 + 8.5 8.5a5 1 1 + 8.5 8.5b1 1 1 + 8.5 8.5.1 1 -1 + 8.5 8.6a0 1 -1 + 8.5 8.6b0 1 -1 + 8.5 8.6.0 1 -1 + 8.5.0 8.5a5 0 1 + 8.5.0 8.5b1 0 1 + 8.5.0 8.5.1 1 -1 + 8.5.0 8.6a0 1 -1 + 8.5.0 8.6b0 1 -1 + 8.5.0 8.6.0 1 -1 + 10 8 0 1 + 8 10 0 -1 + 0.0.1.2 0.1.2 1 -1 +} { + test package-vsatisfies-1.$n {package vsatisfies} { + package vsatisfies $p $r + } $vs + + test package-vcompare-1.$n {package vcompare} { + package vcompare $r $p + } $vc + + incr n +} + +test package-vcompare-2.0 {package vcompare at 32bit boundary} { + package vcompare [expr {1<<31}] [expr {(1<<31)-1}] +} 1 + +# Note: It is correct that the result of the very first test, +# i.e. "5.0 5.0a0" is 1, i.e. that version 5.0a0 satisfies a 5.0 +# requirement. + +# The requirement "5.0" internally translates first to "5.0-6", and +# then to its final form of "5.0a0-6a0". These translations are +# explicitly specified by the TIP (Search for "padded/extended +# internally with 'a0'"). This was done intentionally for exactly the +# tested case, that an alpha package can satisfy a requirement for the +# regular package. An example would be a package FOO requiring Tcl 8.X +# for its operation. It can be used with Tcl 8.Xa0. Without our +# translation that would not be possible. + +set n 0 +foreach {required provided satisfied} { + 5.0 5.0a0 1 + 5.0a0 5.0 1 + + 8.5a0- 8.5a5 1 + 8.5a0- 8.5b1 1 + 8.5a0- 8.5.1 1 + 8.5a0- 8.6a0 1 + 8.5a0- 8.6b0 1 + 8.5a0- 8.6.0 1 + 8.5a6- 8.5a5 0 + 8.5a6- 8.5b1 1 + 8.5a6- 8.5.1 1 + 8.5a6- 8.6a0 1 + 8.5a6- 8.6b0 1 + 8.5a6- 8.6.0 1 + 8.5b0- 8.5a5 0 + 8.5b0- 8.5b1 1 + 8.5b0- 8.5.1 1 + 8.5b0- 8.6a0 1 + 8.5b0- 8.6b0 1 + 8.5b0- 8.6.0 1 + 8.5b2- 8.5a5 0 + 8.5b2- 8.5b1 0 + 8.5b2- 8.5.1 1 + 8.5b2- 8.6a0 1 + 8.5b2- 8.6b0 1 + 8.5b2- 8.6.0 1 + 8.5- 8.5a5 1 + 8.5- 8.5b1 1 + 8.5- 8.5.1 1 + 8.5- 8.6a0 1 + 8.5- 8.6b0 1 + 8.5- 8.6.0 1 + 8.5.0- 8.5a5 0 + 8.5.0- 8.5b1 0 + 8.5.0- 8.5.1 1 + 8.5.0- 8.6a0 1 + 8.5.0- 8.6b0 1 + 8.5.0- 8.6.0 1 + 8.5a0-7 8.5a5 0 + 8.5a0-7 8.5b1 0 + 8.5a0-7 8.5.1 0 + 8.5a0-7 8.6a0 0 + 8.5a0-7 8.6b0 0 + 8.5a0-7 8.6.0 0 + 8.5a6-7 8.5a5 0 + 8.5a6-7 8.5b1 0 + 8.5a6-7 8.5.1 0 + 8.5a6-7 8.6a0 0 + 8.5a6-7 8.6b0 0 + 8.5a6-7 8.6.0 0 + 8.5b0-7 8.5a5 0 + 8.5b0-7 8.5b1 0 + 8.5b0-7 8.5.1 0 + 8.5b0-7 8.6a0 0 + 8.5b0-7 8.6b0 0 + 8.5b0-7 8.6.0 0 + 8.5b2-7 8.5a5 0 + 8.5b2-7 8.5b1 0 + 8.5b2-7 8.5.1 0 + 8.5b2-7 8.6a0 0 + 8.5b2-7 8.6b0 0 + 8.5b2-7 8.6.0 0 + 8.5-7 8.5a5 0 + 8.5-7 8.5b1 0 + 8.5-7 8.5.1 0 + 8.5-7 8.6a0 0 + 8.5-7 8.6b0 0 + 8.5-7 8.6.0 0 + 8.5.0-7 8.5a5 0 + 8.5.0-7 8.5b1 0 + 8.5.0-7 8.5.1 0 + 8.5.0-7 8.6a0 0 + 8.5.0-7 8.6b0 0 + 8.5.0-7 8.6.0 0 + 8.5a0-8.6.1 8.5a5 1 + 8.5a0-8.6.1 8.5b1 1 + 8.5a0-8.6.1 8.5.1 1 + 8.5a0-8.6.1 8.6a0 1 + 8.5a0-8.6.1 8.6b0 1 + 8.5a0-8.6.1 8.6.0 1 + 8.5a6-8.6.1 8.5a5 0 + 8.5a6-8.6.1 8.5b1 1 + 8.5a6-8.6.1 8.5.1 1 + 8.5a6-8.6.1 8.6a0 1 + 8.5a6-8.6.1 8.6b0 1 + 8.5a6-8.6.1 8.6.0 1 + 8.5b0-8.6.1 8.5a5 0 + 8.5b0-8.6.1 8.5b1 1 + 8.5b0-8.6.1 8.5.1 1 + 8.5b0-8.6.1 8.6a0 1 + 8.5b0-8.6.1 8.6b0 1 + 8.5b0-8.6.1 8.6.0 1 + 8.5b2-8.6.1 8.5a5 0 + 8.5b2-8.6.1 8.5b1 0 + 8.5b2-8.6.1 8.5.1 1 + 8.5b2-8.6.1 8.6a0 1 + 8.5b2-8.6.1 8.6b0 1 + 8.5b2-8.6.1 8.6.0 1 + 8.5-8.6.1 8.5a5 1 + 8.5-8.6.1 8.5b1 1 + 8.5-8.6.1 8.5.1 1 + 8.5-8.6.1 8.6a0 1 + 8.5-8.6.1 8.6b0 1 + 8.5-8.6.1 8.6.0 1 + 8.5.0-8.6.1 8.5a5 0 + 8.5.0-8.6.1 8.5b1 0 + 8.5.0-8.6.1 8.5.1 1 + 8.5.0-8.6.1 8.6a0 1 + 8.5.0-8.6.1 8.6b0 1 + 8.5.0-8.6.1 8.6.0 1 + 8.5a0-8.5a0 8.5a0 1 + 8.5a0-8.5a0 8.5b1 0 + 8.5a0-8.5a0 8.4 0 + 8.5b0-8.5b0 8.5a5 0 + 8.5b0-8.5b0 8.5b0 1 + 8.5b0-8.5b0 8.5.1 0 + 8.5-8.5 8.5a5 0 + 8.5-8.5 8.5b1 0 + 8.5-8.5 8.5 1 + 8.5-8.5 8.5.1 0 + 8.5.0-8.5.0 8.5a5 0 + 8.5.0-8.5.0 8.5b1 0 + 8.5.0-8.5.0 8.5.0 1 + 8.5.0-8.5.0 8.5.1 0 + 8.5.0-8.5.0 8.6a0 0 + 8.5.0-8.5.0 8.6b0 0 + 8.5.0-8.5.0 8.6.0 0 + 8.2 9 0 + 8.2- 9 1 + 8.2-8.5 9 0 + 8.2-9.1 9 1 + + 8.5-8.5 8.5b1 0 + 8.5a0-8.5 8.5b1 0 + 8.5a0-8.5.1 8.5b1 1 + + 8.5-8.5 8.5 1 + 8.5.0-8.5.0 8.5 1 + 8.5a0-8.5.0 8.5 0 + +} { + test package-vsatisfies-2.$n "package vsatisfies $provided $required" { + package vsatisfies $provided $required + } $satisfied + incr n +} + +test package-vsatisfies-3.0 "package vsatisfies multiple" { + # yes no + package vsatisfies 8.4 8.4 7.3 +} 1 + +test package-vsatisfies-3.1 "package vsatisfies multiple" { + # no yes + package vsatisfies 8.4 7.3 8.4 +} 1 + +test package-vsatisfies-3.2 "package vsatisfies multiple" { + # yes yes + package vsatisfies 8.4.2 8.4 8.4.1 +} 1 + +test package-vsatisfies-3.3 "package vsatisfies multiple" { + # no no + package vsatisfies 8.4 7.3 6.1 +} 0 + + +proc prefer {args} { + set ip [interp create] + lappend res [$ip eval {package prefer}] + foreach mode $args { + lappend res [$ip eval [list package prefer $mode]] + } + interp delete $ip + return $res +} + +test package-prefer-1.0 {default} { + prefer +} stable + +test package-prefer-1.1 {default} { + set ::env(TCL_PKG_PREFER_LATEST) stable ; # value not relevant! + set res [prefer] + unset ::env(TCL_PKG_PREFER_LATEST) + set res +} latest + +test package-prefer-2.0 {wrong\#args} { + catch {package prefer foo bar} msg + set msg +} {wrong # args: should be "package prefer ?latest|stable?"} + +test package-prefer-2.1 {bogus argument} { + catch {package prefer foo} msg + set msg +} {bad preference "foo": must be latest or stable} + +test package-prefer-3.0 {set, keep} { + package prefer stable +} stable + +test package-prefer-3.1 {set stable, keep} { + prefer stable +} {stable stable} + +test package-prefer-3.2 {set latest, change} { + prefer latest +} {stable latest} + +test package-prefer-3.3 {set latest, keep} { + prefer latest latest +} {stable latest latest} + +test package-prefer-3.4 {set stable, rejected} { + prefer latest stable +} {stable latest latest} + +rename prefer {} + + +set auto_path $oldPath +package unknown $oldPkgUnknown +concat + +cleanupTests +} + +# cleanup +interp delete $i +::tcltest::cleanupTests +return diff --git a/tests/resource.test b/tests/resource.test new file mode 100644 index 0000000..a650d48 --- /dev/null +++ b/tests/resource.test @@ -0,0 +1,369 @@ +# Commands covered: resource +# +# This file contains a collection of tests for one or more of the Tcl +# built-in commands. Sourcing this file into Tcl runs the tests and +# generates output for errors. No output means no errors were found. +# +# Copyright (c) 1996-1997 Sun Microsystems, Inc. +# Copyright (c) 1998-1999 by Scriptics Corporation. +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# +# RCS: @(#) $Id: resource.test,v 1.9 2003/10/23 10:07:30 vincentdarley Exp $ + +if {[lsearch [namespace children] ::tcltest] == -1} { + package require tcltest + namespace import -force ::tcltest::* +} + +test resource-1.1 {resource tests} {macOnly} { + list [catch {resource} msg] $msg +} {1 {wrong # args: should be "resource option ?arg ...?"}} +test resource-1.2 {resource tests} {macOnly} { + list [catch {resource _bad_} msg] $msg +} {1 {bad option "_bad_": must be close, delete, files, list, open, read, types, or write}} + +# resource open & close tests +test resource-2.1 {resource open & close tests} {macOnly} { + list [catch {resource open} msg] $msg +} {1 {wrong # args: should be "resource open fileName ?permissions?"}} +test resource-2.2 {resource open & close tests} {macOnly} { + list [catch {resource open resource.test r extraArg} msg] $msg +} {1 {wrong # args: should be "resource open fileName ?permissions?"}} +test resource-2.3 {resource open & close tests} {macOnly} { + list [catch {resource open resource.test bad_perms} msg] $msg +} {1 {illegal access mode "bad_perms"}} +test resource-2.4 {resource open & close tests} {macOnly} { + list [catch {resource open _bad_file_} msg] $msg +} {1 {file does not exist}} +test resource-2.5 {resource open & close tests} {macOnly} { + testWriteTextResource -rsrc fileRsrcName -file rsrc.file {error "don't source me"} + set id [resource open rsrc.file] + resource close $id + file delete rsrc.file +} {} +test resource-2.6 {resource open & close tests} {macOnly} { + catch {file delete rsrc.file} + testWriteTextResource -rsrc fileRsrcName -file rsrc.file {A test string} + set id [resource open rsrc.file] + set result [string compare [resource open rsrc.file] $id] + lappend result [resource read TEXT fileRsrcName $id] + resource close $id + file delete rsrc.file + set result +} {0 {A test string}} +test resource-2.7 {resource open & close tests} {macOnly} { + catch {file delete rsrc.file} + testWriteTextResource -rsrc fileRsrcName -file rsrc.file {error "don't source me"} + set id [resource open rsrc.file r] + set result [catch {resource open rsrc.file w} mssg] + resource close $id + file delete rsrc.file + lappend result $mssg + set result +} {1 {Resource already open with different permissions.}} +test resource-2.8 {resource open & close tests} {macOnly} { + list [catch {resource close} msg] $msg +} {1 {wrong # args: should be "resource close resourceRef"}} +test resource-2.9 {resource open & close tests} {macOnly} { + list [catch {resource close foo bar} msg] $msg +} {1 {wrong # args: should be "resource close resourceRef"}} +test resource-2.10 {resource open & close tests} {macOnly} { + list [catch {resource close _bad_resource_} msg] $msg +} {1 {invalid resource file reference "_bad_resource_"}} +test resource-2.11 {resource open & close tests} {macOnly} { + set result [catch {resource close System} mssg] + lappend result $mssg +} {1 {can't close "System" resource file}} +test resource-2.12 {resource open & close tests} {macOnly} { + set result [catch {resource close application} mssg] + lappend result $mssg +} {1 {can't close "application" resource file}} + +# Tests for listing resources +test resource-3.1 {resource list tests} {macOnly} { + list [catch {resource list} msg] $msg +} {1 {wrong # args: should be "resource list resourceType ?resourceRef?"}} +test resource-3.2 {resource list tests} {macOnly} { + list [catch {resource list _bad_type_} msg] $msg +} {1 {expected Macintosh OS type but got "_bad_type_"}} +test resource-3.3 {resource list tests} {macOnly} { + list [catch {resource list TEXT _bad_ref_} msg] $msg +} {1 {invalid resource file reference "_bad_ref_"}} +test resource-3.4 {resource list tests} {macOnly} { + list [catch {resource list TEXT _bad_ref_ extraArg} msg] $msg +} {1 {wrong # args: should be "resource list resourceType ?resourceRef?"}} +test resource-3.5 {resource list tests} {macOnly} { + catch {file delete rsrc.file} + testWriteTextResource -rsrc fileRsrcName -file rsrc.file {error "don't source me"} + set id [resource open rsrc.file] + catch "resource list TEXT $id" result + resource close $id + set result +} {fileRsrcName} +test resource-3.6 {resource list tests} {macOnly} { + # There should not be any resource of this type + resource list XXXX +} {} +test resource-3.7 {resource list tests} {macOnly} { + set resourceList [resource list STR#] + if {[lsearch $resourceList {Tcl Environment Variables}] == -1} { + set result {couldn't find resource that should exist} + } else { + set result ok + } +} {ok} + +# Tests for reading resources +test resource-4.1 {resource read tests} {macOnly} { + list [catch {resource read} msg] $msg +} {1 {wrong # args: should be "resource read resourceType resourceId ?resourceRef?"}} +test resource-4.2 {resource read tests} {macOnly} { + list [catch {resource read TEXT} msg] $msg +} {1 {wrong # args: should be "resource read resourceType resourceId ?resourceRef?"}} +test resource-4.3 {resource read tests} {macOnly} { + list [catch {resource read STR# {_non_existant_resource_}} msg] $msg +} {1 {could not load resource}} +test resource-4.4 {resource read tests} {macOnly} { + # The following resource should exist and load OK without error + catch {resource read STR# {Tcl Environment Variables}} +} {0} + +# Tests for getting resource types +test resource-5.1 {resource types tests} {macOnly} { + list [catch {resource types _bad_ref_} msg] $msg +} {1 {invalid resource file reference "_bad_ref_"}} +test resource-5.2 {resource types tests} {macOnly} { + list [catch {resource types _bad_ref_ extraArg} msg] $msg +} {1 {wrong # args: should be "resource types ?resourceRef?"}} +test resource-5.3 {resource types tests} {macOnly} { + # This should never cause an error + catch {resource types} +} {0} +test resource-5.4 {resource types tests} {macOnly} { + testWriteTextResource -rsrc fileRsrcName -file rsrc.file {error "don't source me"} + set id [resource open rsrc.file] + set result [resource types $id] + resource close $id + set result +} {TEXT} +test resource-5.5 {resource types lists} {macOnly} { + # This should not crash + catch {foreach f [resource types] { resource list $f }} +} {0} + +# resource write tests +test resource-6.1 {resource write tests} {macOnly} { + list [catch {resource write} msg] $msg +} {1 {wrong # args: should be "resource write ?-id resourceId? ?-name resourceName? ?-file resourceRef? ?-force? resourceType data"}} +test resource-6.2 {resource write tests} {macOnly} { + list [catch {resource write _bad_type_ data} msg] $msg +} {1 {expected Macintosh OS type but got "_bad_type_"}} +test resource-6.3 {resource write tests} {macOnly} { + catch {file delete rsrc2.file} + set id [resource open rsrc2.file w] + resource close $id + set id [resource open rsrc2.file r] + set result [catch {resource write -file $id -name Hello TEXT foo} errMsg] + lappend result [string compare $errMsg "cannot write to resource file \"$id\", it was opened read only"] + lappend result [lsearch [resource list TEXT $id] Hello] + resource close $id + file delete rsrc2.file + set result +} {1 0 -1} +test resource-6.4 {resource write tests} {macOnly} { + catch {file delete rsrc2.file} + set id [resource open rsrc2.file w] + resource write -file $id -name Hello TEXT {set x "our test data"} + source -rsrc Hello rsrc2.file + resource close $id + file delete rsrc2.file + set x +} {our test data} +test resource-6.5 {resource write tests} {macOnly} { + catch {file delete rsrc2.file} + set id [resource open rsrc2.file w] + resource write -file $id -id 256 TEXT {HAHAHAHAHAHAHA} + set result [catch {resource write -file $id -id 256 TEXT {HOHOHOHOHOHO}} mssg] + resource close $id + file delete rsrc2.file + lappend result $mssg +} {1 {the resource 256 already exists, use "-force" to overwrite it.}} +test resource-6.6 {resource write tests} {macOnly} { + catch {file delete rsrc2.file} + testWriteTextResource -rsrc fileRsrcName -rsrcid 256 -file rsrc2.file -protected {error "don't tread on me"} + set id [resource open rsrc2.file w] + set result [catch {resource write -id 256 -force -file $id TEXT {NAHNAHNANAHNAH}} mssg] + resource close $id + file delete rsrc2.file + lappend result $mssg +} {1 {could not write resource id 256 of type TEXT, it was protected.}} +test resource-6.7 {resource write tests} {macOnly} { + catch {file delete rsrc2.file} + set id [resource open rsrc2.file w] + resource write -file $id -id 256 -name FOO TEXT {set x [list "our first test data"]} + resource write -file $id -id 256 -name BAR -force TEXT {set x [list "our second test data"]} + source -rsrcid 256 rsrc2.file + lappend x [resource list TEXT $id] + resource close $id + file delete rsrc2.file + set x +} {{our second test data} BAR} + +#Tests for listing open resource files +test resource-7.1 {resource file tests} {macOnly} { + catch {resource files foo bar} mssg + set mssg +} {wrong # args: should be "resource files ?resourceId?"} +test resource-7.2 {resource file tests} {macOnly} { + catch {file delete rsrc2.file} + set rsrcFiles [resource files] + set id [resource open rsrc2.file w] + set result [string compare $rsrcFiles [lrange [resource files] 1 end]] + lappend result [string compare $id [lrange [resource files] 0 0]] + resource close $id + file delete rsrc2.file + set result +} {0 0} +test resource-7.3 {resource file tests} {macOnly} { + set result 0 + foreach file [resource files] { + if {[catch {resource types $file}] != 0} { + set result 1 + } + } + set result +} {0} +test resource-7.4 {resource file tests} {macOnly} { + catch {resource files __NO_SUCH_RESOURCE__} mssg + set mssg +} {invalid resource file reference "__NO_SUCH_RESOURCE__"} +test resource-7.5 {resource file tests} {macOnly} { + set sys [resource files System] + string compare $sys [file join $env(SYS_FOLDER) System] +} {0} +test resource-7.6 {resource file tests} {macOnly} { + set app [resource files application] + string compare $app [info nameofexecutable] +} {0} + +#Tests for the resource delete command +test resource-8.1 {resource delete tests} {macOnly} { + list [catch {resource delete} msg] $msg +} {1 {wrong # args: should be "resource delete ?-id resourceId? ?-name resourceName? ?-file resourceRef? resourceType"}} +test resource-8.2 {resource delete tests} {macOnly} { + list [catch {resource delete TEXT} msg] $msg +} {1 {you must specify either "-id" or "-name" or both to "resource delete"}} +test resource-8.3 {resource delete tests} {macOnly} { + set result [catch {resource delete -file ffffff -id 128 TEXT} mssg] + lappend result $mssg +} {1 {invalid resource file reference "ffffff"}} +test resource-8.4 {resource delete tests} {macOnly} { + catch {file delete rsrc2.file} + testWriteTextResource -rsrc fileRsrcName -rsrcid 128 -file rsrc2.file {Some stuff} + set id [resource open rsrc2.file r] + set result [catch {resource delete -id 128 -file $id TEXT} mssg] + resource close $id + file delete rsrc2.file + lappend result [string compare $mssg "cannot delete from resource file \"$id\", it was opened read only"] +} {1 0} +test resource-8.5 {resource delete tests} {macOnly} { + catch {file delete rsrc2.file} + testWriteTextResource -rsrc fileRsrcName -rsrcid 128 -file rsrc2.file {Some stuff} + set id [resource open rsrc2.file w] + set result [catch {resource delete -id 128 -file $id _bad_type_} mssg] + resource close $id + file delete rsrc2.file + lappend result $mssg +} {1 {expected Macintosh OS type but got "_bad_type_"}} +test resource-8.5.1 {resource delete tests} {macOnly} { + catch {file delete rsrc2.file} + set id [resource open rsrc2.file w] + set result [catch {resource delete -id 128 -file $id TEXT} mssg] + resource close $id + file delete rsrc2.file + lappend result $mssg +} {1 {resource not found}} +test resource-8.6 {resource delete tests} {macOnly} { + catch {file delete rsrc2.file} + set id [resource open rsrc2.file w] + set result [catch {resource delete -name foo -file $id TEXT} mssg] + resource close $id + file delete rsrc2.file + lappend result $mssg +} {1 {resource not found}} +test resource-8.7 {resource delete tests} {macOnly} { + catch {file delete rsrc2.file} + set id [resource open rsrc2.file w] + resource write -file $id -name foo -id 128 TEXT {some stuff} + resource write -file $id -name bar -id 129 TEXT {some stuff} + set result [catch {resource delete -name foo -id 129 -file $id TEXT} mssg] + resource close $id + file delete rsrc2.file + lappend result $mssg +} {1 {"-id" and "-name" values do not point to the same resource}} +test resource-8.8 {resource delete tests} {macOnly} { + catch {file delete rsrc2.file} + testWriteTextResource -rsrc fileRsrcName -rsrcid 256 -file rsrc2.file -protected {error "don't tread on me"} + set id [resource open rsrc2.file w] + set result [catch {resource delete -id 256 -file $id TEXT } mssg] + resource close $id + file delete rsrc2.file + lappend result $mssg +} {1 {resource cannot be deleted: it is protected.}} +test resource-8.9 {resource delete tests} {macOnly} { + catch {file delete rsrc2.file} + testWriteTextResource -rsrc fileRsrcName -rsrcid 128 -file rsrc2.file {Some stuff} + set id [resource open rsrc2.file w] + set result [resource list TEXT $id] + resource delete -id 128 -file $id TEXT + lappend result [resource list TEXT $id] + resource close $id + file delete rsrc2.file + set result +} {fileRsrcName {}} + +# Tests for the Mac version of the source command +catch {file delete rsrc.file} +test resource-9.1 {source command} {macOnly} { + testWriteTextResource -rsrc fileRsrcName -rsrcid 128 \ + -file rsrc.file {set rsrc_foo 1} + catch {unset rsrc_foo} + source -rsrc fileRsrcName rsrc.file + list [catch {set rsrc_foo} msg] $msg +} {0 1} +test resource-9.2 {source command} {macOnly} { + catch {unset rsrc_foo} + list [catch {source -rsrc no_resource rsrc.file} msg] $msg +} {1 {The resource "no_resource" could not be loaded from rsrc.file.}} +test resource-9.3 {source command} {macOnly} { + catch {unset rsrc_foo} + source -rsrcid 128 rsrc.file + list [catch {set rsrc_foo} msg] $msg +} {0 1} +test resource-9.4 {source command} {macOnly} { + catch {unset rsrc_foo} + list [catch {source -rsrcid bad_int rsrc.file} msg] $msg +} {1 {expected integer but got "bad_int"}} +test resource-9.5 {source command} {macOnly} { + catch {unset rsrc_foo} + list [catch {source -rsrcid 100 rsrc.file} msg] $msg +} {1 {The resource "ID=100" could not be loaded from rsrc.file.}} + +# cleanup +catch {file delete rsrc.file} +::tcltest::cleanupTests +return + + + + + + + + + + + + diff --git a/tests/unsupported.test b/tests/unsupported.test new file mode 100644 index 0000000..0c706b8 --- /dev/null +++ b/tests/unsupported.test @@ -0,0 +1,914 @@ +# Commands covered: tailcall, atProcExit, coroutine, yield +# +# This file contains a collection of tests for experimental commands that are +# found in ::tcl::unsupported. The tests will migrate to normal test files +# if/when the commands find their way into the core. +# +# Copyright (c) 2008 by Miguel Sofer. +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# +# RCS: @(#) $Id: unsupported.test,v 1.15 2008/10/14 18:49:47 dgp Exp $ + +if {[lsearch [namespace children] ::tcltest] == -1} { + package require tcltest + namespace import -force ::tcltest::* +} + +testConstraint testnrelevels [llength [info commands testnrelevels]] +testConstraint atProcExit [llength [info commands ::tcl::unsupported::atProcExit]] + +if {[namespace exists tcl::unsupported]} { + namespace eval tcl::unsupported namespace export * + namespace import tcl::unsupported::* +} + +# +# The tests that risked blowing the C stack on failure have been removed: we +# can now actually measure using testnrelevels. +# + +if {[testConstraint testnrelevels]} { + namespace eval testnre { + # + # [testnrelevels] returns a 6-list with: C-stack depth, iPtr->numlevels, + # cmdFrame level, callFrame level, tosPtr and callback depth + # + variable last [testnrelevels] + proc depthDiff {} { + variable last + set depth [testnrelevels] + set res {} + foreach t $depth l $last { + lappend res [expr {$t-$l}] + } + set last $depth + return $res + } + proc setabs {} { + uplevel 1 variable abs -[lindex [testnrelevels] 0] + } + + variable body0 { + set x [depthDiff] + if {[incr i] > 10} { + variable abs + incr abs [lindex [testnrelevels] 0] + return [list [lrange $x 0 3] $abs] + } + } + proc makebody txt { + variable body0 + return "$body0; $txt" + } + namespace export * + } + namespace import testnre::* +} + +# +# Test atProcExit +# + +test unsupported-A.1 {atProcExit works} -constraints {atProcExit} -setup { + variable x x y y + proc a {} { + variable x 0 y 0 + atProcExit set ::x 1 + set x 2 + set y $x + set x 3 + } + proc b {} a +} -body { + list [b] $x $y +} -cleanup { + unset x y + rename a {} + rename b {} +} -result {3 1 2} + +test unsupported-A.2 {atProcExit} -constraints {atProcExit} -setup { + variable x x y x + proc a {} { + variable x 0 y 0 + atProcExit set ::x 1 + set x 2 + set y $x + set x 3 + } +} -body { + list [a] $x $y +} -cleanup { + unset x y + rename a {} +} -result {3 1 2} + +test unsupported-A.3 {atProcExit} -constraints {atProcExit} -setup { + variable x x y y + proc a {} { + variable x 0 y 0 + atProcExit lappend ::x 1 + lappend x 2 + atProcExit lappend ::x 3 + lappend y $x + lappend x 4 + return 5 + } +} -body { + list [a] $x $y +} -cleanup { + unset x y + rename a {} +} -result {5 {0 2 4 3 1} {0 {0 2}}} + +test unsupported-A.4 {atProcExit errors} -constraints {atProcExit} -setup { + variable x x y y + proc a {} { + variable x 0 y 0 + atProcExit lappend ::x 1 + lappend x 2 + atProcExit lappend ::x 3 + lappend y $x + lappend x 4 + error foo + } +} -body { + list [a] $x $y +} -cleanup { + unset x y + rename a {} +} -returnCodes error -result foo + +test unsupported-A.5 {atProcExit errors} -constraints {atProcExit} -setup { + variable x x y y + proc a {} { + variable x 0 y 0 + atProcExit error foo + lappend x 2 + atProcExit lappend ::x 3 + lappend y $x + lappend x 4 + return 5 + } +} -body { + list [a] $x $y +} -cleanup { + unset x y + rename a {} +} -result {5 {0 2 4 3} {0 {0 2}}} + +test unsupported-A.6 {atProcExit errors} -constraints {atProcExit} -setup { + variable x x y y + proc a {} { + variable x 0 y 0 + atProcExit lappend ::x 1 + lappend x 2 + atProcExit error foo + lappend y $x + lappend x 4 + return 5 + } +} -body { + list [a] $x $y +} -cleanup { + unset x y + rename a {} +} -result {5 {0 2 4} {0 {0 2}}} + +test unsupported-A.7 {atProcExit non-proc} -constraints {atProcExit} -body { + atProcExit set x 2 + set x 1 +} -cleanup { + unset -nocomplain x +} -match glob -result *atProcExit* -returnCodes error + +test unsupported-A.8 {atProcExit and eval} -constraints {knownBug atProcExit} -setup { + proc a {} { + eval atProcExit lappend ::x 2 + set ::x 1 + } +} -body { + list [a] $::x +} -cleanup { + unset -nocomplain ::x +} -result {1 2} + +test unsupported-A9 {atProcExit and uplevel} -constraints {knownBug atProcExit} -setup { + proc a {} { + uplevel 1 [list atProcExit set ::x 2] + set ::x 1 + } +} -body { + list [a] $::x +} -cleanup { + unset -nocomplain ::x +} -result {1 2} + + +# +# Test tailcalls +# + +test unsupported-T.0 {tailcall is constant space} -constraints testnrelevels -setup { + proc a i { + if {[incr i] > 10} { + return [depthDiff] + } + depthDiff + tailcall a $i + } +} -body { + a 0 +} -cleanup { + rename a {} +} -result {0 0 0 0 0 0} + +test unsupported-T.1 {tailcall} -body { + namespace eval a { + variable x *::a + proc xset {} { + set tmp {} + set ns {[namespace current]} + set level [info level] + for {set i 0} {$i <= [info level]} {incr i} { + uplevel #$i "set x $i$ns" + lappend tmp "$i [info level $i]" + } + lrange $tmp 1 end + } + proc foo {} {tailcall xset; set x noreach} + } + namespace eval b { + variable x *::b + proc xset args {error b::xset} + proc moo {} {set x 0; variable y [::a::foo]; set x} + } + variable x *:: + proc xset args {error ::xset} + list [::b::moo] | $x $a::x $b::x | $::b::y +} -cleanup { + unset x + rename xset {} + namespace delete a b +} -result {1::b | 0:: *::a *::b | {{1 ::b::moo} {2 xset}}} + + +test unsupported-T.2 {tailcall in non-proc} -body { + namespace eval a [list tailcall set x 1] +} -match glob -result *tailcall* -returnCodes error + +test unsupported-T.3 {tailcall falls off tebc} -body { + unset -nocomplain x + proc foo {} {tailcall set x 1} + list [catch foo msg] $msg [set x] +} -cleanup { + rename foo {} + unset x +} -result {0 1 1} + +test unsupported-T.4 {tailcall falls off tebc} -body { + set x 2 + proc foo {} {tailcall set x 1} + foo + set x +} -cleanup { + rename foo {} + unset x +} -result 1 + +test unsupported-T.5 {tailcall falls off tebc} -body { + set x 2 + namespace eval bar { + variable x 3 + proc foo {} {tailcall set x 1} + } + bar::foo + list $x $bar::x +} -cleanup { + unset x + namespace delete bar +} -result {1 3} + +test unsupported-T.6 {tailcall does remove callframes} -body { + proc foo {} {info level} + proc moo {} {tailcall foo} + proc boo {} {expr {[moo] - [info level]}} + boo +} -cleanup { + rename foo {} + rename moo {} + rename boo {} +} -result 1 + +test unsupported-T.7 {tailcall does return} -setup { + namespace eval ::foo { + variable res {} + proc a {} { + variable res + append res a + tailcall set x 1 + append res a + } + proc b {} { + variable res + append res b + a + append res b + } + proc c {} { + variable res + append res c + b + append res c + } + } +} -body { + namespace eval ::foo c +} -cleanup { + namespace delete ::foo +} -result cbabc + +test unsupported-T.8 {tailcall tailcall} -setup { + namespace eval ::foo { + variable res {} + proc a {} { + variable res + append res a + tailcall tailcall set x 1 + append res a + } + proc b {} { + variable res + append res b + a + append res b + } + proc c {} { + variable res + append res c + b + append res c + } + } +} -body { + namespace eval ::foo c +} -cleanup { + namespace delete ::foo +} -match glob -result *tailcall* -returnCodes error + +test unsupported-T.9 {tailcall factorial} -setup { + proc fact {n {b 1}} { + if {$n == 1} { + return $b + } + tailcall fact [expr {$n-1}] [expr {$n*$b}] + } +} -body { + list [fact 1] [fact 5] [fact 10] [fact 15] +} -cleanup { + rename fact {} +} -result {1 120 3628800 1307674368000} + +test unsupported-T.10 {tailcall and eval} -constraints {knownBug atProcExit} -setup { + proc a {} { + eval [list tailcall lappend ::x 2] + set ::x 1 + } +} -body { + list [a] $::x +} -cleanup { + unset -nocomplain ::x +} -result {1 2} + +test unsupported-T.11 {tailcall and uplevel} -constraints {knownBug atProcExit} -setup { + proc a {} { + uplevel 1 [list tailcall set ::x 2] + set ::x 1 + } +} -body { + list [a] $::x +} -cleanup { + unset -nocomplain ::x +} -result {1 2} + +# +# Test both together +# + +test unsupported-AT.1 {atProcExit and tailcall} -constraints { + atProcExit +} -setup { + variable x x y y + proc a {} { + variable x 0 y 0 + atProcExit lappend ::x 1 + lappend x 2 + atProcExit lappend ::x 3 + tailcall lappend ::x 6 + lappend y $x + lappend x 4 + return 5 + } +} -body { + list [a] $x $y +} -cleanup { + unset x y + rename a {} +} -result {{0 2 3 1 6} {0 2 3 1 6} 0} + +# +# Test coroutines +# + +set lambda [list {{start 0} {stop 10}} { + # init + set i $start + set imax $stop + yield + + while {$i < $imax} { + yield [expr {$i*$stop}] + incr i + } +}] + + +test unsupported-C.1.1 {coroutine basic} -setup { + coroutine foo ::apply $lambda + set res {} +} -body { + for {set k 1} {$k < 4} {incr k} { + lappend res [foo] + } + set res +} -cleanup { + rename foo {} + unset res +} -result {0 10 20} + +test unsupported-C.1.2 {coroutine basic} -setup { + coroutine foo ::apply $lambda 2 8 + set res {} +} -body { + for {set k 1} {$k < 4} {incr k} { + lappend res [foo] + } + set res +} -cleanup { + rename foo {} + unset res +} -result {16 24 32} + +test unsupported-C.1.3 {yield returns new arg} -setup { + set body { + # init + set i $start + set imax $stop + yield + + while {$i < $imax} { + set stop [yield [expr {$i*$stop}]] + incr i + } + } + coroutine foo ::apply [list {{start 2} {stop 10}} $body] + set res {} +} -body { + for {set k 1} {$k < 4} {incr k} { + lappend res [foo $k] + } + set res +} -cleanup { + rename foo {} + unset res +} -result {20 6 12} + +test unsupported-C.1.4 {yield in nested proc} -setup { + proc moo {} { + upvar 1 i i stop stop + yield [expr {$i*$stop}] + } + set body { + # init + set i $start + set imax $stop + yield + + while {$i < $imax} { + moo + incr i + } + } + coroutine foo ::apply [list {{start 0} {stop 10}} $body] + set res {} +} -body { + for {set k 1} {$k < 4} {incr k} { + lappend res [foo $k] + } + set res +} -cleanup { + rename foo {} + rename moo {} + unset body res +} -result {0 10 20} + +test unsupported-C.1.5 {just yield} -body { + coroutine foo yield + list [foo] [catch foo msg] $msg +} -cleanup { + unset msg +} -result {{} 1 {invalid command name "foo"}} + +test unsupported-C.1.6 {just yield} -body { + coroutine foo [list yield] + list [foo] [catch foo msg] $msg +} -cleanup { + unset msg +} -result {{} 1 {invalid command name "foo"}} + +test unsupported-C.1.7 {yield in nested uplevel} -setup { + set body { + # init + set i $start + set imax $stop + yield + + while {$i < $imax} { + uplevel 0 [list yield [expr {$i*$stop}]] + incr i + } + } + coroutine foo ::apply [list {{start 0} {stop 10}} $body] + set res {} +} -body { + for {set k 1} {$k < 4} {incr k} { + lappend res [eval foo $k] + } + set res +} -cleanup { + rename foo {} + unset body res +} -result {0 10 20} + +test unsupported-C.1.8 {yield in nested uplevel} -setup { + set body { + # init + set i $start + set imax $stop + yield + + while {$i < $imax} { + uplevel 0 yield [expr {$i*$stop}] + incr i + } + } + coroutine foo ::apply [list {{start 0} {stop 10}} $body] + set res {} +} -body { + for {set k 1} {$k < 4} {incr k} { + lappend res [eval foo $k] + } + set res +} -cleanup { + rename foo {} + unset body res +} -result {0 10 20} + +test unsupported-C.1.9 {yield in nested eval} -setup { + proc moo {} { + upvar 1 i i stop stop + yield [expr {$i*$stop}] + } + set body { + # init + set i $start + set imax $stop + yield + + while {$i < $imax} { + eval moo + incr i + } + } + coroutine foo ::apply [list {{start 0} {stop 10}} $body] + set res {} +} -body { + for {set k 1} {$k < 4} {incr k} { + lappend res [foo $k] + } + set res +} -cleanup { + rename moo {} + unset body res +} -result {0 10 20} + +test unsupported-C.1.10 {yield in nested eval} -setup { + set body { + # init + set i $start + set imax $stop + yield + + while {$i < $imax} { + eval yield [expr {$i*$stop}] + incr i + } + } + coroutine foo ::apply [list {{start 0} {stop 10}} $body] + set res {} +} -body { + for {set k 1} {$k < 4} {incr k} { + lappend res [eval foo $k] + } + set res +} -cleanup { + unset body res +} -result {0 10 20} + +test unsupported-C.1.11 {yield outside coroutine} -setup { + proc moo {} { + upvar 1 i i stop stop + yield [expr {$i*$stop}] + } +} -body { + variable i 5 stop 6 + moo +} -cleanup { + rename moo {} + unset i stop +} -returnCodes error -result {yield can only be called in a coroutine} + +test unsupported-C.1.12 {proc as coroutine} -setup { + set body { + # init + set i $start + set imax $stop + yield + + while {$i < $imax} { + uplevel 0 [list yield [expr {$i*$stop}]] + incr i + } + } + proc moo {{start 0} {stop 10}} $body + coroutine foo moo 2 8 +} -body { + list [foo] [foo] +} -cleanup { + unset body + rename moo {} + rename foo {} +} -result {16 24} + +test unsupported-C.2.1 {self deletion on return} -body { + coroutine foo set x 3 + foo +} -returnCodes error -result {invalid command name "foo"} + +test unsupported-C.2.2 {self deletion on return} -body { + coroutine foo ::apply [list {} {yield; yield 1; return 2}] + list [foo] [foo] [catch foo msg] $msg +} -result {1 2 1 {invalid command name "foo"}} + +test unsupported-C.2.3 {self deletion on error return} -body { + coroutine foo ::apply [list {} {yield;yield 1; error ouch!}] + list [foo] [catch foo msg] $msg [catch foo msg] $msg +} -result {1 1 ouch! 1 {invalid command name "foo"}} + +test unsupported-C.2.4 {self deletion on other return} -body { + coroutine foo ::apply [list {} {yield;yield 1; return -code 100 ouch!}] + list [foo] [catch foo msg] $msg [catch foo msg] $msg +} -result {1 100 ouch! 1 {invalid command name "foo"}} + +test unsupported-C.2.5 {deletion of suspended coroutine} -body { + coroutine foo ::apply [list {} {yield; yield 1; return 2}] + list [foo] [rename foo {}] [catch foo msg] $msg +} -result {1 {} 1 {invalid command name "foo"}} + +test unsupported-C.2.6 {deletion of running coroutine} -body { + coroutine foo ::apply [list {} {yield; rename foo {}; yield 1; return 2}] + list [foo] [catch foo msg] $msg +} -result {1 1 {invalid command name "foo"}} + +test unsupported-C.3.1 {info level computation} -setup { + proc a {} {while 1 {yield [info level]}} + proc b {} foo +} -body { + # note that coroutines execute in uplevel #0 + set l0 [coroutine foo a] + set l1 [foo] + set l2 [b] + list $l0 $l1 $l2 +} -cleanup { + rename a {} + rename b {} +} -result {1 1 1} + +test unsupported-C.3.2 {info frame computation} -setup { + proc a {} {while 1 {yield [info frame]}} + proc b {} foo +} -body { + set l0 [coroutine foo a] + set l1 [foo] + set l2 [b] + expr {$l2 - $l1} +} -cleanup { + rename a {} + rename b {} +} -result 1 + +test unsupported-C.3.3 {info coroutine} -setup { + proc a {} {info coroutine} + proc b {} a +} -body { + b +} -cleanup { + rename a {} + rename b {} +} -result {} + +test unsupported-C.3.4 {info coroutine} -setup { + proc a {} {info coroutine} + proc b {} a +} -body { + coroutine foo b +} -cleanup { + rename a {} + rename b {} +} -result ::foo + +test unsupported-C.3.5 {info coroutine} -setup { + proc a {} {info coroutine} + proc b {} {rename [info coroutine] {}; a} +} -body { + coroutine foo b +} -cleanup { + rename a {} + rename b {} +} -result {} + + +test unsupported-C.4.1 {bug #2093188} -setup { + proc foo {} { + set v 1 + trace add variable v {write unset} bar + yield + set v 2 + yield + set v 3 + } + proc bar args {lappend ::res $args} + coroutine a foo +} -body { + list [a] [a] $::res +} -cleanup { + rename foo {} + rename bar {} + unset ::res +} -result {{} 3 {{v {} write} {v {} write} {v {} unset}}} + +test unsupported-C.4.2 {bug #2093188} -setup { + proc foo {} { + set v 1 + trace add variable v {read unset} bar + yield + set v 2 + set v + yield + set v 3 + } + proc bar args {lappend ::res $args} + coroutine a foo +} -body { + list [a] [a] $::res +} -cleanup { + rename foo {} + rename bar {} + unset ::res +} -result {{} 3 {{v {} read} {v {} unset}}} + +test unsupported-C.4.3 {bug #2093947} -setup { + proc foo {} { + set v 1 + trace add variable v {write unset} bar + yield + set v 2 + yield + set v 3 + } + proc bar args {lappend ::res $args} +} -body { + coroutine a foo + a + a + coroutine a foo + a + rename a {} + set ::res +} -cleanup { + rename foo {} + rename bar {} + unset ::res +} -result {{v {} write} {v {} write} {v {} unset} {v {} write} {v {} unset}} + +test unsupported-C.5.1 {right numLevels on coro return} -constraints {testnrelevels} \ +-setup { + proc nestedYield {{val {}}} { + yield $val + } + proc getNumLevel {} { + # remove the level for this proc's call + expr {[lindex [testnrelevels] 1] - 1} + } + proc relativeLevel base { + # remove the level for this proc's call + expr {[getNumLevel] - $base - 1} + } + proc foo {} { + while 1 { + nestedYield + } + } + set res {} +} -body { + set base [getNumLevel] + lappend res [relativeLevel $base] + eval {coroutine a foo} + + # back to base level + lappend res [relativeLevel $base] + a + lappend res [relativeLevel $base] + eval a + lappend res [relativeLevel $base] + eval {eval a} + lappend res [relativeLevel $base] + rename a {} + lappend res [relativeLevel $base] + set res +} -cleanup { + rename foo {} + rename nestedYield {} + rename getNumLevel {} + rename relativeLevel {} + unset res +} -result {0 0 0 0 0 0} + +test unsupported-C.5.2 {right numLevels within coro} -constraints {testnrelevels} \ +-setup { + proc nestedYield {{val {}}} { + yield $val + } + proc getNumLevel {} { + # remove the level for this proc's call + expr {[lindex [testnrelevels] 1] - 1} + } + proc relativeLevel base { + # remove the level for this proc's call + expr {[getNumLevel] - $base - 1} + } + proc foo base { + while 1 { + set base [nestedYield [relativeLevel $base]] + } + } + set res {} +} -body { + lappend res [eval {coroutine a foo [getNumLevel]}] + lappend res [a [getNumLevel]] + lappend res [eval {a [getNumLevel]}] + lappend res [eval {eval {a [getNumLevel]}}] + set base [lindex $res 0] + foreach x $res[set res {}] { + lappend res [expr {$x-$base}] + } + set res +} -cleanup { + rename a {} + rename foo {} + rename nestedYield {} + rename getNumLevel {} + rename relativeLevel {} + unset res +} -result {0 0 0 0} + + + +# cleanup +::tcltest::cleanupTests + + +unset -nocomplain lambda + +if {[testConstraint atProcExit]} { + namespace forget tcl::unsupported::atProcExit +} + +if {[testConstraint testnrelevels]} { + namespace forget testnre::* + namespace delete testnre +} + +return diff --git a/tools/cvtEOL.tcl b/tools/cvtEOL.tcl new file mode 100644 index 0000000..e2df341 --- /dev/null +++ b/tools/cvtEOL.tcl @@ -0,0 +1,35 @@ +# cvtEOL.tcl -- +# +# This file contains a script to parse a Tcl/Tk distribution and +# convert the EOL from \n to \r on all text files. +# +# Copyright (c) 1996-1997 by Sun Microsystems, Inc. +# +# SCCS: @(#) cvtEOL.tcl 1.1 97/01/30 11:33:33 +# + +# +# Convert files in the distribution to Mac style +# + +set distDir [lindex $argv 0] + +set dirs {unix mac generic win library compat tests unix/dltest \ + library/demos library/demos/images bitmaps xlib xlib/X11 .} +set files {*.c *.y *.h *.r *.tcl *.test *.rc *.bc *.vc *.bmp *.html \ + *.in *.notes *.terms all defs \ + README ToDo changes tclIndex configure install-sh mkLinks \ + square widget rmt ixset hello browse rolodex tcolor timer} + +foreach x $dirs { + if [catch {cd $distDir/$x}] continue + puts "Working on $x..." + foreach y [eval glob $files] { + exec chmod 666 $y + exec cp $y $y.tmp + exec tr \012 \015 < $y.tmp > $y + exec chmod 444 $y + exec rm $y.tmp + } +} + diff --git a/tools/genWinImage.tcl b/tools/genWinImage.tcl new file mode 100644 index 0000000..e57d018 --- /dev/null +++ b/tools/genWinImage.tcl @@ -0,0 +1,157 @@ +# genWinImage.tcl -- +# +# This script generates the Windows installer. +# +# Copyright (c) 1999 by Scriptics Corporation. +# All rights reserved. +# +# RCS: @(#) $Id: genWinImage.tcl,v 1.5 2000/04/25 22:29:21 hobbs Exp $ + + +# This file is insensitive to the directory from which it is invoked. + +namespace eval genWinImage { + # toolsDir -- + # + # This variable points to the platform specific tools directory. + + variable toolsDir + + # tclBuildDir -- + # + # This variable points to the directory containing the Tcl built tree. + + variable tclBuildDir + + # tkBuildDir -- + # + # This variable points to the directory containing the Tk built tree. + + variable tkBuildDir + + # our script name at runtime + variable script [info script] +} + +# genWinImage::init -- +# +# This is the main entry point. +# +# Arguments: +# None. +# +# Results: +# None. + +proc genWinImage::init {} { + global tcl_platform argv argv0 + variable tclBuildDir + variable tkBuildDir + variable toolsDir + variable script + + puts "\n--- $script started: \ + [clock format [clock seconds] -format "%Y%m%d-%H:%M"] --\n" + + if {$tcl_platform(platform) != "windows"} { + puts stderr "ERROR: Cannot build TCL.EXE on Unix systems" + exit 1 + } + + if {[llength $argv] != 3} { + puts stderr "usage: $argv0 <tclBuildDir> <tkBuildDir> <toolsDir>" + exit 0 + } + + set tclBuildDir [lindex $argv 0] + set tkBuildDir [lindex $argv 1] + set toolsDir [lindex $argv 2] + + generateInstallers + + puts "\n--- $script finished: \ + [clock format [clock seconds] -format "%Y%m%d-%H:%M"] --\n\n" +} + +# genWinImage::makeTextFile -- +# +# Convert the input file into a CRLF terminated text file. +# +# Arguments: +# infile The input file to convert. +# outfile The location where the text file should be stored. +# +# Results: +# None. + +proc genWinImage::makeTextFile {infile outfile} { + set f [open $infile r] + set text [read $f] + close $f + set f [open $outfile w] + fconfigure $f -translation crlf + puts -nonewline $f $text + close $f +} + +# genWinImage::generateInstallers -- +# +# Perform substitutions on the pro.wse.in file and then +# invoke the WSE script twice; once for CD and once for web. +# +# Arguments: +# None. +# +# Results: +# Leaves proweb.exe and procd.exe sitting in the curent directory. + +proc genWinImage::generateInstallers {} { + variable toolsDir + variable tclBuildDir + variable tkBuildDir + + # Now read the "pro/srcs/install/pro.wse.in" file, have Tcl make + # appropriate substitutions, write out the resulting file in a + # current-working-directory. Use this new file to perform installation + # image creation. Note that we have to use this technique to set + # the value of _WISE_ because wise32 won't use a /d switch for this + # variable. + + set __TCLBASEDIR__ [file native $tclBuildDir] + set __TKBASEDIR__ [file native $tkBuildDir] + set __WISE__ [file native [file join $toolsDir wise]] + + set f [open [file join $__TCLBASEDIR__ generic/tcl.h] r] + set s [read $f] + close $f + regexp {TCL_PATCH_LEVEL\s*\"([^\"]*)\"} $s dummy __TCL_PATCH_LEVEL__ + + set f [open tcl.wse.in r] + set s [read $f] + close $f + set s [subst -nocommands -nobackslashes $s] + set f [open tcl.wse w] + puts $f $s + close $f + + # Ensure the text files are CRLF terminated + + makeTextFile [file join $tclBuildDir win/README.binary] \ + [file join $tclBuildDir win/readme.txt] + makeTextFile [file join $tclBuildDir license.terms] \ + [file join $tclBuildDir license.txt] + + set wise32ProgFilePath [file native [file join $__WISE__ wise32.exe]] + + # Run the Wise installer to create the Windows install images. + + if {[catch {exec [file native $wise32ProgFilePath] /c tcl.wse} errMsg]} { + puts stderr "ERROR: $errMsg" + } else { + puts "\"TCL.EXE\" created." + } + + return +} + +genWinImage::init diff --git a/unix/dltest/pkgf.c b/unix/dltest/pkgf.c new file mode 100644 index 0000000..c32aaf0 --- /dev/null +++ b/unix/dltest/pkgf.c @@ -0,0 +1,46 @@ +/* + * pkgf.c -- + * + * This file contains a simple Tcl package "pkgf" that is intended for + * testing the Tcl dynamic loading facilities. Its Init procedure returns + * an error in order to test how this is handled. + * + * Copyright (c) 1995 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: pkgf.c,v 1.7 2007/05/29 14:05:53 dgp Exp $ + */ + +#include "tcl.h" + + +/* + *---------------------------------------------------------------------- + * + * Pkgf_Init -- + * + * This is a package initialization procedure, which is called by Tcl + * when this package is to be added to an interpreter. + * + * Results: + * Returns TCL_ERROR and leaves an error message in interp->result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +Pkgf_Init( + Tcl_Interp *interp) /* Interpreter in which the package is to be + * made available. */ +{ + static char script[] = "if 44 {open non_existent}"; + if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) { + return TCL_ERROR; + } + return Tcl_Eval(interp, script); +} diff --git a/unix/mkLinks b/unix/mkLinks new file mode 100644 index 0000000..edfbeb4 --- /dev/null +++ b/unix/mkLinks @@ -0,0 +1,1937 @@ +#!/bin/sh +# This script is invoked when installing manual entries. It generates +# additional links to manual entries, corresponding to the procedure +# and command names described by the manual entry. For example, the +# Tcl manual entry Hash.3 describes procedures Tcl_InitHashTable, +# Tcl_CreateHashEntry, and many more. This script will make hard +# links so that Tcl_InitHashTable.3, Tcl_CreateHashEntry.3, and so +# on all refer to Hash.3 in the installed directory. +# +# Because of the length of command and procedure names, this mechanism +# only works on machines that support file names longer than 14 characters. +# This script checks to see if long file names are supported, and it +# doesn't make any links if they are not. +# +# The script takes one argument, which is the name of the directory +# where the manual entries have been installed. + +ZIP=true +while true; do + case $1 in + -s | --symlinks ) + S=-s + ;; + -z | --compress ) + ZIP=$2 + shift + ;; + *) break + ;; + esac + shift +done + +if test $# != 1; then + echo "Usage: mkLinks <options> dir" + exit 1 +fi + +if test "x$ZIP" != "xtrue"; then + touch TeST + $ZIP TeST + Z=`ls TeST* | sed 's/^[^.]*//'` + rm -f TeST* +fi + +cd $1 +echo foo > xyzzyTestingAVeryLongFileName.foo +x=`echo xyzzyTe*` +echo foo > xyzzyTestingaverylongfilename.foo +y=`echo xyzzyTestingav*` +rm xyzzyTe* +if test "$x" != "xyzzyTestingAVeryLongFileName.foo"; then + exit +fi +if test "$y" != "xyzzyTestingaverylongfilename.foo"; then + CASEINSENSITIVEFS=1 +fi + +if test -r Access.3; then + rm -f Access.3.* + $ZIP Access.3 + rm -f Tcl_Access.3 Tcl_Access.3.* + rm -f Tcl_Stat.3 Tcl_Stat.3.* + ln $S Access.3$Z Tcl_Access.3$Z + ln $S Access.3$Z Tcl_Stat.3$Z +fi +if test -r AddErrInfo.3; then + rm -f AddErrInfo.3.* + $ZIP AddErrInfo.3 + rm -f Tcl_AddObjErrorInfo.3 Tcl_AddObjErrorInfo.3.* + rm -f Tcl_AddErrorInfo.3 Tcl_AddErrorInfo.3.* + rm -f Tcl_SetObjErrorCode.3 Tcl_SetObjErrorCode.3.* + rm -f Tcl_SetErrorCode.3 Tcl_SetErrorCode.3.* + rm -f Tcl_SetErrorCodeVA.3 Tcl_SetErrorCodeVA.3.* + rm -f Tcl_PosixError.3 Tcl_PosixError.3.* + rm -f Tcl_LogCommandInfo.3 Tcl_LogCommandInfo.3.* + ln $S AddErrInfo.3$Z Tcl_AddObjErrorInfo.3$Z + ln $S AddErrInfo.3$Z Tcl_AddErrorInfo.3$Z + ln $S AddErrInfo.3$Z Tcl_SetObjErrorCode.3$Z + ln $S AddErrInfo.3$Z Tcl_SetErrorCode.3$Z + ln $S AddErrInfo.3$Z Tcl_SetErrorCodeVA.3$Z + ln $S AddErrInfo.3$Z Tcl_PosixError.3$Z + ln $S AddErrInfo.3$Z Tcl_LogCommandInfo.3$Z +fi +if test -r Alloc.3; then + rm -f Alloc.3.* + $ZIP Alloc.3 + rm -f Tcl_Alloc.3 Tcl_Alloc.3.* + rm -f Tcl_Free.3 Tcl_Free.3.* + rm -f Tcl_Realloc.3 Tcl_Realloc.3.* + rm -f Tcl_AttemptAlloc.3 Tcl_AttemptAlloc.3.* + rm -f Tcl_AttemptRealloc.3 Tcl_AttemptRealloc.3.* + rm -f ckalloc.3 ckalloc.3.* + rm -f ckfree.3 ckfree.3.* + rm -f ckrealloc.3 ckrealloc.3.* + rm -f attemptckalloc.3 attemptckalloc.3.* + rm -f attemptckrealloc.3 attemptckrealloc.3.* + ln $S Alloc.3$Z Tcl_Alloc.3$Z + ln $S Alloc.3$Z Tcl_Free.3$Z + ln $S Alloc.3$Z Tcl_Realloc.3$Z + ln $S Alloc.3$Z Tcl_AttemptAlloc.3$Z + ln $S Alloc.3$Z Tcl_AttemptRealloc.3$Z + ln $S Alloc.3$Z ckalloc.3$Z + ln $S Alloc.3$Z ckfree.3$Z + ln $S Alloc.3$Z ckrealloc.3$Z + ln $S Alloc.3$Z attemptckalloc.3$Z + ln $S Alloc.3$Z attemptckrealloc.3$Z +fi +if test -r AllowExc.3; then + rm -f AllowExc.3.* + $ZIP AllowExc.3 + rm -f Tcl_AllowExceptions.3 Tcl_AllowExceptions.3.* + ln $S AllowExc.3$Z Tcl_AllowExceptions.3$Z +fi +if test -r AppInit.3; then + rm -f AppInit.3.* + $ZIP AppInit.3 + rm -f Tcl_AppInit.3 Tcl_AppInit.3.* + ln $S AppInit.3$Z Tcl_AppInit.3$Z +fi +if test -r AssocData.3; then + rm -f AssocData.3.* + $ZIP AssocData.3 + rm -f Tcl_GetAssocData.3 Tcl_GetAssocData.3.* + rm -f Tcl_SetAssocData.3 Tcl_SetAssocData.3.* + rm -f Tcl_DeleteAssocData.3 Tcl_DeleteAssocData.3.* + ln $S AssocData.3$Z Tcl_GetAssocData.3$Z + ln $S AssocData.3$Z Tcl_SetAssocData.3$Z + ln $S AssocData.3$Z Tcl_DeleteAssocData.3$Z +fi +if test -r Async.3; then + rm -f Async.3.* + $ZIP Async.3 + rm -f Tcl_AsyncCreate.3 Tcl_AsyncCreate.3.* + rm -f Tcl_AsyncMark.3 Tcl_AsyncMark.3.* + rm -f Tcl_AsyncInvoke.3 Tcl_AsyncInvoke.3.* + rm -f Tcl_AsyncDelete.3 Tcl_AsyncDelete.3.* + rm -f Tcl_AsyncReady.3 Tcl_AsyncReady.3.* + ln $S Async.3$Z Tcl_AsyncCreate.3$Z + ln $S Async.3$Z Tcl_AsyncMark.3$Z + ln $S Async.3$Z Tcl_AsyncInvoke.3$Z + ln $S Async.3$Z Tcl_AsyncDelete.3$Z + ln $S Async.3$Z Tcl_AsyncReady.3$Z +fi +if test -r BackgdErr.3; then + rm -f BackgdErr.3.* + $ZIP BackgdErr.3 + rm -f Tcl_BackgroundError.3 Tcl_BackgroundError.3.* + ln $S BackgdErr.3$Z Tcl_BackgroundError.3$Z +fi +if test -r Backslash.3; then + rm -f Backslash.3.* + $ZIP Backslash.3 + rm -f Tcl_Backslash.3 Tcl_Backslash.3.* + ln $S Backslash.3$Z Tcl_Backslash.3$Z +fi +if test -r BoolObj.3; then + rm -f BoolObj.3.* + $ZIP BoolObj.3 + rm -f Tcl_NewBooleanObj.3 Tcl_NewBooleanObj.3.* + rm -f Tcl_SetBooleanObj.3 Tcl_SetBooleanObj.3.* + rm -f Tcl_GetBooleanFromObj.3 Tcl_GetBooleanFromObj.3.* + ln $S BoolObj.3$Z Tcl_NewBooleanObj.3$Z + ln $S BoolObj.3$Z Tcl_SetBooleanObj.3$Z + ln $S BoolObj.3$Z Tcl_GetBooleanFromObj.3$Z +fi +if test -r ByteArrObj.3; then + rm -f ByteArrObj.3.* + $ZIP ByteArrObj.3 + rm -f Tcl_NewByteArrayObj.3 Tcl_NewByteArrayObj.3.* + rm -f Tcl_SetByteArrayObj.3 Tcl_SetByteArrayObj.3.* + rm -f Tcl_GetByteArrayFromObj.3 Tcl_GetByteArrayFromObj.3.* + rm -f Tcl_SetByteArrayLength.3 Tcl_SetByteArrayLength.3.* + ln $S ByteArrObj.3$Z Tcl_NewByteArrayObj.3$Z + ln $S ByteArrObj.3$Z Tcl_SetByteArrayObj.3$Z + ln $S ByteArrObj.3$Z Tcl_GetByteArrayFromObj.3$Z + ln $S ByteArrObj.3$Z Tcl_SetByteArrayLength.3$Z +fi +if test -r CallDel.3; then + rm -f CallDel.3.* + $ZIP CallDel.3 + rm -f Tcl_CallWhenDeleted.3 Tcl_CallWhenDeleted.3.* + rm -f Tcl_DontCallWhenDeleted.3 Tcl_DontCallWhenDeleted.3.* + ln $S CallDel.3$Z Tcl_CallWhenDeleted.3$Z + ln $S CallDel.3$Z Tcl_DontCallWhenDeleted.3$Z +fi +if test -r ChnlStack.3; then + rm -f ChnlStack.3.* + $ZIP ChnlStack.3 + rm -f Tcl_StackChannel.3 Tcl_StackChannel.3.* + rm -f Tcl_UnstackChannel.3 Tcl_UnstackChannel.3.* + rm -f Tcl_GetStackedChannel.3 Tcl_GetStackedChannel.3.* + rm -f Tcl_GetTopChannel.3 Tcl_GetTopChannel.3.* + ln $S ChnlStack.3$Z Tcl_StackChannel.3$Z + ln $S ChnlStack.3$Z Tcl_UnstackChannel.3$Z + ln $S ChnlStack.3$Z Tcl_GetStackedChannel.3$Z + ln $S ChnlStack.3$Z Tcl_GetTopChannel.3$Z +fi +if test -r CmdCmplt.3; then + rm -f CmdCmplt.3.* + $ZIP CmdCmplt.3 + rm -f Tcl_CommandComplete.3 Tcl_CommandComplete.3.* + ln $S CmdCmplt.3$Z Tcl_CommandComplete.3$Z +fi +if test -r Concat.3; then + rm -f Concat.3.* + $ZIP Concat.3 + rm -f Tcl_Concat.3 Tcl_Concat.3.* + ln $S Concat.3$Z Tcl_Concat.3$Z +fi +if test -r CrtChannel.3; then + rm -f CrtChannel.3.* + $ZIP CrtChannel.3 + rm -f Tcl_CreateChannel.3 Tcl_CreateChannel.3.* + rm -f Tcl_GetChannelInstanceData.3 Tcl_GetChannelInstanceData.3.* + rm -f Tcl_GetChannelType.3 Tcl_GetChannelType.3.* + rm -f Tcl_GetChannelName.3 Tcl_GetChannelName.3.* + rm -f Tcl_GetChannelHandle.3 Tcl_GetChannelHandle.3.* + rm -f Tcl_GetChannelMode.3 Tcl_GetChannelMode.3.* + rm -f Tcl_GetChannelBufferSize.3 Tcl_GetChannelBufferSize.3.* + rm -f Tcl_SetChannelBufferSize.3 Tcl_SetChannelBufferSize.3.* + rm -f Tcl_NotifyChannel.3 Tcl_NotifyChannel.3.* + rm -f Tcl_BadChannelOption.3 Tcl_BadChannelOption.3.* + rm -f Tcl_ChannelName.3 Tcl_ChannelName.3.* + rm -f Tcl_ChannelVersion.3 Tcl_ChannelVersion.3.* + rm -f Tcl_ChannelBlockModeProc.3 Tcl_ChannelBlockModeProc.3.* + rm -f Tcl_ChannelCloseProc.3 Tcl_ChannelCloseProc.3.* + rm -f Tcl_ChannelClose2Proc.3 Tcl_ChannelClose2Proc.3.* + rm -f Tcl_ChannelInputProc.3 Tcl_ChannelInputProc.3.* + rm -f Tcl_ChannelOutputProc.3 Tcl_ChannelOutputProc.3.* + rm -f Tcl_ChannelSeekProc.3 Tcl_ChannelSeekProc.3.* + rm -f Tcl_ChannelWideSeekProc.3 Tcl_ChannelWideSeekProc.3.* + rm -f Tcl_ChannelSetOptionProc.3 Tcl_ChannelSetOptionProc.3.* + rm -f Tcl_ChannelGetOptionProc.3 Tcl_ChannelGetOptionProc.3.* + rm -f Tcl_ChannelWatchProc.3 Tcl_ChannelWatchProc.3.* + rm -f Tcl_ChannelGetHandleProc.3 Tcl_ChannelGetHandleProc.3.* + rm -f Tcl_ChannelFlushProc.3 Tcl_ChannelFlushProc.3.* + rm -f Tcl_ChannelHandlerProc.3 Tcl_ChannelHandlerProc.3.* + rm -f Tcl_IsChannelShared.3 Tcl_IsChannelShared.3.* + rm -f Tcl_IsChannelRegistered.3 Tcl_IsChannelRegistered.3.* + rm -f Tcl_CutChannel.3 Tcl_CutChannel.3.* + rm -f Tcl_SpliceChannel.3 Tcl_SpliceChannel.3.* + rm -f Tcl_IsChannelExisting.3 Tcl_IsChannelExisting.3.* + rm -f Tcl_ClearChannelHandlers.3 Tcl_ClearChannelHandlers.3.* + rm -f Tcl_GetChannelThread.3 Tcl_GetChannelThread.3.* + rm -f Tcl_ChannelBuffered.3 Tcl_ChannelBuffered.3.* + ln $S CrtChannel.3$Z Tcl_CreateChannel.3$Z + ln $S CrtChannel.3$Z Tcl_GetChannelInstanceData.3$Z + ln $S CrtChannel.3$Z Tcl_GetChannelType.3$Z + ln $S CrtChannel.3$Z Tcl_GetChannelName.3$Z + ln $S CrtChannel.3$Z Tcl_GetChannelHandle.3$Z + ln $S CrtChannel.3$Z Tcl_GetChannelMode.3$Z + ln $S CrtChannel.3$Z Tcl_GetChannelBufferSize.3$Z + ln $S CrtChannel.3$Z Tcl_SetChannelBufferSize.3$Z + ln $S CrtChannel.3$Z Tcl_NotifyChannel.3$Z + ln $S CrtChannel.3$Z Tcl_BadChannelOption.3$Z + ln $S CrtChannel.3$Z Tcl_ChannelName.3$Z + ln $S CrtChannel.3$Z Tcl_ChannelVersion.3$Z + ln $S CrtChannel.3$Z Tcl_ChannelBlockModeProc.3$Z + ln $S CrtChannel.3$Z Tcl_ChannelCloseProc.3$Z + ln $S CrtChannel.3$Z Tcl_ChannelClose2Proc.3$Z + ln $S CrtChannel.3$Z Tcl_ChannelInputProc.3$Z + ln $S CrtChannel.3$Z Tcl_ChannelOutputProc.3$Z + ln $S CrtChannel.3$Z Tcl_ChannelSeekProc.3$Z + ln $S CrtChannel.3$Z Tcl_ChannelWideSeekProc.3$Z + ln $S CrtChannel.3$Z Tcl_ChannelSetOptionProc.3$Z + ln $S CrtChannel.3$Z Tcl_ChannelGetOptionProc.3$Z + ln $S CrtChannel.3$Z Tcl_ChannelWatchProc.3$Z + ln $S CrtChannel.3$Z Tcl_ChannelGetHandleProc.3$Z + ln $S CrtChannel.3$Z Tcl_ChannelFlushProc.3$Z + ln $S CrtChannel.3$Z Tcl_ChannelHandlerProc.3$Z + ln $S CrtChannel.3$Z Tcl_IsChannelShared.3$Z + ln $S CrtChannel.3$Z Tcl_IsChannelRegistered.3$Z + ln $S CrtChannel.3$Z Tcl_CutChannel.3$Z + ln $S CrtChannel.3$Z Tcl_SpliceChannel.3$Z + ln $S CrtChannel.3$Z Tcl_IsChannelExisting.3$Z + ln $S CrtChannel.3$Z Tcl_ClearChannelHandlers.3$Z + ln $S CrtChannel.3$Z Tcl_GetChannelThread.3$Z + ln $S CrtChannel.3$Z Tcl_ChannelBuffered.3$Z +fi +if test -r CrtChnlHdlr.3; then + rm -f CrtChnlHdlr.3.* + $ZIP CrtChnlHdlr.3 + rm -f Tcl_CreateChannelHandler.3 Tcl_CreateChannelHandler.3.* + rm -f Tcl_DeleteChannelHandler.3 Tcl_DeleteChannelHandler.3.* + ln $S CrtChnlHdlr.3$Z Tcl_CreateChannelHandler.3$Z + ln $S CrtChnlHdlr.3$Z Tcl_DeleteChannelHandler.3$Z +fi +if test -r CrtCloseHdlr.3; then + rm -f CrtCloseHdlr.3.* + $ZIP CrtCloseHdlr.3 + rm -f Tcl_CreateCloseHandler.3 Tcl_CreateCloseHandler.3.* + rm -f Tcl_DeleteCloseHandler.3 Tcl_DeleteCloseHandler.3.* + ln $S CrtCloseHdlr.3$Z Tcl_CreateCloseHandler.3$Z + ln $S CrtCloseHdlr.3$Z Tcl_DeleteCloseHandler.3$Z +fi +if test -r CrtCommand.3; then + rm -f CrtCommand.3.* + $ZIP CrtCommand.3 + rm -f Tcl_CreateCommand.3 Tcl_CreateCommand.3.* + ln $S CrtCommand.3$Z Tcl_CreateCommand.3$Z +fi +if test -r CrtFileHdlr.3; then + rm -f CrtFileHdlr.3.* + $ZIP CrtFileHdlr.3 + rm -f Tcl_CreateFileHandler.3 Tcl_CreateFileHandler.3.* + rm -f Tcl_DeleteFileHandler.3 Tcl_DeleteFileHandler.3.* + ln $S CrtFileHdlr.3$Z Tcl_CreateFileHandler.3$Z + ln $S CrtFileHdlr.3$Z Tcl_DeleteFileHandler.3$Z +fi +if test -r CrtInterp.3; then + rm -f CrtInterp.3.* + $ZIP CrtInterp.3 + rm -f Tcl_CreateInterp.3 Tcl_CreateInterp.3.* + rm -f Tcl_DeleteInterp.3 Tcl_DeleteInterp.3.* + rm -f Tcl_InterpDeleted.3 Tcl_InterpDeleted.3.* + ln $S CrtInterp.3$Z Tcl_CreateInterp.3$Z + ln $S CrtInterp.3$Z Tcl_DeleteInterp.3$Z + ln $S CrtInterp.3$Z Tcl_InterpDeleted.3$Z +fi +if test -r CrtMathFnc.3; then + rm -f CrtMathFnc.3.* + $ZIP CrtMathFnc.3 + rm -f Tcl_CreateMathFunc.3 Tcl_CreateMathFunc.3.* + rm -f Tcl_GetMathFuncInfo.3 Tcl_GetMathFuncInfo.3.* + rm -f Tcl_ListMathFuncs.3 Tcl_ListMathFuncs.3.* + ln $S CrtMathFnc.3$Z Tcl_CreateMathFunc.3$Z + ln $S CrtMathFnc.3$Z Tcl_GetMathFuncInfo.3$Z + ln $S CrtMathFnc.3$Z Tcl_ListMathFuncs.3$Z +fi +if test -r CrtObjCmd.3; then + rm -f CrtObjCmd.3.* + $ZIP CrtObjCmd.3 + rm -f Tcl_CreateObjCommand.3 Tcl_CreateObjCommand.3.* + rm -f Tcl_DeleteCommand.3 Tcl_DeleteCommand.3.* + rm -f Tcl_DeleteCommandFromToken.3 Tcl_DeleteCommandFromToken.3.* + rm -f Tcl_GetCommandInfo.3 Tcl_GetCommandInfo.3.* + rm -f Tcl_GetCommandInfoFromToken.3 Tcl_GetCommandInfoFromToken.3.* + rm -f Tcl_SetCommandInfo.3 Tcl_SetCommandInfo.3.* + rm -f Tcl_SetCommandInfoFromToken.3 Tcl_SetCommandInfoFromToken.3.* + rm -f Tcl_GetCommandName.3 Tcl_GetCommandName.3.* + rm -f Tcl_GetCommandFullName.3 Tcl_GetCommandFullName.3.* + rm -f Tcl_GetCommandFromObj.3 Tcl_GetCommandFromObj.3.* + ln $S CrtObjCmd.3$Z Tcl_CreateObjCommand.3$Z + ln $S CrtObjCmd.3$Z Tcl_DeleteCommand.3$Z + ln $S CrtObjCmd.3$Z Tcl_DeleteCommandFromToken.3$Z + ln $S CrtObjCmd.3$Z Tcl_GetCommandInfo.3$Z + ln $S CrtObjCmd.3$Z Tcl_GetCommandInfoFromToken.3$Z + ln $S CrtObjCmd.3$Z Tcl_SetCommandInfo.3$Z + ln $S CrtObjCmd.3$Z Tcl_SetCommandInfoFromToken.3$Z + ln $S CrtObjCmd.3$Z Tcl_GetCommandName.3$Z + ln $S CrtObjCmd.3$Z Tcl_GetCommandFullName.3$Z + ln $S CrtObjCmd.3$Z Tcl_GetCommandFromObj.3$Z +fi +if test -r CrtSlave.3; then + rm -f CrtSlave.3.* + $ZIP CrtSlave.3 + rm -f Tcl_IsSafe.3 Tcl_IsSafe.3.* + rm -f Tcl_MakeSafe.3 Tcl_MakeSafe.3.* + rm -f Tcl_CreateSlave.3 Tcl_CreateSlave.3.* + rm -f Tcl_GetSlave.3 Tcl_GetSlave.3.* + rm -f Tcl_GetMaster.3 Tcl_GetMaster.3.* + rm -f Tcl_GetInterpPath.3 Tcl_GetInterpPath.3.* + rm -f Tcl_CreateAlias.3 Tcl_CreateAlias.3.* + rm -f Tcl_CreateAliasObj.3 Tcl_CreateAliasObj.3.* + rm -f Tcl_GetAlias.3 Tcl_GetAlias.3.* + rm -f Tcl_GetAliasObj.3 Tcl_GetAliasObj.3.* + rm -f Tcl_ExposeCommand.3 Tcl_ExposeCommand.3.* + rm -f Tcl_HideCommand.3 Tcl_HideCommand.3.* + ln $S CrtSlave.3$Z Tcl_IsSafe.3$Z + ln $S CrtSlave.3$Z Tcl_MakeSafe.3$Z + ln $S CrtSlave.3$Z Tcl_CreateSlave.3$Z + ln $S CrtSlave.3$Z Tcl_GetSlave.3$Z + ln $S CrtSlave.3$Z Tcl_GetMaster.3$Z + ln $S CrtSlave.3$Z Tcl_GetInterpPath.3$Z + ln $S CrtSlave.3$Z Tcl_CreateAlias.3$Z + ln $S CrtSlave.3$Z Tcl_CreateAliasObj.3$Z + ln $S CrtSlave.3$Z Tcl_GetAlias.3$Z + ln $S CrtSlave.3$Z Tcl_GetAliasObj.3$Z + ln $S CrtSlave.3$Z Tcl_ExposeCommand.3$Z + ln $S CrtSlave.3$Z Tcl_HideCommand.3$Z +fi +if test -r CrtTimerHdlr.3; then + rm -f CrtTimerHdlr.3.* + $ZIP CrtTimerHdlr.3 + rm -f Tcl_CreateTimerHandler.3 Tcl_CreateTimerHandler.3.* + rm -f Tcl_DeleteTimerHandler.3 Tcl_DeleteTimerHandler.3.* + ln $S CrtTimerHdlr.3$Z Tcl_CreateTimerHandler.3$Z + ln $S CrtTimerHdlr.3$Z Tcl_DeleteTimerHandler.3$Z +fi +if test -r CrtTrace.3; then + rm -f CrtTrace.3.* + $ZIP CrtTrace.3 + rm -f Tcl_CreateTrace.3 Tcl_CreateTrace.3.* + rm -f Tcl_CreateObjTrace.3 Tcl_CreateObjTrace.3.* + rm -f Tcl_DeleteTrace.3 Tcl_DeleteTrace.3.* + ln $S CrtTrace.3$Z Tcl_CreateTrace.3$Z + ln $S CrtTrace.3$Z Tcl_CreateObjTrace.3$Z + ln $S CrtTrace.3$Z Tcl_DeleteTrace.3$Z +fi +if test -r DString.3; then + rm -f DString.3.* + $ZIP DString.3 + rm -f Tcl_DStringInit.3 Tcl_DStringInit.3.* + rm -f Tcl_DStringAppend.3 Tcl_DStringAppend.3.* + rm -f Tcl_DStringAppendElement.3 Tcl_DStringAppendElement.3.* + rm -f Tcl_DStringStartSublist.3 Tcl_DStringStartSublist.3.* + rm -f Tcl_DStringEndSublist.3 Tcl_DStringEndSublist.3.* + rm -f Tcl_DStringLength.3 Tcl_DStringLength.3.* + rm -f Tcl_DStringValue.3 Tcl_DStringValue.3.* + rm -f Tcl_DStringSetLength.3 Tcl_DStringSetLength.3.* + rm -f Tcl_DStringTrunc.3 Tcl_DStringTrunc.3.* + rm -f Tcl_DStringFree.3 Tcl_DStringFree.3.* + rm -f Tcl_DStringResult.3 Tcl_DStringResult.3.* + rm -f Tcl_DStringGetResult.3 Tcl_DStringGetResult.3.* + ln $S DString.3$Z Tcl_DStringInit.3$Z + ln $S DString.3$Z Tcl_DStringAppend.3$Z + ln $S DString.3$Z Tcl_DStringAppendElement.3$Z + ln $S DString.3$Z Tcl_DStringStartSublist.3$Z + ln $S DString.3$Z Tcl_DStringEndSublist.3$Z + ln $S DString.3$Z Tcl_DStringLength.3$Z + ln $S DString.3$Z Tcl_DStringValue.3$Z + ln $S DString.3$Z Tcl_DStringSetLength.3$Z + ln $S DString.3$Z Tcl_DStringTrunc.3$Z + ln $S DString.3$Z Tcl_DStringFree.3$Z + ln $S DString.3$Z Tcl_DStringResult.3$Z + ln $S DString.3$Z Tcl_DStringGetResult.3$Z +fi +if test -r DetachPids.3; then + rm -f DetachPids.3.* + $ZIP DetachPids.3 + rm -f Tcl_DetachPids.3 Tcl_DetachPids.3.* + rm -f Tcl_ReapDetachedProcs.3 Tcl_ReapDetachedProcs.3.* + rm -f Tcl_WaitPid.3 Tcl_WaitPid.3.* + ln $S DetachPids.3$Z Tcl_DetachPids.3$Z + ln $S DetachPids.3$Z Tcl_ReapDetachedProcs.3$Z + ln $S DetachPids.3$Z Tcl_WaitPid.3$Z +fi +if test -r DictObj.3; then + rm -f DictObj.3.* + $ZIP DictObj.3 + rm -f Tcl_NewDictObj.3 Tcl_NewDictObj.3.* + rm -f Tcl_DictObjPut.3 Tcl_DictObjPut.3.* + rm -f Tcl_DictObjGet.3 Tcl_DictObjGet.3.* + rm -f Tcl_DictObjRemove.3 Tcl_DictObjRemove.3.* + rm -f Tcl_DictObjSize.3 Tcl_DictObjSize.3.* + rm -f Tcl_DictObjFirst.3 Tcl_DictObjFirst.3.* + rm -f Tcl_DictObjNext.3 Tcl_DictObjNext.3.* + rm -f Tcl_DictObjDone.3 Tcl_DictObjDone.3.* + rm -f Tcl_DictObjPutKeyList.3 Tcl_DictObjPutKeyList.3.* + rm -f Tcl_DictObjRemoveKeyList.3 Tcl_DictObjRemoveKeyList.3.* + ln $S DictObj.3$Z Tcl_NewDictObj.3$Z + ln $S DictObj.3$Z Tcl_DictObjPut.3$Z + ln $S DictObj.3$Z Tcl_DictObjGet.3$Z + ln $S DictObj.3$Z Tcl_DictObjRemove.3$Z + ln $S DictObj.3$Z Tcl_DictObjSize.3$Z + ln $S DictObj.3$Z Tcl_DictObjFirst.3$Z + ln $S DictObj.3$Z Tcl_DictObjNext.3$Z + ln $S DictObj.3$Z Tcl_DictObjDone.3$Z + ln $S DictObj.3$Z Tcl_DictObjPutKeyList.3$Z + ln $S DictObj.3$Z Tcl_DictObjRemoveKeyList.3$Z +fi +if test -r DoOneEvent.3; then + rm -f DoOneEvent.3.* + $ZIP DoOneEvent.3 + rm -f Tcl_DoOneEvent.3 Tcl_DoOneEvent.3.* + ln $S DoOneEvent.3$Z Tcl_DoOneEvent.3$Z +fi +if test -r DoWhenIdle.3; then + rm -f DoWhenIdle.3.* + $ZIP DoWhenIdle.3 + rm -f Tcl_DoWhenIdle.3 Tcl_DoWhenIdle.3.* + rm -f Tcl_CancelIdleCall.3 Tcl_CancelIdleCall.3.* + ln $S DoWhenIdle.3$Z Tcl_DoWhenIdle.3$Z + ln $S DoWhenIdle.3$Z Tcl_CancelIdleCall.3$Z +fi +if test -r DoubleObj.3; then + rm -f DoubleObj.3.* + $ZIP DoubleObj.3 + rm -f Tcl_NewDoubleObj.3 Tcl_NewDoubleObj.3.* + rm -f Tcl_SetDoubleObj.3 Tcl_SetDoubleObj.3.* + rm -f Tcl_GetDoubleFromObj.3 Tcl_GetDoubleFromObj.3.* + ln $S DoubleObj.3$Z Tcl_NewDoubleObj.3$Z + ln $S DoubleObj.3$Z Tcl_SetDoubleObj.3$Z + ln $S DoubleObj.3$Z Tcl_GetDoubleFromObj.3$Z +fi +if test -r DumpActiveMemory.3; then + rm -f DumpActiveMemory.3.* + $ZIP DumpActiveMemory.3 + rm -f Tcl_DumpActiveMemory.3 Tcl_DumpActiveMemory.3.* + rm -f Tcl_InitMemory.3 Tcl_InitMemory.3.* + rm -f Tcl_ValidateAllMemory.3 Tcl_ValidateAllMemory.3.* + ln $S DumpActiveMemory.3$Z Tcl_DumpActiveMemory.3$Z + ln $S DumpActiveMemory.3$Z Tcl_InitMemory.3$Z + ln $S DumpActiveMemory.3$Z Tcl_ValidateAllMemory.3$Z +fi +if test -r Encoding.3; then + rm -f Encoding.3.* + $ZIP Encoding.3 + rm -f Tcl_GetEncoding.3 Tcl_GetEncoding.3.* + rm -f Tcl_FreeEncoding.3 Tcl_FreeEncoding.3.* + rm -f Tcl_ExternalToUtfDString.3 Tcl_ExternalToUtfDString.3.* + rm -f Tcl_ExternalToUtf.3 Tcl_ExternalToUtf.3.* + rm -f Tcl_UtfToExternalDString.3 Tcl_UtfToExternalDString.3.* + rm -f Tcl_UtfToExternal.3 Tcl_UtfToExternal.3.* + rm -f Tcl_WinTCharToUtf.3 Tcl_WinTCharToUtf.3.* + rm -f Tcl_WinUtfToTChar.3 Tcl_WinUtfToTChar.3.* + rm -f Tcl_GetEncodingName.3 Tcl_GetEncodingName.3.* + rm -f Tcl_SetSystemEncoding.3 Tcl_SetSystemEncoding.3.* + rm -f Tcl_GetEncodingNames.3 Tcl_GetEncodingNames.3.* + rm -f Tcl_CreateEncoding.3 Tcl_CreateEncoding.3.* + rm -f Tcl_GetDefaultEncodingDir.3 Tcl_GetDefaultEncodingDir.3.* + rm -f Tcl_SetDefaultEncodingDir.3 Tcl_SetDefaultEncodingDir.3.* + ln $S Encoding.3$Z Tcl_GetEncoding.3$Z + ln $S Encoding.3$Z Tcl_FreeEncoding.3$Z + ln $S Encoding.3$Z Tcl_ExternalToUtfDString.3$Z + ln $S Encoding.3$Z Tcl_ExternalToUtf.3$Z + ln $S Encoding.3$Z Tcl_UtfToExternalDString.3$Z + ln $S Encoding.3$Z Tcl_UtfToExternal.3$Z + ln $S Encoding.3$Z Tcl_WinTCharToUtf.3$Z + ln $S Encoding.3$Z Tcl_WinUtfToTChar.3$Z + ln $S Encoding.3$Z Tcl_GetEncodingName.3$Z + ln $S Encoding.3$Z Tcl_SetSystemEncoding.3$Z + ln $S Encoding.3$Z Tcl_GetEncodingNames.3$Z + ln $S Encoding.3$Z Tcl_CreateEncoding.3$Z + ln $S Encoding.3$Z Tcl_GetDefaultEncodingDir.3$Z + ln $S Encoding.3$Z Tcl_SetDefaultEncodingDir.3$Z +fi +if test -r Environment.3; then + rm -f Environment.3.* + $ZIP Environment.3 + rm -f Tcl_PutEnv.3 Tcl_PutEnv.3.* + ln $S Environment.3$Z Tcl_PutEnv.3$Z +fi +if test -r Eval.3; then + rm -f Eval.3.* + $ZIP Eval.3 + rm -f Tcl_EvalObjEx.3 Tcl_EvalObjEx.3.* + rm -f Tcl_EvalFile.3 Tcl_EvalFile.3.* + rm -f Tcl_EvalObjv.3 Tcl_EvalObjv.3.* + rm -f Tcl_Eval.3 Tcl_Eval.3.* + rm -f Tcl_EvalEx.3 Tcl_EvalEx.3.* + rm -f Tcl_GlobalEval.3 Tcl_GlobalEval.3.* + rm -f Tcl_GlobalEvalObj.3 Tcl_GlobalEvalObj.3.* + rm -f Tcl_VarEval.3 Tcl_VarEval.3.* + rm -f Tcl_VarEvalVA.3 Tcl_VarEvalVA.3.* + ln $S Eval.3$Z Tcl_EvalObjEx.3$Z + ln $S Eval.3$Z Tcl_EvalFile.3$Z + ln $S Eval.3$Z Tcl_EvalObjv.3$Z + ln $S Eval.3$Z Tcl_Eval.3$Z + ln $S Eval.3$Z Tcl_EvalEx.3$Z + ln $S Eval.3$Z Tcl_GlobalEval.3$Z + ln $S Eval.3$Z Tcl_GlobalEvalObj.3$Z + ln $S Eval.3$Z Tcl_VarEval.3$Z + ln $S Eval.3$Z Tcl_VarEvalVA.3$Z +fi +if test -r Exit.3; then + rm -f Exit.3.* + $ZIP Exit.3 + rm -f Tcl_Exit.3 Tcl_Exit.3.* + rm -f Tcl_Finalize.3 Tcl_Finalize.3.* + rm -f Tcl_CreateExitHandler.3 Tcl_CreateExitHandler.3.* + rm -f Tcl_DeleteExitHandler.3 Tcl_DeleteExitHandler.3.* + rm -f Tcl_ExitThread.3 Tcl_ExitThread.3.* + rm -f Tcl_FinalizeThread.3 Tcl_FinalizeThread.3.* + rm -f Tcl_CreateThreadExitHandler.3 Tcl_CreateThreadExitHandler.3.* + rm -f Tcl_DeleteThreadExitHandler.3 Tcl_DeleteThreadExitHandler.3.* + rm -f Tcl_SetExitProc.3 Tcl_SetExitProc.3.* + ln $S Exit.3$Z Tcl_Exit.3$Z + ln $S Exit.3$Z Tcl_Finalize.3$Z + ln $S Exit.3$Z Tcl_CreateExitHandler.3$Z + ln $S Exit.3$Z Tcl_DeleteExitHandler.3$Z + ln $S Exit.3$Z Tcl_ExitThread.3$Z + ln $S Exit.3$Z Tcl_FinalizeThread.3$Z + ln $S Exit.3$Z Tcl_CreateThreadExitHandler.3$Z + ln $S Exit.3$Z Tcl_DeleteThreadExitHandler.3$Z + ln $S Exit.3$Z Tcl_SetExitProc.3$Z +fi +if test -r ExprLong.3; then + rm -f ExprLong.3.* + $ZIP ExprLong.3 + rm -f Tcl_ExprLong.3 Tcl_ExprLong.3.* + rm -f Tcl_ExprDouble.3 Tcl_ExprDouble.3.* + rm -f Tcl_ExprBoolean.3 Tcl_ExprBoolean.3.* + rm -f Tcl_ExprString.3 Tcl_ExprString.3.* + ln $S ExprLong.3$Z Tcl_ExprLong.3$Z + ln $S ExprLong.3$Z Tcl_ExprDouble.3$Z + ln $S ExprLong.3$Z Tcl_ExprBoolean.3$Z + ln $S ExprLong.3$Z Tcl_ExprString.3$Z +fi +if test -r ExprLongObj.3; then + rm -f ExprLongObj.3.* + $ZIP ExprLongObj.3 + rm -f Tcl_ExprLongObj.3 Tcl_ExprLongObj.3.* + rm -f Tcl_ExprDoubleObj.3 Tcl_ExprDoubleObj.3.* + rm -f Tcl_ExprBooleanObj.3 Tcl_ExprBooleanObj.3.* + rm -f Tcl_ExprObj.3 Tcl_ExprObj.3.* + ln $S ExprLongObj.3$Z Tcl_ExprLongObj.3$Z + ln $S ExprLongObj.3$Z Tcl_ExprDoubleObj.3$Z + ln $S ExprLongObj.3$Z Tcl_ExprBooleanObj.3$Z + ln $S ExprLongObj.3$Z Tcl_ExprObj.3$Z +fi +if test -r FileSystem.3; then + rm -f FileSystem.3.* + $ZIP FileSystem.3 + rm -f Tcl_FSRegister.3 Tcl_FSRegister.3.* + rm -f Tcl_FSUnregister.3 Tcl_FSUnregister.3.* + rm -f Tcl_FSData.3 Tcl_FSData.3.* + rm -f Tcl_FSMountsChanged.3 Tcl_FSMountsChanged.3.* + rm -f Tcl_FSGetFileSystemForPath.3 Tcl_FSGetFileSystemForPath.3.* + rm -f Tcl_FSGetPathType.3 Tcl_FSGetPathType.3.* + rm -f Tcl_FSCopyFile.3 Tcl_FSCopyFile.3.* + rm -f Tcl_FSCopyDirectory.3 Tcl_FSCopyDirectory.3.* + rm -f Tcl_FSCreateDirectory.3 Tcl_FSCreateDirectory.3.* + rm -f Tcl_FSDeleteFile.3 Tcl_FSDeleteFile.3.* + rm -f Tcl_FSRemoveDirectory.3 Tcl_FSRemoveDirectory.3.* + rm -f Tcl_FSRenameFile.3 Tcl_FSRenameFile.3.* + rm -f Tcl_FSListVolumes.3 Tcl_FSListVolumes.3.* + rm -f Tcl_FSEvalFile.3 Tcl_FSEvalFile.3.* + rm -f Tcl_FSLoadFile.3 Tcl_FSLoadFile.3.* + rm -f Tcl_FSMatchInDirectory.3 Tcl_FSMatchInDirectory.3.* + rm -f Tcl_FSLink.3 Tcl_FSLink.3.* + rm -f Tcl_FSLstat.3 Tcl_FSLstat.3.* + rm -f Tcl_FSUtime.3 Tcl_FSUtime.3.* + rm -f Tcl_FSFileAttrsGet.3 Tcl_FSFileAttrsGet.3.* + rm -f Tcl_FSFileAttrsSet.3 Tcl_FSFileAttrsSet.3.* + rm -f Tcl_FSFileAttrStrings.3 Tcl_FSFileAttrStrings.3.* + rm -f Tcl_FSStat.3 Tcl_FSStat.3.* + rm -f Tcl_FSAccess.3 Tcl_FSAccess.3.* + rm -f Tcl_FSOpenFileChannel.3 Tcl_FSOpenFileChannel.3.* + rm -f Tcl_FSGetCwd.3 Tcl_FSGetCwd.3.* + rm -f Tcl_FSChdir.3 Tcl_FSChdir.3.* + rm -f Tcl_FSPathSeparator.3 Tcl_FSPathSeparator.3.* + rm -f Tcl_FSJoinPath.3 Tcl_FSJoinPath.3.* + rm -f Tcl_FSSplitPath.3 Tcl_FSSplitPath.3.* + rm -f Tcl_FSEqualPaths.3 Tcl_FSEqualPaths.3.* + rm -f Tcl_FSGetNormalizedPath.3 Tcl_FSGetNormalizedPath.3.* + rm -f Tcl_FSJoinToPath.3 Tcl_FSJoinToPath.3.* + rm -f Tcl_FSConvertToPathType.3 Tcl_FSConvertToPathType.3.* + rm -f Tcl_FSGetInternalRep.3 Tcl_FSGetInternalRep.3.* + rm -f Tcl_FSGetTranslatedPath.3 Tcl_FSGetTranslatedPath.3.* + rm -f Tcl_FSGetTranslatedStringPath.3 Tcl_FSGetTranslatedStringPath.3.* + rm -f Tcl_FSNewNativePath.3 Tcl_FSNewNativePath.3.* + rm -f Tcl_FSGetNativePath.3 Tcl_FSGetNativePath.3.* + rm -f Tcl_FSFileSystemInfo.3 Tcl_FSFileSystemInfo.3.* + rm -f Tcl_AllocStatBuf.3 Tcl_AllocStatBuf.3.* + ln $S FileSystem.3$Z Tcl_FSRegister.3$Z + ln $S FileSystem.3$Z Tcl_FSUnregister.3$Z + ln $S FileSystem.3$Z Tcl_FSData.3$Z + ln $S FileSystem.3$Z Tcl_FSMountsChanged.3$Z + ln $S FileSystem.3$Z Tcl_FSGetFileSystemForPath.3$Z + ln $S FileSystem.3$Z Tcl_FSGetPathType.3$Z + ln $S FileSystem.3$Z Tcl_FSCopyFile.3$Z + ln $S FileSystem.3$Z Tcl_FSCopyDirectory.3$Z + ln $S FileSystem.3$Z Tcl_FSCreateDirectory.3$Z + ln $S FileSystem.3$Z Tcl_FSDeleteFile.3$Z + ln $S FileSystem.3$Z Tcl_FSRemoveDirectory.3$Z + ln $S FileSystem.3$Z Tcl_FSRenameFile.3$Z + ln $S FileSystem.3$Z Tcl_FSListVolumes.3$Z + ln $S FileSystem.3$Z Tcl_FSEvalFile.3$Z + ln $S FileSystem.3$Z Tcl_FSLoadFile.3$Z + ln $S FileSystem.3$Z Tcl_FSMatchInDirectory.3$Z + ln $S FileSystem.3$Z Tcl_FSLink.3$Z + ln $S FileSystem.3$Z Tcl_FSLstat.3$Z + ln $S FileSystem.3$Z Tcl_FSUtime.3$Z + ln $S FileSystem.3$Z Tcl_FSFileAttrsGet.3$Z + ln $S FileSystem.3$Z Tcl_FSFileAttrsSet.3$Z + ln $S FileSystem.3$Z Tcl_FSFileAttrStrings.3$Z + ln $S FileSystem.3$Z Tcl_FSStat.3$Z + ln $S FileSystem.3$Z Tcl_FSAccess.3$Z + ln $S FileSystem.3$Z Tcl_FSOpenFileChannel.3$Z + ln $S FileSystem.3$Z Tcl_FSGetCwd.3$Z + ln $S FileSystem.3$Z Tcl_FSChdir.3$Z + ln $S FileSystem.3$Z Tcl_FSPathSeparator.3$Z + ln $S FileSystem.3$Z Tcl_FSJoinPath.3$Z + ln $S FileSystem.3$Z Tcl_FSSplitPath.3$Z + ln $S FileSystem.3$Z Tcl_FSEqualPaths.3$Z + ln $S FileSystem.3$Z Tcl_FSGetNormalizedPath.3$Z + ln $S FileSystem.3$Z Tcl_FSJoinToPath.3$Z + ln $S FileSystem.3$Z Tcl_FSConvertToPathType.3$Z + ln $S FileSystem.3$Z Tcl_FSGetInternalRep.3$Z + ln $S FileSystem.3$Z Tcl_FSGetTranslatedPath.3$Z + ln $S FileSystem.3$Z Tcl_FSGetTranslatedStringPath.3$Z + ln $S FileSystem.3$Z Tcl_FSNewNativePath.3$Z + ln $S FileSystem.3$Z Tcl_FSGetNativePath.3$Z + ln $S FileSystem.3$Z Tcl_FSFileSystemInfo.3$Z + ln $S FileSystem.3$Z Tcl_AllocStatBuf.3$Z +fi +if test -r FindExec.3; then + rm -f FindExec.3.* + $ZIP FindExec.3 + rm -f Tcl_FindExecutable.3 Tcl_FindExecutable.3.* + rm -f Tcl_GetNameOfExecutable.3 Tcl_GetNameOfExecutable.3.* + ln $S FindExec.3$Z Tcl_FindExecutable.3$Z + ln $S FindExec.3$Z Tcl_GetNameOfExecutable.3$Z +fi +if test -r GetCwd.3; then + rm -f GetCwd.3.* + $ZIP GetCwd.3 + rm -f Tcl_GetCwd.3 Tcl_GetCwd.3.* + rm -f Tcl_Chdir.3 Tcl_Chdir.3.* + ln $S GetCwd.3$Z Tcl_GetCwd.3$Z + ln $S GetCwd.3$Z Tcl_Chdir.3$Z +fi +if test -r GetHostName.3; then + rm -f GetHostName.3.* + $ZIP GetHostName.3 + rm -f Tcl_GetHostName.3 Tcl_GetHostName.3.* + ln $S GetHostName.3$Z Tcl_GetHostName.3$Z +fi +if test -r GetIndex.3; then + rm -f GetIndex.3.* + $ZIP GetIndex.3 + rm -f Tcl_GetIndexFromObj.3 Tcl_GetIndexFromObj.3.* + rm -f Tcl_GetIndexFromObjStruct.3 Tcl_GetIndexFromObjStruct.3.* + ln $S GetIndex.3$Z Tcl_GetIndexFromObj.3$Z + ln $S GetIndex.3$Z Tcl_GetIndexFromObjStruct.3$Z +fi +if test -r GetInt.3; then + rm -f GetInt.3.* + $ZIP GetInt.3 + rm -f Tcl_GetInt.3 Tcl_GetInt.3.* + rm -f Tcl_GetDouble.3 Tcl_GetDouble.3.* + rm -f Tcl_GetBoolean.3 Tcl_GetBoolean.3.* + ln $S GetInt.3$Z Tcl_GetInt.3$Z + ln $S GetInt.3$Z Tcl_GetDouble.3$Z + ln $S GetInt.3$Z Tcl_GetBoolean.3$Z +fi +if test -r GetOpnFl.3; then + rm -f GetOpnFl.3.* + $ZIP GetOpnFl.3 + rm -f Tcl_GetOpenFile.3 Tcl_GetOpenFile.3.* + ln $S GetOpnFl.3$Z Tcl_GetOpenFile.3$Z +fi +if test -r GetStdChan.3; then + rm -f GetStdChan.3.* + $ZIP GetStdChan.3 + rm -f Tcl_GetStdChannel.3 Tcl_GetStdChannel.3.* + rm -f Tcl_SetStdChannel.3 Tcl_SetStdChannel.3.* + ln $S GetStdChan.3$Z Tcl_GetStdChannel.3$Z + ln $S GetStdChan.3$Z Tcl_SetStdChannel.3$Z +fi +if test -r GetTime.3; then + rm -f GetTime.3.* + $ZIP GetTime.3 + rm -f Tcl_GetTime.3 Tcl_GetTime.3.* + ln $S GetTime.3$Z Tcl_GetTime.3$Z +fi +if test -r GetVersion.3; then + rm -f GetVersion.3.* + $ZIP GetVersion.3 + rm -f Tcl_GetVersion.3 Tcl_GetVersion.3.* + ln $S GetVersion.3$Z Tcl_GetVersion.3$Z +fi +if test -r Hash.3; then + rm -f Hash.3.* + $ZIP Hash.3 + rm -f Tcl_InitHashTable.3 Tcl_InitHashTable.3.* + rm -f Tcl_InitCustomHashTable.3 Tcl_InitCustomHashTable.3.* + rm -f Tcl_InitObjHashTable.3 Tcl_InitObjHashTable.3.* + rm -f Tcl_DeleteHashTable.3 Tcl_DeleteHashTable.3.* + rm -f Tcl_CreateHashEntry.3 Tcl_CreateHashEntry.3.* + rm -f Tcl_DeleteHashEntry.3 Tcl_DeleteHashEntry.3.* + rm -f Tcl_FindHashEntry.3 Tcl_FindHashEntry.3.* + rm -f Tcl_GetHashValue.3 Tcl_GetHashValue.3.* + rm -f Tcl_SetHashValue.3 Tcl_SetHashValue.3.* + rm -f Tcl_GetHashKey.3 Tcl_GetHashKey.3.* + rm -f Tcl_FirstHashEntry.3 Tcl_FirstHashEntry.3.* + rm -f Tcl_NextHashEntry.3 Tcl_NextHashEntry.3.* + rm -f Tcl_HashStats.3 Tcl_HashStats.3.* + ln $S Hash.3$Z Tcl_InitHashTable.3$Z + ln $S Hash.3$Z Tcl_InitCustomHashTable.3$Z + ln $S Hash.3$Z Tcl_InitObjHashTable.3$Z + ln $S Hash.3$Z Tcl_DeleteHashTable.3$Z + ln $S Hash.3$Z Tcl_CreateHashEntry.3$Z + ln $S Hash.3$Z Tcl_DeleteHashEntry.3$Z + ln $S Hash.3$Z Tcl_FindHashEntry.3$Z + ln $S Hash.3$Z Tcl_GetHashValue.3$Z + ln $S Hash.3$Z Tcl_SetHashValue.3$Z + ln $S Hash.3$Z Tcl_GetHashKey.3$Z + ln $S Hash.3$Z Tcl_FirstHashEntry.3$Z + ln $S Hash.3$Z Tcl_NextHashEntry.3$Z + ln $S Hash.3$Z Tcl_HashStats.3$Z +fi +if test -r Init.3; then + rm -f Init.3.* + $ZIP Init.3 + rm -f Tcl_Init.3 Tcl_Init.3.* + ln $S Init.3$Z Tcl_Init.3$Z +fi +if test -r InitStubs.3; then + rm -f InitStubs.3.* + $ZIP InitStubs.3 + rm -f Tcl_InitStubs.3 Tcl_InitStubs.3.* + ln $S InitStubs.3$Z Tcl_InitStubs.3$Z +fi +if test -r IntObj.3; then + rm -f IntObj.3.* + $ZIP IntObj.3 + rm -f Tcl_NewIntObj.3 Tcl_NewIntObj.3.* + rm -f Tcl_NewLongObj.3 Tcl_NewLongObj.3.* + rm -f Tcl_NewWideIntObj.3 Tcl_NewWideIntObj.3.* + rm -f Tcl_SetIntObj.3 Tcl_SetIntObj.3.* + rm -f Tcl_SetLongObj.3 Tcl_SetLongObj.3.* + rm -f Tcl_SetWideIntObj.3 Tcl_SetWideIntObj.3.* + rm -f Tcl_GetIntFromObj.3 Tcl_GetIntFromObj.3.* + rm -f Tcl_GetLongFromObj.3 Tcl_GetLongFromObj.3.* + rm -f Tcl_GetWideIntFromObj.3 Tcl_GetWideIntFromObj.3.* + ln $S IntObj.3$Z Tcl_NewIntObj.3$Z + ln $S IntObj.3$Z Tcl_NewLongObj.3$Z + ln $S IntObj.3$Z Tcl_NewWideIntObj.3$Z + ln $S IntObj.3$Z Tcl_SetIntObj.3$Z + ln $S IntObj.3$Z Tcl_SetLongObj.3$Z + ln $S IntObj.3$Z Tcl_SetWideIntObj.3$Z + ln $S IntObj.3$Z Tcl_GetIntFromObj.3$Z + ln $S IntObj.3$Z Tcl_GetLongFromObj.3$Z + ln $S IntObj.3$Z Tcl_GetWideIntFromObj.3$Z +fi +if test -r Interp.3; then + rm -f Interp.3.* + $ZIP Interp.3 + rm -f Tcl_Interp.3 Tcl_Interp.3.* + ln $S Interp.3$Z Tcl_Interp.3$Z +fi +if test -r Limit.3; then + rm -f Limit.3.* + $ZIP Limit.3 + rm -f Tcl_LimitAddHandler.3 Tcl_LimitAddHandler.3.* + rm -f Tcl_LimitCheck.3 Tcl_LimitCheck.3.* + rm -f Tcl_LimitExceeded.3 Tcl_LimitExceeded.3.* + rm -f Tcl_LimitGetCommands.3 Tcl_LimitGetCommands.3.* + rm -f Tcl_LimitGetGranularity.3 Tcl_LimitGetGranularity.3.* + rm -f Tcl_LimitGetTime.3 Tcl_LimitGetTime.3.* + rm -f Tcl_LimitReady.3 Tcl_LimitReady.3.* + rm -f Tcl_LimitRemoveHandler.3 Tcl_LimitRemoveHandler.3.* + rm -f Tcl_LimitSetCommands.3 Tcl_LimitSetCommands.3.* + rm -f Tcl_LimitSetGranularity.3 Tcl_LimitSetGranularity.3.* + rm -f Tcl_LimitSetTime.3 Tcl_LimitSetTime.3.* + rm -f Tcl_LimitTypeEnabled.3 Tcl_LimitTypeEnabled.3.* + rm -f Tcl_LimitTypeExceeded.3 Tcl_LimitTypeExceeded.3.* + rm -f Tcl_LimitTypeReset.3 Tcl_LimitTypeReset.3.* + rm -f Tcl_LimitTypeSet.3 Tcl_LimitTypeSet.3.* + ln $S Limit.3$Z Tcl_LimitAddHandler.3$Z + ln $S Limit.3$Z Tcl_LimitCheck.3$Z + ln $S Limit.3$Z Tcl_LimitExceeded.3$Z + ln $S Limit.3$Z Tcl_LimitGetCommands.3$Z + ln $S Limit.3$Z Tcl_LimitGetGranularity.3$Z + ln $S Limit.3$Z Tcl_LimitGetTime.3$Z + ln $S Limit.3$Z Tcl_LimitReady.3$Z + ln $S Limit.3$Z Tcl_LimitRemoveHandler.3$Z + ln $S Limit.3$Z Tcl_LimitSetCommands.3$Z + ln $S Limit.3$Z Tcl_LimitSetGranularity.3$Z + ln $S Limit.3$Z Tcl_LimitSetTime.3$Z + ln $S Limit.3$Z Tcl_LimitTypeEnabled.3$Z + ln $S Limit.3$Z Tcl_LimitTypeExceeded.3$Z + ln $S Limit.3$Z Tcl_LimitTypeReset.3$Z + ln $S Limit.3$Z Tcl_LimitTypeSet.3$Z +fi +if test -r LinkVar.3; then + rm -f LinkVar.3.* + $ZIP LinkVar.3 + rm -f Tcl_LinkVar.3 Tcl_LinkVar.3.* + rm -f Tcl_UnlinkVar.3 Tcl_UnlinkVar.3.* + rm -f Tcl_UpdateLinkedVar.3 Tcl_UpdateLinkedVar.3.* + ln $S LinkVar.3$Z Tcl_LinkVar.3$Z + ln $S LinkVar.3$Z Tcl_UnlinkVar.3$Z + ln $S LinkVar.3$Z Tcl_UpdateLinkedVar.3$Z +fi +if test -r ListObj.3; then + rm -f ListObj.3.* + $ZIP ListObj.3 + rm -f Tcl_ListObjAppendList.3 Tcl_ListObjAppendList.3.* + rm -f Tcl_ListObjAppendElement.3 Tcl_ListObjAppendElement.3.* + rm -f Tcl_NewListObj.3 Tcl_NewListObj.3.* + rm -f Tcl_SetListObj.3 Tcl_SetListObj.3.* + rm -f Tcl_ListObjGetElements.3 Tcl_ListObjGetElements.3.* + rm -f Tcl_ListObjLength.3 Tcl_ListObjLength.3.* + rm -f Tcl_ListObjIndex.3 Tcl_ListObjIndex.3.* + rm -f Tcl_ListObjReplace.3 Tcl_ListObjReplace.3.* + ln $S ListObj.3$Z Tcl_ListObjAppendList.3$Z + ln $S ListObj.3$Z Tcl_ListObjAppendElement.3$Z + ln $S ListObj.3$Z Tcl_NewListObj.3$Z + ln $S ListObj.3$Z Tcl_SetListObj.3$Z + ln $S ListObj.3$Z Tcl_ListObjGetElements.3$Z + ln $S ListObj.3$Z Tcl_ListObjLength.3$Z + ln $S ListObj.3$Z Tcl_ListObjIndex.3$Z + ln $S ListObj.3$Z Tcl_ListObjReplace.3$Z +fi +if test -r Namespace.3; then + rm -f Namespace.3.* + $ZIP Namespace.3 + rm -f Tcl_AppendExportList.3 Tcl_AppendExportList.3.* + rm -f Tcl_CreateNamespace.3 Tcl_CreateNamespace.3.* + rm -f Tcl_DeleteNamespace.3 Tcl_DeleteNamespace.3.* + rm -f Tcl_Export.3 Tcl_Export.3.* + rm -f Tcl_FindCommand.3 Tcl_FindCommand.3.* + rm -f Tcl_FindNamespace.3 Tcl_FindNamespace.3.* + rm -f Tcl_ForgetImport.3 Tcl_ForgetImport.3.* + rm -f Tcl_GetCurrentNamespace.3 Tcl_GetCurrentNamespace.3.* + rm -f Tcl_GetGloblaNamespace.3 Tcl_GetGloblaNamespace.3.* + rm -f Tcl_Import.3 Tcl_Import.3.* + ln $S Namespace.3$Z Tcl_AppendExportList.3$Z + ln $S Namespace.3$Z Tcl_CreateNamespace.3$Z + ln $S Namespace.3$Z Tcl_DeleteNamespace.3$Z + ln $S Namespace.3$Z Tcl_Export.3$Z + ln $S Namespace.3$Z Tcl_FindCommand.3$Z + ln $S Namespace.3$Z Tcl_FindNamespace.3$Z + ln $S Namespace.3$Z Tcl_ForgetImport.3$Z + ln $S Namespace.3$Z Tcl_GetCurrentNamespace.3$Z + ln $S Namespace.3$Z Tcl_GetGloblaNamespace.3$Z + ln $S Namespace.3$Z Tcl_Import.3$Z +fi +if test -r Notifier.3; then + rm -f Notifier.3.* + $ZIP Notifier.3 + rm -f Tcl_CreateEventSource.3 Tcl_CreateEventSource.3.* + rm -f Tcl_DeleteEventSource.3 Tcl_DeleteEventSource.3.* + rm -f Tcl_SetMaxBlockTime.3 Tcl_SetMaxBlockTime.3.* + rm -f Tcl_QueueEvent.3 Tcl_QueueEvent.3.* + rm -f Tcl_ThreadQueueEvent.3 Tcl_ThreadQueueEvent.3.* + rm -f Tcl_ThreadAlert.3 Tcl_ThreadAlert.3.* + rm -f Tcl_GetCurrentThread.3 Tcl_GetCurrentThread.3.* + rm -f Tcl_DeleteEvents.3 Tcl_DeleteEvents.3.* + rm -f Tcl_InitNotifier.3 Tcl_InitNotifier.3.* + rm -f Tcl_FinalizeNotifier.3 Tcl_FinalizeNotifier.3.* + rm -f Tcl_WaitForEvent.3 Tcl_WaitForEvent.3.* + rm -f Tcl_AlertNotifier.3 Tcl_AlertNotifier.3.* + rm -f Tcl_SetTimer.3 Tcl_SetTimer.3.* + rm -f Tcl_ServiceAll.3 Tcl_ServiceAll.3.* + rm -f Tcl_ServiceEvent.3 Tcl_ServiceEvent.3.* + rm -f Tcl_GetServiceMode.3 Tcl_GetServiceMode.3.* + rm -f Tcl_SetServiceMode.3 Tcl_SetServiceMode.3.* + ln $S Notifier.3$Z Tcl_CreateEventSource.3$Z + ln $S Notifier.3$Z Tcl_DeleteEventSource.3$Z + ln $S Notifier.3$Z Tcl_SetMaxBlockTime.3$Z + ln $S Notifier.3$Z Tcl_QueueEvent.3$Z + ln $S Notifier.3$Z Tcl_ThreadQueueEvent.3$Z + ln $S Notifier.3$Z Tcl_ThreadAlert.3$Z + ln $S Notifier.3$Z Tcl_GetCurrentThread.3$Z + ln $S Notifier.3$Z Tcl_DeleteEvents.3$Z + ln $S Notifier.3$Z Tcl_InitNotifier.3$Z + ln $S Notifier.3$Z Tcl_FinalizeNotifier.3$Z + ln $S Notifier.3$Z Tcl_WaitForEvent.3$Z + ln $S Notifier.3$Z Tcl_AlertNotifier.3$Z + ln $S Notifier.3$Z Tcl_SetTimer.3$Z + ln $S Notifier.3$Z Tcl_ServiceAll.3$Z + ln $S Notifier.3$Z Tcl_ServiceEvent.3$Z + ln $S Notifier.3$Z Tcl_GetServiceMode.3$Z + ln $S Notifier.3$Z Tcl_SetServiceMode.3$Z +fi +if test -r Object.3; then + rm -f Object.3.* + $ZIP Object.3 + rm -f Tcl_NewObj.3 Tcl_NewObj.3.* + rm -f Tcl_DuplicateObj.3 Tcl_DuplicateObj.3.* + rm -f Tcl_IncrRefCount.3 Tcl_IncrRefCount.3.* + rm -f Tcl_DecrRefCount.3 Tcl_DecrRefCount.3.* + rm -f Tcl_IsShared.3 Tcl_IsShared.3.* + rm -f Tcl_InvalidateStringRep.3 Tcl_InvalidateStringRep.3.* + ln $S Object.3$Z Tcl_NewObj.3$Z + ln $S Object.3$Z Tcl_DuplicateObj.3$Z + ln $S Object.3$Z Tcl_IncrRefCount.3$Z + ln $S Object.3$Z Tcl_DecrRefCount.3$Z + ln $S Object.3$Z Tcl_IsShared.3$Z + ln $S Object.3$Z Tcl_InvalidateStringRep.3$Z +fi +if test -r ObjectType.3; then + rm -f ObjectType.3.* + $ZIP ObjectType.3 + rm -f Tcl_RegisterObjType.3 Tcl_RegisterObjType.3.* + rm -f Tcl_GetObjType.3 Tcl_GetObjType.3.* + rm -f Tcl_AppendAllObjTypes.3 Tcl_AppendAllObjTypes.3.* + rm -f Tcl_ConvertToType.3 Tcl_ConvertToType.3.* + ln $S ObjectType.3$Z Tcl_RegisterObjType.3$Z + ln $S ObjectType.3$Z Tcl_GetObjType.3$Z + ln $S ObjectType.3$Z Tcl_AppendAllObjTypes.3$Z + ln $S ObjectType.3$Z Tcl_ConvertToType.3$Z +fi +if test -r OpenFileChnl.3; then + rm -f OpenFileChnl.3.* + $ZIP OpenFileChnl.3 + rm -f Tcl_OpenFileChannel.3 Tcl_OpenFileChannel.3.* + rm -f Tcl_OpenCommandChannel.3 Tcl_OpenCommandChannel.3.* + rm -f Tcl_MakeFileChannel.3 Tcl_MakeFileChannel.3.* + rm -f Tcl_GetChannel.3 Tcl_GetChannel.3.* + rm -f Tcl_GetChannelNames.3 Tcl_GetChannelNames.3.* + rm -f Tcl_GetChannelNamesEx.3 Tcl_GetChannelNamesEx.3.* + rm -f Tcl_RegisterChannel.3 Tcl_RegisterChannel.3.* + rm -f Tcl_UnregisterChannel.3 Tcl_UnregisterChannel.3.* + rm -f Tcl_DetachChannel.3 Tcl_DetachChannel.3.* + rm -f Tcl_IsStandardChannel.3 Tcl_IsStandardChannel.3.* + rm -f Tcl_Close.3 Tcl_Close.3.* + rm -f Tcl_ReadChars.3 Tcl_ReadChars.3.* + rm -f Tcl_Read.3 Tcl_Read.3.* + rm -f Tcl_GetsObj.3 Tcl_GetsObj.3.* + rm -f Tcl_Gets.3 Tcl_Gets.3.* + rm -f Tcl_WriteObj.3 Tcl_WriteObj.3.* + rm -f Tcl_WriteChars.3 Tcl_WriteChars.3.* + rm -f Tcl_Write.3 Tcl_Write.3.* + rm -f Tcl_Flush.3 Tcl_Flush.3.* + rm -f Tcl_Seek.3 Tcl_Seek.3.* + rm -f Tcl_Tell.3 Tcl_Tell.3.* + rm -f Tcl_GetChannelOption.3 Tcl_GetChannelOption.3.* + rm -f Tcl_SetChannelOption.3 Tcl_SetChannelOption.3.* + rm -f Tcl_Eof.3 Tcl_Eof.3.* + rm -f Tcl_InputBlocked.3 Tcl_InputBlocked.3.* + rm -f Tcl_InputBuffered.3 Tcl_InputBuffered.3.* + rm -f Tcl_OutputBuffered.3 Tcl_OutputBuffered.3.* + rm -f Tcl_Ungets.3 Tcl_Ungets.3.* + rm -f Tcl_ReadRaw.3 Tcl_ReadRaw.3.* + rm -f Tcl_WriteRaw.3 Tcl_WriteRaw.3.* + ln $S OpenFileChnl.3$Z Tcl_OpenFileChannel.3$Z + ln $S OpenFileChnl.3$Z Tcl_OpenCommandChannel.3$Z + ln $S OpenFileChnl.3$Z Tcl_MakeFileChannel.3$Z + ln $S OpenFileChnl.3$Z Tcl_GetChannel.3$Z + ln $S OpenFileChnl.3$Z Tcl_GetChannelNames.3$Z + ln $S OpenFileChnl.3$Z Tcl_GetChannelNamesEx.3$Z + ln $S OpenFileChnl.3$Z Tcl_RegisterChannel.3$Z + ln $S OpenFileChnl.3$Z Tcl_UnregisterChannel.3$Z + ln $S OpenFileChnl.3$Z Tcl_DetachChannel.3$Z + ln $S OpenFileChnl.3$Z Tcl_IsStandardChannel.3$Z + ln $S OpenFileChnl.3$Z Tcl_Close.3$Z + ln $S OpenFileChnl.3$Z Tcl_ReadChars.3$Z + ln $S OpenFileChnl.3$Z Tcl_Read.3$Z + ln $S OpenFileChnl.3$Z Tcl_GetsObj.3$Z + ln $S OpenFileChnl.3$Z Tcl_Gets.3$Z + ln $S OpenFileChnl.3$Z Tcl_WriteObj.3$Z + ln $S OpenFileChnl.3$Z Tcl_WriteChars.3$Z + ln $S OpenFileChnl.3$Z Tcl_Write.3$Z + ln $S OpenFileChnl.3$Z Tcl_Flush.3$Z + ln $S OpenFileChnl.3$Z Tcl_Seek.3$Z + ln $S OpenFileChnl.3$Z Tcl_Tell.3$Z + ln $S OpenFileChnl.3$Z Tcl_GetChannelOption.3$Z + ln $S OpenFileChnl.3$Z Tcl_SetChannelOption.3$Z + ln $S OpenFileChnl.3$Z Tcl_Eof.3$Z + ln $S OpenFileChnl.3$Z Tcl_InputBlocked.3$Z + ln $S OpenFileChnl.3$Z Tcl_InputBuffered.3$Z + ln $S OpenFileChnl.3$Z Tcl_OutputBuffered.3$Z + ln $S OpenFileChnl.3$Z Tcl_Ungets.3$Z + ln $S OpenFileChnl.3$Z Tcl_ReadRaw.3$Z + ln $S OpenFileChnl.3$Z Tcl_WriteRaw.3$Z +fi +if test -r OpenTcp.3; then + rm -f OpenTcp.3.* + $ZIP OpenTcp.3 + rm -f Tcl_OpenTcpClient.3 Tcl_OpenTcpClient.3.* + rm -f Tcl_MakeTcpClientChannel.3 Tcl_MakeTcpClientChannel.3.* + rm -f Tcl_OpenTcpServer.3 Tcl_OpenTcpServer.3.* + ln $S OpenTcp.3$Z Tcl_OpenTcpClient.3$Z + ln $S OpenTcp.3$Z Tcl_MakeTcpClientChannel.3$Z + ln $S OpenTcp.3$Z Tcl_OpenTcpServer.3$Z +fi +if test -r Panic.3; then + rm -f Panic.3.* + $ZIP Panic.3 + rm -f Tcl_Panic.3 Tcl_Panic.3.* + rm -f Tcl_PanicVA.3 Tcl_PanicVA.3.* + rm -f Tcl_SetPanicProc.3 Tcl_SetPanicProc.3.* + ln $S Panic.3$Z Tcl_Panic.3$Z + ln $S Panic.3$Z Tcl_PanicVA.3$Z + ln $S Panic.3$Z Tcl_SetPanicProc.3$Z +fi +if test -r ParseCmd.3; then + rm -f ParseCmd.3.* + $ZIP ParseCmd.3 + rm -f Tcl_ParseCommand.3 Tcl_ParseCommand.3.* + rm -f Tcl_ParseExpr.3 Tcl_ParseExpr.3.* + rm -f Tcl_ParseBraces.3 Tcl_ParseBraces.3.* + rm -f Tcl_ParseQuotedString.3 Tcl_ParseQuotedString.3.* + rm -f Tcl_ParseVarName.3 Tcl_ParseVarName.3.* + rm -f Tcl_ParseVar.3 Tcl_ParseVar.3.* + rm -f Tcl_FreeParse.3 Tcl_FreeParse.3.* + rm -f Tcl_EvalTokens.3 Tcl_EvalTokens.3.* + rm -f Tcl_EvalTokensStandard.3 Tcl_EvalTokensStandard.3.* + ln $S ParseCmd.3$Z Tcl_ParseCommand.3$Z + ln $S ParseCmd.3$Z Tcl_ParseExpr.3$Z + ln $S ParseCmd.3$Z Tcl_ParseBraces.3$Z + ln $S ParseCmd.3$Z Tcl_ParseQuotedString.3$Z + ln $S ParseCmd.3$Z Tcl_ParseVarName.3$Z + ln $S ParseCmd.3$Z Tcl_ParseVar.3$Z + ln $S ParseCmd.3$Z Tcl_FreeParse.3$Z + ln $S ParseCmd.3$Z Tcl_EvalTokens.3$Z + ln $S ParseCmd.3$Z Tcl_EvalTokensStandard.3$Z +fi +if test -r PkgRequire.3; then + rm -f PkgRequire.3.* + $ZIP PkgRequire.3 + rm -f Tcl_PkgRequire.3 Tcl_PkgRequire.3.* + rm -f Tcl_PkgRequireEx.3 Tcl_PkgRequireEx.3.* + rm -f Tcl_PkgPresent.3 Tcl_PkgPresent.3.* + rm -f Tcl_PkgPresentEx.3 Tcl_PkgPresentEx.3.* + rm -f Tcl_PkgProvide.3 Tcl_PkgProvide.3.* + rm -f Tcl_PkgProvideEx.3 Tcl_PkgProvideEx.3.* + ln $S PkgRequire.3$Z Tcl_PkgRequire.3$Z + ln $S PkgRequire.3$Z Tcl_PkgRequireEx.3$Z + ln $S PkgRequire.3$Z Tcl_PkgPresent.3$Z + ln $S PkgRequire.3$Z Tcl_PkgPresentEx.3$Z + ln $S PkgRequire.3$Z Tcl_PkgProvide.3$Z + ln $S PkgRequire.3$Z Tcl_PkgProvideEx.3$Z +fi +if test -r Preserve.3; then + rm -f Preserve.3.* + $ZIP Preserve.3 + rm -f Tcl_Preserve.3 Tcl_Preserve.3.* + rm -f Tcl_Release.3 Tcl_Release.3.* + rm -f Tcl_EventuallyFree.3 Tcl_EventuallyFree.3.* + ln $S Preserve.3$Z Tcl_Preserve.3$Z + ln $S Preserve.3$Z Tcl_Release.3$Z + ln $S Preserve.3$Z Tcl_EventuallyFree.3$Z +fi +if test -r PrintDbl.3; then + rm -f PrintDbl.3.* + $ZIP PrintDbl.3 + rm -f Tcl_PrintDouble.3 Tcl_PrintDouble.3.* + ln $S PrintDbl.3$Z Tcl_PrintDouble.3$Z +fi +if test -r RecEvalObj.3; then + rm -f RecEvalObj.3.* + $ZIP RecEvalObj.3 + rm -f Tcl_RecordAndEvalObj.3 Tcl_RecordAndEvalObj.3.* + ln $S RecEvalObj.3$Z Tcl_RecordAndEvalObj.3$Z +fi +if test -r RecordEval.3; then + rm -f RecordEval.3.* + $ZIP RecordEval.3 + rm -f Tcl_RecordAndEval.3 Tcl_RecordAndEval.3.* + ln $S RecordEval.3$Z Tcl_RecordAndEval.3$Z +fi +if test -r RegConfig.3; then + rm -f RegConfig.3.* + $ZIP RegConfig.3 + rm -f Tcl_RegisterConfig.3 Tcl_RegisterConfig.3.* + ln $S RegConfig.3$Z Tcl_RegisterConfig.3$Z +fi +if test -r RegExp.3; then + rm -f RegExp.3.* + $ZIP RegExp.3 + rm -f Tcl_RegExpMatch.3 Tcl_RegExpMatch.3.* + rm -f Tcl_RegExpCompile.3 Tcl_RegExpCompile.3.* + rm -f Tcl_RegExpExec.3 Tcl_RegExpExec.3.* + rm -f Tcl_RegExpRange.3 Tcl_RegExpRange.3.* + rm -f Tcl_GetRegExpFromObj.3 Tcl_GetRegExpFromObj.3.* + rm -f Tcl_RegExpMatchObj.3 Tcl_RegExpMatchObj.3.* + rm -f Tcl_RegExpExecObj.3 Tcl_RegExpExecObj.3.* + rm -f Tcl_RegExpGetInfo.3 Tcl_RegExpGetInfo.3.* + ln $S RegExp.3$Z Tcl_RegExpMatch.3$Z + ln $S RegExp.3$Z Tcl_RegExpCompile.3$Z + ln $S RegExp.3$Z Tcl_RegExpExec.3$Z + ln $S RegExp.3$Z Tcl_RegExpRange.3$Z + ln $S RegExp.3$Z Tcl_GetRegExpFromObj.3$Z + ln $S RegExp.3$Z Tcl_RegExpMatchObj.3$Z + ln $S RegExp.3$Z Tcl_RegExpExecObj.3$Z + ln $S RegExp.3$Z Tcl_RegExpGetInfo.3$Z +fi +if test -r SaveResult.3; then + rm -f SaveResult.3.* + $ZIP SaveResult.3 + rm -f Tcl_SaveResult.3 Tcl_SaveResult.3.* + rm -f Tcl_RestoreResult.3 Tcl_RestoreResult.3.* + rm -f Tcl_DiscardResult.3 Tcl_DiscardResult.3.* + ln $S SaveResult.3$Z Tcl_SaveResult.3$Z + ln $S SaveResult.3$Z Tcl_RestoreResult.3$Z + ln $S SaveResult.3$Z Tcl_DiscardResult.3$Z +fi +if test -r SetErrno.3; then + rm -f SetErrno.3.* + $ZIP SetErrno.3 + rm -f Tcl_SetErrno.3 Tcl_SetErrno.3.* + rm -f Tcl_GetErrno.3 Tcl_GetErrno.3.* + rm -f Tcl_ErrnoId.3 Tcl_ErrnoId.3.* + rm -f Tcl_ErrnoMsg.3 Tcl_ErrnoMsg.3.* + ln $S SetErrno.3$Z Tcl_SetErrno.3$Z + ln $S SetErrno.3$Z Tcl_GetErrno.3$Z + ln $S SetErrno.3$Z Tcl_ErrnoId.3$Z + ln $S SetErrno.3$Z Tcl_ErrnoMsg.3$Z +fi +if test -r SetRecLmt.3; then + rm -f SetRecLmt.3.* + $ZIP SetRecLmt.3 + rm -f Tcl_SetRecursionLimit.3 Tcl_SetRecursionLimit.3.* + ln $S SetRecLmt.3$Z Tcl_SetRecursionLimit.3$Z +fi +if test -r SetResult.3; then + rm -f SetResult.3.* + $ZIP SetResult.3 + rm -f Tcl_SetObjResult.3 Tcl_SetObjResult.3.* + rm -f Tcl_GetObjResult.3 Tcl_GetObjResult.3.* + rm -f Tcl_SetResult.3 Tcl_SetResult.3.* + rm -f Tcl_GetStringResult.3 Tcl_GetStringResult.3.* + rm -f Tcl_AppendResult.3 Tcl_AppendResult.3.* + rm -f Tcl_AppendResultVA.3 Tcl_AppendResultVA.3.* + rm -f Tcl_AppendElement.3 Tcl_AppendElement.3.* + rm -f Tcl_ResetResult.3 Tcl_ResetResult.3.* + rm -f Tcl_FreeResult.3 Tcl_FreeResult.3.* + ln $S SetResult.3$Z Tcl_SetObjResult.3$Z + ln $S SetResult.3$Z Tcl_GetObjResult.3$Z + ln $S SetResult.3$Z Tcl_SetResult.3$Z + ln $S SetResult.3$Z Tcl_GetStringResult.3$Z + ln $S SetResult.3$Z Tcl_AppendResult.3$Z + ln $S SetResult.3$Z Tcl_AppendResultVA.3$Z + ln $S SetResult.3$Z Tcl_AppendElement.3$Z + ln $S SetResult.3$Z Tcl_ResetResult.3$Z + ln $S SetResult.3$Z Tcl_FreeResult.3$Z +fi +if test -r SetVar.3; then + rm -f SetVar.3.* + $ZIP SetVar.3 + rm -f Tcl_SetVar2Ex.3 Tcl_SetVar2Ex.3.* + rm -f Tcl_SetVar.3 Tcl_SetVar.3.* + rm -f Tcl_SetVar2.3 Tcl_SetVar2.3.* + rm -f Tcl_ObjSetVar2.3 Tcl_ObjSetVar2.3.* + rm -f Tcl_GetVar2Ex.3 Tcl_GetVar2Ex.3.* + rm -f Tcl_GetVar.3 Tcl_GetVar.3.* + rm -f Tcl_GetVar2.3 Tcl_GetVar2.3.* + rm -f Tcl_ObjGetVar2.3 Tcl_ObjGetVar2.3.* + rm -f Tcl_UnsetVar.3 Tcl_UnsetVar.3.* + rm -f Tcl_UnsetVar2.3 Tcl_UnsetVar2.3.* + ln $S SetVar.3$Z Tcl_SetVar2Ex.3$Z + ln $S SetVar.3$Z Tcl_SetVar.3$Z + ln $S SetVar.3$Z Tcl_SetVar2.3$Z + ln $S SetVar.3$Z Tcl_ObjSetVar2.3$Z + ln $S SetVar.3$Z Tcl_GetVar2Ex.3$Z + ln $S SetVar.3$Z Tcl_GetVar.3$Z + ln $S SetVar.3$Z Tcl_GetVar2.3$Z + ln $S SetVar.3$Z Tcl_ObjGetVar2.3$Z + ln $S SetVar.3$Z Tcl_UnsetVar.3$Z + ln $S SetVar.3$Z Tcl_UnsetVar2.3$Z +fi +if test -r Signal.3; then + rm -f Signal.3.* + $ZIP Signal.3 + rm -f Tcl_SignalId.3 Tcl_SignalId.3.* + rm -f Tcl_SignalMsg.3 Tcl_SignalMsg.3.* + ln $S Signal.3$Z Tcl_SignalId.3$Z + ln $S Signal.3$Z Tcl_SignalMsg.3$Z +fi +if test -r Sleep.3; then + rm -f Sleep.3.* + $ZIP Sleep.3 + rm -f Tcl_Sleep.3 Tcl_Sleep.3.* + ln $S Sleep.3$Z Tcl_Sleep.3$Z +fi +if test -r SourceRCFile.3; then + rm -f SourceRCFile.3.* + $ZIP SourceRCFile.3 + rm -f Tcl_SourceRCFile.3 Tcl_SourceRCFile.3.* + ln $S SourceRCFile.3$Z Tcl_SourceRCFile.3$Z +fi +if test -r SplitList.3; then + rm -f SplitList.3.* + $ZIP SplitList.3 + rm -f Tcl_SplitList.3 Tcl_SplitList.3.* + rm -f Tcl_Merge.3 Tcl_Merge.3.* + rm -f Tcl_ScanElement.3 Tcl_ScanElement.3.* + rm -f Tcl_ConvertElement.3 Tcl_ConvertElement.3.* + rm -f Tcl_ScanCountedElement.3 Tcl_ScanCountedElement.3.* + rm -f Tcl_ConvertCountedElement.3 Tcl_ConvertCountedElement.3.* + ln $S SplitList.3$Z Tcl_SplitList.3$Z + ln $S SplitList.3$Z Tcl_Merge.3$Z + ln $S SplitList.3$Z Tcl_ScanElement.3$Z + ln $S SplitList.3$Z Tcl_ConvertElement.3$Z + ln $S SplitList.3$Z Tcl_ScanCountedElement.3$Z + ln $S SplitList.3$Z Tcl_ConvertCountedElement.3$Z +fi +if test -r SplitPath.3; then + rm -f SplitPath.3.* + $ZIP SplitPath.3 + rm -f Tcl_SplitPath.3 Tcl_SplitPath.3.* + rm -f Tcl_JoinPath.3 Tcl_JoinPath.3.* + rm -f Tcl_GetPathType.3 Tcl_GetPathType.3.* + ln $S SplitPath.3$Z Tcl_SplitPath.3$Z + ln $S SplitPath.3$Z Tcl_JoinPath.3$Z + ln $S SplitPath.3$Z Tcl_GetPathType.3$Z +fi +if test -r StaticPkg.3; then + rm -f StaticPkg.3.* + $ZIP StaticPkg.3 + rm -f Tcl_StaticPackage.3 Tcl_StaticPackage.3.* + ln $S StaticPkg.3$Z Tcl_StaticPackage.3$Z +fi +if test -r StdChannels.3; then + rm -f StdChannels.3.* + $ZIP StdChannels.3 + rm -f Tcl_StandardChannels.3 Tcl_StandardChannels.3.* + ln $S StdChannels.3$Z Tcl_StandardChannels.3$Z +fi +if test -r StrMatch.3; then + rm -f StrMatch.3.* + $ZIP StrMatch.3 + rm -f Tcl_StringMatch.3 Tcl_StringMatch.3.* + rm -f Tcl_StringCaseMatch.3 Tcl_StringCaseMatch.3.* + ln $S StrMatch.3$Z Tcl_StringMatch.3$Z + ln $S StrMatch.3$Z Tcl_StringCaseMatch.3$Z +fi +if test -r StringObj.3; then + rm -f StringObj.3.* + $ZIP StringObj.3 + rm -f Tcl_NewStringObj.3 Tcl_NewStringObj.3.* + rm -f Tcl_NewUnicodeObj.3 Tcl_NewUnicodeObj.3.* + rm -f Tcl_SetStringObj.3 Tcl_SetStringObj.3.* + rm -f Tcl_SetUnicodeObj.3 Tcl_SetUnicodeObj.3.* + rm -f Tcl_GetStringFromObj.3 Tcl_GetStringFromObj.3.* + rm -f Tcl_GetString.3 Tcl_GetString.3.* + rm -f Tcl_GetUnicodeFromObj.3 Tcl_GetUnicodeFromObj.3.* + rm -f Tcl_GetUnicode.3 Tcl_GetUnicode.3.* + rm -f Tcl_GetUniChar.3 Tcl_GetUniChar.3.* + rm -f Tcl_GetCharLength.3 Tcl_GetCharLength.3.* + rm -f Tcl_GetRange.3 Tcl_GetRange.3.* + rm -f Tcl_AppendToObj.3 Tcl_AppendToObj.3.* + rm -f Tcl_AppendUnicodeToObj.3 Tcl_AppendUnicodeToObj.3.* + rm -f Tcl_AppendStringsToObj.3 Tcl_AppendStringsToObj.3.* + rm -f Tcl_AppendStringsToObjVA.3 Tcl_AppendStringsToObjVA.3.* + rm -f Tcl_AppendObjToObj.3 Tcl_AppendObjToObj.3.* + rm -f Tcl_SetObjLength.3 Tcl_SetObjLength.3.* + rm -f Tcl_ConcatObj.3 Tcl_ConcatObj.3.* + rm -f Tcl_AttemptSetObjLength.3 Tcl_AttemptSetObjLength.3.* + ln $S StringObj.3$Z Tcl_NewStringObj.3$Z + ln $S StringObj.3$Z Tcl_NewUnicodeObj.3$Z + ln $S StringObj.3$Z Tcl_SetStringObj.3$Z + ln $S StringObj.3$Z Tcl_SetUnicodeObj.3$Z + ln $S StringObj.3$Z Tcl_GetStringFromObj.3$Z + ln $S StringObj.3$Z Tcl_GetString.3$Z + ln $S StringObj.3$Z Tcl_GetUnicodeFromObj.3$Z + ln $S StringObj.3$Z Tcl_GetUnicode.3$Z + ln $S StringObj.3$Z Tcl_GetUniChar.3$Z + ln $S StringObj.3$Z Tcl_GetCharLength.3$Z + ln $S StringObj.3$Z Tcl_GetRange.3$Z + ln $S StringObj.3$Z Tcl_AppendToObj.3$Z + ln $S StringObj.3$Z Tcl_AppendUnicodeToObj.3$Z + ln $S StringObj.3$Z Tcl_AppendStringsToObj.3$Z + ln $S StringObj.3$Z Tcl_AppendStringsToObjVA.3$Z + ln $S StringObj.3$Z Tcl_AppendObjToObj.3$Z + ln $S StringObj.3$Z Tcl_SetObjLength.3$Z + ln $S StringObj.3$Z Tcl_ConcatObj.3$Z + ln $S StringObj.3$Z Tcl_AttemptSetObjLength.3$Z +fi +if test -r SubstObj.3; then + rm -f SubstObj.3.* + $ZIP SubstObj.3 + rm -f Tcl_SubstObj.3 Tcl_SubstObj.3.* + ln $S SubstObj.3$Z Tcl_SubstObj.3$Z +fi +if test -r TCL_MEM_DEBUG.3; then + rm -f TCL_MEM_DEBUG.3.* + $ZIP TCL_MEM_DEBUG.3 +fi +if test -r Tcl.n; then + rm -f Tcl.n.* + $ZIP Tcl.n +fi +if test -r Tcl_Main.3; then + rm -f Tcl_Main.3.* + $ZIP Tcl_Main.3 + rm -f Tcl_SetMainLoop.3 Tcl_SetMainLoop.3.* + ln $S Tcl_Main.3$Z Tcl_SetMainLoop.3$Z +fi +if test -r Thread.3; then + rm -f Thread.3.* + $ZIP Thread.3 + rm -f Tcl_ConditionNotify.3 Tcl_ConditionNotify.3.* + rm -f Tcl_ConditionWait.3 Tcl_ConditionWait.3.* + rm -f Tcl_ConditionFinalize.3 Tcl_ConditionFinalize.3.* + rm -f Tcl_GetThreadData.3 Tcl_GetThreadData.3.* + rm -f Tcl_MutexLock.3 Tcl_MutexLock.3.* + rm -f Tcl_MutexUnlock.3 Tcl_MutexUnlock.3.* + rm -f Tcl_MutexFinalize.3 Tcl_MutexFinalize.3.* + rm -f Tcl_CreateThread.3 Tcl_CreateThread.3.* + rm -f Tcl_JoinThread.3 Tcl_JoinThread.3.* + ln $S Thread.3$Z Tcl_ConditionNotify.3$Z + ln $S Thread.3$Z Tcl_ConditionWait.3$Z + ln $S Thread.3$Z Tcl_ConditionFinalize.3$Z + ln $S Thread.3$Z Tcl_GetThreadData.3$Z + ln $S Thread.3$Z Tcl_MutexLock.3$Z + ln $S Thread.3$Z Tcl_MutexUnlock.3$Z + ln $S Thread.3$Z Tcl_MutexFinalize.3$Z + ln $S Thread.3$Z Tcl_CreateThread.3$Z + ln $S Thread.3$Z Tcl_JoinThread.3$Z +fi +if test -r ToUpper.3; then + rm -f ToUpper.3.* + $ZIP ToUpper.3 + rm -f Tcl_UniCharToUpper.3 Tcl_UniCharToUpper.3.* + rm -f Tcl_UniCharToLower.3 Tcl_UniCharToLower.3.* + rm -f Tcl_UniCharToTitle.3 Tcl_UniCharToTitle.3.* + rm -f Tcl_UtfToUpper.3 Tcl_UtfToUpper.3.* + rm -f Tcl_UtfToLower.3 Tcl_UtfToLower.3.* + rm -f Tcl_UtfToTitle.3 Tcl_UtfToTitle.3.* + ln $S ToUpper.3$Z Tcl_UniCharToUpper.3$Z + ln $S ToUpper.3$Z Tcl_UniCharToLower.3$Z + ln $S ToUpper.3$Z Tcl_UniCharToTitle.3$Z + ln $S ToUpper.3$Z Tcl_UtfToUpper.3$Z + ln $S ToUpper.3$Z Tcl_UtfToLower.3$Z + ln $S ToUpper.3$Z Tcl_UtfToTitle.3$Z +fi +if test -r TraceCmd.3; then + rm -f TraceCmd.3.* + $ZIP TraceCmd.3 + rm -f Tcl_CommandTraceInfo.3 Tcl_CommandTraceInfo.3.* + rm -f Tcl_TraceCommand.3 Tcl_TraceCommand.3.* + rm -f Tcl_UntraceCommand.3 Tcl_UntraceCommand.3.* + ln $S TraceCmd.3$Z Tcl_CommandTraceInfo.3$Z + ln $S TraceCmd.3$Z Tcl_TraceCommand.3$Z + ln $S TraceCmd.3$Z Tcl_UntraceCommand.3$Z +fi +if test -r TraceVar.3; then + rm -f TraceVar.3.* + $ZIP TraceVar.3 + rm -f Tcl_TraceVar.3 Tcl_TraceVar.3.* + rm -f Tcl_TraceVar2.3 Tcl_TraceVar2.3.* + rm -f Tcl_UntraceVar.3 Tcl_UntraceVar.3.* + rm -f Tcl_UntraceVar2.3 Tcl_UntraceVar2.3.* + rm -f Tcl_VarTraceInfo.3 Tcl_VarTraceInfo.3.* + rm -f Tcl_VarTraceInfo2.3 Tcl_VarTraceInfo2.3.* + ln $S TraceVar.3$Z Tcl_TraceVar.3$Z + ln $S TraceVar.3$Z Tcl_TraceVar2.3$Z + ln $S TraceVar.3$Z Tcl_UntraceVar.3$Z + ln $S TraceVar.3$Z Tcl_UntraceVar2.3$Z + ln $S TraceVar.3$Z Tcl_VarTraceInfo.3$Z + ln $S TraceVar.3$Z Tcl_VarTraceInfo2.3$Z +fi +if test -r Translate.3; then + rm -f Translate.3.* + $ZIP Translate.3 + rm -f Tcl_TranslateFileName.3 Tcl_TranslateFileName.3.* + ln $S Translate.3$Z Tcl_TranslateFileName.3$Z +fi +if test -r UniCharIsAlpha.3; then + rm -f UniCharIsAlpha.3.* + $ZIP UniCharIsAlpha.3 + rm -f Tcl_UniCharIsAlnum.3 Tcl_UniCharIsAlnum.3.* + rm -f Tcl_UniCharIsAlpha.3 Tcl_UniCharIsAlpha.3.* + rm -f Tcl_UniCharIsControl.3 Tcl_UniCharIsControl.3.* + rm -f Tcl_UniCharIsDigit.3 Tcl_UniCharIsDigit.3.* + rm -f Tcl_UniCharIsGraph.3 Tcl_UniCharIsGraph.3.* + rm -f Tcl_UniCharIsLower.3 Tcl_UniCharIsLower.3.* + rm -f Tcl_UniCharIsPrint.3 Tcl_UniCharIsPrint.3.* + rm -f Tcl_UniCharIsPunct.3 Tcl_UniCharIsPunct.3.* + rm -f Tcl_UniCharIsSpace.3 Tcl_UniCharIsSpace.3.* + rm -f Tcl_UniCharIsUpper.3 Tcl_UniCharIsUpper.3.* + rm -f Tcl_UniCharIsWordChar.3 Tcl_UniCharIsWordChar.3.* + ln $S UniCharIsAlpha.3$Z Tcl_UniCharIsAlnum.3$Z + ln $S UniCharIsAlpha.3$Z Tcl_UniCharIsAlpha.3$Z + ln $S UniCharIsAlpha.3$Z Tcl_UniCharIsControl.3$Z + ln $S UniCharIsAlpha.3$Z Tcl_UniCharIsDigit.3$Z + ln $S UniCharIsAlpha.3$Z Tcl_UniCharIsGraph.3$Z + ln $S UniCharIsAlpha.3$Z Tcl_UniCharIsLower.3$Z + ln $S UniCharIsAlpha.3$Z Tcl_UniCharIsPrint.3$Z + ln $S UniCharIsAlpha.3$Z Tcl_UniCharIsPunct.3$Z + ln $S UniCharIsAlpha.3$Z Tcl_UniCharIsSpace.3$Z + ln $S UniCharIsAlpha.3$Z Tcl_UniCharIsUpper.3$Z + ln $S UniCharIsAlpha.3$Z Tcl_UniCharIsWordChar.3$Z +fi +if test -r UpVar.3; then + rm -f UpVar.3.* + $ZIP UpVar.3 + rm -f Tcl_UpVar.3 Tcl_UpVar.3.* + rm -f Tcl_UpVar2.3 Tcl_UpVar2.3.* + ln $S UpVar.3$Z Tcl_UpVar.3$Z + ln $S UpVar.3$Z Tcl_UpVar2.3$Z +fi +if test -r Utf.3; then + rm -f Utf.3.* + $ZIP Utf.3 + rm -f Tcl_UniChar.3 Tcl_UniChar.3.* + rm -f Tcl_UniCharCaseMatch.3 Tcl_UniCharCaseMatch.3.* + rm -f Tcl_UniCharNcasecmp.3 Tcl_UniCharNcasecmp.3.* + rm -f Tcl_UniCharToUtf.3 Tcl_UniCharToUtf.3.* + rm -f Tcl_UtfToUniChar.3 Tcl_UtfToUniChar.3.* + rm -f Tcl_UniCharToUtfDString.3 Tcl_UniCharToUtfDString.3.* + rm -f Tcl_UtfToUniCharDString.3 Tcl_UtfToUniCharDString.3.* + rm -f Tcl_UniCharLen.3 Tcl_UniCharLen.3.* + rm -f Tcl_UniCharNcmp.3 Tcl_UniCharNcmp.3.* + rm -f Tcl_UtfCharComplete.3 Tcl_UtfCharComplete.3.* + rm -f Tcl_NumUtfChars.3 Tcl_NumUtfChars.3.* + rm -f Tcl_UtfFindFirst.3 Tcl_UtfFindFirst.3.* + rm -f Tcl_UtfFindLast.3 Tcl_UtfFindLast.3.* + rm -f Tcl_UtfNext.3 Tcl_UtfNext.3.* + rm -f Tcl_UtfPrev.3 Tcl_UtfPrev.3.* + rm -f Tcl_UniCharAtIndex.3 Tcl_UniCharAtIndex.3.* + rm -f Tcl_UtfAtIndex.3 Tcl_UtfAtIndex.3.* + rm -f Tcl_UtfBackslash.3 Tcl_UtfBackslash.3.* + ln $S Utf.3$Z Tcl_UniChar.3$Z + ln $S Utf.3$Z Tcl_UniCharCaseMatch.3$Z + ln $S Utf.3$Z Tcl_UniCharNcasecmp.3$Z + ln $S Utf.3$Z Tcl_UniCharToUtf.3$Z + ln $S Utf.3$Z Tcl_UtfToUniChar.3$Z + ln $S Utf.3$Z Tcl_UniCharToUtfDString.3$Z + ln $S Utf.3$Z Tcl_UtfToUniCharDString.3$Z + ln $S Utf.3$Z Tcl_UniCharLen.3$Z + ln $S Utf.3$Z Tcl_UniCharNcmp.3$Z + ln $S Utf.3$Z Tcl_UtfCharComplete.3$Z + ln $S Utf.3$Z Tcl_NumUtfChars.3$Z + ln $S Utf.3$Z Tcl_UtfFindFirst.3$Z + ln $S Utf.3$Z Tcl_UtfFindLast.3$Z + ln $S Utf.3$Z Tcl_UtfNext.3$Z + ln $S Utf.3$Z Tcl_UtfPrev.3$Z + ln $S Utf.3$Z Tcl_UniCharAtIndex.3$Z + ln $S Utf.3$Z Tcl_UtfAtIndex.3$Z + ln $S Utf.3$Z Tcl_UtfBackslash.3$Z +fi +if test -r WrongNumArgs.3; then + rm -f WrongNumArgs.3.* + $ZIP WrongNumArgs.3 + rm -f Tcl_WrongNumArgs.3 Tcl_WrongNumArgs.3.* + ln $S WrongNumArgs.3$Z Tcl_WrongNumArgs.3$Z +fi +if test -r after.n; then + rm -f after.n.* + $ZIP after.n +fi +if test -r append.n; then + rm -f append.n.* + $ZIP append.n +fi +if test -r array.n; then + rm -f array.n.* + $ZIP array.n +fi +if test -r bgerror.n; then + rm -f bgerror.n.* + $ZIP bgerror.n +fi +if test -r binary.n; then + rm -f binary.n.* + $ZIP binary.n +fi +if test -r break.n; then + rm -f break.n.* + $ZIP break.n +fi +if test -r case.n; then + rm -f case.n.* + $ZIP case.n +fi +if test -r catch.n; then + rm -f catch.n.* + $ZIP catch.n +fi +if test -r cd.n; then + rm -f cd.n.* + $ZIP cd.n +fi +if test -r close.n; then + rm -f close.n.* + $ZIP close.n +fi +if test -r concat.n; then + rm -f concat.n.* + $ZIP concat.n +fi +if test -r continue.n; then + rm -f continue.n.* + $ZIP continue.n +fi +if test -r dde.n; then + rm -f dde.n.* + $ZIP dde.n +fi +if test -r dict.n; then + rm -f dict.n.* + $ZIP dict.n +fi +if test -r encoding.n; then + rm -f encoding.n.* + $ZIP encoding.n +fi +if test -r eof.n; then + rm -f eof.n.* + $ZIP eof.n +fi +if test -r error.n; then + rm -f error.n.* + $ZIP error.n +fi +if test -r eval.n; then + rm -f eval.n.* + $ZIP eval.n +fi +if test -r exec.n; then + rm -f exec.n.* + $ZIP exec.n +fi +if test -r exit.n; then + rm -f exit.n.* + $ZIP exit.n +fi +if test -r expr.n; then + rm -f expr.n.* + $ZIP expr.n +fi +if test -r fblocked.n; then + rm -f fblocked.n.* + $ZIP fblocked.n +fi +if test -r fconfigure.n; then + rm -f fconfigure.n.* + $ZIP fconfigure.n +fi +if test -r fcopy.n; then + rm -f fcopy.n.* + $ZIP fcopy.n +fi +if test -r file.n; then + rm -f file.n.* + $ZIP file.n +fi +if test -r fileevent.n; then + rm -f fileevent.n.* + $ZIP fileevent.n +fi +if test -r filename.n; then + rm -f filename.n.* + $ZIP filename.n +fi +if test -r flush.n; then + rm -f flush.n.* + $ZIP flush.n +fi +if test -r for.n; then + rm -f for.n.* + $ZIP for.n +fi +if test -r foreach.n; then + rm -f foreach.n.* + $ZIP foreach.n +fi +if test -r format.n; then + rm -f format.n.* + $ZIP format.n +fi +if test -r gets.n; then + rm -f gets.n.* + $ZIP gets.n +fi +if test -r glob.n; then + rm -f glob.n.* + $ZIP glob.n +fi +if test -r global.n; then + rm -f global.n.* + $ZIP global.n +fi +if test -r history.n; then + rm -f history.n.* + $ZIP history.n +fi +if test -r http.n; then + rm -f http.n.* + $ZIP http.n +fi +if test -r if.n; then + rm -f if.n.* + $ZIP if.n +fi +if test -r incr.n; then + rm -f incr.n.* + $ZIP incr.n +fi +if test -r info.n; then + rm -f info.n.* + $ZIP info.n +fi +if test -r interp.n; then + rm -f interp.n.* + $ZIP interp.n +fi +if test -r join.n; then + rm -f join.n.* + $ZIP join.n +fi +if test -r lappend.n; then + rm -f lappend.n.* + $ZIP lappend.n +fi +if test -r lassign.n; then + rm -f lassign.n.* + $ZIP lassign.n +fi +if test -r library.n; then + rm -f library.n.* + $ZIP library.n + rm -f auto_execok.n auto_execok.n.* + rm -f auto_import.n auto_import.n.* + rm -f auto_load.n auto_load.n.* + rm -f auto_mkindex.n auto_mkindex.n.* + rm -f auto_mkindex_old.n auto_mkindex_old.n.* + rm -f auto_qualify.n auto_qualify.n.* + rm -f auto_reset.n auto_reset.n.* + rm -f tcl_findLibrary.n tcl_findLibrary.n.* + rm -f parray.n parray.n.* + rm -f tcl_endOfWord.n tcl_endOfWord.n.* + rm -f tcl_startOfNextWord.n tcl_startOfNextWord.n.* + rm -f tcl_startOfPreviousWord.n tcl_startOfPreviousWord.n.* + rm -f tcl_wordBreakAfter.n tcl_wordBreakAfter.n.* + rm -f tcl_wordBreakBefore.n tcl_wordBreakBefore.n.* + ln $S library.n$Z auto_execok.n$Z + ln $S library.n$Z auto_import.n$Z + ln $S library.n$Z auto_load.n$Z + ln $S library.n$Z auto_mkindex.n$Z + ln $S library.n$Z auto_mkindex_old.n$Z + ln $S library.n$Z auto_qualify.n$Z + ln $S library.n$Z auto_reset.n$Z + ln $S library.n$Z tcl_findLibrary.n$Z + ln $S library.n$Z parray.n$Z + ln $S library.n$Z tcl_endOfWord.n$Z + ln $S library.n$Z tcl_startOfNextWord.n$Z + ln $S library.n$Z tcl_startOfPreviousWord.n$Z + ln $S library.n$Z tcl_wordBreakAfter.n$Z + ln $S library.n$Z tcl_wordBreakBefore.n$Z +fi +if test -r lindex.n; then + rm -f lindex.n.* + $ZIP lindex.n +fi +if test -r linsert.n; then + rm -f linsert.n.* + $ZIP linsert.n +fi +if test -r list.n; then + rm -f list.n.* + $ZIP list.n +fi +if test -r llength.n; then + rm -f llength.n.* + $ZIP llength.n +fi +if test -r load.n; then + rm -f load.n.* + $ZIP load.n +fi +if test -r lrange.n; then + rm -f lrange.n.* + $ZIP lrange.n +fi +if test -r lrepeat.n; then + rm -f lrepeat.n.* + $ZIP lrepeat.n +fi +if test -r lreplace.n; then + rm -f lreplace.n.* + $ZIP lreplace.n +fi +if test -r lsearch.n; then + rm -f lsearch.n.* + $ZIP lsearch.n +fi +if test -r lset.n; then + rm -f lset.n.* + $ZIP lset.n +fi +if test -r lsort.n; then + rm -f lsort.n.* + $ZIP lsort.n +fi +if test -r memory.n; then + rm -f memory.n.* + $ZIP memory.n +fi +if test -r msgcat.n; then + rm -f msgcat.n.* + $ZIP msgcat.n +fi +if test -r namespace.n; then + rm -f namespace.n.* + $ZIP namespace.n +fi +if test -r open.n; then + rm -f open.n.* + $ZIP open.n +fi +if test -r package.n; then + rm -f package.n.* + $ZIP package.n +fi +if test -r packagens.n; then + rm -f packagens.n.* + $ZIP packagens.n + rm -f pkg::create.n pkg::create.n.* + ln $S packagens.n$Z pkg::create.n$Z +fi +if test -r pid.n; then + rm -f pid.n.* + $ZIP pid.n +fi +if test -r pkgMkIndex.n; then + rm -f pkgMkIndex.n.* + $ZIP pkgMkIndex.n + rm -f pkg_mkIndex.n pkg_mkIndex.n.* + ln $S pkgMkIndex.n$Z pkg_mkIndex.n$Z +fi +if test -r proc.n; then + rm -f proc.n.* + $ZIP proc.n +fi +if test -r puts.n; then + rm -f puts.n.* + $ZIP puts.n +fi +if test -r pwd.n; then + rm -f pwd.n.* + $ZIP pwd.n +fi +if test -r re_syntax.n; then + rm -f re_syntax.n.* + $ZIP re_syntax.n +fi +if test -r read.n; then + rm -f read.n.* + $ZIP read.n +fi +if test -r regexp.n; then + rm -f regexp.n.* + $ZIP regexp.n +fi +if test -r registry.n; then + rm -f registry.n.* + $ZIP registry.n +fi +if test -r regsub.n; then + rm -f regsub.n.* + $ZIP regsub.n +fi +if test -r rename.n; then + rm -f rename.n.* + $ZIP rename.n +fi +if test -r return.n; then + rm -f return.n.* + $ZIP return.n +fi +if test -r safe.n; then + rm -f safe.n.* + $ZIP safe.n + rm -f SafeBase.n SafeBase.n.* + ln $S safe.n$Z SafeBase.n$Z +fi +if test -r scan.n; then + rm -f scan.n.* + $ZIP scan.n +fi +if test -r seek.n; then + rm -f seek.n.* + $ZIP seek.n +fi +if test -r set.n; then + rm -f set.n.* + $ZIP set.n +fi +if test -r socket.n; then + rm -f socket.n.* + $ZIP socket.n +fi +if test -r source.n; then + rm -f source.n.* + $ZIP source.n +fi +if test -r split.n; then + rm -f split.n.* + $ZIP split.n +fi +if test -r string.n; then + rm -f string.n.* + $ZIP string.n +fi +if test -r subst.n; then + rm -f subst.n.* + $ZIP subst.n +fi +if test -r switch.n; then + rm -f switch.n.* + $ZIP switch.n +fi +if test -r tclsh.1; then + rm -f tclsh.1.* + $ZIP tclsh.1 +fi +if test -r tcltest.n; then + rm -f tcltest.n.* + $ZIP tcltest.n +fi +if test -r tclvars.n; then + rm -f tclvars.n.* + $ZIP tclvars.n +fi +if test -r tell.n; then + rm -f tell.n.* + $ZIP tell.n +fi +if test -r time.n; then + rm -f time.n.* + $ZIP time.n +fi +if test -r tm.n; then + rm -f tm.n.* + $ZIP tm.n +fi +if test -r trace.n; then + rm -f trace.n.* + $ZIP trace.n +fi +if test -r unknown.n; then + rm -f unknown.n.* + $ZIP unknown.n +fi +if test -r unload.n; then + rm -f unload.n.* + $ZIP unload.n +fi +if test -r unset.n; then + rm -f unset.n.* + $ZIP unset.n +fi +if test -r update.n; then + rm -f update.n.* + $ZIP update.n +fi +if test -r uplevel.n; then + rm -f uplevel.n.* + $ZIP uplevel.n +fi +if test -r upvar.n; then + rm -f upvar.n.* + $ZIP upvar.n +fi +if test -r variable.n; then + rm -f variable.n.* + $ZIP variable.n +fi +if test -r vwait.n; then + rm -f vwait.n.* + $ZIP vwait.n +fi +if test -r while.n; then + rm -f while.n.* + $ZIP while.n +fi +exit 0 diff --git a/unix/mkLinks.tcl b/unix/mkLinks.tcl new file mode 100644 index 0000000..85ef575 --- /dev/null +++ b/unix/mkLinks.tcl @@ -0,0 +1,119 @@ +#!/bin/sh +# mkLinks.tcl -- +# This generates the mkLinks script +# \ +exec tclsh "$0" ${1+"$@"} + +puts stdout \ +{#!/bin/sh +# This script is invoked when installing manual entries. It generates +# additional links to manual entries, corresponding to the procedure +# and command names described by the manual entry. For example, the +# Tcl manual entry Hash.3 describes procedures Tcl_InitHashTable, +# Tcl_CreateHashEntry, and many more. This script will make hard +# links so that Tcl_InitHashTable.3, Tcl_CreateHashEntry.3, and so +# on all refer to Hash.3 in the installed directory. +# +# Because of the length of command and procedure names, this mechanism +# only works on machines that support file names longer than 14 characters. +# This script checks to see if long file names are supported, and it +# doesn't make any links if they are not. +# +# The script takes one argument, which is the name of the directory +# where the manual entries have been installed. + +ZIP=true +while true; do + case $1 in + -s | --symlinks ) + S=-s + ;; + -z | --compress ) + ZIP=$2 + shift + ;; + *) break + ;; + esac + shift +done + +if test $# != 1; then + echo "Usage: mkLinks <options> dir" + exit 1 +fi + +if test "x$ZIP" != "xtrue"; then + touch TeST + $ZIP TeST + Z=`ls TeST* | sed 's/^[^.]*//'` + rm -f TeST* +fi + +cd $1 +echo foo > xyzzyTestingAVeryLongFileName.foo +x=`echo xyzzyTe*` +echo foo > xyzzyTestingaverylongfilename.foo +y=`echo xyzzyTestingav*` +rm xyzzyTe* +if test "$x" != "xyzzyTestingAVeryLongFileName.foo"; then + exit +fi +if test "$y" != "xyzzyTestingaverylongfilename.foo"; then + CASEINSENSITIVEFS=1 +fi +} + +set case_insensitive_test { if test "${CASEINSENSITIVEFS:-}" != "1"; then} +set case_insensitive_test_fi {; fi} + +foreach file $argv { + set in [open $file] + set tail [file tail $file] + set ext [file extension $file] + set state begin + while {[gets $in line] >= 0} { + switch $state { + begin { + if {[string match ".SH NAME*" $line]} { + set state name + } + } + name { + regsub {\\-.*} $line {} line + set rmOutput "" + set lnOutput "" + set namelist {} + foreach name [split $line ,] { + regsub -all {(\\)? } $name "" name + if {![string match $name*$ext $tail]} { + if {[string match -nocase $name*$ext $tail]} { + set tst $case_insensitive_test + set tstfi $case_insensitive_test_fi + } else { + set tst "" + set tstfi "" + } + lappend namelist $name$ext + append rmOutput " $tst rm -f $name$ext $name$ext.* $tstfi\n" + append lnOutput " $tst ln \$S $tail\$Z $name$ext\$Z $tstfi\n" + } + } + puts "if test -r $tail; then" + puts " rm -f $tail.*" + puts " \$ZIP $tail" + if { [llength $namelist] } { + puts -nonewline $rmOutput + puts -nonewline $lnOutput + } + puts "fi" + set state end + } + end { + break + } + } + } + close $in +} +puts "exit 0" diff --git a/unix/tclLoadAout.c b/unix/tclLoadAout.c new file mode 100644 index 0000000..d4ef456 --- /dev/null +++ b/unix/tclLoadAout.c @@ -0,0 +1,536 @@ +/* + * tclLoadAout.c -- + * + * This procedure provides a version of the TclLoadFile that + * provides pseudo-static linking using version-7 compatible + * a.out files described in either sys/exec.h or sys/a.out.h. + * + * Copyright (c) 1995, by General Electric Company. All rights reserved. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * This work was supported in part by the ARPA Manufacturing Automation + * and Design Engineering (MADE) Initiative through ARPA contract + * F33615-94-C-4400. + * + * RCS: @(#) $Id: tclLoadAout.c,v 1.14 2002/10/10 12:25:53 vincentdarley Exp $ + */ + +#include "tclInt.h" +#include <fcntl.h> +#ifdef HAVE_EXEC_AOUT_H +# include <sys/exec_aout.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#else +# include "../compat/unistd.h" +#endif + +/* + * Some systems describe the a.out header in sys/exec.h, and some in + * a.out.h. + */ + +#ifdef USE_SYS_EXEC_H +#include <sys/exec.h> +#endif +#ifdef USE_A_OUT_H +#include <a.out.h> +#endif +#ifdef USE_SYS_EXEC_AOUT_H +#include <sys/exec_aout.h> +#define a_magic a_midmag +#endif + +/* + * TCL_LOADSHIM is the amount by which to shim the break when loading + */ + +#ifndef TCL_LOADSHIM +#define TCL_LOADSHIM 0x4000L +#endif + +/* + * TCL_LOADALIGN must be a power of 2, and is the alignment to which + * to force the origin of load modules + */ + +#ifndef TCL_LOADALIGN +#define TCL_LOADALIGN 0x4000L +#endif + +/* + * TCL_LOADMAX is the maximum size of a load module, and is used as + * a sanity check when loading + */ + +#ifndef TCL_LOADMAX +#define TCL_LOADMAX 2000000L +#endif + +/* + * Kernel calls that appear to be missing from the system .h files: + */ + +extern char * brk _ANSI_ARGS_((char *)); +extern char * sbrk _ANSI_ARGS_((size_t)); + +/* + * The static variable SymbolTableFile contains the file name where the + * result of the last link was stored. The file is kept because doing so + * allows one load module to use the symbols defined in another. + */ + +static char * SymbolTableFile = NULL; + +/* + * Type of the dictionary function that begins each load module. + */ + +typedef Tcl_PackageInitProc * (* DictFn) _ANSI_ARGS_ ((CONST char * symbol)); + +/* + * Prototypes for procedures referenced only in this file: + */ + +static int FindLibraries _ANSI_ARGS_((Tcl_Interp * interp, Tcl_Obj * pathPtr, + Tcl_DString * buf)); +static void UnlinkSymbolTable _ANSI_ARGS_((void)); + +/* + *---------------------------------------------------------------------- + * + * TclpDlopen -- + * + * Dynamically loads a binary code file into memory and returns + * a handle to the new code. + * + * Results: + * A standard Tcl completion code. If an error occurs, an error + * message is left in the interp's result. + * + * Side effects: + * New code suddenly appears in memory. + * + * + * Bugs: + * This function does not attempt to handle the case where the + * BSS segment is not executable. It will therefore fail on + * Encore Multimax, Pyramid 90x, and similar machines. The + * reason is that the mprotect() kernel call, which would + * otherwise be employed to mark the newly-loaded text segment + * executable, results in a system crash on BSD/386. + * + * In an effort to make it fast, this function eschews the + * technique of linking the load module once, reading its header + * to determine its size, allocating memory for it, and linking + * it again. Instead, it `shims out' memory allocation by + * placing the module TCL_LOADSHIM bytes beyond the break, + * and assuming that any malloc() calls required to run the + * linker will not advance the break beyond that point. If + * the break is advanced beyonnd that point, the load will + * fail with an `inconsistent memory allocation' error. + * It perhaps ought to retry the link, but the failure has + * not been observed in two years of daily use of this function. + *---------------------------------------------------------------------- + */ + +int +TclpDlopen(interp, pathPtr, loadHandle, unloadProcPtr) + Tcl_Interp *interp; /* Used for error reporting. */ + Tcl_Obj *pathPtr; /* Name of the file containing the desired + * code (UTF-8). */ + Tcl_LoadHandle *loadHandle; /* Filled with token for dynamically loaded + * file which will be passed back to + * (*unloadProcPtr)() to unload the file. */ + Tcl_FSUnloadFileProc **unloadProcPtr; + /* Filled with address of Tcl_FSUnloadFileProc + * function which should be used for + * this file. */ +{ + char * inputSymbolTable; /* Name of the file containing the + * symbol table from the last link. */ + Tcl_DString linkCommandBuf; /* Command to do the run-time relocation + * of the module.*/ + char * linkCommand; + char relocatedFileName [L_tmpnam]; + /* Name of the file holding the relocated */ + /* text of the module */ + int relocatedFd; /* File descriptor of the file holding + * relocated text */ + struct exec relocatedHead; /* Header of the relocated text */ + unsigned long relocatedSize;/* Size of the relocated text */ + char * startAddress; /* Starting address of the module */ + int status; /* Status return from Tcl_ calls */ + char * p; + + /* Find the file that contains the symbols for the run-time link. */ + + if (SymbolTableFile != NULL) { + inputSymbolTable = SymbolTableFile; + } else if (tclExecutableName == NULL) { + Tcl_SetResult (interp, "can't find the tclsh executable", TCL_STATIC); + return TCL_ERROR; + } else { + inputSymbolTable = tclExecutableName; + } + + /* Construct the `ld' command that builds the relocated module */ + + tmpnam (relocatedFileName); + Tcl_DStringInit (&linkCommandBuf); + Tcl_DStringAppend (&linkCommandBuf, "exec ld -o ", -1); + Tcl_DStringAppend (&linkCommandBuf, relocatedFileName, -1); +#if defined(__mips) || defined(mips) + Tcl_DStringAppend (&linkCommandBuf, " -G 0 ", -1); +#endif + Tcl_DStringAppend (&linkCommandBuf, " -u TclLoadDictionary_", -1); + TclGuessPackageName(Tcl_GetString(pathPtr), &linkCommandBuf); + Tcl_DStringAppend (&linkCommandBuf, " -A ", -1); + Tcl_DStringAppend (&linkCommandBuf, inputSymbolTable, -1); + Tcl_DStringAppend (&linkCommandBuf, " -N -T XXXXXXXX ", -1); + Tcl_DStringAppend (&linkCommandBuf, Tcl_GetString(pathPtr), -1); + Tcl_DStringAppend (&linkCommandBuf, " ", -1); + + if (FindLibraries (interp, pathPtr, &linkCommandBuf) != TCL_OK) { + Tcl_DStringFree (&linkCommandBuf); + return TCL_ERROR; + } + + linkCommand = Tcl_DStringValue (&linkCommandBuf); + + /* Determine the starting address, and plug it into the command */ + + startAddress = (char *) (((unsigned long) sbrk (0) + + TCL_LOADSHIM + TCL_LOADALIGN - 1) + & (- TCL_LOADALIGN)); + p = strstr (linkCommand, "-T") + 3; + sprintf (p, "%08lx", (long) startAddress); + p [8] = ' '; + + /* Run the linker */ + + status = Tcl_Eval (interp, linkCommand); + Tcl_DStringFree (&linkCommandBuf); + if (status != 0) { + return TCL_ERROR; + } + + /* Open the linker's result file and read the header */ + + relocatedFd = open (relocatedFileName, O_RDONLY); + if (relocatedFd < 0) { + goto ioError; + } + status= read (relocatedFd, (char *) & relocatedHead, sizeof relocatedHead); + if (status < sizeof relocatedHead) { + goto ioError; + } + + /* Check the magic number */ + + if (relocatedHead.a_magic != OMAGIC) { + Tcl_AppendResult (interp, "bad magic number in intermediate file \"", + relocatedFileName, "\"", (char *) NULL); + goto failure; + } + + /* Make sure that memory allocation is still consistent */ + + if ((unsigned long) sbrk (0) > (unsigned long) startAddress) { + Tcl_SetResult (interp, "can't load, memory allocation is inconsistent.", + TCL_STATIC); + goto failure; + } + + /* Make sure that the relocated module's size is reasonable */ + + relocatedSize = relocatedHead.a_text + relocatedHead.a_data + + relocatedHead.a_bss; + if (relocatedSize > TCL_LOADMAX) { + Tcl_SetResult (interp, "module too big to load", TCL_STATIC); + goto failure; + } + + /* Advance the break to protect the loaded module */ + + (void) brk (startAddress + relocatedSize); + + /* + * Seek to the start of the module's text. + * + * Note that this does not really work with large files (i.e. where + * lseek64 exists and is different to lseek), but anyone trying to + * dynamically load a binary that is larger than what can fit in + * addressable memory is in trouble anyway... + */ + +#if defined(__mips) || defined(mips) + status = lseek (relocatedFd, + (off_t) N_TXTOFF (relocatedHead.ex_f, relocatedHead.ex_o), + SEEK_SET); +#else + status = lseek (relocatedFd, (off_t) N_TXTOFF (relocatedHead), SEEK_SET); +#endif + if (status < 0) { + goto ioError; + } + + /* Read in the module's text and data */ + + relocatedSize = relocatedHead.a_text + relocatedHead.a_data; + if (read (relocatedFd, startAddress, relocatedSize) < relocatedSize) { + brk (startAddress); + ioError: + Tcl_AppendResult (interp, "error on intermediate file \"", + relocatedFileName, "\": ", Tcl_PosixError (interp), + (char *) NULL); + failure: + (void) unlink (relocatedFileName); + return TCL_ERROR; + } + + /* Close the intermediate file. */ + + (void) close (relocatedFd); + + /* Arrange things so that intermediate symbol tables eventually get + * deleted. */ + + if (SymbolTableFile != NULL) { + UnlinkSymbolTable (); + } else { + atexit (UnlinkSymbolTable); + } + SymbolTableFile = ckalloc (strlen (relocatedFileName) + 1); + strcpy (SymbolTableFile, relocatedFileName); + + *loadHandle = startAddress; + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclpFindSymbol -- + * + * Looks up a symbol, by name, through a handle associated with + * a previously loaded piece of code (shared library). + * + * Results: + * Returns a pointer to the function associated with 'symbol' if + * it is found. Otherwise returns NULL and may leave an error + * message in the interp's result. + * + *---------------------------------------------------------------------- + */ +Tcl_PackageInitProc* +TclpFindSymbol(interp, loadHandle, symbol) + Tcl_Interp *interp; + Tcl_LoadHandle loadHandle; + CONST char *symbol; +{ + /* Look up the entry point in the load module's dictionary. */ + DictFn dictionary = (DictFn) loadHandle; + return (Tcl_PackageInitProc*) dictionary(sym1); +} + + +/* + *------------------------------------------------------------------------ + * + * FindLibraries -- + * + * Find the libraries needed to link a load module at run time. + * + * Results: + * A standard Tcl completion code. If an error occurs, + * an error message is left in the interp's result. The -l and -L + * flags are concatenated onto the dynamic string `buf'. + * + *------------------------------------------------------------------------ + */ + +static int +FindLibraries (interp, pathPtr, buf) + Tcl_Interp * interp; /* Used for error reporting */ + Tcl_Obj * pathPtr; /* Name of the load module */ + Tcl_DString * buf; /* Buffer where the -l an -L flags */ +{ + FILE * f; /* The load module */ + int c = 0; /* Byte from the load module */ + char * p; + CONST char *native; + + char *fileName = Tcl_GetString(pathPtr); + + /* Open the load module */ + + native = Tcl_FSGetNativePath(pathPtr); + f = fopen(native, "rb"); /* INTL: Native. */ + + if (f == NULL) { + Tcl_AppendResult (interp, "couldn't open \"", fileName, "\": ", + Tcl_PosixError (interp), (char *) NULL); + return TCL_ERROR; + } + + /* Search for the library list in the load module */ + + p = "@LIBS: "; + while (*p != '\0' && (c = getc (f)) != EOF) { + if (c == *p) { + ++p; + } + else { + p = "@LIBS: "; + if (c == *p) { + ++p; + } + } + } + + /* No library list -- this must be an ill-formed module */ + + if (c == EOF) { + Tcl_AppendResult (interp, "File \"", fileName, + "\" is not a Tcl load module.", (char *) NULL); + (void) fclose (f); + return TCL_ERROR; + } + + /* Accumulate the library list */ + + while ((c = getc (f)) != '\0' && c != EOF) { + char cc = c; + Tcl_DStringAppend (buf, &cc, 1); + } + (void) fclose (f); + + if (c == EOF) { + Tcl_AppendResult (interp, "Library directory in \"", fileName, + "\" ends prematurely.", (char *) NULL); + return TCL_ERROR; + } + + return TCL_OK; +} + +/* + *------------------------------------------------------------------------ + * + * UnlinkSymbolTable -- + * + * Remove the symbol table file from the last dynamic link. + * + * Results: + * None. + * + * Side effects: + * The symbol table file from the last dynamic link is removed. + * This function is called when (a) a new symbol table is present + * because another dynamic link is complete, or (b) the process + * is exiting. + *------------------------------------------------------------------------ + */ + +static void +UnlinkSymbolTable () +{ + (void) unlink (SymbolTableFile); + ckfree (SymbolTableFile); + SymbolTableFile = NULL; +} + +/* + *---------------------------------------------------------------------- + * + * TclpUnloadFile -- + * + * Unloads a dynamically loaded binary code file from memory. + * Code pointers in the formerly loaded file are no longer valid + * after calling this function. + * + * Results: + * None. + * + * Side effects: + * Does nothing. Can anything be done? + * + *---------------------------------------------------------------------- + */ + +void +TclpUnloadFile(loadHandle) + Tcl_LoadHandle loadHandle; /* loadHandle returned by a previous call + * to TclpDlopen(). The loadHandle is + * a token that represents the loaded + * file. */ +{ +} + +/* + *---------------------------------------------------------------------- + * + * TclGuessPackageName -- + * + * If the "load" command is invoked without providing a package + * name, this procedure is invoked to try to figure it out. + * + * Results: + * Always returns 0 to indicate that we couldn't figure out a + * package name; generic code will then try to guess the package + * from the file name. A return value of 1 would have meant that + * we figured out the package name and put it in bufPtr. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TclGuessPackageName(fileName, bufPtr) + CONST char *fileName; /* Name of file containing package (already + * translated to local form if needed). */ + Tcl_DString *bufPtr; /* Initialized empty dstring. Append + * package name to this if possible. */ +{ + CONST char *p, *q; + char *r; + + if ((q = strrchr(fileName,'/'))) { + q++; + } else { + q = fileName; + } + if (!strncmp(q,"lib",3)) { + q+=3; + } + p = q; + while ((*p) && (*p != '.') && ((*p<'0') || (*p>'9'))) { + p++; + } + if ((p>q+2) && !strncmp(p-2,"_G0.",4)) { + p-=2; + } + if (p<q) { + return 0; + } + + Tcl_DStringAppend(bufPtr,q, p-q); + + r = Tcl_DStringValue(bufPtr); + r += strlen(r) - (p-q); + + /* + * Capitalize the string and then recompute the length. + */ + + Tcl_UtfToTitle(r); + Tcl_DStringSetLength(bufPtr, strlen(Tcl_DStringValue(bufPtr))); + + return 1; +} diff --git a/unix/tclLoadDld.c b/unix/tclLoadDld.c new file mode 100644 index 0000000..fe2f8fc --- /dev/null +++ b/unix/tclLoadDld.c @@ -0,0 +1,209 @@ +/* + * tclLoadDld.c -- + * + * This procedure provides a version of the TclLoadFile that works with + * the "dld_link" and "dld_get_func" library procedures for dynamic + * loading. It has been tested on Linux 1.1.95 and dld-3.2.7. This file + * probably isn't needed anymore, since it makes more sense to use + * "dl_open" etc. + * + * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclLoadDld.c,v 1.13 2005/07/19 13:37:18 dkf Exp $ + */ + +#include "tclInt.h" +#include "dld.h" + +/* + * In some systems, like SunOS 4.1.3, the RTLD_NOW flag isn't defined and this + * argument to dlopen must always be 1. + */ + +#ifndef RTLD_NOW +# define RTLD_NOW 1 +#endif + +/* + *---------------------------------------------------------------------- + * + * TclpDlopen -- + * + * Dynamically loads a binary code file into memory and returns a handle + * to the new code. + * + * Results: + * A standard Tcl completion code. If an error occurs, an error message + * is left in the interp's result. + * + * Side effects: + * New code suddenly appears in memory. + * + *---------------------------------------------------------------------- + */ + +int +TclpDlopen(interp, pathPtr, loadHandle, unloadProcPtr) + Tcl_Interp *interp; /* Used for error reporting. */ + Tcl_Obj *pathPtr; /* Name of the file containing the desired + * code (UTF-8). */ + Tcl_LoadHandle *loadHandle; /* Filled with token for dynamically loaded + * file which will be passed back to + * (*unloadProcPtr)() to unload the file. */ + Tcl_FSUnloadFileProc **unloadProcPtr; + /* Filled with address of Tcl_FSUnloadFileProc + * function which should be used for this + * file. */ +{ + static int firstTime = 1; + int returnCode; + char *fileName; + CONST char *native; + + /* + * The dld package needs to know the pathname to the tcl binary. If + * that's not known, return an error. + */ + + if (firstTime) { + if (tclExecutableName == NULL) { + Tcl_SetResult(interp, + "don't know name of application binary file, so can't initialize dynamic loader", + TCL_STATIC); + return TCL_ERROR; + } + returnCode = dld_init(tclExecutableName); + if (returnCode != 0) { + Tcl_AppendResult(interp, + "initialization failed for dynamic loader: ", + dld_strerror(returnCode), (char *) NULL); + return TCL_ERROR; + } + firstTime = 0; + } + + fileName = Tcl_GetString(pathPtr); + + /* + * First try the full path the user gave us. This is particularly + * important if the cwd is inside a vfs, and we are trying to load using a + * relative path. + */ + + native = Tcl_FSGetNativePath(pathPtr); + returnCode = dld_link(native); + + if (returnCode != 0) { + Tcl_DString ds; + native = Tcl_UtfToExternalDString(NULL, fileName, -1, &ds); + returnCode = dld_link(native); + Tcl_DStringFree(&ds); + } + + if (returnCode != 0) { + Tcl_AppendResult(interp, "couldn't load file \"", fileName, "\": ", + dld_strerror(returnCode), (char *) NULL); + return TCL_ERROR; + } + *loadHandle = (Tcl_LoadHandle) strcpy( + (char *) ckalloc((unsigned) (strlen(fileName) + 1)), fileName); + *unloadProcPtr = &TclpUnloadFile; + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclpFindSymbol -- + * + * Looks up a symbol, by name, through a handle associated with a + * previously loaded piece of code (shared library). + * + * Results: + * Returns a pointer to the function associated with 'symbol' if it is + * found. Otherwise returns NULL and may leave an error message in the + * interp's result. + * + *---------------------------------------------------------------------- + */ + +Tcl_PackageInitProc* +TclpFindSymbol(interp, loadHandle, symbol) + Tcl_Interp *interp; + Tcl_LoadHandle loadHandle; + CONST char *symbol; +{ + return (Tcl_PackageInitProc *) dld_get_func(symbol); +} + +/* + *---------------------------------------------------------------------- + * + * TclpUnloadFile -- + * + * Unloads a dynamically loaded binary code file from memory. Code + * pointers in the formerly loaded file are no longer valid after calling + * this function. + * + * Results: + * None. + * + * Side effects: + * Code removed from memory. + * + *---------------------------------------------------------------------- + */ + +void +TclpUnloadFile(loadHandle) + Tcl_LoadHandle loadHandle; /* loadHandle returned by a previous call to + * TclpDlopen(). The loadHandle is a token + * that represents the loaded file. */ +{ + char *fileName; + + handle = (char *) loadHandle; + dld_unlink_by_file(handle, 0); + ckfree(handle); +} + +/* + *---------------------------------------------------------------------- + * + * TclGuessPackageName -- + * + * If the "load" command is invoked without providing a package name, + * this procedure is invoked to try to figure it out. + * + * Results: + * Always returns 0 to indicate that we couldn't figure out a package + * name; generic code will then try to guess the package from the file + * name. A return value of 1 would have meant that we figured out the + * package name and put it in bufPtr. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TclGuessPackageName(fileName, bufPtr) + CONST char *fileName; /* Name of file containing package (already + * translated to local form if needed). */ + Tcl_DString *bufPtr; /* Initialized empty dstring. Append package + * name to this if possible. */ +{ + return 0; +} + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/win/README.binary b/win/README.binary new file mode 100644 index 0000000..c5d1285 --- /dev/null +++ b/win/README.binary @@ -0,0 +1,143 @@ +Tcl/Tk 8.5 for Windows, Binary Distribution + +RCS: @(#) $Id: README.binary,v 1.43 2006/10/23 19:42:19 dgp Exp $ + +1. Introduction +--------------- + +This directory contains the binary distribution of Tcl/Tk 8.5a6 for +Windows. It was compiled with Microsoft Visual C++ 6.0 using Win32 +API, so that it will run under Windows 98, NT, 2000 and XP. + +Tcl provides a powerful platform for creating integration applications +that tie together diverse applications, protocols, devices, and +frameworks. When paired with the Tk toolkit, Tcl provides the fastest +and most powerful way to create GUI applications that run on PCs, Unix, +and Mac OS X. Tcl can also be used for a variety of web-related +tasks and for creating powerful command languages for applications. + +Tcl is maintained, enhanced, and distributed freely by the Tcl community. + +2. Documentation +---------------- + +The home of Tcl and Tk sources and bug database on the Web is at: + http://tcl.sourceforge.net/ + +The home page for the Tcl Developer Xchange is at: + http://www.tcl.tk/ + +The home page for the Tcl/Tk 8.5 release is + http://www.tcl.tk/software/tcltk/8.5.html + +Detailed release notes can be found at the file distributions page +by clicking on the relevant version. + http://sourceforge.net/project/showfiles.php?group_id=10894 + +Information about Tcl itself can be found at + http://www.tcl.tk/scripting/ + +There are many Tcl books on the market. Most are listed at + http://www.tcl.tk/resource/doc/books/ + +There are notes about compiling Tcl at + http://www.tcl.tk/doc/howto/compile.html + +3. Installation +--------------- + +The binary release is distributed as a self-extracting archive called +tcl<version>.exe. The setup program which will prompt you for an +installation directory. It will create the installation heirarchy +under the specified directory, and install a wish application icon +under the program manager group of your choice. + +We are no longer supporting use of Tcl with 16-bit versions of +Windows. Microsoft has completely dropped support of the Win32s +subsystem. + +4. Linking against the binary release +-------------------------------------- + +In order to link your applications against the .dll files shipped with +this release, you will need to use the appropriate .lib file for your +compiler. In the lib directory of the installation directory, there +are library files for the Microsoft Visual C++ compiler: + + tcl85.lib + tk85.lib + +5. Building dynamically loadable extensions +-------------------------------------------- + +Please refer to the example dynamically loadable extension provided on +our ftp site: + + ftp://ftp.scriptics.com/pub/tcl/misc/example.zip + +This archive contains a template that you can use for building +extensions that will be loadable on Unix, Windows, and Mac OS X +systems. + +6. Reporting Bugs +----------------- +If you have comments or bug reports for the Windows version of Tcl, +please use our online database at: + + http://tcl.sourceforge.net/ + +or post them to the newsgroup comp.lang.tcl. + +7. Tcl newsgroup +----------------- + +There is a network news group "comp.lang.tcl" intended for the exchange +of information about Tcl, Tk, and related applications. Feel free to use +the newsgroup both for general information questions and for bug reports. +We read the newsgroup and will attempt to fix bugs and problems reported +to it. + +When using comp.lang.tcl, please be sure that your e-mail return address +is correctly set in your postings. This allows people to respond directly +to you, rather than the entire newsgroup, for answers that are not of +general interest. A bad e-mail return address may prevent you from +getting answers to your questions. You may have to reconfigure your news +reading software to ensure that it is supplying valid e-mail addresses. + +8. Tcl contributed archive +-------------------------- + +Many people have created exciting packages and applications based on Tcl +and/or Tk and made them freely available to the Tcl community. An archive +of these contributions is kept on the machine ftp.neosoft.com. You +can access the archive using anonymous FTP; the Tcl contributed archive is +in the directory "/pub/tcl". The archive also contains several FAQ +("frequently asked questions") documents that provide solutions to problems +that are commonly encountered by TCL newcomers. + +9. Tcl Resource Center +---------------------- + +Visit http://www.tcl.tk/resource/ to see an annotated index of +many Tcl resources available on the World Wide Web. This includes papers, +books, and FAQs, as well as extensions, applications, binary releases, and +patches. You can contribute patches by using the Tracker at + + http://tcl.sourceforge.net/ + +You can also recommend more URLs for the resource center using the forms +labeled "Add a Resource". + +10. Mailing lists +---------------- + +Several mailing lists are hosted at SourceForge to discuss development or +use issues (like Macintosh and Windows topics). For more information and +to subscribe, visit: + + http://sourceforge.net/projects/tcl/ + +and go to the Mailing Lists page. There are also Special Interest Groups +(SIGs) setup for these topics and more at: + + http://www.tcl.tk/ diff --git a/win/stub16.c b/win/stub16.c new file mode 100644 index 0000000..52460c3 --- /dev/null +++ b/win/stub16.c @@ -0,0 +1,197 @@ +/* + * stub16.c + * + * A helper program used for running 16-bit DOS applications under + * Windows 95. + * + * Copyright (c) 1996 by Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: stub16.c,v 1.6 2010/03/20 12:00:41 nijtmans Exp $ + */ + +#define STRICT + +#include <windows.h> +#include <stdio.h> + +static HANDLE CreateTempFile(void); + +/* + *--------------------------------------------------------------------------- + * + * main + * + * Entry point for the 32-bit console mode app used by Windows 95 to help + * run the 16-bit program specified on the command line. + * + * 1. EOF on a pipe that connects a detached 16-bit process and a 32-bit + * process is never seen. So, this process runs the 16-bit process + * _attached_, and then it is run detached from the calling 32-bit + * process. + * + * 2. If a 16-bit process blocks reading from or writing to a pipe, it + * never wakes up, and eventually brings the whole system down with it if + * you try to kill the process. This app simulates pipes. If any of the + * stdio handles is a pipe, this program accumulates information into + * temp files and forwards it to or from the DOS application as + * appropriate. This means that this program must receive EOF from a + * stdin pipe before it will actually start the DOS app, and the DOS app + * must finish generating stdout or stderr before the data will be sent + * to the next stage of the pipe. If the stdio handles are not pipes, no + * accumulation occurs and the data is passed straight through to and + * from the DOS application. + * + * Results: + * None. + * + * Side effects: + * The child process is created and this process waits for it to + * complete. + * + *--------------------------------------------------------------------------- + */ + +int +main(void) +{ + DWORD dwRead, dwWrite; + char *cmdLine; + HANDLE hStdInput, hStdOutput, hStdError; + HANDLE hFileInput, hFileOutput, hFileError; + STARTUPINFOA si; + PROCESS_INFORMATION pi; + char buf[8192]; + DWORD result; + + hFileInput = INVALID_HANDLE_VALUE; + hFileOutput = INVALID_HANDLE_VALUE; + hFileError = INVALID_HANDLE_VALUE; + result = 1; + + /* + * Don't get command line from argc, argv, because the command line + * tokenizer will have stripped off all the escape sequences needed for + * quotes and backslashes, and then we'd have to put them all back in + * again. Get the raw command line and parse off what we want ourselves. + * The command line should be of the form: + * + * stub16.exe program arg1 arg2 ... + */ + + cmdLine = strchr(GetCommandLineA(), ' '); + if (cmdLine == NULL) { + return 1; + } + cmdLine++; + + hStdInput = GetStdHandle(STD_INPUT_HANDLE); + hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); + hStdError = GetStdHandle(STD_ERROR_HANDLE); + + if (GetFileType(hStdInput) == FILE_TYPE_PIPE) { + hFileInput = CreateTempFile(); + if (hFileInput == INVALID_HANDLE_VALUE) { + goto cleanup; + } + while (ReadFile(hStdInput, buf, sizeof(buf), &dwRead, NULL) != FALSE) { + if (dwRead == 0) { + break; + } + if (WriteFile(hFileInput, buf, dwRead, &dwWrite, NULL) == FALSE) { + goto cleanup; + } + } + SetFilePointer(hFileInput, 0, 0, FILE_BEGIN); + SetStdHandle(STD_INPUT_HANDLE, hFileInput); + } + if (GetFileType(hStdOutput) == FILE_TYPE_PIPE) { + hFileOutput = CreateTempFile(); + if (hFileOutput == INVALID_HANDLE_VALUE) { + goto cleanup; + } + SetStdHandle(STD_OUTPUT_HANDLE, hFileOutput); + } + if (GetFileType(hStdError) == FILE_TYPE_PIPE) { + hFileError = CreateTempFile(); + if (hFileError == INVALID_HANDLE_VALUE) { + goto cleanup; + } + SetStdHandle(STD_ERROR_HANDLE, hFileError); + } + + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + if (CreateProcessA(NULL, cmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, + &pi) == FALSE) { + goto cleanup; + } + + WaitForInputIdle(pi.hProcess, 5000); + WaitForSingleObject(pi.hProcess, INFINITE); + GetExitCodeProcess(pi.hProcess, &result); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + + if (hFileOutput != INVALID_HANDLE_VALUE) { + SetFilePointer(hFileOutput, 0, 0, FILE_BEGIN); + while (ReadFile(hFileOutput, buf, sizeof(buf), &dwRead, NULL) != FALSE) { + if (dwRead == 0) { + break; + } + if (WriteFile(hStdOutput, buf, dwRead, &dwWrite, NULL) == FALSE) { + break; + } + } + } + if (hFileError != INVALID_HANDLE_VALUE) { + SetFilePointer(hFileError, 0, 0, FILE_BEGIN); + while (ReadFile(hFileError, buf, sizeof(buf), &dwRead, NULL) != FALSE) { + if (dwRead == 0) { + break; + } + if (WriteFile(hStdError, buf, dwRead, &dwWrite, NULL) == FALSE) { + break; + } + } + } + + cleanup: + if (hFileInput != INVALID_HANDLE_VALUE) { + CloseHandle(hFileInput); + } + if (hFileOutput != INVALID_HANDLE_VALUE) { + CloseHandle(hFileOutput); + } + if (hFileError != INVALID_HANDLE_VALUE) { + CloseHandle(hFileError); + } + CloseHandle(hStdInput); + CloseHandle(hStdOutput); + CloseHandle(hStdError); + ExitProcess(result); + return 1; +} + +static HANDLE +CreateTempFile(void) +{ + char name[MAX_PATH]; + SECURITY_ATTRIBUTES sa; + + if (GetTempPathA(MAX_PATH, name) == 0) { + return INVALID_HANDLE_VALUE; + } + if (GetTempFileNameA(name, "tcl", 0, name) == 0) { + return INVALID_HANDLE_VALUE; + } + + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = TRUE; + return CreateFileA(name, GENERIC_READ | GENERIC_WRITE, 0, &sa, + CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, + NULL); +} diff --git a/win/tclWinMtherr.c b/win/tclWinMtherr.c new file mode 100644 index 0000000..b90c0f2 --- /dev/null +++ b/win/tclWinMtherr.c @@ -0,0 +1,53 @@ +/* + * tclWinMtherr.c -- + * + * This function provides a default implementation of the + * _matherr function for Borland C++. + * + * Copyright (c) 1995 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id: tclWinMtherr.c,v 1.5 2002/05/31 22:20:22 dgp Exp $ + */ + +#include "tclWinInt.h" +#include <math.h> + + +/* + *---------------------------------------------------------------------- + * + * _matherr -- + * + * This procedure is invoked by Borland C++ when certain + * errors occur in mathematical functions. This procedure + * replaces the default implementation which generates pop-up + * warnings. + * + * Results: + * Returns 1 to indicate that we've handled the error + * locally. + * + * Side effects: + * Sets errno based on what's in xPtr. + * + *---------------------------------------------------------------------- + */ + +int +_matherr(xPtr) + struct exception *xPtr; /* Describes error that occurred. */ +{ + if ((xPtr->type == DOMAIN) +#ifdef __BORLANDC__ + || (xPtr->type == TLOSS) +#endif + || (xPtr->type == SING)) { + errno = EDOM; + } else { + errno = ERANGE; + } + return 1; +} diff --git a/win/tclWinThrd.h b/win/tclWinThrd.h new file mode 100644 index 0000000..2572d1b --- /dev/null +++ b/win/tclWinThrd.h @@ -0,0 +1,21 @@ +/* + * tclWinThrd.h -- + * + * This header file defines things for thread support. + * + * Copyright (c) 1998 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * SCCS: @(#) tclWinThrd.h 1.2 98/01/27 11:48:05 + */ + +#ifndef _TCLWINTHRD +#define _TCLWINTHRD + +#ifdef TCL_THREADS + +#endif /* TCL_THREADS */ + +#endif /* _TCLWINTHRD */ |