diff options
Diffstat (limited to 'mac')
56 files changed, 0 insertions, 28913 deletions
diff --git a/mac/AppleScript.html b/mac/AppleScript.html deleted file mode 100644 index 4a73fbb..0000000 --- a/mac/AppleScript.html +++ /dev/null @@ -1,298 +0,0 @@ -<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 delete </B><I>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>delete </B><I>scriptName</I> - <BR> - <DD> - This deletes the script data compiled into the script scriptName, - and frees up all the resources associated with it. - <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 deleted file mode 100644 index d23235a..0000000 --- a/mac/Background.doc +++ /dev/null @@ -1,92 +0,0 @@ -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 deleted file mode 100755 index 6ce3853..0000000 --- a/mac/MW_TclAppleScriptHeader.h +++ /dev/null @@ -1,7 +0,0 @@ -#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 deleted file mode 100644 index 12fec3f..0000000 --- a/mac/MW_TclAppleScriptHeader.pch +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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 deleted file mode 100644 index f6a6f61..0000000 --- a/mac/MW_TclBuildLibHeader.h +++ /dev/null @@ -1,7 +0,0 @@ -#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 deleted file mode 100644 index a727451..0000000 --- a/mac/MW_TclBuildLibHeader.pch +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 deleted file mode 100755 index 43a9029..0000000 --- a/mac/MW_TclHeader.h +++ /dev/null @@ -1,7 +0,0 @@ -#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 deleted file mode 100644 index 14bf41a..0000000 --- a/mac/MW_TclHeader.pch +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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 deleted file mode 100644 index 56ea59c..0000000 --- a/mac/MW_TclHeaderCommon.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 deleted file mode 100644 index 0c1abc2..0000000 --- a/mac/MW_TclStaticHeader.h +++ /dev/null @@ -1,7 +0,0 @@ -#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 deleted file mode 100644 index f23021f..0000000 --- a/mac/MW_TclStaticHeader.pch +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 deleted file mode 100755 index c47bb97..0000000 --- a/mac/MW_TclTestHeader.h +++ /dev/null @@ -1,7 +0,0 @@ -#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 deleted file mode 100755 index dbb297a..0000000 --- a/mac/MW_TclTestHeader.pch +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 deleted file mode 100644 index 7cf0c81..0000000 --- a/mac/README +++ /dev/null @@ -1,69 +0,0 @@ -Tcl 8.4 for Macintosh - -RCS: @(#) $Id: README,v 1.16 2001/08/07 02:44:40 hobbs 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.purl.org/tcl/home/software/mac/ - -A summary of what's new in this release is at - http://www.purl.org/tcl/home/software/tcltk/8.4.html - -A summary of Macintosh-specific features is at - http://www.purl.org/tcl/home/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.purl.org/tcl/home/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.purl.org/tcl/home/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 deleted file mode 100644 index 730f115..0000000 --- a/mac/bugs.doc +++ /dev/null @@ -1,44 +0,0 @@ -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 deleted file mode 100644 index 2183651..0000000 --- a/mac/libmoto.doc +++ /dev/null @@ -1,39 +0,0 @@ -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 deleted file mode 100644 index 58f0929..0000000 --- a/mac/morefiles.doc +++ /dev/null @@ -1,74 +0,0 @@ -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 deleted file mode 100644 index 5e71969..0000000 --- a/mac/porting.notes +++ /dev/null @@ -1,23 +0,0 @@ -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 deleted file mode 100644 index b937342..0000000 --- a/mac/tclMac.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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 deleted file mode 100644 index be9dd11..0000000 --- a/mac/tclMacAETE.r +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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 deleted file mode 100644 index 3e6a948..0000000 --- a/mac/tclMacAlloc.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * 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 deleted file mode 100644 index 65f79e8..0000000 --- a/mac/tclMacAppInit.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * 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 deleted file mode 100644 index b848da1..0000000 --- a/mac/tclMacApplication.r +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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.5 2001/12/27 22:46:15 das Exp $ - */ - -#include <Types.r> -#include <SysTypes.r> - -/* - * The folowing include and defines help construct - * the version string for Tcl. - */ - -#define RESOURCE_INCLUDED -#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 deleted file mode 100644 index 0f7687b..0000000 --- a/mac/tclMacBOAAppInit.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * 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 deleted file mode 100644 index ff1a943..0000000 --- a/mac/tclMacBOAMain.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * 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 deleted file mode 100644 index 6b83e2f..0000000 --- a/mac/tclMacChan.c +++ /dev/null @@ -1,1389 +0,0 @@ -/* - * 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.13 2002/02/15 14:28:49 dkf 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> - - -/* - * The following are flags returned by GetOpenMode. They - * are or'd together to determine how opening and handling - * a file should occur. - */ - -#define TCL_RDONLY (1<<0) -#define TCL_WRONLY (1<<1) -#define TCL_RDWR (1<<2) -#define TCL_CREAT (1<<3) -#define TCL_TRUNC (1<<4) -#define TCL_APPEND (1<<5) -#define TCL_ALWAYS_APPEND (1<<6) -#define TCL_EXCL (1<<7) -#define TCL_NOCTTY (1<<8) -#define TCL_NONBLOCK (1<<9) -#define TCL_RW_MODES (TCL_RDONLY|TCL_WRONLY|TCL_RDWR) - -/* - * 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 Tcl_WideInt FileSeek _ANSI_ARGS_((ClientData instanceData, - Tcl_WideInt offset, int mode, int *errorCode)); -static void FileSetupProc _ANSI_ARGS_((ClientData clientData, - int flags)); -static int GetOpenMode _ANSI_ARGS_((Tcl_Interp *interp, - CONST char *string)); -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 Tcl_WideInt StdIOSeek _ANSI_ARGS_((ClientData instanceData, - Tcl_WideInt 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 (!TclInExit()) { - if (fd == 0) { - tsdPtr->stdinChannel = NULL; - } else if (fd == 1) { - tsdPtr->stdoutChannel = NULL; - } else if (fd == 2) { - tsdPtr->stderrChannel = NULL; - } else { - 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 Tcl_WideInt -StdIOSeek( - ClientData instanceData, /* Unused. */ - Tcl_WideInt 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: - 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 an File based channel on Unix 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. */ - CONST char *modeString, /* A list of POSIX open modes or - * a string such as "rw". */ - int permissions) /* If the open involves creating a - * file, with what modes to create - * it? */ -{ - Tcl_Channel chan; - int mode; - CONST char *native; - int errorCode; - - mode = GetOpenMode(interp, modeString); - if (mode == -1) { - return NULL; - } - - 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]; - - /* - * 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 & (TCL_RDONLY | TCL_WRONLY | TCL_RDWR)) { - case TCL_RDWR: - channelPermissions = (TCL_READABLE | TCL_WRITABLE); - macPermision = fsRdWrShPerm; - break; - case TCL_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 TCL_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 & TCL_CREAT)) { - err = HCreate(fileSpec.vRefNum, fileSpec.parID, fileSpec.name, 'MPW ', 'TEXT'); - if (err != noErr) { - *errorCodePtr = errno = TclMacOSErrorToPosixError(err); - Tcl_SetErrno(errno); - return NULL; - } - } else if ((mode & TCL_CREAT) && (mode & TCL_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 & TCL_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->volumeRef = fileSpec.vRefNum; - fileState->fileRef = fileRef; - fileState->pending = 0; - fileState->watchMask = 0; - if (mode & TCL_ALWAYS_APPEND) { - fileState->appendMode = true; - } else { - fileState->appendMode = false; - } - - if ((mode & TCL_ALWAYS_APPEND) || (mode & TCL_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); - 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 Tcl_WideInt -FileSeek( - ClientData instanceData, /* Unused. */ - Tcl_WideInt 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 **nextPtrPtr, *ptr; - FileState *infoPtr = (FileState *) instanceData; - int oldMask = infoPtr->watchMask; - ThreadSpecificData *tsdPtr; - - tsdPtr = FileInit(); - - infoPtr->watchMask = mask; - if (infoPtr->watchMask) { - if (!oldMask) { - infoPtr->nextPtr = tsdPtr->firstFilePtr; - tsdPtr->firstFilePtr = infoPtr; - } - } else { - if (oldMask) { - /* - * Remove the file from the list of watched files. - */ - - for (nextPtrPtr = &(tsdPtr->firstFilePtr), ptr = *nextPtrPtr; - ptr != NULL; - nextPtrPtr = &ptr->nextPtr, ptr = *nextPtrPtr) { - if (infoPtr == ptr) { - *nextPtrPtr = ptr->nextPtr; - break; - } - } - } - } -} - -/* - *---------------------------------------------------------------------- - * - * GetOpenMode -- - * - * Description: - * Computes a POSIX mode mask from a given string and also sets - * a flag to indicate whether the caller should seek to EOF during - * opening of the file. - * - * Results: - * On success, returns mode to pass to "open". If an error occurs, the - * returns -1 and if interp is not NULL, sets the interp's result to an - * error message. - * - * Side effects: - * Sets the integer referenced by seekFlagPtr to 1 if the caller - * should seek to EOF during opening the file. - * - * Special note: - * This code is based on a prototype implementation contributed - * by Mark Diekhans. - * - *---------------------------------------------------------------------- - */ - -static int -GetOpenMode( - Tcl_Interp *interp, /* Interpreter to use for error - * reporting - may be NULL. */ - CONST char *string) /* Mode string, e.g. "r+" or - * "RDONLY CREAT". */ -{ - int mode, modeArgc, c, i, gotRW; - CONST char **modeArgv, *flag; - - /* - * Check for the simpler fopen-like access modes (e.g. "r"). They - * are distinguished from the POSIX access modes by the presence - * of a lower-case first letter. - */ - - mode = 0; - /* - * Guard against international characters before using byte oriented - * routines. - */ - - if (!(string[0] & 0x80) - && islower(UCHAR(string[0]))) { /* INTL: ISO only. */ - switch (string[0]) { - case 'r': - mode = TCL_RDONLY; - break; - case 'w': - mode = TCL_WRONLY|TCL_CREAT|TCL_TRUNC; - break; - case 'a': - mode = TCL_WRONLY|TCL_CREAT|TCL_APPEND; - break; - default: - error: - if (interp != (Tcl_Interp *) NULL) { - Tcl_AppendResult(interp, - "illegal access mode \"", string, "\"", - (char *) NULL); - } - return -1; - } - if (string[1] == '+') { - mode &= ~(TCL_RDONLY|TCL_WRONLY); - mode |= TCL_RDWR; - if (string[2] != 0) { - goto error; - } - } else if (string[1] != 0) { - goto error; - } - return mode; - } - - /* - * The access modes are specified using a list of POSIX modes - * such as TCL_CREAT. - */ - - if (Tcl_SplitList(interp, string, &modeArgc, &modeArgv) != TCL_OK) { - if (interp != (Tcl_Interp *) NULL) { - Tcl_AddErrorInfo(interp, - "\n while processing open access modes \""); - Tcl_AddErrorInfo(interp, string); - Tcl_AddErrorInfo(interp, "\""); - } - return -1; - } - - gotRW = 0; - for (i = 0; i < modeArgc; i++) { - flag = modeArgv[i]; - c = flag[0]; - if ((c == 'R') && (strcmp(flag, "RDONLY") == 0)) { - mode = (mode & ~TCL_RW_MODES) | TCL_RDONLY; - gotRW = 1; - } else if ((c == 'W') && (strcmp(flag, "WRONLY") == 0)) { - mode = (mode & ~TCL_RW_MODES) | TCL_WRONLY; - gotRW = 1; - } else if ((c == 'R') && (strcmp(flag, "RDWR") == 0)) { - mode = (mode & ~TCL_RW_MODES) | TCL_RDWR; - gotRW = 1; - } else if ((c == 'A') && (strcmp(flag, "APPEND") == 0)) { - mode |= TCL_ALWAYS_APPEND; - } else if ((c == 'C') && (strcmp(flag, "CREAT") == 0)) { - mode |= TCL_CREAT; - } else if ((c == 'E') && (strcmp(flag, "EXCL") == 0)) { - mode |= TCL_EXCL; - } else if ((c == 'N') && (strcmp(flag, "NOCTTY") == 0)) { - mode |= TCL_NOCTTY; - } else if ((c == 'N') && (strcmp(flag, "NONBLOCK") == 0)) { - mode |= TCL_NONBLOCK; - } else if ((c == 'T') && (strcmp(flag, "TRUNC") == 0)) { - mode |= TCL_TRUNC; - } else { - if (interp != (Tcl_Interp *) NULL) { - Tcl_AppendResult(interp, "invalid access mode \"", flag, - "\": must be RDONLY, WRONLY, RDWR, APPEND, CREAT", - " EXCL, NOCTTY, NONBLOCK, or TRUNC", (char *) NULL); - } - ckfree((char *) modeArgv); - return -1; - } - } - ckfree((char *) modeArgv); - if (!gotRW) { - if (interp != (Tcl_Interp *) NULL) { - Tcl_AppendResult(interp, "access mode must include either", - " RDONLY, WRONLY, or RDWR", (char *) NULL); - } - return -1; - } - return mode; -} diff --git a/mac/tclMacCommonPch.h b/mac/tclMacCommonPch.h deleted file mode 100755 index c0deb9d..0000000 --- a/mac/tclMacCommonPch.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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 deleted file mode 100644 index fa7058b..0000000 --- a/mac/tclMacDNR.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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 deleted file mode 100644 index 8f6b58f..0000000 --- a/mac/tclMacEnv.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - * 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 deleted file mode 100644 index 347ff4e..0000000 --- a/mac/tclMacExit.c +++ /dev/null @@ -1,333 +0,0 @@ -/* - * 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 deleted file mode 100644 index 1a75ce7..0000000 --- a/mac/tclMacFCmd.c +++ /dev/null @@ -1,1703 +0,0 @@ -/* - * 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.16 2002/01/27 11:09:44 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> - -/* - * 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 - -/* - * Global variables for the file attributes code. - */ - -CONST char *tclpFileAttrStrings[] = {"-creator", "-hidden", "-readonly", - "-type", (char *) NULL}; -CONST TclFileAttrProcs tclpFileAttrProcs[] = { - {GetFileFinderAttributes, SetFileFinderAttributes}, - {GetFileFinderAttributes, SetFileFinderAttributes}, - {GetFileReadOnly, SetFileReadOnly}, - {GetFileFinderAttributes, SetFileFinderAttributes}}; - - -/* - * 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 DoDeleteFile _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 GenerateUniqueName _ANSI_ARGS_((short vRefNum, - long dirID1, long dirID2, Str31 uniqueName)); -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 = FSpLocationFromPath(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, - 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, - 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 = FSpLocationFromPath(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, 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, DoDeleteFile -- - * - * 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 DoDeleteFile(Tcl_FSGetNativePath(pathPtr)); -} - -static int -DoDeleteFile( - CONST char *path) /* Pathname of file to be removed (native). */ -{ - OSErr err; - FSSpec fileSpec; - Boolean isDirectory; - long dirID; - - err = FSpLocationFromPath(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, 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; -} - -/* - *--------------------------------------------------------------------------- - * - * GenerateUniqueName -- - * - * Generate a filename that is not in either of the two specified - * directories (on the same volume). - * - * Results: - * Standard macintosh error. On success, uniqueName is filled with - * the name of the temporary file. - * - * Side effects: - * None. - * - *--------------------------------------------------------------------------- - */ - -static OSErr -GenerateUniqueName( - short vRefNum, /* Volume on which the following directories - * are located. */ - long dirID1, /* ID of first directory. */ - long dirID2, /* ID of second directory. May be the same - * as the first. */ - Str31 uniqueName) /* Filled with filename for a file that is - * not located in either of the above two - * directories. */ -{ - OSErr err; - long i; - CInfoPBRec pb; - static unsigned char hexStr[16] = "0123456789ABCDEF"; - static long startSeed = 248923489; - - pb.hFileInfo.ioVRefNum = vRefNum; - pb.hFileInfo.ioFDirIndex = 0; - pb.hFileInfo.ioNamePtr = uniqueName; - - while (1) { - startSeed++; - pb.hFileInfo.ioNamePtr[0] = 8; - for (i = 1; i <= 8; i++) { - pb.hFileInfo.ioNamePtr[i] = hexStr[((startSeed >> ((8-i)*4)) & 0xf)]; - } - pb.hFileInfo.ioDirID = dirID1; - err = PBGetCatInfoSync(&pb); - if (err == fnfErr) { - if (dirID1 != dirID2) { - pb.hFileInfo.ioDirID = dirID2; - err = PBGetCatInfoSync(&pb); - } - if (err == fnfErr) { - return noErr; - } - } - if (err == noErr) { - continue; - } - return err; - } -} - -/* - *--------------------------------------------------------------------------- - * - * 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; - CONST char *native; - - native=Tcl_FSGetNativePath(fileName); - err = FSpLocationFromPath(strlen(native), - native, &fileSpec); - - if (err == noErr) { - err = FSpGetFInfo(&fileSpec, &finfo); - } - - 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; - } - } 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 { - *attributePtrPtr = Tcl_NewOSTypeObj('Fldr'); - } - } - } - - 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 = FSpLocationFromPath(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; - CONST char *native; - - native=Tcl_FSGetNativePath(fileName); - err = FSpLocationFromPath(strlen(native), - native, &fileSpec); - - if (err == noErr) { - err = FSpGetFInfo(&fileSpec, &finfo); - } - - 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; - } - 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 = FSpLocationFromPath(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; - FSSpec fileSpec; - - 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 = FSpLocationFromPath(Tcl_DStringLength(&nativeds), - Tcl_DStringValue(&nativeds), - &fileSpec); - Tcl_DStringFree(&nativeds); - 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 */ - 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; - } - nextCheckpoint++; - } - - /* - * 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 deleted file mode 100644 index fe26027..0000000 --- a/mac/tclMacFile.c +++ /dev/null @@ -1,1089 +0,0 @@ -/* - * 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.17 2002/02/15 14:28:49 dkf 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 <Errors.h> -#include <Processes.h> -#include <Strings.h> -#include <Types.h> -#include <MoreFiles.h> -#include <MoreFilesExtras.h> -#include <FSpCompat.h> - -static OSErr FspLocationFromFsPath _ANSI_ARGS_((Tcl_Obj *pathPtr, - FSSpec* specPtr)); - -static OSErr -FspLocationFromFsPath(pathPtr, specPtr) - Tcl_Obj *pathPtr; - FSSpec* specPtr; -{ - CONST char *native = Tcl_FSGetNativePath(pathPtr); - return FSpLocationFromPath(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. */ - Tcl_GlobTypeData *types; /* Object containing list of acceptable types. - * May be NULL. In particular the directory - * flag is very important. */ -{ - 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; - OSType okType = 0; - OSType okCreator = 0; - Tcl_DString dsOrig; - Tcl_Obj *fileNamePtr; - - fileNamePtr = Tcl_FSGetTranslatedPath(interp, pathPtr); - if (fileNamePtr == NULL) { - return TCL_ERROR; - } - 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); - 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; - - if (types != NULL) { - if (types->macType != NULL) { - Tcl_GetOSTypeFromObj(NULL, types->macType, &okType); - } - if (types->macCreator != NULL) { - Tcl_GetOSTypeFromObj(NULL, types->macCreator, &okCreator); - } - } - - 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)) { - int typeOk = 1; - 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); - - if (types == NULL) { - /* If invisible, don't return the file */ - if (pb.hFileInfo.ioFlFndrInfo.fdFlags & kIsInvisible) { - typeOk = 0; - } - } else { - Tcl_StatBuf buf; - - if (pb.hFileInfo.ioFlFndrInfo.fdFlags & kIsInvisible) { - /* If invisible */ - if ((types->perm == 0) || - !(types->perm & TCL_GLOB_PERM_HIDDEN)) { - typeOk = 0; - } - } else { - /* Visible */ - if (types->perm & TCL_GLOB_PERM_HIDDEN) { - typeOk = 0; - } - } - if (typeOk == 1 && types->perm != 0) { - if ( - ((types->perm & TCL_GLOB_PERM_RONLY) && - !(pb.hFileInfo.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)) - ) { - typeOk = 0; - } - } - if (typeOk == 1 && types->type != 0) { - if (TclpObjStat(tempName, &buf) != 0) { - /* Posix error occurred */ - typeOk = 0; - } - if (typeOk) { - /* - * 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 { - 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 && ( - ((okType != 0) && (okType != - pb.hFileInfo.ioFlFndrInfo.fdType)) || - ((okCreator != 0) && (okCreator != - pb.hFileInfo.ioFlFndrInfo.fdCreator)))) { - typeOk = 0; - } - } - if (typeOk) { - 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); - return result; -} - -/* - *---------------------------------------------------------------------- - * - * 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 = FspLocationFromFsPath(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; -} - -/* - *---------------------------------------------------------------------- - * - * TclpObjGetCwd -- - * - * This function replaces the library version of getcwd(). - * - * 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. - * - *---------------------------------------------------------------------- - */ - -Tcl_Obj* -TclpObjGetCwd(interp) - Tcl_Interp *interp; -{ - Tcl_DString ds; - if (TclpGetCwd(interp, &ds) != NULL) { - Tcl_Obj *cwdPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1); - Tcl_IncrRefCount(cwdPtr); - Tcl_DStringFree(&ds); - return cwdPtr; - } else { - return NULL; - } -} - -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); -} - -/* - *---------------------------------------------------------------------- - * - * 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; -{ - /* This needs to be enhanced to deal with aliases */ - return TclpObjStat(pathPtr, buf); -} - -/* - *---------------------------------------------------------------------- - * - * 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; -{ - HFileInfo fpb; - HVolumeParam vpb; - OSErr err; - FSSpec fileSpec; - Boolean isDirectory; - long dirID; - - err = FspLocationFromFsPath(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) - Tcl_Obj *pathPtr; - Tcl_Obj *toPtr; -{ - Tcl_Obj* link = NULL; - - if (toPtr != NULL) { - 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); - } - } - return link; -} - -#endif diff --git a/mac/tclMacInit.c b/mac/tclMacInit.c deleted file mode 100644 index f132577..0000000 --- a/mac/tclMacInit.c +++ /dev/null @@ -1,802 +0,0 @@ -/* - * 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 deleted file mode 100644 index ab7bc7f..0000000 --- a/mac/tclMacInt.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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 deleted file mode 100644 index 7f37d2f..0000000 --- a/mac/tclMacInterupt.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * 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 deleted file mode 100644 index 59d4612..0000000 --- a/mac/tclMacLibrary.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * 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 deleted file mode 100644 index 8aa8c25..0000000 --- a/mac/tclMacLibrary.r +++ /dev/null @@ -1,209 +0,0 @@ -/* - * 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.6 2001/12/27 22:46:22 das Exp $ - */ - -#include <Types.r> -#include <SysTypes.r> - -/* - * The folowing include and defines help construct - * the version string for Tcl. - */ - -#define RESOURCE_INCLUDED -#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 deleted file mode 100644 index e767651..0000000 --- a/mac/tclMacLoad.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * 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.12 2002/01/27 11:09:58 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; - -/* - *---------------------------------------------------------------------- - * - * TclLoadFile -- - * - * 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 -TclpLoadFile( - Tcl_Interp *interp, /* Used for error reporting. */ - Tcl_Obj *pathPtr, /* Name of the file containing the desired - * code. */ - CONST char *sym1, - CONST char *sym2, /* Names of two procedures to look up in - * the file's symbol table. */ - Tcl_PackageInitProc **proc1Ptr, - Tcl_PackageInitProc **proc2Ptr, - /* Where to return the addresses corresponding - * to sym1 and sym2. */ - ClientData *clientDataPtr, /* 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. */ -{ - CFragConnectionID connID; - Ptr dummy; - OSErr err; - CFragSymbolClass symClass; - FSSpec fileSpec; - short fragFileRef, saveFileRef; - Handle fragResource; - UInt32 offset = 0; - UInt32 length = kCFragGoesToEOF; - StringPtr fragName=NULL; - Str255 errName, symbolName; - Tcl_DString ds; - CONST char *native; - - 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; - } - - /* - * First thing we must do is infer the package name from the sym1 - * variable (by removing the "_Init" suffix). This is kind of dumb - * since the caller actually knows this value, it just doesn't give - * it to us. - */ - native = Tcl_UtfToExternalDString(NULL, sym1, -1, &ds); - Tcl_DStringSetLength(&ds, Tcl_DStringLength(&ds) - 5); - - /* - * 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(&fileSpec, fsRdPerm); - SetResLoad(true); - if (fragFileRef != -1) { - 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(native, (char *) srcItem->name + 1, - strlen(native))) { - 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); - } - Tcl_DStringFree(&ds); - - /* - * Now we can attempt to load the fragement 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(&fileSpec, offset, length, fragName, - kLoadCFrag, &connID, &dummy, errName); - - *clientDataPtr = (ClientData) connID; - - if (err != fragNoErr) { - p2cstr(errName); - Tcl_AppendResult(interp, "couldn't load file \"", - Tcl_GetString(pathPtr), - "\": ", errName, (char *) NULL); - return TCL_ERROR; - } - - *unloadProcPtr = &TclpUnloadFile; - - Tcl_UtfToExternalDString(NULL, sym1, -1, &ds); - strcpy((char *) symbolName + 1, Tcl_DStringValue(&ds)); - symbolName[0] = (unsigned) Tcl_DStringLength(&ds); - err = FindSymbol(connID, symbolName, (Ptr *) proc1Ptr, &symClass); - Tcl_DStringFree(&ds); - if (err != fragNoErr || symClass == kDataCFragSymbol) { - Tcl_SetResult(interp, - "could not find Initialization routine in library", - TCL_STATIC); - return TCL_ERROR; - } - - Tcl_UtfToExternalDString(NULL, sym2, -1, &ds); - strcpy((char *) symbolName + 1, Tcl_DStringValue(&ds)); - symbolName[0] = (unsigned) Tcl_DStringLength(&ds); - err = FindSymbol(connID, symbolName, (Ptr *) proc2Ptr, &symClass); - Tcl_DStringFree(&ds); - if (err != fragNoErr || symClass == kDataCFragSymbol) { - *proc2Ptr = NULL; - } - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * 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(clientData) - ClientData clientData; /* ClientData returned by a previous call - * to TclpLoadFile(). The clientData is - * a token that represents the loaded - * file. */ -{ - CloseConnection((CFragConnectionID*) &clientData); -} - -/* - *---------------------------------------------------------------------- - * - * 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 deleted file mode 100644 index 6366dc3..0000000 --- a/mac/tclMacMath.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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 deleted file mode 100644 index f27645e..0000000 --- a/mac/tclMacNotify.c +++ /dev/null @@ -1,580 +0,0 @@ -/* - * 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.8 2001/11/23 01:27:53 das 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; - -/* - * 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 != Tcl_SetTimer) { - 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 != Tcl_WaitForEvent) { - 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 deleted file mode 100644 index 8402df5..0000000 --- a/mac/tclMacOSA.c +++ /dev/null @@ -1,2949 +0,0 @@ -/* - * 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.8 2002/01/25 20:40:56 dgp 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, - char **argv)); -static int tclOSADecompileCmd _ANSI_ARGS_((Tcl_Interp * Interp, - tclOSAComponent *OSAComponent, int argc, - char **argv)); -static int tclOSADeleteCmd _ANSI_ARGS_((Tcl_Interp *interp, - tclOSAComponent *OSAComponent, int argc, - char **argv)); -static int tclOSAExecuteCmd _ANSI_ARGS_((Tcl_Interp *interp, - tclOSAComponent *OSAComponent, int argc, - char **argv)); -static int tclOSAInfoCmd _ANSI_ARGS_((Tcl_Interp *interp, - tclOSAComponent *OSAComponent, int argc, - char **argv)); -static int tclOSALoadCmd _ANSI_ARGS_((Tcl_Interp *interp, - tclOSAComponent *OSAComponent, int argc, - char **argv)); -static int tclOSARunCmd _ANSI_ARGS_((Tcl_Interp *interp, - tclOSAComponent *OSAComponent, int argc, - char **argv)); -static int tclOSAStoreCmd _ANSI_ARGS_((Tcl_Interp *interp, - tclOSAComponent *OSAComponent, int argc, 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, char **argv)); -static void getSortedHashKeys _ANSI_ARGS_((Tcl_HashTable *theTable, - 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, 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, 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, - char *contextName, OSAID *theContext)); -static void tclOSAAddContext _ANSI_ARGS_((tclOSAComponent *theComponent, - char *contextName, const OSAID theContext)); -static int tclOSAMakeContext _ANSI_ARGS_((tclOSAComponent *theComponent, - char *contextName, OSAID *theContext)); -static int tclOSADeleteContext _ANSI_ARGS_((tclOSAComponent *theComponent, - char *contextName)); -static int tclOSALoad _ANSI_ARGS_((Tcl_Interp *interp, - tclOSAComponent *theComponent, char *resourceName, - int resourceNumber, char *fileName,OSAID *resultID)); -static int tclOSAStore _ANSI_ARGS_((Tcl_Interp *interp, - tclOSAComponent *theComponent, char *resourceName, - int resourceNumber, char *fileName,char *scriptName)); -static int tclOSAAddScript _ANSI_ARGS_((tclOSAComponent *theComponent, - char *scriptName, long modeFlags, OSAID scriptID)); -static int tclOSAGetScriptID _ANSI_ARGS_((tclOSAComponent *theComponent, - char *scriptName, OSAID *scriptID)); -static tclOSAScript * tclOSAGetScript _ANSI_ARGS_((tclOSAComponent *theComponent, - char *scriptName)); -static int tclOSADeleteScript _ANSI_ARGS_((tclOSAComponent *theComponent, - 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) { - 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) { - 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, - 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, - 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, - 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) { - resultName = argv[1]; - } 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) { - makeNewContext = false; - } else { - makeNewContext = true; - resultID = kOSANullScript; - } - - /* - * Deal with the augment now... - */ - if (augment && !makeNewContext) { - modeFlags |= kOSAModeAugmentContext; - } - } - - /* - * 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 #%-6d 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, - 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, - 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, - 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 #%-6d 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, - 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, - char **argv) -{ - int tclError = TCL_OK, resID = 128; - char c, autoName[24], - *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; - 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, - 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; - 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, - char **argv) -{ - int tclError = TCL_OK, resID = 128; - char c, *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; - 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.6d", 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 = NewOSAActiveProc(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) { - 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, - 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, - 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, - 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) { - tclOSAAddContext(theComponent, contextName, *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, - char *resourceName, - int resourceNumber, - char *scriptName, - char *fileName) -{ - Handle resHandle; - Str255 rezName; - int result = TCL_OK; - short saveRef, fileRef = -1; - char idStr[16 + TCL_INTEGER_SPACE]; - FSSpec fileSpec; - Tcl_DString 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; - - Tcl_DStringInit(&buffer); - nativeName = Tcl_TranslateFileName(interp, fileName, &buffer); - if (nativeName == NULL) { - return TCL_ERROR; - } - err = FSpLocationFromPath(strlen(nativeName), nativeName, &fileSpec); - - 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, - char *resourceName, - int resourceNumber, - 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 buffer; - CONST char *nativeName; - - saveRef = CurResFile(); - - if (fileName != NULL) { - OSErr err; - - Tcl_DStringInit(&buffer); - nativeName = Tcl_TranslateFileName(interp, fileName, &buffer); - if (nativeName == NULL) { - return TCL_ERROR; - } - err = FSpLocationFromPath(strlen(nativeName), nativeName, &fileSpec); - 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, - 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, - 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, - 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); - CallOSAActiveProc(theComponent->defActiveProc, theComponent->defRefCon); - - 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, - 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, - 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 deleted file mode 100644 index c994e60..0000000 --- a/mac/tclMacOSA.r +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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 deleted file mode 100644 index d916cab..0000000 --- a/mac/tclMacPanic.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 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/tclMacPort.h b/mac/tclMacPort.h deleted file mode 100644 index abc30aa..0000000 --- a/mac/tclMacPort.h +++ /dev/null @@ -1,312 +0,0 @@ -/* - * 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.14 2001/11/23 01:28:12 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" -#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> - -/* - * The following definitions are usually found if fcntl.h. - * However, MetroWerks has screwed that file up a couple of times - * and all we need are the defines. - */ -#ifndef _FCNTL -# define O_RDWR 0x0 /* open the file in read/write mode */ -# define O_RDONLY 0x1 /* open the file in read only mode */ -# define O_WRONLY 0x2 /* open the file in write only mode */ -# define O_APPEND 0x0100 /* open the file in append mode */ -# define O_CREAT 0x0200 /* create the file if it doesn't exist */ -# define O_EXCL 0x0400 /* if the file exists don't create it again */ -# define O_TRUNC 0x0800 /* truncate the file after opening it */ -#endif -/* - * MetroWerks stat.h file is rather weak. The defines - * after the include are needed to fill in the missing - * defines. - */ - -# include <stat.h> -# ifndef S_IFIFO -# define S_IFIFO 0x0100 -# endif -# ifndef S_IFBLK -# define S_IFBLK 0x0600 -# endif -# ifndef S_ISLNK -# define S_ISLNK(m) (((m)&(S_IFMT)) == (S_IFLNK)) -# endif -# ifndef S_ISSOCK -# define S_ISSOCK(m) (((m)&(S_IFMT)) == (S_IFSOCK)) -# endif -# ifndef S_IRWXU -# define S_IRWXU 00007 /* read, write, execute: owner */ -# define S_IRUSR 00004 /* read permission: owner */ -# define S_IWUSR 00002 /* write permission: owner */ -# define S_IXUSR 00001 /* execute permission: owner */ -# define S_IRWXG 00007 /* read, write, execute: group */ -# define S_IRGRP 00004 /* read permission: group */ -# define S_IWGRP 00002 /* write permission: group */ -# define S_IXGRP 00001 /* execute permission: group */ -# define S_IRWXO 00007 /* read, write, execute: other */ -# define S_IROTH 00004 /* read permission: other */ -# define S_IWOTH 00002 /* write permission: other */ -# define S_IXOTH 00001 /* execute permission: other */ -# endif - -#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__ */ - -/* - * 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 deleted file mode 100644 index a0686bf..0000000 --- a/mac/tclMacProjects.sea.hqx +++ /dev/null @@ -1,3864 +0,0 @@ -(This file must be converted with BinHex 4.0) -:%R4ME%eKBe"bEfTPBh4c,R0PB3""8&"-BA9cG#%!!!%Y3J!"U09VQe0dG@CQ5A3 -J+'-T-6Nj0bda16Ni)%&XB@4ND@iJ8hPcG'9YFb`J5@jM,L`JD(4dF$S[,hH3!bj -KE'&NC'PZFhPc,Q0[E5p6G(9QCNPd,`d+'J!&%!!",8)!N!0b!!%!N!0b)aJ0TD9 -5CA0PFRCPC+@P!+@3"!%!!$J!4,Ea6[1fm8mc!*!0#)B&!*!$cJ!Q)L%!!5ad!!) -Y2L"#G@PXC!!!&e)!43!L!9-#3J(!rj!%!alrq2r`bd3!!)!!N!HPN!3"!!!f!%5 -d(A&cZ#2FJ!#3!h)!!5`V!*!$FJ!'h`-!!!%S!#BJ1`!"+`-!##dq)(4ME!!!M%i -!I3!3!GN"p!(!rj!%!Klrq2r`bd!!!)!!N!HPN!3"!!"!!)#f"X)LYh!(iJ#3!mi -!!#$+!*!$cJ!3j3B!!PXD!!!I2J#3"!m!3Np"Ae4ME&0SC@aXFbl2J!!!3,*069" -b3eG*43%!rj!%!*!+J(!!N!C#`G4TA)3FKdFB9Vjc[S"j9Z"(P%(IQk8f+56NDRU -5pB3pqpZ&4hM@%p(`!kJSMT&0c@IMqN+AIQQ9Ur&[KCX)&PHl[plQD92bUEJb1P# -LX&0[E0r+,YJ!B(fUT5+hHLGS(jYE-EDeN`13!&1EZ"El+m5VENB!"J``M8UlNiQ -*(K)5LJFl$C9ckF#P20mJCC[TGPc*B*!!T5pZ5009m21P8ZTTCBU2+Ub4D*YV8kk -&5VpeDRcm(+!3J&`P4RKN'`CE,lET`HT,,2)NaZkVbaTFPB`#Y*65c8m9pD`1hpk -D5R6B5ZcCmU8r,"aD4[-FST3F6j2i#IRF#Rk#4[)@AVV58T*LT@hf`4@cX#h#AMD -i"lQ"f,H)S2(i'[DL3[0FJS*IV3$[L$*fa@f"9!Ml@JqKPYDcMPDKYNhTa2K'"BD -lLV0`[99B8HY"QZTJ%c1Akp8rRPUL)*,AFMD@+RE(%FLD9U#3!0FeKP'8-k&-k,* -4+aT'SqiJ'&R4K$KdL8Hb2BEN+"Hf9rp)K#48hNrDmp"JH6!iLAY`TqhFBS09JVC -L12KTL)%S0&b5Y6HqHl(b%)Dr,91$h'%if2jIKi`VrZ@5K%'SP@`cb)96C[ccAQ% -N-qDTZB6aJHD'II09NlD59M4jLbT6YflN-MPVZFfQ%cHIGe%2CmNV"+1PYTS+eVM -q)45!m&3bP,3D@Y0GNHd$C,UPVUPl4@5+[pp!40YK4jF$)'f+60X[QT4&UhRC((* -aSL@1mNCcACUe@1CK[EDGMkVJK0Sc8d+MCCRG)[qcT[mcM9(bb!J2@HE"liQ3!0Q -IEe#NCTeVM4j8+1@[(C--KjifTc0LG,"e8mYMDaDL5#Q5P4ZqD"KF`[r6#5'$er0 -EQa6J%&Gq-bDhUB[EmV8V1EK$*@@b+e#CZ!Qif!ST,@)2aKE0iIkrj*S3-`bZKBD -PqYH+`FiDQEqSM[9epiMp$49kTT+aZ223MdY$S8D2&Z2*k@Vjf$l0Z()"m&KQIi@ -l3dGB@B!&a1[1F!SL#HCdb#6N[e"4D&LR,$1CA$1Zak2pfKR6b-VArq56D1i)lRE -BE[A0!q5D3X$FYC!!I0jrVYdbk6rJGheYN!#J4bk'9c42D+MmeJQlD&MDGpe@21` -8ZdHNJp9c*rYR[UJ2Hfk`ErACJAP9#If)V'p5*1@S!5Y%+HmT%#lMCG0`+c(Qq-N -@3UBEM8LBB0fmBbam#k`a6C!!`,B1rccpZ!DfaVc)YDA&@dMXe6Lh8I'+(KkN5YQ -d13TS*(VlCDir!A6-dPaHR0QafC@RUpQ!6-$T$PF3X$0d6%(!#'2aVhI%i5FHP)Q -q&J)9-Z@$LH*J$iB*(q5EBVJ0jj3G,YI+c-`3YZ4GbK$#(+DKEM*iZdER$5lhl,& -Aji#rTEBMHU%X)0U2US&Pp,cRSEH)RGbBXlm5&"*iL!2DdUGcD$92ZI`D&-IATrN -NG,!X,V!5j%!&fq$JA*cUIrha2P#Mh2LX#mCTQJZJ`)KdHJLE+mMQrh3*[E8Jdk, -9Y&%0CGJAGQ#&[Vf22qKjG&*2Y+F$-L5"T35f-jq%!12"hb0$CD)-9$q+BAA[#q[ -mZ2bEN!#H),UV(NV%)prrFI!Zl2,3h2(J9GPk0+&ibYfajY2*EVGE-kl"B+Jk`$6 -IAMAXR`6EdZi"G@)EGV!#X8'#!%(c'"G[lpM0U%k9Z1rj90[5)Hi1q#BCDFSdLD1 -Af29+!b)T3i*E#X)#5TYbQ$l0hm&E-mPjfm[3!2ce@@FS5!qV2[[J3Q9Vc+4Jp3( -Qf3IU'!0)f4lPFS6%[rI(q#L#,E2SKXKVe,446)fl'TYm#L(QV`"ZUSY`+1dip6U -@*'0UAb@2Im4&Z)5II5HcS@b0TZUdh@J2Hd6d4jc-%,)[C-N`EfH#mQa*m"4`R`b -ah4X2AImZii5fH),c&CpI+&4mP8$NL,2G*pjFqN8V2'qZf#ECRTJ[VA8Um-@!Zj& -S8DZGrjDS["SU(35G2PMZU$80U)%qh%Np+NAG&6fPeqcA@fG2JPak82@"DQ33*%2 -%Dp(KcR0dQ`*6RC9A-l03fp$[F*c8jSpj1dpqr%cX)+e**Vak`"`dmXYU`XJ@mD# -%dUfU`+jGQ@88Zh(Fc,B&5'l``8A8bhHS#hS&)Hje"15D5k4lQP-lYFlM%c9Y+&- -CpaSc9"SIG1$!MMcDTqalhK`M[Qm!!dmMDJA1Ei$h#IA6Q-"iAFGN*R!bG&H3!!E -&YTABa85dS9AA`mSm*M#Y$j21r5)!`RFkKB,&'m8Xr43i8("3L#P8kGKQ6P81i6e -`-aTa49mrNS#e8BD%&ekQ!Mj0`S`NcZAVhLJPU-L#$c%[f$+-Sk-YI,YKp@8mBUc -#4(%jD(4mj+LAEZTTpEFMc%R@GUUmpEq,6E%3D5-B-j8MpPr-@&8B4Ej9C69E8p, -T066D$(HiN!!XE!8j9LjlJ26SU'8f!*(+6@b%YH!"`QZc[PiEkKS&([FTCp!jp0e -i-jbATcBTUm!bb1*Lm@F!m88jpkVPCq'FQb6444jRI@8dNUUXmMJlJ'J,(ETECb[ -Lfclqd5HeN!"kpS(TdGqc%S@-V!iQSX`ii6AG2C!!bP[q0'PQmH@2K8rrL*PQS44 -1B5h`)0p$Pbq%DmJfPEAUYjI&i,Y[J8#"qTZETRb6(YT-bD$*qVRNPdCPfFQeqbU -ZYaEr,e##+Ph0@)+mdd@-CY1M64*!HrfUY!'KeaN#`*!!8C(qpZX@MCfU9$h@J9H -SJ8bA@&1[G%*%F+0*ZKCmf`baUkJr('M0#%!Ch8UGiKC4Z,Y!1fP@3eA6MeUVqdb -Dedji3Z4QQF)ciFd-9D4FS(BISI!Z!bTPJZZ3!("Y2P6DVHC@38iFq31IZPUf2VR -pj!B6jT*'ANUd'ml8e9RVQ"k0``c)Z2d*kTAGLm,21P$X3FR!"Xe$2bYD#@4%%9[ -,TET3EL"PF`b$%P4YCFFEkbI'1MR,&%GM-Q+fA4D$0'"p",B-D%SL!Pj!RhJ[McR -YqX`jfm#ajGLF%!B#,YJfD5NY6#QjlK)AA,QH0kbT6rRdZLCGi&9+&pFfXakXL(l -dJUre)[D3!1"-QlT+r'3'fTHIJ+P*c`&c2QYj-2iU`H'h!ZaQJm&rY,E6lm69j`C -0FN[$[QakJ2Sa5+(XIF`qk@CTD3l"!rSpkB&'f(*P`p6L+D93*$C3I"P$26F8Ye- -&Xmrdi9eZcc06%--!1'1-b658"lJ2,hJN![Z8fip6jV$Pd@Nc%N16RZQ*Dc2M$d9 -X3FL!bGDA5DSC&#N5iHT#%UJ4-l3G1($hR`VqIkB#EbC,JC9lJ@&P8BhQ[,KKc,a -e!bZeX%e,rIYjqA#+Jr,p-G1"h3fCiM,!kV!QN!$h%iaNrf$!Mc9`V&96Yik#M#D -#Q"%R",ApXEA9@X+Kh*!!(EHP1[-#2l"(Ufc+)hl,REYZP6lXPB()E8QG-+[EcY' -([iHl(YJSlNbEhFYfl,h8$F(6[jB8-#&`F$G$,b`CK9C@1I&2JDAKS"URAF(JDN- -Khf4*l-4DH%DR%CR-0icBSNDd6khB8T)bDCEK*NhFfKGGCe%DT%eP"Xk@0@[29D+ -ZCj9Aa&`N,6SC#-Nih)@j)h(XjHb('T14h&1I-2UDd)SSF13YK+J!&9HAjEDMN!" --5P!Y-AP&$VhKZdqXlP6JNm66ZqAebah[rb[R'$XiRTD@#6[q*-51X@(FJ&5+CVh -jJfUkYk#4bZi9p0HLire*U3Rm9a![[J+"2QIfpjZ0*R,T@`Uc[4lQ8m%BV3-bG+Q -cT[)eB*+Gcm[DA3qM62%--+Q'APIf!M3hCf2R&m6XRXC3[UZ+aCE(`Zaq#N)LMkp -6L'*ZiTcBCJB![dHbGPfh$UX!fBPY11U`$TT%jZ*KA*(akpDk1TR0#02h4P9'a&Y -,ID8-Rrci8&"Y)R3M*8NMlrFHZFhMG)@ipQHaZ2'4YUX19jT[SFXTqEqcFC,22`l -ecP1$e"9C2'4piD-cH@*6Sf"DX0Lf2M831GE*@i[bl+bCl)T-T-[i-kflh*8Ch-0 -KbdCAV2DY3"0*2@@TjLT2Z`j8Ud0NQA&"(SmQ`G`S6K[ZqD`XU,B)hP"$,CcL)2b -%r1Y*I-P2cjAVe&a9B$5!-!Yr&RkT"Lb02+b$h4FiK!+pPbbTm5rP#jMG08iIcT0 -8ZeGY5A9dY5KeVSR53B60cm[X%@6#Qb[!Y3MR3#a26N*hjB%Q8YEASGLS+EB"IqC -+fE5E!eqLP*R*(HX+KDfF8&BEr8H#leK9pI`Z*K&hUXcp5M#DMbh)4,rp[p#Rd0f -8,qfQ+L%,m(!'Af@3!#B-[-G9B1qk`!e&"1CJe!*aDESdF1(`RJJ#Y-X(06MKU3D -Rf4hkfS$%5Q8,J8bHr4DiB@Nf[hXVj[mfQP"c32X0)LLRrae00pb@E2EA+0Hjq!% -F)UNjF)h&e[,$@Ck%A%A4U-DeCK"@!bJ#Y@D21NYGKVHbe9kcPE!j-l4a!lh3E8C -rqP[ricTbj4hN2h2IJGeQL$$2fc#SF)$0f1M14mp"GHUJ9`Q%3SPHpc59ep'p*D# -6@,f0fMTR+@LUdYmQ$k+j#3+-(TSA8VC,c)+YLJYElJhY0@'XGq-ZHlN*2$Y52dc -(0,+pS["2056hF%&lK30eEVIDbk`hL4TV6a1Kf*jrE-3i"RMXeVmM2m8rBS"0ZDm -8$P5*T(UIaN`6Ffk[A+j50Xe*4i35'DE+)Xmi[)ZTkb%GM,KmcrM'dh"S)m[@rbV -Eb`1SRpCHD*6la$++-h2EGJ0c!lQB$j@0@`CJjN(qEF4qp$kH4*eZ#N256(PTc0G -)"dK9rU2`ZY11k(k00aRe#MA`F5C(VJMY%,ie24a55S"LkT55e,K6J*K1S2S-E(Z -Tc5T,S@F&fD'8R$a5C+ZCT@IP1ADSD1h39GNJr4E[Vj2imV"3`(YJqCTSdUV4%J0 -cAJXZfMJlP0a,eip3SL,EAK[N["#FlSfiKX+h-*!!(Z8`F4*Q+aH`QJSS4L9C)G@ -%*+80jNCa-`T&NCJ$P*`MV%a4K%68qDjTjdleQ+L#$#U`e$!Dh+4DN!!%",VY*U) -rkI*d#Dm"'BCCZK9""QaGc+FN8ja53FKfQ2`[$F5Dfa(I9A'c,AlA"m@b,dc6Zbl -)5,0iBZc"Pm!4UPj%pqVQ&PKD$HRJcQ3feR,*)A@#mBL%k!-MYkh9!ZR8%c89p'D -S03TbUJ54%+*HEMTfBa*X8EiC5imq&-XKi%T6md%2c5hCS(m"j0SjHa+$1*S4j#Y -d0aCCh5@$6e`!1)Abr!'"3$k[1-["hS0+5+e99(L5"3ZHc(%pKKmPU4h2@4GM[Vp -3Y@RX,jCIH1ibQD`j*`cRh5V2E$Dh9I#8b)F%)Zkkb`HR4#I&118B4-i6J$LBXCe -QGM5e)BT"+Dj*J26ip)mTKLi&)IJZ$KVNZhFPeR`A2LSE30hU[4@6#$+VaP4!9'i -8khG80*6+qVZ#rR4UN!$pNK43#+I#-Vb+!Q8hIF(0Ga5"6Gl9J`I&(p2Y+P)paE$ -T3qY*8i5mhIqpN`9*GFQ9EFDCqH+ldSBLNiNV"`*J0rB5J*64b"+kbhp1((K[+a9 -HV)Xi1-KJPA1@IDZJSR#+LN`9!eeeQ+#8rYMY'Api3Ikm2"dXAjlM+KRQiSq%@(5 -IJ!V2e14QFMV4fD+E4QTQTP9R(K$GGXfVAVL`m[NE&)1GU(&b$'`,24Lh1VMT0i8 -$ik,34mP[AB*k@TbRUc5@B!0%@Dq&[,e`r!NJ3iN5j#`Y(F9H&ULb-3DkI5r3L1L -)ZP"$+P"bQ+b4L$i[pBLFML"1'E'%2mRA`M(9`5*J(f)j@U13!0&`jd2r64BY3F$ -)"`E'GU91"Q8ldUbQ%"TZh4ICS@',l`0`+-$Q5)VHV1`MjU3Era&rmL2Tmf8bF%[ -`1U!TBRm$#-F6SLJb@'m5*rU9hIG61CMpEPBir!SpSY*$lAp,jJqbM&Am[UVN$JQ -f4qm)er8X+aceFc2CDhC$GXICJ-*HR(D8jPfU3B1-GDjKCd#d"mcmH02,'Q@LdpL -j0"eeqMIQHFD!Ke!h0Baa'k%3lG)F4`+BNUGbrV[dehZQCqE*HbZ4lXTbC3j-(TN -UB&&!Jh(DY,*m'#h91bXQ,1kB4b,lmdBaQNV"KTqGb0L@dNh1hKH-E`18&!@ESN% -2'C&J5L0iTfE1@SQZk6`+qTJC&LX3'k&C!IU&jPKR8`-MbF9dU+(AXmZ)X,[,*h' -B3!fMG19K3T0E8IRcrdh#!T!!'!M#i0Q,2NYJh5Mr1Nl'*cl,D#qYTTT3k*T6J90 -D&A2G@$f(+,8NA)6M&EIRN!$`*E5BEl2`hZTCe#[S1QG)4(8-8eJh#'f"%EJ%ReM -Ta"SfUXQp8+pfdhbF$Di95U*FLUeX$iFSLrL"[0qlT)"-%Tki6jJN!!2j%@HM#0H -ElK1CMA0I@92[&TkCj(-hPUik&mRcIll1NrHN'P$1$p845hm6qjbH3mqf-KicTp* -Pf@8BEc!i"ekdUFCT389rbdA"DQ!pN3ZZ2%`J)9([C&l`aX%FMH(5jJ*D4LRaiSB -5@M`-hZc4)D4N`akFRQe4qELI42R%"bTfIEj[r"Q&ar1e4h")V'(VKfT,-pj&krC -TV'eRL8"cS-K1dZdXkA'l+bS!XAa3LiTZ21cpqE%(YYRK9kd)i&IqR9Ml6-B$6UU -FIrUh1([lNhI6DVql"d86iV0e4,rFI[V401S%1*AJDfh&ZS3XG*!!PXfU0d"SSlP -&aKbd`83ahV`Z`j,HLN2JlBC&3eC*cYHB%h9194%TILjD&ckD*Im#AKCH9hSMS!E -Ki6jPjdD0YK0FP!3q'kCbbUBLZh&Xkj)C8jJ,S2e4YlpkFD2J#U*Rm@#XQJ5NkaS -L`+c-EJ`([0YapB&F+X8KQb`L-RH%$`0FG&f@`'@',3N45R(FGi144K*4rG4&"Ke -FSa)dm59(N5U1K`AN1rC8fR+e2*%qHKB+`6Be[qYimB*2#04*%q@3!&'D24M@5I8 -Y,,[+RkNU*Rq$&e$2KM9mJ'DIiFF,N!!h`R3#YU+Dl+55+Z%ljhZ0K&IbM,QCr"` -eaQQh$GM,Uf8q'VS&8#c9E+LU@fUd,YX[EAeVj@$f)AY1-5Y8!(A5F-Q#6#Ui0[C -,I,bj%1!Y0Car5eliKf3i0"RmbQfYcP,[JHAiBRC11p)U*(+Z0'$*508(+ddDHF` -L+KAMdTVA`$1#4X0XKamDATD9$G)d+N0`f5RS+S4Ik2Ger&dS@NkRaUA2J1NFmZX --EGRj!#m80i9Sr,KT,#&-je2QHM2JQ(50CdENr)a4,'*`c`1UP)PUVpPh#9D(!Cb -Tjd6Bc['GV(aqY%CPaqp!q8dmdSUekMBC*DacI&ErJq!18%YXCk5r2T!!*jbmb,d -913a$3(PRmS4@+hP+IU"L@'",8phdqmbCa,6PCc!!S"m1R5G298@iT-[b3k8Uk'p -peAX[V#KTqbNQ'H*qK$q5!8i2KE1TK98`p-8,D`XThIi$mqh&1A(ZA[iJ5'0`hjC -Ak8mY&644Vcm`,d*)R,QTrHrLLDErcVafTiMLpH'h3@k-6P9pChk3!29$,J10Ej' -Q([@EGqISc+XqKGNIp$"D1#C!83%'Z1$&G$AM)aQ5HiijS#)HQ-*AIUT#Dc'C%1f -!*)T8TGTS#Vmp(LpEL&fYeJh[eUlAcC!!8eErLKbkl")2G0jS$&URXZAjA5FMl1H -M@RKAdVGV[FGJ*Kc%k$aVhfk%PV&!Qf,J&(&KlFA&MCKebbXG`3,RQ[c#6r3l0V1 -TjU"2k85(mbE""4lJc[r(lkcY-"G3ePi8)T4RQT68!%A69U@'ikIXRYFKUJP59I( -A[@2dflJeR*Rr@5iqSTj2@$pHhSG`iCHm%[A)aHQG)Afkl5#$AAE#l%M)ZcLc00[ -`5rLi*P`Z"akjXR1r[LRPMf)A$)H29-Zla)Fi4%e%5M0"b'i&maa4(HLAi8DXT0d -#Gl`PC*I%9mRM"#EPG#X+A2Ce`q3&(V"'hrq-#jCml,DI55QIL'qk0XcaAjkX5YG -2PSk)UPLZ`ZF(M"lImSe#m!EP&SfDpa&h306P35@MM$TFq4JLJ8#c4m2K'9LccCS -F,GkLIIjBMcLi18@c@X'CXYEBemM#@5+N+1C8F%$Fk2l6UX1eRekFL[%*N5eYh)h -lJ+U*CGPEJbpSH5G9pFMGcJm)A2%Z*i#%5hT-,3@0U5UBFHdr8$T4d9qb+H'Ep-4 -AJ+3BPYLj21,AEekEpTS"T8F6r*Gada,!@93`G9bb&'EEY'bRCG)(Zq4d@pq6!9q -aHR"Ij#kP[CeXR'VfQS&df,&@JhpGEj'Fj-)m3V)[k)hDC3bLiCcRP3CUe%UA&)b -D`V5RT"jL4MLp69+@R)*&6I0N+I'0JSS)*Jk+5+3VehC+X3a$5q4r,XLma$h-3M2 -HA26QqXFB3DNU!*&LM!QD"BhUR+4V"qq21jd)DLaFcSC9[*L@5Cil[l6%a%61IFp -Bb@d0DhTl0Pm!6CD9dQ3AH9f2Qq59@JBrYZ3jGNPjP+kG#UmES6@5eqGVCIYf$Nb -iRK)`Zl4brB@4%aZaqbXEP06+DlZ+T5%m`5T6c"YX!SGG[0Y,88Qi0%FD[5[hA[Z -K!Kp#8bP1-cNTHU,%BH90"r$$03VMp!+C&Hb)dC9,S4"'`bHUA')mGIC1$*E3Ffm -QdPTRP#DXi,qGS`fd&hD"2MLBkeH`h0B@PTSf%9)P29QCKb#1&IErj+YFQ@r!,Gm -N1lP@k2%(E`bCNi8mph*aSPF%[(ZATlc09",ADXpEmIe[EAIXcT,E@H1c0qF!bP@ -1qANCl,JPBeVHhMYMPK2#&@bcAlM5QT8!%"2mUZ-1Y'8J$%`GA@CVYLaaG#KYBdQ -im0Zpb6$JBq`,A)YN)HRFq-iKdNNDr-lme%l0YU0J&BKE!M"!`I[GH0e!b9(XJPF -(d-X%jHe`$b4fUQirUXj[2bK&AE-b8Cl9lk*1,dr#Hc%TGXZPX9F%&02qlB88XpE -@*2UTD#l<(c'Z4I'RQL,H@IVS+2p5[J!PTiNXl-)8-Gr(`&R6,-BVLbrSZ5aZ@ -X`$j[5RQK1Mp&!FRfVdqliSKQm+M35rQ$U*Dl5@T,@ZS2mad2[Q'XeXR6cX0eiBp -&S[6'`d0$ENHf0qV$$C3D`5"le2-fB-SPCXDi[idEeG`ZJIG"Dh%IkSi[&b3bZFU -rB5i&a6+RZ6+GBCY,jiEM86L&YIVbim8&"E4epej[VEmGVeMMSh$X(NkeXEPY3bR -a0`B@8-0%JL5*a!VHL&JTqH`[*0XRlQ)pUhVYDcNFr4[M&#`pY3kX0[YLX*GE%,h -2j4A5A30RUZdRMi3"kMdQSl!fp##MHZ@CiCq#a56PpV1hq@arb'-Ub1@e@54T)h- -R*N#ZkFZ"0*A)9N8@iqPd1#J(4MA6BM5ZKh22#c(@K)QAb@H+"`@1I`)pIdk+RLQ -jI0I9aQ*BCdJScl(Kea"J#Xq8lJd!Hr'lme1Q0!6Gj1VU)T'#2%@fBPhD`@ki`l! -eZ5$Cd(&VJe1CLf6C&"m81X[MbeRTFjIef!SXTa[,P*NV$04$b,+X#X[EBe[M@p5 -28!&(YS#GSd8JQMHXfCLSe[dX)k0lNEIGe`p"XBf*F+#@`pjqea)kC[+IMlFDmHp -01`di*6FNb3@ICQmG#J%4'8h(8ji5M9e1,d8P@1#3!'22aKXI[4KR@-R9K8DLdX( -$LrGTfkd9)IQ6KNkQ+3@Y$+KK*&NmbaC6lce%9hU!a55DD+d3D`9A`M-&'Je1F(q -5`GNI+(fKql8PZ`MhY*HQYmSMT-I"'iJQdeTBmE,QDMpp-qr"(LL0B()@!%cVjLT -SJ6arXK)Ua8q@N4P&BN&&SQEILV@3!*lb$&&1`lU"KElJ3"pf+*JBcf+PLNh#f2) -4mVS3N3PQX*Q3!"9q["Apkkb%K`b1ac"#i%Pj)'!+!@ZU+iVHZN6HI1U+6!MqrDF -S$ppR04L)cQd,CIfieHQkAd,XDi45b!@TMNA,%5%fL","e&EYEdVR+lM$T,&hfJb -BXb`&eRlfABpfe#TDHS,Q5f2*X*`8mXSB'!*fVDlrT)A'@pElQ[!c%b$C)jXk5Fh -pH,,bC+0Ee68CH-kPI-[4,[hjk1V5F15VJ+$BR(dQQiq3!+F9BbM%ki[FdCFNLEf -+cZleHr4Ah&M[[c#@8*R`*HV("bL5!B4ZaITX[F%3NB2F$d9QiV(JbrDLpRbE'0Y -0)Gf'@UH)J"q)DJQ8DU8BiXL5cMDMrb+!#"fcl$Mh4"6l&#q,%+h!3&9GI9f-,Ha -AkHKK+CG@V$)Z#f"%GhrGhqmpXGSFGZr(+i[D$i-&,i-mEN1kBrV'dXce#HDN3hV -f!H(3''*M)5HK"[10M!ZBTrYN#rI3P-'i,9SI#0bBBq+`NTS9B!hHYFa-E3GljY& -QffJ'Cij8iHXUG$R`VQ)[eGVSNp'3!!5!VdK`&kMpLVR-aL'TEMd8[&rlTY+U8X3 -I[M,')c,HKmYpG*akq'I,"X"(cUb(G6Ef'jDFeM-N0EQY&D)kh%+D+LU4CbN3'%3 -G94+,6$L-&ZHRR,4p3NZq!)49XCNJp6+Ti&F5!04J6ad,ajfNPA5)Xq1bPdE-)16 -L!$S4k6+j1mhM"[`Xf!C$VeA'dBq9D1j$YR#Xea[-Jik9@XDLlCbrS0%#ZRYI6h$ -Ta4%1@e5i[8,2fhPA"hfMhl2Gd,DT`GQMq2FY'3N8,'Xr`,K4Uph-aUFj$-&"8G4 -D'%RdSEP6jB30eS*KZmSj-f9%Iq'TNh62FBE$BpHM$TDZI-#PN!3"!!"%!"#i)pU -VZ#2DU`!!!5J!!$Uf!*!$cJ!8Rim!!qmY!!!C2`#3"!m!3Np"Ae4ME&0SC@aXFbl -2J#jiE@`!!6Ff9%9B9%0A588"!2q3"!#3#S!!N!N"1J#3!cF!N!32!%,"e3Yp9Ii -)G@q1M&+eZVY+UcfdQBlbjJ*TIXpAm28Bq"(rbr9bq+0NK'C*Ni'aAdAGKmN8l!" -#`G82Y@aZ1`rdha9`9fYTim6JNY'qNmj+0Vl*J+I1)Hhri*Yrq@Ip1MP@,j-S`VF -LR9Tem31SREKcSfPH[U&9rGDk0*FI80-*$Q2cbR`CLB&J#[iJ@k@kiBTEKEI8&*' -j'L9Fb'#8'!Xf+iBpCB2[LT%N@ER%qQ90FY#+kIpHq)*i95#YZm@E&Le)fEae92# -QQ-cT*M'+&!bQVZA1Mm$$Ph[PH)CD$-aq#!P22I3!fYGB`,UN*lHiIQpLI#f`[N1 -H4'6RD#,KR5VP`'r#&)hYG`5lXkUmNU3!IPV98d,FQB4*j2fVPSEL&Q6a`qT5FZ0 -Q,DZ,H2R2mLR'aPN9`0HTe%cf,M"Cia98)PrV#idI%UpN83Fc'pcSXCZ$EeZea,- -CSU#`KbCrlGjqD&M96$KN@@+G8FCY992!AdSjNbil-98"@S@lrXT2+`*(b`Ep`"p -kaN4jd,i@SB+8D[M"pGELVBXp0R$JDDq-QH1GLUep0+EH'R-$A(-%6%S949&0@!` -Ce"@"8*(qTCG&CVU'@Kh8#$P29kbm#,'[2c5NQ%L#ZQ+p5cdap9iE`PKhm,BPjHa -D%RNbA18kh#Jc%-@Ia",5@il@5`Z)@IGI%N%Kq2qdAaHIVFBbGMEFja#!-KD#0JG -03P-%+AJ[UV4l`D*ZiArUcC*aYRmS(*Zj(feJ(Kc+ZYUEj9ZhH-cE!qjCqSVF+eq -ZXPMXI!)B9,IpidKmNJme%4qZG-P"L1P3j`H5!L(fT,q"hUDTrGc(bB,Uc&U5bLk -I+K6G#Kd1[6%qEPi&%N)Ql&fdENQPPa6V&[i`U,UQIYEeCi@jL&+Zajdr%Sk8*8i -NL0d"YJpGJ$$0[PLUC-UhL0(kHTd*3PL,3GCCAQ1e-[`dcdG,)mVqdPBN0ZNCZ0E -pMUfmVB9(%SX)dr-k-f2['fN3@8a"[rFENHcAi26[9i-aNB4Mi@H-qcl6XTSZhA' --ee9[r#TjDeCV[BhEhDE5,CI"BEibVl#ca)(5c*Q0pIRqHfmc`XN[@&aTT%$qV+6 -[%#dKF6DYbeL3!)8!R!#[U5J&NPq4rm(mcQlPVIi&9(+ZKKrLX5praRhS'r%Kdf+ -h,'c+I&Zl$D1)2F5XFG2md%bS95FiH$[8($S@2J@hK)Y6!V+DmCZf'JBLKkL#cpe -60d$Jl4%GHplhZ)&l8&PM-AY@#J06UX6&B4VV*Fc8#%-RX13-0b9-cZ,%[J-S1d' -P$@Tp16(#0h@RifCZC5k+pkKE+5fljY&"f*K))'i$d)dM%RQ'L5V,jR4TMib8[lR -k-UEp5!*Q2U3#imcR4Zhi2%6GfJ$%PeqaMNQhV&62V["Y%P1$d"Z+@T!!E&i9kar -iq1TS"ZD!+PGX6B)$-jkEjHE3[c*P(bJr&$-)J%*r@YHRC!Teb0c"pPia-ShI`iL -6b2jZNHHSl!VK&J#e5P)0RINS5YpAVENU%pERFp3#+DNI%VIM6VGbpHKcaDBP-q2 -BDm6M,#!C56kc+240m0f21U#&Uc,R1qIS!U$`i%!lGFeRF+FdD9e1Nl"aBd*G9jH -Bj*hDQ4#GhYIZ[C8ImdU$i428ZQQAkqZ#eJVGiLMQSh43%TLE1)IK$3FPMVaDcp! -)j+@3!)rkGdrT`m&*"'8@jEhV51Kr9P2--C!!VmeI$Yr5c2#Y4m+1bbUf,!`h'qZ -hrYjPFU`#*F1&%14+,aCljIkLAZk-C96k+UNjGI`bp8L#q,`d19J)#,CrGEQ(m8P -MM0E@d1eZCD8PU(0Y2mp6+$IR)%C901e*LakJjHRP!@4(JFJ%i(RNAFT"KMJia$X -XeY,l8V8r@IR('ZBYVEAVkha+1%9Q)V1aJc'U-2Xl&bCh1QC+)1H!98(-8S4lNbd -#16@QD-8,AbJj9mTdcH5ITLHA"llAfhJ%,LH"3AP&)K8Bc)$91Lmd,@Ef)4fb)k8 -$P)DK'R23Tc52,29D%VaBi&,U+mPP!L@X4&hTT3jC4Cp0q2BI8!-0`B0q1icjhmJ -VJLPPH3MYSqrY&@NZmhXb`e1)pj2)DejlN[PpE5*JG'@P@fCqH5eQT2QNAh*)Zbj -90'Mq&#C'!mHC3)dHSQhIP[d3GP9,CG45LXPlG"aG4Jd8b4`iP%%RTNZm%@,H'Pm -E[32bL(HP9#T8qmV-%ET3"2,K*rP9%546%Aibk(!CSQG1SGG,c-9TEZSB9@,TSQ6 -GaB8@DH`(`2E%IKKeBr&U5p1&dcBH#41)MdIIPSU#DNa`RZT#jB-%%[J*(qdVFX$ -fSm#3!,$ajf!X0B'RaX(-8mjFD1%chlPQ#R!SVef[)`8)*H*p4XpH3E$PC9KUCGf -(K#G8Y#NVaC6iP`EK!G"ePLSrl)`L'P6rT9QL4pXC%Tc(4@'$BhYDRB[Gf5T'+$i -+h)fUM4I32G*,C16#V!a1fPN9%h86MTU"[-QYr2#+Fr4JVYH*Q@KVXL6pERXPmGh -5$'im'N8,Llkr2IEHUE%AUhm28-5i&MSqZZ8,qmC05pdqbbeJml6jU*298-f8#bY -NXSf1mZ-PQ18YAS%RD#U0rY`Se9K6JZQHc)`8rq[0%i"MJ4llc`eEXDVH8Z6mJ%h -#9k5BC(dc&Z&CQ"iYQP1MJ)853@UQII#SjpE4D+apPqL2%D#V,rN++rd`"94DZc2 -(+j@4#p4`AKA[YN')(9[S"Uq$rdPHLXDiUU9L'9r8R(4F`9qiSb))2XaA2)M'"!J -3a#8BmSGEqUr(b`8&Y0F0NGUGcef+Sf1j!P2LdfJXA99l#Gq"A4[q,KFP*1PqKJM -THlJI4*AMa5D-'TK45"EGGjCQ8`@L)d4i##93&Ie8*rXJj94X)l5QpfcKmKepbeU -0Q4iZ0%*`&N%d9SS+)R(bmD%$fVZ1!+K@I@XL([`"%ab#%#Ea6q9Kjlbj4M*5)MI -GXPRZPh$3()*l%$m,faC2X#G3iRP9JeaK(%'PVAAiDef$hQ#dC+Ckj&Pa%4VScfM -6&VQr8PUC1SD6hL3$@FUUMmql[8V!@VT2BJal1XF8PVLK4cVGYM2h6q24Bihl$NI -aI%krCFbEQcB#(9aSLDeF*)cINa!*R3rEeb)mR1**M)eYEdh+rVdJ*SfchkhZBLe -dIaUmjUZNGr8DmrNG968mCIGHfd1fr%P`abNfP4ZqTh0[%`DjHD[fN!!0Dj+RJ8A -X0r+abdG26ck0j[4BUeII(a[QPX%62lebN!!F89&860hN$Ti"Xr2+1U(mlpZMM61 -Sd#ACRXcfb)L@FAH40KJbL641m)lbP%(@)K$cmaYaNf44L#&%8U#EX@rUc&p1AF( -X'[6pPUY5Ai$9b"[[lU(DUDBp61Zl@,GEYBq8)p[#b!p&cGK968VB,8G-M-6)0VV -*6VbQj%f[1X3GM3d3,218JlhR3GSJ$eQL9ha5p+r&JAG!L0V+`@%9I[LR@R5ME'J -*@9XUrPC)8$C2m5B*cRF#6dQ#HS+,ZX!H)r$NDcA3E3j4"1FT'00,eh$YQ@LX8Ra -"U@`U+QPII[*Shjhl)K!BlY(`Jp)jfF&(b"NZf(#Z0A,j32V1Tmf`j"jH3$aa6CL -UCkH+Er#,fFp'F0)"NM8,IK%rHFkDr6"3Z"R)G'-S11rYTKV2U+&(39M!TYbGr@$ -rJ*Lid%dH-@f%L2(6YPY4SX&NXXd5TY$km'+iaF45(S26[#&$8G$0mY1h$ci2%VS -eAJB-R)ZdR!Z6kB&e0jkACl0Y62Uf-hQ,G,GD(kRAmSNmPacZk2!3&KTr3&-"2(" -)E)eceCiX3BZJ(T,"(b[)F'9mT9CNYUQJ`L9S(X'eU@#rp)lKRpT9q1#h#ZQK'-i -emrq&LEj1bFhddeK9LGPL4)8E&P!1GCqBXZHIV$8PXq0X')E+$LZm*hF*Y*d&1H% -`f[&NV+Zlq5$6RB(,Q+iBF'$SqphQ&2A1dEYY,8Z8T*LC8Ufl[fA"rIMpUh!IDB2 -#f#cj$`jh9q)44fQD5AjQMkXr9rG#3+fpAqTp6L*8H)mSBr`,M0cRlpjG@2VI"R8 -l0YT6!AXmiLcBYN@U5Nr#4e0N-9N(RL`lSfSP0TDLS+PZkr&r,Sk'"6Iqr#bB(0- -(JK8Z1f5fB5@acMp41ZCk*$6#2Db2f"9ITZlm9Q''Z4l9mGL)'Mmh)Ie`)T(fX2- -T9[1q4(e,f5&K(kpKf%,ahM`J,k0fQ5*`Dr")eGIfr,ecE`#EAV&c@9Q)b6ZYlXE -J[rVB$'4K"eZrf52Z)0m',DK$S3-a)+mMH$jTrMIQG`9eTL!BYE*PjN3I%6PmlhH -`AmaCGr#C`-Fka&c4#Nb-2A2U2[%QbHh""fi@B`1p)dU2b1Sm+kr6rM"ZGA"TqBL -d,JH@KCm9lP*K1pUAqd6"36aC1JUqGrl'DeZfLe6h")T5!Qf)0M088'QUrPd5k*S -[HB',[#DIDDXjPPeF8PTF9M`8T`)NqXD"VhBE9ddQjp2*jApH8p#-eqa@34,Yr(- -p%8MiZ$L'kQ3Lijq+fI8&%!R%'q9L"(KU-pm[D[N(Tjb-ifJLMm3-Lr,#SEaLl8$ -E9qXea"i(&`Gj8qjY2'-[Ca)$dJl%6G)CCBd'-6K$4Eb*3h5!9!H22%@NXQR3aD4 -@0@F5%&YU@6'JHbQrR)CVZR+!6q-rm8`-KF6'S5i-LlR*"5-A(J)lQYYphL%9ch' -S3fD9#0LTEX"q(9VcM2Bh9!AN5M-8Jej8QZ1XD,&LMR(R[4mj[C[Z1BHdr2`T"Uq -UB!9SA1UR%DLpU$*PiP0ZX```YXFj&lll3EAPliK`PV'U`[Qr%UNmP&3$aNrrM5q -CFd(q)PK*DLbaL8X6l"J9jY1m4+PTY%@X!0qL58``Sf@G#qURVe$D6Lm,Y3F)+r& -lh@@%[DX2E%BC'3(5'T6p35MK(Yq+"@4934N2%PC%YEQmLF)N#Fm6LXEA+6`[1ak -U'5H*C2Xe*iCf3T3-5+ZB(a88BB0r#j)SLCQ6ilYEe"#cUe2DkYpfb5[@Qm3R9`2 -Pi'3-&I(@F-j',K3%4SpNdV'f@J%qCj5HP2(ki&J#154G6#c$58rBNE'A'ir(+!% -D2*YVZ3-pT14ZZE58p&b3!)KLi21$+TifiaD#HiVm(VUmYRB+ipHLjV30fTm64,8 -42hX-mk,U6EHmHc,P)3GZPV2#$AJJ)6'fPrMHLjL1'Y$f"1q3!()CibdQEfV60qq -UR,k3!%Z5!50IJ-,(XM)#e1r8LZAb12SV1$1F[HqhEpLDb5LD6JA(S(rCJ-YLLBD --355JeC1QKqUj%0[CJ%lilM9T[PcJU1*rU15VS3KbMd8Ui(++[4Fkqq"'V6Nqm*% -$B6G3FIGVl1[IPF4!TXpI*$&`0c(P[*[bXG,[QTUKjbA4jA1@IIb4`i(e`S@&A&T -lJ,`(5*5lmMLi'i@&Gq8KNbhkRC-dGj@&1rRNhr@bR%c(AFE!3Nf$0P$XcjeM+&0 -Im%K"QCpP,Fm@K![*aJEBZ6%iK*)m58!*#ePT5F)k3DBI-l&*bc$CfZJA'fENSeL -4ecTJa4HE#"!&qGVlRPM8Q9F%PdmXAf4L3f$K6B@BMq0frIjc!L@-[,USjC&L8%E -CIjkQ(3KE4Ld%hel&qhhaJ"Z-'%U59fHHhH6*82UZDh5S9eNi9Z6)*)`"HUcE,*9 -Ga*D`@3G#NfL8V-*@+&a*TTp-D#h%,U%*@lik`,%eQrSrGA,M'*[*@'j[,TVmMPZ -kX$#e!Ehp$*Jr2*UPcM#$8`%9Um&CELbXEr4e$j!!qrLP*0FEXXTNrke)'Ch-i#B -88K$bZ14J#M$X-3UU@1'mKl'd#SeIm6b'L44-YVDVB+"4,N,)IMmBpGdTd9Bb!&" -i"2)fUT!!0M,1'5KIdQi,Xm`0TIj&p+fcb)mmP@p(KcC321+c""A+[3XUELphXmX -Jqak[33LCFKJqbY*$3"")[*8!rGS[LmJA4#MdMfibjDGS5+JpYTa-I)2X-C5-Df4 -*0*Lqr""(SqEVTMZXe$kd-T8fa#``l#%e3jd-`XKq#*FZ-V'FRAM4J14#@JQeIQU -N2Um!-A89qZTIlaXGaF2Nl[&-4AYd8jrHI9@ELKlp!fi6KBeC3P%1eRlqLSF-T$B -D-RPZR@K96qN8Q,V%$ZA0"j@Fp9@AX%4@,jadRVm@lTBq0E4fT!!*j"X%Vbl(%6K -6qq,k"GR4m$%04)Kc"HiAc'PMB4LM#NdAd%hXc6K$48VF1YjUp)-H*%BFVZfU'k5 -PaRk4MaMrHjL,aVKGrNR`MQ*kjrMfC*(krH-5Pcpa+UJpHE(e--'maqra1'aKL'H -kHrc2dQ&P@#LiX,K1BNlfR4"%Y8(b3BbU(HSJ*HD!!QD(+Q'N5Y8lhdLUE#'H(&R -V(FkR(mP"F%rYp[61+ja4L4Q!'GNH4BNqJi30!6$F%aqI*fLeY&kdVJf*%p*RR1h -F,1&a-Z(0XR9d*PKU@e0XUGlA!R3PXlPf*%q&RT@(0R4*PdT+`aZF"f@1,FkH1KC -qm62V+I"X18M9%"1mE5C&c,6kT"Qp[hjpZEVm-,I(3ADfC-IH-q-%G#8V3CjG@C' -Y)k6#pG(RI03LFJ@J@%1@bdp1URBe`GMicj(@-[#2Z#DC3G@#55(Hj(YKiq6KB$c -#QB3&i6'D9F"B*6'E&IP+jQ9$dLcJ&3APLQf(V+,2XB"pM3lal&QGYZZXAR"D*E1 -T'PLh'6Z#jY8NdHG[j('#X'83$aD8I4qK#)(QQ(pe!eQVk#`GSAl&h5kjPJc0fjM -A5ZIZ8Zm%"$@5''JCMdq0E@rDZ8Z4qrT3XAV+&'H$'@+%[TJr-Ye'-@Q4DZ1B-E+ -TPQ2T!k&diPCGl%a60P3l@DGaj+VphhKi)Z4lX,aXXa3KE809,89q9-JNb9D@CHi -,-Z%`(G-Fd!6NZVJ"8a+2Y''pkHB+IL',m'EaRIQj5*45T6CiVaC934A(Nl8"dK, -'NR`a)E0@!Vrq`@ilT$IEehHd#@Q%*G2,QG"jG!iIHjI)LSRqGZqF!"f42pfl*Kj -eQ%GS6V#%YVf$I0H961GiEPBBSUV"i*Lf2%l`jI82`N*A+PM#D%kr3(XNHI59-Ne -6"G!fD45$49ccR,UBBN4SY!Ik@Smja)9e+cDe3J2(GP(HTBKi`B+m,hA*%b9Z+PK -GajBD2F-80,,VAA"k0bEm1kNlcqlAqX,e'lI4GeNb59I4SVNRKLZ45k*&QrDjR6j -0c1,Brq2MKK96)0C3K4"1Fh`IPJUX`ETf&j15q`!dddXGM3DhfdX$91k`%*fP!5H -)SQ[R%X1)c)G2a"Y8#AVMdqSLT)V'RR6dm4`SUeI1[m#XKIV$rbF#q2IHHq9fm2K -F3[Y##5#Q2!1p[@!Y-0h2@!--Kf8A9J&YL(peCRh9%fB#L6ES+BQLJ9QAS(0ZXqJ -',S1rJU5P#F$T2'LPGF$%EY,1f)ke(13I6C!!P9MUT,l)Di5mA`QXAIMpBk'VUeB -mB4!iQ*jF%MY4(YQrLU[1A$3MZB,XBHckI8&U"TQhRm6H[*!!C3%JPlL!K+lRC+- -UR3kAGFL*NVrdDMG))M*6!1EKmUh%Z"J'#0dL$pKJ0R&YDbh$`9KYd$V#a$lK%DD -B`J)+FSNHlqE8!Yh$*F"(AYHhJd23VAR6%($08lGYd[-KGJhhGjhhHi8BY&kpTdC -0#8Sq*lYQ!VMIfB%imi2CU-#BIbr1if8IUQq$Ad,i2C&D-(9f3jBXpINS'HEmVNT -%r!GHJNH1rdUJM5ma`SXiNU(*%(`RLIC%c(Trl(M2F5dbd88fXI6Pfc"K&ah&#VA -idc`l41Z,PX%LGJ$lYJll@*L&2Z6Chfd541RX$B24hU0JkF+ETj3laib098JDJ#Y -cjdeGZh5a,3)$8NDSJSf@rA$EU*lqh4%#XD0'iQV0fV+28%m'Z*iSNY19l1XL,[@ -1f'&bRaBkSFDAqMT(C8'&,I[U!@PK`Jq#pI'**'-H[VkURQZci'V[2IK30fAI96$ -!UlJD@ilf5mLQCYplY+QIidK`KKL$-N38`B8&k6*HJf`qZY!P6hh9A*IcTq6J'cI -0V,H#18LeGRP-)[H)i*B5ZGD3!*UVjJ-f@lPc)H@-Kh5QEkJ80SQJ(6c"4CZb,Vp -iY$bV4--q(C%j,B415BaLK,L!9qH$dQ0"%3iIUR#9"B3h-p3-5,L(D#5Tp*1"q*L -1*FkbV&$1+!"+UJ2qfH$[d)jc)qJ#Xji`jS1MURahAmKqZ)ASc0U$YbjH3m+Dp[+ -T`m6M*G0ecdDHV1be,Kj6T2ALUbZ%q18r,r(pe2VKc+LHrqkc&5"%BIPQ0Qbl9-C -DJT')H)q!*3i,$G%d#[0USBZ3!2ML@`kb"qmjfV('H1VXQ`BcHFYSjVQQBj9deXY -Z4)@`Xfd%9K,l9ekbFMQ4Rf&%`N5R)35ZRIkJ2LmX3D(Rl05#,$+%AdZ0-Ud,Sr+ -3!2h0jaN"QMrrPjHRd%eYP-V9Ib%c%JYM-$Hr%qc&Pe03T%ZTU0KbN5*2+3R25'9 -+(ibd&)2`S29`2"X*NUBXLY(qhXlYImiMj"mdDD5@RpjDGSDSU*KjX@EA(+S3+ip -0NpQ'J6%4$Ib&aP$pPe8G!'3PA(jIaQ66$*aN8SY'!UXqq*61Urm1qTkp1i8H&%@ -J'#Rcd`3QqL&M0,'Qp"a!Sm1CkMAL%0fHNN!*,"lpBU-GGATi,QpK(9i)G6EH`T1 -@[3MM64[fFJrl"9TNFkLQ"BCLclU+EjHAfP[(ileC-2m@jM*ijGR0S-([3&0F&N# -PN!3"!!""!)#dSDNkYddlJJ!!)-S!!&KP!*!$cJ!4DHS!!H2N!!!G5J#3"!m!9'0 -XBA"`E'9cBh*TF(3Zci!!!%#b68e3FN0A588"!2q3"!#3#S"`!*!'3X(8a&YX(BZ -$5%@ZT,mNCf6blr3R4K@-8X(N[0HfNDAiZV*-ap+QN9efYEGm!FG90KipU1L)Pd* -C6Xld!Lm6qF-2RE'qrTDBHN)AE"U@ZJ0kf%A0X,pbHiUQKSX#Q*%mb[GeKT3"5RT -Q62b*c4RbI$#eJq`"VjP(A+Y&K$l$bk3BZ34LMMX#CFcjE([,SrLqMIp'3i"#3-A -HUc%lX&b56Q-0L1R&AcGh9`D&GBdUUKCM@RKC-p4!rd`'@k5YdAq5Qb9iE5+8Ij! -!0GCdeI1ee8U+i5l%iTC8$'@fkTpi44U6XE189L8ZKBL80Hp(4U%q@49@cMF4h*C -T[)IRrl&800MZJVXNA1S+P0C"B2,bYSm#MPFaLLmP*6b,&e$BLV"!NchYAXRJ"F+ -DHLc[)q5AQI&`2V5Z6P1dD19-!fJ48c*#jILEAqem8!hS24JYh'l`C$!i3LA*ca$ -rNVj&Dq%#Y*K3eb$)@4'"YEjC@!qNb5YLTXNmRK-Pl9jeiLM6qEmE"29141@QPVh -+LKcIJ800f$CIV"R0rLdIUq#A6Trqh$KC(Gd(VfB`fP!!(cDhRApJNQb)qA3ZMTb -p!PYlJ$YIl43J9eHmVdrclTa4Vqh[k6d[hG-09RG0fIr[C,qH'Sp)k+mHf2r-"J5 -3!)VU*I%[0@Qkq#BU-VFKmJS4lSk1FG,D518DY5phTS4l)RBa1%i+b!X$`hqJ[Lc -5QdM",BMlaE%@F[[#rdXNi&iX*5)lALUU'1$-$R5@!-e2*[2PTAAb'M56c-IT3Gi -Z(,*Ib03,VUea1X5+bR'UB')JKdB3#[F5N[D'5&B3`UGB+rC2h$(PLL@,pYXHi5T -d0'$Kf&CVCRp&RJIerKD@ck`$ecXfR0)i-*AQ1@MFZM@iARUJQ@2aq9XIV`&+K,' -+VZk'[6V&@`6kDD4Y9p)%cVdQ#Abd9TS9a,E5IYXB-FNAHM#qNj&Urp5S)RbIYdc -d%F*ia5G$[FFeSQ5@$,DNfC(fNGR(29a50UKJlh4A52MZiTHBF&NUr9C-%CB`ZfC -+*G"BmPU'Np""VE"Mlp-LfUF)ereP$8KNK-V945+$$YHib'9X`Pk"h'ZjCVB!V!d -hMfB8%,`#YQ5+Qpk##45I3a@l-Z@[8[+N#[%VH2PYT)f)#Alidb6MMH*52URH3pl -Re&*L)(-$K9PcaNr4dS88p%-*-J)aMD",DHSH89d-+HkB0ZbQmNl!#L2p+l"N6PU -XT+(XlV5'2PX0fT@1IUQ*e9R*r'0+Y),T50e[fmF8!)@mFCVE$SPflD1Y'ZEhlJ# -XKXJUiYL2R$XEcZMiC@301dCERNILXL$6G!(UHYSPVMkShdLeB'1a#pHI0`j'YI` -iR0f1#BDJ$fj#9B'a)kI8VYF)ifKLBb,Q3k8K*85e1V!TZ4*Vm*V!RP#cmRYeaVK -L*#'B1Tmb)[A-JI5a1%CpZ*M#Q8m$2@DkKC5XTRL5)NS-"fmikUEIl1$EXA0eHpJ -[Ueab#NSqGC5E`eUEB(r$!!fARjjhZ&1@md2%MmMAK"CPFVmCjTY&'-,d[1B0(i9 -Fbr3*40'593!XEPVcm+XEUbTe!JVH')qRBpaFSrU92qa3J5Q+chDd9-m-&(5UrJe -a12(G$XK9klc)i+G-MH#G21f@AAr5l#BmM8mc%4(EYCTHhI&9HEY41b&VbY6d1+@ -+q0#Jd8NC`DDF+RXS9pT#AR)U2,9-6drC[3p,)CMmJ93GI`4"`Tq$!!Uim'qAQ'5 -LhabUMicV'h-@b!rJEbkf2I4-LbkFMKQE9!kG#pBmH-4"VA)f&S!lMSqm)Ik3!!* -b6D3+b4kKLp0M9U6+!6!,Vq0@LHK*"9A4M+)del,',[Y,Y*,AfZ!*L,b-+C-'JKh -3qqhQQh6-&pY[[@a0!bK#HBF!'kI,j8r-fmTP'lUi*B60B6h*1cKrmpM&(,qEiUq -cVD9H5QG',KLB'Uk,Kp!S*pHiT"M+%$2Q0ErZlr0'K[Ri,DiSf2pqhJTQ@i@!D-I -*Df&09%DXHH%!D1-8F9pAVSDqVTP@2XKZL9FZ&4c3hNXEmR82M(6DJpb45H6D#Y@ -LGV@PrSE(k)"0*)m[53&GSX-hJ`VG'D3#XJ2@bQ4#1[XV3cL`H)Gr$AcUYrir,`A -e6Tl8X#G!$Y`YE5!kheTV&NG8"I3QLR-AUEh+Zqf+D%BUZTB@1k!3AR)`M65!lPj -#,2i6H5(6ep$BJMd)mq5UC@l5q'*3`-ISi13[#,aK*k56"3N8"Y4IXY(jJ#K#BX, -[4"qjRf"r!qHEcqpDNFRBmhiP#1RRMmN+L3*bc$Z8Y(Ca+&N@65!R$$Q)PRd`2UU -MB28&r''2,Hh#i(mf+&IH&*p'h"K+HZR1BC-`YXC1j8Bm*f2NKPjDeJ+'%1Y`+E5 -kRZMD#'r(bGNPL5i2&6!S0`R5a6RIMR#"UGJYj3$r3l4,J46,CER`9iB,UI#@N!! -DrM4c2)9*BSCiBZ['PIl#i4$NQhcKh9M%N!!TS95#S183KK+Jkdmm)L!#6[BI5ES -0U"bLjJlm#@&fZELJ-54pTEM*C%[chPRerI&KT!DCjM9+Q(Tk'M2$r4NMd!2pMD* -Bf68QQ-#j#6*e%6)LS5Te9$$fV[dKZ""KL$ZeT@eqLS4cS&D++(9qfaH%%iJqK8f -CK6)`@mmrLcSJN!$dAd6e#p@b"RDBXk*Fd#lBLVEPTD*Q6HmqN!#R-QTl*LkZb-K -@jA,-N`&r'R#Ue84Rr)a9&1Z#q2AF69Z%rU'Lc5(!5*HK6GU8MFUM*D*Z-Df'K*6 -bl-edI(`"*M2`Q0j'bJ9I-"q*rCCHkN-(h(P!cS!YNjBQ'GM2RYEBLQ9LkAPT9UC -CUYaJ9'j1!GC1@CF*Gc3VY3jDrXeIHEBZ4jNrVSUPERekfcYQa+@X'chd*8HJrR` -QI#YGNci%pcDef[`mL5e`E$8K+'@(!8e+b+8IeBpp!F@ZGcH%I,,!FU6eG%1QX@A -TfJXr6h[rYmRK@MNkK*EkR&)d&PKX&#IZAUU`R9r*F2`k&)R%INX&1!m69*I(bRr -)K4*$A@Jm"(Q"2Xhi[PHG&8(MG(#Gf!1%H)C`4%r3pDHN&GlM9Y&-bMlRrp@R*1! -'*5N%YBqpF,EU`i9TE((r,m&$Q@1M-`Pi!BH)mY-pe1[0T5hT[bj81f&UDEr@cAE -L`'LamGPb#jHSiCid%C@*-1fbk$*2Y`lTSJ-&V'+H+Eaq#)iQ-[YNFJ(EZDpNe1$ -D&J2BS&lY+#d`pD#d[V!pM3eYKFD&-GjE1c$b5H#FKB$LYbE@,A'$l959)JP[L&B -Y!-I5ZqV,,2)3*!3fiUf14#)$-"E!Z3Lk#J!05VJKIITL6`1&fF'DIZ&XVcc+)N5 -hc-m6m!Fe'"V$D&GlI,#$jmY3Bj%T*Xqrjb9&c%@alC0Y"V[pP-B$`05c5q21ihQ -#&+JC@jH[*)U(`#IHN5XPZhBiBFaZqkK8c1&Q-QCGBSR&9KjYV#D92`UA4d5R5,Q -@*kVb*8h+Ce%9DBj0+6I-rE(A2lAaICe4r0dIQ-U5Lp9h,+B4T`j-(0#Gk'Ck(L@ -LVCT$V,k5jSpX&L`AD!bED9&ZE-"@ETF@G(X1Ac&Teep*kj6e&I[(fCJP!Ll)pi* -Nb,h6J18UaaLlPS,Gm[XPDG42Yk2LR8Zj*9)9+pLMrVI2j%k25BhR$Tkl2V4cG8a -%PFMF*`a(e,UIdbhlI#DLKjAHhVmXh9+NpML3!,[#@#!j-[f)38X2"1dp9j!!4XQ -M&Q'-'#qjMQp+&U6N5b&'b`kIB0FALjDDXrVFr@d`YTFZCqPQII-a5hIa#CRXa`r -R%&+&YPei!9pH+1[CdZ[NT0[!5BEJLHqPq0XfVD&+Yc1eh1N&Le)!r30qk#drfla -%S[Z`9k`Kq`SYh`J,"d&pY8&@2ZNAXE['VKNRECm+dRr"l8qDYkmE@-c'&1m)f`& -+Brmqp"BLh$GqFT'Vl1ij$PbNjfjFMK,E9YR[P1UIN8%GJ`Xa8ZG%4iVd4jcD+SV -"`CJb5H9f%FqMSDkde-0p*DAZmGb'&2qA5jcN!YY*p'"mp6Qhm"[a`Rd)"K$16EI -eSL&Iq[*FKEH`q"8mZK0*U*i(dPk2`lhB"ACXSaq0@E[GLN49%3bjC"!MY3K![,S -*`0(R(U)S!'N[lmmPMQ9[*Q6*!M1HhpP&rX2c4L"CCAe9$Bj,CXr&R`$e)!dQic# -$[FXeR-*qR"Cr1a3N'#J[R)8SI01&DP%k&afpMhJFclFhdP$FPchhZ!iG6#h$ecB -Fb$(p8d-UHp[rJAq(JIQB-+Nk1MP4*kH4rYG(V1fQC4eAl`"dM#MbcfGXL3T8"fF -cGp)1Qq`VJc[+*$S1YH(Bmd*YJXmUPhp'!H#!S4I&mAVlIG3Kf-26(4$+riK")rX -iID6A`&mBp$YT*ICQ8BbM0,MqemL-&DNY,XfMA6rGia2iZmUS*e[6d*kPer"rHY) --kPQbXbbPJqCd%N1P-bVVYZYjCXb(RR(Y2rV)&Yd3ZC81L#2G$"llC@+meT5(X#b -XD)85bBq216R3L&pLh"amQiCEk[q('Lq+IpH#Ep@Jh!C6lKm)IYq'@G6XYk89#9U -DV2TRLGlRj*jF8&,DqGZYSkQV14eL#e@H&+0rU-DMYih#8J6"`@YD0@B6q[[e8lk -U+Gf%Z#PL4$cK%pZS8UB!A)dRjrY'fBLjZV`pPi$@B6N9$IJL3IQr5XA`e+2kKA* -@$6[HHXQZ1((pD,SdlHdF8!#HGFa4mYrFkie'k[b"R[qe[hLG,p`QGXPMiFZqH*9 -ScXQj(8jDq+$ASH$N"a`'U'bJ*d01`e2Bk8`dNhmULK`QIpZr&i$LRd,h314Q8kL -2E1ijhEm6aD%h(%Vc0i,dBf"630Q-ZiYaUARLb2RaIq"&qQqbT0@AKZrqHHICA#r -+'C*GZ@a`)DbmGHAa0i@[lYffGY*S-K,QlTPdXBqble6D!5,8A!8$PiJ$@e(e#"Y -HUSa#A+U+F'6&61+D4Kdk1$VJac*'eqP&TpIJ*AF5%Umeq)EZ)&dpGkQHHhh0-MF -(T@f0C6dJ'm0ISN'Fjf`k!cN'4%D2%eScB1r@a`VC3(QQX9BX8k5FfFD"`S&p@'[ -6TGXc*mQCSFpr[&0FflDRi#aKHfia-(60CLC&S9(eXq(N)m,&Gb!Z!EdZ12p9!(r -LaZkJ#Z#0YmBIckc55q$SHdN1pNm"YVJ$*#U(h`k)bE$DU$63T'%*!%d@ILQj8%8 -Z,2X$'h,Bd%RHb2ZQqGHVTS3#hj!!*K@FY94XaKF+0e1XMZZqka2,'KlTZf*jih4 -K3p2Pp1`#NDm0f)5pVKecB45Q*ef&EP[K*p5YX*[)h6BAPGp%le"#F&D(P8,3'YT -P&bRNGUqUjll0&,[MJ,pQhTQe[GI*U"KlhC*+41kER%0k3,G)ARPDb6iFL,iC8qp -)ej@[S"lL@UCcDjmT4Y5I@q9,3bEQNCK"$ib4k03TUkq-N!$SAF2`A1l9HkA"mSa -*DrIKX(Z3!'2e'FXLBY,JQ&,Tbj'&-E2Z3RaB)jS4qhfN&f,8CMM@FaZ"9)UeSUX -89Eq"cVdU,[Kj[+2GdU'-cZ4PeZf8"$k[Q6L@fd5hpLV`Q4-I1qMi)lr0EjF@3dj -F&G5c[r*,f&4ZqH$8%$mVZmp5aTaH")Dk'IYSL%2BPlb6(!NZD3F#%(jbp(Sa+cl -DUF2YM,ZE0G6)dE52Cc[Ak%Pec!UMHb0TR#YVfV9%6Eb*&@H6)qNTf)9"D6Ekm1J -(+ClQZ3TbMbE64qQVbkJd)i$h3c'Uj[BM(X33h3`68ASfA`I@@4jYGRCR$CQe!f@ -XRPl,6RMa5h@kP-V1c['ECiiEq+Z+d1EYQ3bJ+YPX%Ir$",qTK-('K**9ZZ!Le3! -GFYSH$q,UK6JTJKH$dc9Rp23(HAqFp1Rh%!EV#!LR&3!,[arMT0V,iYK`TB5ZF6e -N4@haI,UX"SG$e$Tm4Yl,i@bk28D`K`cAYpd11J6G,,!2J1iM,@8I`hX9T,,XJ0R -R*eA+fUa6"+U[c9HiEpqHk`HNkhI'QYSj[HD'@Ajf6[Mf&R-!el)F+rfeZT*F+f" -dE0iSU9@%IQ+%D-36(R(H(MdlJDE#eErhfS#($!F'[-@AQKZC-L4f6RZTk3*YQR@ -GP#$0ZbV%P1Ullqb,K!4V)+BadTa5La'KZN@j6@B@@EE6XX1e'mX'1@89J8K$J@1 -'Tp)Ud0he&-S$PK$CB)4dVISR&apED2KDQqM!d2Tc#8p%mK1Fh!&,,T%P*''m*AH -,e6,kH4i,VNT+3hi5&qk`dSZS8G%HKB6QVCY0XjkK"PNr0ePkNJaDVUe4THZ-q[K -F+LG@Q"3D8GDMZE2KQG8IJ*!!@@#jEfXrjf%A2MLmQGdCH(Yf)T[M5Urb+dZFGJ$ -CrirQ293T@VBDm)-b@AFGrIpC'$a9d@%+`4(EAp-*6aHHHc+3!)Ymq2I))(UUMHa -!)8p3[EqB%HP@mGD+&q[)CiC',CKSfIcm'H95*6kKQr1idKUNjE8+U8ZL8H!qCZN -,HBf5'")j%aP(,62V0Z![SZSAqk$dh&BNj89YUKMFPmKNf0rmN!""2hKKEbH13-L -h!*a4I5$Xh00"+Cb3!+"KKXaaGdP5fSX@p-KiGPXiXKi,(L-%SSrfA4J!FVS$96* -b5XQ+2[66[hGm'T!!b+51i-KC$lV$$)9'KXAdZ[+pHF#MmE`T!jcAQ([I'%V3Gr` -C[',ISaiBDF0RT%SjMjqlj'ZQ+9T4K3EM-k`AH%3(2`JGPY-)(FiY%GTkZPVA!fP -M9I[!a3@l6"C+0'S!!8Q%TF+MrNTJY9aL!%"5J5@iCBbchfL4&9e8mHd*RTl2@5E -RbK8T#JZC'!d`#bF,m8iX64fcX'*SaXh"q1jSfa,2(b9(#"Lb)MHTmrK6V%[cNBC -5m9!JQYFfaC1Hd63jdBbEFfafG!#eC@RViS2ZGrL%M5"'b"kF5I@)2ArFe`NJl!p -+YG2S(+"f+(KQMeL"q@bBNe0@p$fSa1TSqYdrN!#(',kH[YHh59I)c)T0#T1I4PN -ePA4Q0Nfde6DYV4CpqdJl%hG%iG-)C5l8(i8'GP$KX8YkJ*)Kj6@6F'`9JMNq+cQ --f3mPRfpKPdVU6HQK`$jIc9VTrDGf+MNEmd5RrNR`Ld#MPVTLl9jY0%5B"q,YR(` --+U3*)VbjGpeEM,[q2K+Q6Ph`0-5cQ1q-Q"!KdABcUliN,CKYR51#@!kQXQ*kPF` -DI+bUVT@'ARd`a@BYE'UG)-h2!q@DAS!3$-8hA-*cqEE!20H9CQSN&a!Mh-[)q!P -98KdRMjJ%0eMVQP!%FAfE0S1iUJ9RV+SiF[6,ee3R3DDh&K+M`l9pe6!MH!6PI@D -8ijfFM21e!G5HYFCa"%H%hH,CAceFe[AMUiJT+6HHj-9,TlIm[VmS"kJKp-9VjqS -*Kim5mRpJ3M1#B9NXL+kN5jRCY0jjqN6U(6+TFT&8j'[341Y2)NVIB-A(DJG@+Ur -EP@[p2NY2Yq+0A'IMYR5d8mI*dfM66c($iTASbJ'I@1E"2jih+V(X!![DY#8J94A -@'l&9R#fMVi3S53V#5i`d&FL@rNMqVjHN*QkK)BZEZ@N4'k&aeSc[JYB6[XC6A2C -AX$q526M6,K"qK8YK`2'80hkPlp6+1XT+FpS1HMc+IT@$XU[[ZRldpIh+*Z!efVA -5a@C%Gr"(Kk80Ykj)mE4QQpJmQ1"k2dZUFFfZUAr@QLkr2P**6`ck1IT*H9De-r& -3H8D1Ub(!m9)E34Ka(*4&!h%(IIIELDRZ-i6r%F1IcJARlj@5p%*,J2)JFaUJ6XJ -!GDk-E5,@Z4eTD'3e9GMSZ9CrYLS&K9"'NFf69)AhGU"SpDTlEIC[rE(ai)6d5eI -B%8$mGBBPX9)f6P$pEDL-E"$L'bN#&DSUNh[R'Yk5N!$mPCrF3Yc3HhQ%CaGfA@J -%SXH2Sfr-cc"kjMeT3V!40-CX$NXjR3R)bkKQmTA3+rE&6HRT04%kJLJ!("R#TkH -4)eEXb4jd49'4&4*m5c)d5diI5HlcDl%aQBcENkU)"Ip[VC`[@AAV4FSN3jjhAF+ -rFBJefaRA3D%Hl)F$kb3dZr"AmNDbHA*$RSlppT-k!9-(38APUEUm*UI80rGFhIr -XG'VUVmce&fU%kP@*268,,JmYUkLHV+b3!1$V923%kGYp[mMHHAV)%Qc`&ejQeHQ -CT!DlSI'4EG1D+9cFSc8p8cBaM9SM-PKHYFdk5i8)(al015UI!GF@H2`LXV9l+hR -d0cjb"P@0[M'P8ZmmPR`E*R3$)@INar0C"!hC3Li6c)VaSGZe#l*jL'$d0Kh9b'r -bj@[@$,b2jBFQCm6#l)[)NiCYC,cae,[khA+80I@P0*a%mU*-P&`J(2Pe3fq6(NH -UB8XD5f+E+#6ZDGl'$2IVL@h+N!"Pm%eRE8U)cH3eTjNi8r8mC1"$3h8i!ADir%r -@[G5*mp&1550p6+TFJAi`Nf%1a!bZXk[pCGq"0!"eE!QCpdJA4'rXmXHY64Za"GA -2B%%GacV`Q1jLZQ!(eS'QQP,Ue'%hki`9UR5jRG11AJh$ZMbPBm'h`"4m!iVd#JK -QRdmrl#35`ML9R*GSM(X6+UJhfEmVEhE(fUZ)$b83FYFlq#TJArR!&Z[$I[[%$&4 --)H+IZRc[m$c+*5VMGiae`Y0T*MmNPJ--9HC!@@!U`hIA"Z'*)!mLQ30U@qVHI1- -irlGFb[d4BYJ2#qJlb8%DYM&bUK-Eq1U+R,!6(jhNl2Dk``8`)A6Zce[SZL!#3Ca -B(f"(ZF6[D9pTNTF[8MVjXI"kS"1C4r,9p3QJEcQM"NB9BRrJ[+p[Gem'pGjYfhA -i6YA`j[%FpF$A0!ii[6)Q'9JP2U,UiH#lP&`&,KNC42pdVqZMC13R'+Jj!1MkK%& -d2jGYf6HUJ%FcRILVZSXLM+4`JK6+pFj+ZbEEcYZ`Vif$![T)mEM[#`5B#AAhd,M -j+DjZ`)CPC[S0j3iGU,"2Cj-Sm5Y6LkQ`amqPVlS&!pG*9T`&h!U&NCCA$4K4KhH -@NX29bXkJSE3mbGfU&Y2e8305N!"&j'M$5RadSm%DV2LM8RaD9mk-0"DP'%h6SQf -ki["G1TG#Uc#&#!pBe,prG"jJbd[`,bTCp%eped-UQHh$,,&*Q1p@jJe6"J&5e%R -"4&4ilf0)(a$`DFMd9`fLb5dfZl1IUTX'6"9e@$KMpkS,YJB6adZ"%h`*[LJR4+` -&AAh`6)i-XmMZdPR%PdAZjUCQ#'#FZM`i-#Q["D--Y#pibN,(00J0$4PcX9YIL5l -)i5k'pAa2,c-k55$TVTAkc9&CmkHeLad0GmfS5@P$LNFRfIkql+rqZZiK4GdKS3a -ZGTIJ)IUL84lbMHjQU'I+FD#,qM2eH0mIrmNL%*9iSRCRURa0X4$kj63N#H5[cpq -,TCmiX4$!Um!BHhB)8Hj%&f#(31AF-%""c!M6NRhLKaZSCcYq#PkaEm"3E!M@kMA -rR(!%@2DM9ZZeDVR60rp"fE46q+X,qeNMEN[@DP`![lhR)EHI4K)Ylq$D#1AJLID -EC+Bc$C!!GH"5Sba3($Ck,8j4[K5NQ,6`1SKki))dGYBU!82k1(9TRFpD"XI$!)J -5h(YG-9I59+`U0C(!-!V6IVBi#5plX6,F#ZJHZCY4bjk969Z[5m2,feeAQL5MNip -IB$eeF%a%09k(MiQhiBmqYNjqjc1T%2lhcCEIXA)3je1b0*`!D%*!SI3,NaiESEj -G(PbX81SGTAAKq6cR*ENBl*I4`C*FBfP[Xa299N(HVM%2HCI5Z1k**""CBPUA0a9 -6D3!)R+DYS,YH+pU`[N6kHV$rbUCYhqlc*93&+5Z`F8#cYYc-D9r1%l-FY#aHAfl -GU4,TLQ6!b(j*KS(B"D(Si(926LqE8MfQ[Ql$$i@j`&'&8bU`4)0#LElHSHS2QR* -KU"[VaGHAB)(ZlXmH)Rk$,&BIbLTeE,-+il,rXdcYMU)!&Ta2[A4(QU,PATFkQ8h -3K4KhI4-f8(2S$$l53eXXBq0X`NA4K26frJK-Eq#"3YX,A40FRBiJ8$`JS%(Gl,* -CFbfl)D[BMKT`I3'2m$+(FCViF@&h!)83TC!%!3!!43!3Z#2DSEJMfU%!!$Uf!!" -[HJ#3!mi!&Ab"!!+N@`!!&U`!N!32!&4ME'&`F'aPFf0bDA"d,Xq!,RKYE!!!Fm& -849K83eG*43%!rj!%!*!+J!#3"d,"e1,,,[4c1[kGP(l3CH2J[q1L`A0AZ$9CE,# -R[UmT+,(r18[&%a"P%)!$6c69(Z(K%BL4mb(fq%,`eBFPQXC,P3SM-fbZ3@L5#Ir -(IarMAb2EDf%%bddK@8Ce$CB[$Q6r'%1qUa1-80!c8LQR&D94cq"*I5jaLaBEB%L -e2H3LG8,Gi!SMBpK8AI8CK$4U3%(iTJQ$+61E8ZF",TrZH[pVMZp[G[L-'e1H@$& -2Ak2%Ar55l2Qcl*I`[V6)9$2`TEj"KdPBa"h9bRb4d`JMb-2NXU%KJS&r9N8fB94 -hli%5FpfTdFc,D2bEl8)%1!e206-C[i*%9KT,PbYl1'Zd0ZhEc(Ee+T0KGbhIceC -0LBF)N!$Za!mUZeB5Z"m-[@fEimm)SH@I'#iKV$Z2HD@rYLh)`0J`r8f85eYbQii --Z!kJdeU"N8P6)8-2CZ$F['XkjiU0Ri)*26-@YqZ0MfMJ%9SI[!#0bHrT8GCVP9' -kJ5C[+C00#LKGZG[TBKN24L@R4AEJ@BGJ+4+`m1Z$V!YD1BQK44QX(%*Bia[i"PP -KYh%VM8KXr4'[*NF5Zb6"D98d53Db&pD[I'ICcpcK2+)h"rLM"UH%h3QdTdIK!F6 -Z'L6'cBFYIXaEA`2Ep5lXh2@r"P@LKhrJXRQdU5efMeV0JK-Iki&QhG2QXdJ3@K' -j-apI4!&53F0eZ)bl1bAdSjI@p4,LIGf40YQK'%41NHaQ'&pMNp6ZI32QBS#PH%m -N%rZ4a0hFN!#U(bIhZ0%2j&!QHhK0BR4++6V0aaF(q!rH",UD*$k!3G'iMbd#,PB -+PDPdM[0rYbfV@Jl#JX,rV[V'3Cp!pH@9SkX0FA6SaMRi&9J&Lrj&Bj9aM*9e!l9 -!RiZ!m&YD2EFMST%3@M-KRi0"NPKJYfeaBpmEN4U+)SRk-Y0+!JUErp#S1NSMD3e -a!I!kQ3U$YQAX@fL0j1C0JmQ9bc8I&%'ZbJ!+GQT#@E6BQY2*VPpKPrr+R991hf0 -fB'i&4A[C`6iT$0)U066U`@d(b4IHc%2$pGcU-L'Y"VqhMAQ8jRaeY$Y$dJJ9+LJ -R!K`K6mKSL5EkI[eB-i$X6!j)MJhe8ep5KQII9"TCI&qMQ4BRp"H,lmb`hK!ilES -5-#qN+M#KUNSAQE5-!9"YTRiK4ZAqqA18HB4Yq'h`P2P6)G%I3X!5DDXlZ'+YA4Q -G*'"Flkf*[-N1!$Zm4bCRj+8Z$NJFTcjI+c3am+m$3ThlEi@"4[I3P,er[H"!a90 -*fLF[A`XeFM3V5J,1qbZNaX'l,ScmF`ALZ6p2jZ'3!"*YD6T!#F'H%f3Z[r&jHb% -r8BT'P8`Gf&",`6%*pqlc#cHedljTpaahE$@2V'@EI&AFk8B"HUb6'[6c6X[4pT8 -Qr8q[9ipS$(Q+h`3,c+NrX[413(em+SbLPBq`RQi*lY9f8m+'R`SHh0X%Dr%Jh"D -ST4AMSF)R[XERYde["h9`hfLb)C0QM*Pc5HC18Ji9'20%)PIrG"!99aaaTjVq[K% -mMY)Z'mcXrS3Z$l0UIhdL)+J5J+!`hSa[r`MPcq55*"1Ga@PScIiPXjJJ80f2`U( -c%i!kFN*$3F*'`KS*SE6h"[`#-AEIM2BM%BhGPcB!iX-c81*pN36U4Y!-e40Icl( -q2RrJG8$B1D3S!h*2FP$cAk&6%@0*%&jeS08hDpA0ePD65[Hqa)M'V+ha!V#*+k$ -jm,[S!dbL@ekj,)3XXNFfHLP-@N0"KZceKh,Ce(jaGUa%+e))hEa-KJ#66KQB"h# -Zr#+NSjVLaeU5,8C0r2TBX2YU$@hZeN$kNT2pE6,&)lAej*GA69kK0pJ0BfJBYbk -%da8``L`-*&i1hF2hDiNLQVRl%(46LB2l%-UINKZ'%BhHAA03YQKUT6afNB"Zk#P -Td'TmjIT#`k*mp`@XEhXN`(E)bL3FTX9MF01`RA0iVJ"1m6LkA"QYlaD@62+9r#Q -JC`6P)5SEG9ZQ,l3pf23`N6U6[1i(-P%2KQ(KAPUFd)Gf*"fMk4B5F@KCf0p52MF -dZMR2TD25'h%DHK'YNAlL'(30SfCP8NDCi6PG$kPK5r1RG"[p2Y*4EVHfJKeIepE -E-,K6A)aF0J$d@h8k0)+1'X$5a0IXkeId`)S,BrIQ[T8ik3k"URFBkVa88)'80MT -KSZ0*4$kqB-Nd3aPMa34j%+pZ3$TY3bDk&ZG(0mIl[A'b3!(midmGFfVLPZfeJ1) -T)5m8pVRLI,bqhK[m&6TqMm@2acE$UlAE05eI*"5cUMhFLf6k1JBMMR#4PX!9J1G -bSeHS&"-6YB)33e2ja1f@9A%[*@83%D!#UkGc0&)$`h5q0Uef9A[QfG,2!bIc4(@ --hh&`&i%#0H6K*q%3BjZ-cHZcfI'V@PdH"db*Y280fr'#)bZ%*bd0"hGp"*FLR+" -$rZFQR'%T!-EIiE3YKAU(@&lB0l9Yi*e2(UI`*qC0&`f8KGE1m6Q,rfkZX#*-KE2 -Z5%NQpdUT$J!G*[j%'#'NL(JE[VSIcVc,9Q[bNbA!%@)"8&P@F`c#9HHk49#M&aF -3S@G"K6pj$T1eUrEYH"m5U(%'9d")KhP2N!$fY$pCPKqJdR9`Q9Vlfje4`PQ94b4 --cZM44pU)G+(ZK'@cVQ9cS#@*caPhmG(@HR&N[q1[ak,9Ck9+Aj6E1+P#%,THLDU -N'+C9GpcJLS,jjhF*ZB2EU5C,Bk,B[cU5jI*Q80(p8Vr4E&CXRBI#XNl`6EFGXjL -!"dIPXi6e2T-jPAKEh#AFPPpFpX,DaMrq![Q6-f!&d5V$cDMQNQpHPlfY3"'0M)f -Z6A[kLp(*HX$Lf3YDV,iY@cRIiMGSplCh%3`VAMR*PcQaS1*Z8)pe(!q4e5*-Er0 -mNCZ*4)f9SNm2`HfZkjb8-5AJa-cr@4T5eYZDS4NciT!!5$+qfCbUHBcm!9ClFd( -pEqDQV%2dPXM"HhQVfHB8bG'NH*8TK0[aSVm$"%`EaAb#YN948F&iQH8@##3BA)3 -$Uq8IiS!3'k*FG'cEAd#p@jjkp5Ba+GT5`Z%rb$!1frGBqP5cG[J"P#'i!cJ'LV# -IIPp(ZTQcFi)eUZ'F*a1RbjSrbTSaKN8L!iIrGb5ab8(m9*4Rk9JD3(RS8(B2Qp% -3C"bZkBB'FrE)(Ym!F4B#jU@af91CNEGJU`a3EMA`6`0Ze2lMN!!XcYGi2Uc+L%0 -"$'++&GjD!)eCNSXkQ`j&!Hddpi8+KThBI"HaD@[#46J*8CCZlFQRC!cQ2VXA3F9 -2dN)kD,cFcUB8,#-E!QTdk)`$,Mbm4H(@CS"PJke3QF00VZNA4b,mFG13!$)AYI$ -'(AjAach+,RTXPG3NPf5fZcJeIp9-1LKa3IeUh1c4GNND`h"-dfd`4f,J0f8qKTC -Z%AJkrPSk(L9l+4mL"p3bBj!!6,2D9@Lh6dU*JfhH&lb*PYX%&JI%qCGYp5ZkS@p -cl50m&NGV$PhA4J34GeYFd0jDL-Up"'3K@P%fNa,lHh$4@eVBLI-R(CT!8f*i31Z -`YrCkQ1pISe(N2UpbYqE0fQr&PG`$RlXC$hdF!R,Xm5D9iIV@@Z'(rPZS(G"Y$V* -43$1G"R(428eBPV0!A!41DVHTJK1aeFIr3chJN!!Z!$Tp56e''R1JFcdJG)'lkDX -('1BlCqM'KKfF4[M3T0Al%RDTV3UaE'[F`%CG,Y5h4HdN[%q[r'8"SacGBRF-c!l -YEUDebP+,D#Jf'+'Rlk%D+m1Vc9e&`@AHU6'AAG%cSG9!HIe*DDF@idi3q*pcGEa -FLeYNVcYb$h9p$K!@[Z9l43-Tr5U9CbC3LXdafT`45-p*[plR+l-q(NE,XpUK9T' -E%emjcC5Xq)(Xl1A[$G16'8mQ4X&TmXfmm48L@A2F`Lf8$*m3qj43ZZcV,KqX&AG -P0*hHc3%KHSIXXNB8V@[6f9rKaRV$El8*i9AP+K2pJDcBa4U`U,Hr%K4ihcT-#3- -kJF#CQ2rc!M*N"NNNrGQX$aXl-iGhVG)U&LM4HYCf*Y8%JD*h$)[-9,pcZ8,LZ2I -XC4,9)YV,VA-$P&f0UaH')**XVMKZ10&cKjhch8ddm5lEPqk+S[4+F4&C[iR(Qif -8IeCTr5+[hKB8ZalG$PdMl*M+"A@!X@03G,q!EqU-RmD#F`jXq)[c)6()CX+ZXNi -r*mm3-ci`JZd`pIH1rBd0&m1m6hjb`1E$1A`Qc`l!j1K@(5[#,E'!kG+c`CGY@0Q -BfrS@j5DL4imCKmDS"HifQYbVKIES)DFXb5"4NbiNTX&DmCmc(5,3@03+3)f%JJ+ -6+6XRerSN3(AdD`%"Db8mZr!$d"k!YI*PrQF%IBj[r*[+AYJ-(U&G-eC0TH*Nlm[ -[eXU,b(B3RVa[#E(r-QVhi,B3Ic-f@DkimHdJep4b'+im[c'Dl$''8A2AT51i'J@ -fPXIDQ)[U9B9m,8j1rLr0ePfeKR0'$$FT'TdYHJrqB(MFHH8dBiRK*A35+lCA+pL -i%rkmEGUlBZ"GX#"RqB6hXi5LeAQpR*LhbESe,84XeCZ+(c0IV[aUEF&I"PbRalQ -pD8$5YqIF9H`,VbF)aQr!Rbp*Ql@BE[idIG0ql6lDE'XmQ)*rYFQZPTj4X)"h1RF -aE[MS,EmM%,c*kdbdD5jIUkb5TYHFf$Yii[q"bSJrBd3Y`CYRmH4#V()3ef%eF4k -@5@pX-#3QqUqmqK&%XqX-Y(G&IaR'Q0R1"JGSI0+GDXAhK&e#KrQF@&eh1Ua$jC1 -`Q#L5#R`)E!9r"MSad1kD"QI'jAeXZ9U!3QH-j9m)8Hi"5*)#E%-cafUc6b63JG4 -E31eIDH6eRadA2dpqM("66M-CrKrVIrq3!%mQk'"M8%ZTTp(Cb10(L`m2$&462Tq -621q!jXekMP&pS1+2f,m'PVdrCIE,db1X*)r2)DLqJ3R9R%r03!BAl6F@Y'0"Qi! -6502FJSdECABYj,*SAr+G&f(XFj`qDMhUUr&h5l(crpr'R3Jp!!-d0UQAd)-e#25 -1J*F&i3d8R[J`D-pl-@2GKXMAKh!,A)B+&H3KeVYP`HYBA%'G,T4qkGSU9c01ED+ -PElc2@%lFE2LeE9#[SJC"r[Br1ia'pYBUbAr6(c[FBAE1S3dL4V%qM#G[5X[I3La -4+A51qkV&,,$6[[PHPT4h'mPVc!D$V5S6KK!0Ydj6IDam2K@H'qqkd-*cHj&#ELe -m`r4''d6900i+8F1'&X8M6*3I$9!R+qUm,rPJVqc[9X[0ZaSK@32rhMM45#FIf-& -jpMhG!2'b43)@V'h#0l,&XTGHAXh+)T["+S$QP5LaF`*kQZ'R1Nj1kR"*,@h"8rH -c*J!LLf`NiL0eM14Sr9q`US4h4ZcHP0bPeYk(&8[,ReAGIlNj*9rIGblhqr+,(ja -%`D-f08RpGKkr)2(14GhkeIcSiJ5N$#MYQR!mMm[hj%*Q+MCKiJiDQ0@e,-j2"LX -8ea2idVq"1Fre$DSF0l&UqEb`656L%BDrfb`NBbIT@lMbJKq*j80$km'9P!I#f2b -U@4SRMZ36E$!@Ra4'$,'821KIY&Ep*aS6lcGGF9B$,34b,0`6Ham1BAJQS9M9mGb -+Z)@@FA#mVYr63#)kS[[DdrBdD#YRYL"IpS+ah6F-!3a9"-6JC-CiEVG&BlZ0r$p -SL02F'I@`UQ`GMdil$S)F)Vq!DD"+Y@i"j[-6aq1SBUN%4D9VE*K-e0SLLq0Lb3G -)NBAj`HY"j$9Ak+8p$0M#fV,jST!!c8UBa"V*D-j"LR"P2JQE,*CAF`HC@e8DfCa -@C4C2TScV4AeP*`Y*dmj3e0XNL#2*ZNqfFKIQ#rFekNpENdrh,"[%DVRXI,pidAU -0k+Tk**2%&e6b#T1hCU-pr%Qp)`13!%@bIEqkK#r9)4ANFfe[q[jK3Zm([-DfbqV -i8,D`+rNm"rGQS$jlFS0PC+*Zb3$l)G$8)4Q,mN`TEG1r30UIlp4pIUY'SR%KaAr -6a4M5+`JJIpX6LcA$q1lC%$I2m&TA&fI5)8qLp%IB2L,Df(c9QXjmi-lKd#ND&S$ -)KL$lN[SERi@VkfPiA9GDM3m0d`H@5aiFlYKm[G'(f2Q)DFV90C!!erbdk((U8J8 -+UENPG,ahMlK3URrAf0Thq6A`VLN-H'$JB94rM(C+LX[@)pZMFP,J@TJ4ke-FV*) -jdYP[IAT6cl[L))a[3SQ1HH'5UlA51cHe4I#fQfLqm3dB$0*P1M+"N!"c89pV(6M -"3*0)0PK'-[C,P&**R,q!IY[pa099D2jQRqJ")E1&h,rhkH494apLS5*E*!%jSkZ -R1hGDZ,AP993rH@H[&3qRDKC@XB4+[d1SPpYEEa3Q-LHp%CpphJAhkhlP`Jdl%lG -RqC!!"FP@UFkN9$%adj!!1'LX,LUlS4fC*0qJjHN(K#Ufp"i,Rq95B,&-5MI%pqp -%GB@*+Xi!38'DXl4940TA'5Mh+EbG*fVfVmP'c!YcC9["P4X$m6&TfMN4bD66T%$ -5IIZA4H(bGPlI`&lGVQI`ClBI(il85K)#M5fTSq&(d1T11aK)Ne,irE`jK`a6+mU -EIJD'P1IkLM[e!UURqB0)+5I*4$Ab9,`9h&9+&af`jl,0jbZYNPMB03dDA`ZZqM( -ibH+%4Kf*h4eLFhG*J8I3CQeK+(U'&FJ%(TIJHdcGQcU)9"R6$A9$lh`Ydr'rFJ, -L*XiF0UkjdP9(#DkaN!$ifbdhdM(GTB,U*'!Z'j88lKR"'1fEfR[mV,[35ZQk1Kd -,Ref58-N(Nf[0)3AVU(lkhME00Cr$UQQ!LVXYha#2(mpZ)Kd!)bfj4cRk@MiKiGI -9T##RL!8*80!%diJr@0BVN!#1%@)NjXQ5fiAhkG!r5h1i6"XXY5"+3N@EGZIcl!b -9"4jj'C3P53!j2rF%iPVQM-k,b`Y#M$`r9KdJVAKXijXBTX6TBmL9-DAmYmhT33L -hJY$CV5FBF&kliieM#'"lA%XTbjmErDa3Y21k,k82+$&(ZYP#d1Q!YDYabY4`P@f -,Pdlq*IcA`Z04Zqm5Z-"r+jAcCarNDmq-V1HlcRX,qKSBrqT,m@%U9A0r23qDCZ# -kPiRFF6A2+R[eA432VF"IqTUB+b4Yp%GS9,MH('I9ZYC`))H(SB"2mAAf$@TP4ZP -[rJqrVcVHKNXqq'p"NAA2R)%q9X4QCZTead(e!ZQh*N0(HkkHC,VhpAC'5fU$)Ka -mL$[d`,qkHP2e$D[8L-Ub*`&0Cff4d9p+LF'5VJhjG&8#R*3SjB&*fNLajEf(L-j -`244fB&j2TbRC(HU4k+!MEY$KjaQY8@`Ml`MSbH3RUdC+fL*9L`(,jI9iAlL49,C -N-mN9,SmQS`#lI2mB2B[M9K@XFHlIX9*hD)M[GLV15L,2elIH)T&PMTAIHLNdSpK -SGBCeld),!U,1Zf5,dD-i+0Cdmm5+6pQL,qV1Im&Im$5V39+[ZNkd#em)Pa-3*%4 -d%@42EBbp)XK(Jm%,mGQ-Hh0!KVi)G'8,)j!!bae8SA-j&B,690p@V$+H-"K8m8G -0RjZ`+RHGkfFX5'`"`c8!"Y3q8FB&1VXD"iJ*GpVqA`[C!!63CQ,FX-QqcE8, -rAkEqlkc9Jb$m`6p-@Ih%pIB@me#a$G(eQc%fY8**PGaCT#,1l6C%NI5QEZK'Uq[ -FF@e+IC!!('%rJ,)iS--HJ-jR1`"'(TPe*3`&2G8NfQh5qAB@FKkm)36K[LRc"1q -N)9"l6C53!-%YHf$2-&QM2[S93[&kf-(*Q3T#8%0$VrHD`#-peL$Z8F@Y""b)SFB -VJ18L6bU,6GmP(k3`h#d'pKV#Q'J45*r(fYHGd+4FXK2R-Bk!TC!%!3!!2`#!Y+' -MYVJMIH)!!&KP!!#i)!#3!mi!$i!l!!9UH3!!5%-!N!32!&4ME%aTBR*KFQPPFbl -2J!!!3,*069"b3eG*43%!rj!%!*!+J(!!N!C#`G6"DVkE#E,5Nl9qmI))CVU"cJC -!ChD)!ci,F&BKe1BZp)I`)@hrrZ&aaLU)@hM1i!hNjXd&QJ,0iATRd3Q("p-9`qP -K$`[4l$i4%*KJl*JrVYpUia%06r5qAQKXd$I[Y5b5HajdjFj`'kqBa@U10X@l!BA -KBS'r[UP6G1E$MTjI-ApG!cQJer(SK`B!8"(b8%E1mH'XMl2q8eC0QiNTp[PP,@V -G)pA(Zm0B0`#CA$+T9I`VBJ%D,0UPB2FrbQe)jjZ09`#S9d5A!))-eI30Gi2EI%5 -IG*aVj)m6`HeLY,Ia+5fA9`lBeH-mALb@)HHB$94Nb!Bb1a8jMbrB[THQYh+VR9b -)N!$)FmZNU$PIl8jG$Z4S,dR,HIi#"JKm@$RIR`-@&'9p*2pL$Dhl4rRr`S3TEpf -UHZ!0@Xi-J-SY9Q0Zb4A'$T'-(D-9X"S,DH"!jqHX@5&"Dhl`#UH)JY"fSP+c&LL -[h0C3QEh*0kdHH%E-*dd6G%XK(Y$,V189!m'9bTc+RDdT3JpQQ&EQ5U6FkV9-i)! -40L`Bl"H-T0c$"C0#('N*i*k-!S+k#jj6rIf1!h[lGYUXkZlPYHjm3,CMA!KQ)BZ -DR%e2JE"GB%Qd*8Nri%$!Z!"3cREfN!$+!ZR,cpL[aabB540H&jCE"aXZ`NeDDkl -IZhBC6!Z44GIJ&HCh-!GYNTYpQ,*i-ASK@E$Td"R6Q$MBZRk8,Jpm&)IL5+MM,4( -'e-CrK60%2$2,NeD-kDB!pJ8q&LrXh[kVai9`%Xi9jSHM[2E(a$e"50qBe!&8RI! -"`Nr$DI)eD9Xp&0&Ulj0XSJa0G"bkBL,@Y#6e[TI`pI4p[RH5e68lm1bRmXi1rU' -@i0d-1-UN8TS3'$`Q0h!Vhk5ETh[l+mUf`0B45ZeXSr2Y`4EY)'c1U&jAPI-G5kI -MNk3hqBM5G$CVr4iFa332eY+Ak,H2B(53!'k#RZGlq#$I4Rf"eMl2-l*#93PEq+D -%0#$U8QHQ`qI[2A@KZ'#@YJL)"+!fKD3Im5k"09XU@0[J+VJAcC-,JF'jZbXG*iQ -8lR+(#%GXT&9AN5L3!$NCAMe4Nb9H(c5bd3Nmj13!LkZF1bMrkmSZBHAjVGm(ZT0 -05@1QX&81D2mNRA4H(j`kb`IPMLCT,3c80&C8B8BaFBLXh1`YphC`,VT$[XR&*J( -2A&G-J"1(Q)D3!)[,A`NGCDKP"Bajla,Sm6HQL@HhYp@Sk&E!!`daj1BlKTEE6,( -X$KIErC%Z!TE0A&F)I,U-Kk#%pTI!B@KR(K6,S`jf(4f")AeK"eiaV9*-'"3BURe -ILK1F8QCe4r2Yk6pIfqJcG1ii,XQC)`lN*9*iPCIpF2S41Q[fE'ZKAQaZpbfN3-R -[9K(q1L+'H!0(!pH`3&6,qh%S0[TQ[Id2iA)ZS'C1P6LI9$SqI"K![hC9FMkN-&0 -j#eL,HaSb'I6IU*[9C#,0'#j'4DceZVprRT6I3bae%Rdl,$,+c[RUDleE1)&GM$J -2[aE6mH&4c'km&FAL)1C&TZN$(k0S1JETJSFQDSe'p&65QUIMmj%r!0SCqq`3Nj' -[8'#6k0Tj"N*Pd&ca')rii(V+iM%-*V%mf)Td%C4h,kEjG&L%%kVF`)A6qMCAbY4 -kSTDcb,[V[lpF%lAYA*%C3+2*d%TH%Bi6GNbBkHP'a'[j*m(&`UTGiHSPFSj-i0r -53&BV%pcqdCIMC2H`hEik19Kiq9XGN5Y34+P&8m#e2qPCEl654SI#i8USJbXq#*5 -*NdV)clpV`2GH`r0(h1B$9L[EIHjrYB@FXP'cEp0daVYb13de3L8A4VF*@MI5Ue$ -8pMR!$MZfF'GNqNU5IhVd#FfSHG+hV)P"h9fIKMC+5QBhZQ#`4e%jqAK(Tmc0FU+ -*#1c1bYQ+8T(j9)$$MI9X0TF[PD+I+[M5&&0SMA$IXXqqV9PUmkH3!!@LG&kSPAJ -96F+L*0,4KAH-MbDqceS@)C41H"d'p&dehYE0h"UdiT8)BLlR,"G)&+pE"CEYc+m -QQ)JhTb$5p#)M$AdA"%qj1&2GbYZD"["rrZK+-h4`Xc%N*$b'ck$L30Z`VHe'4+R -G2)hK$5"dHN,3IU*")-5QV"A0@G46%`hkMZ!Zl95`'P+JV32rlbN8'klNi$e1%3I -SLLY1,e'42Cab%`qLqi%4L1Y6dKpU1`Z(VrC,k50G9XlKpZ)A"X-+A1Q,1N4%hTG -5#aq'e&jU)62X'2"N%HL9Ne%JSGd!%M@'A8BmFp4`U,%"dPi6a2cjiVM[XC&ER%L -TSh-kQD0TCJL`bd"d'fM,k5$J,!d5EZrAk8F'q&4KJF*-D+*S#MjCLDaAPHZ[k'a -JGpGTGPXE,SB-LM$c`6BC6R,Q$-0emmL,KZ,U-T5K!rV8Ie4qcdrA,KF1V,hN@lE -#03lR&l$J8L(cN!$5NeSYlFR(3l0[d[0KF(jRqCRPbMHp%&60$l)40a-2'*VfRAT -fM&3&lSUBbV"lN3ANd0MlVf'jd&R&iV2FpqUY"Ue*RleU`N',318S0RMRjCTAh`" -h3Jp$+jVVK0)jkr)CQ[cUL"C9*pCECMa"KXm4DPC4k1RK@jCD9+LLck!Q0VQI25I -13*A+hT`AH@9Hha9pj'1b6Z@k+$K,FllG@$'""+YK[QMI0%&!"YV"C@K!X@SqfjM -5I*[48G"*55hJ,'X#KDS"kV&jJ0Fc%l$lPR&BhVL((D1!+[Z,Hm3ERrq*HC!!G[X -b'R(EZ[4#FCI+1E%CINll(dl5&5f@c!M#F+QX!B)55)mp8d6`1&,e,236Y#Y6Dai -"c4ci&VQY[QiRk2'cG#dPZMHP[(2QfY"meUG4qHY3GDQ2*rm'ImPiM9EKNp10`fJ -#k[9&p8lbZXf[I68`TQfVMP2@4&p%&#h,+jcZUQlQZ)DqelcNfUjT5MP[QQ%k9+V -4@22@eCI$LjM,6+k@-@NVh6q2GLiU4R@HiM@$+arb2&JU6HK(jMA2832%L'8V$!e -daCTYM'@HSb*`1UJa89'cPqLk4-0q+FYQ85Ta(VaCEFlMSmNBQRPf%'YGSV`i6d0 -E'A5S$54fF@*'ZUF$qQq,1!8NccD[Nd'X&aL[%$PPQ&DXTFLL[$BcqG[m@NJDPp# -Z+T%5V`(a'%eklQR2S`T$-%BC4kl*HFe*(('q0hCALS&-$!b3!#pcd#5e)bF-5ce -92F&Z)Mmb,l)-Z2b9f@l$ZMh"f005MZDUYMVqd@%[LS'NI,51#Ve%`Ml!DIl!0ld -SSF8G1)pJ!18!A!cfFp8X2c%rV[S40C4UP11lXUjSaYlHj2V!RTF2aiCJSR&H0YK -[X3lTK@IkI0BkT`AA3X&*21AqU$lE+463'9F4[CHTPZa%UG-NDSXNABb"kiCP*i# -4JF#A6jR%lL%qUMAAH8YB#UNM'NBk3Q9FI2S%8i3DYrQb5VH[@P")N91%eARe6V[ -fH4"GEHZEITjVlb'I0ZRU+'p#jl)U'P`E&@qYc'HV0P3LbUh95$abq2FPPXfQ4@i -D'B6)`iH$*[Jlb1SlVU1R@diB%rGqmH#iSX@6V-+'Pc`*j@3'0X(A#cimGfqYiR# -56PUaQ00%j&e04eeP8K6(Zj2lKZ1`iMqQm&Thl(H+L8F$*BYH)EqrU0dGAcRH-2i -!cei'qjbD`"IdLX@NNDTT$3l$krX**4(hpP(q@jfN`,Fe@G)hJdqFRI@&D,D6'), -9ZmqBZP`QYp2M4kH9PceeFIra'Sa#+E"YUY1kPmYf&M'GGcp8d&caP!)[2le)PUV -Se"0G+2I,[!b+%1ZcUXSS@RXKccm,38MG*F+X66H8`eYr(AKT2c(*cZH-j!Dj9'* -ALm4ZEMf6)N*%PCJB1YVqMc#+ADbj!L+j'9Ia-9$Iq"K[3kdJ%T(')FLkZR8P["8 -FHHZVE1j5*TQIA5GAIE6Ndi3cEj!!Mlrd#Y"G`#**$+X-"J'mTU4Lp+pEFr"MJDk -IZPKFNH5GpAeGQrEU#GeS1Lr#Y()VTA'AQcKi6bL#RdIKf5MLY&f&23p8A*!!KKL -55*&S&"R+1D3"BbhcNK4%AUeF-R1QB01RbLSHSR&l1Nj1G$+C-,H'DRNd*XbfD@[ -&5!-'mA%XDaCMb42D-qJpPiQmYc59kR3mJr-JYE%fT8mdc0mZMLm('Qbh@PN%rSd -HFR5mbJ"hacT9jf'IEe(84kYDp@!,4%LYTQU$5FPU'(RcmS,l#D1qSH[V(*GYDaP -jrfX,cBaRL"m3ejD+6SZX'1KI4DFEcKkGk1M(IAilUC,'5+6E5ke[6icCZFV%6Vd -9,rq862-%R$!F&C0UA1BCh*ZqqD2q8`0VC@RMbJ1hScjU('1rR,Qf["YYM)Y@44H -RPNerF8ZbGc("X3h3rL9X(P!&Z!M-&Z)89fZa'fG#8B!QmV!L*bKm2(YajdGNpe! -P[UFBmp,L8KUZ(-Ul0N(('p!hp4EEVDD5ER+a@5YF(5JD@0H)&GC*AaqMJUAi'EI -Tl"1ccR@[6[65%m5G)RTJMcL(PU@66K"&6*9Z6r`6#Z9q+4MSUQh9((d6"FFVl$' -M+D%FePZG3&([Ja*M)RMdHY&SdP!VY(pipGF'YKlKhe!-)(jP@2c,bK+,,i6KcMk -U!NckPVH6L!keY$(5!Z,kG,qG+8@)6#f8S@$f&`VjP!0HR%DE&8RRe)KE![9jjjm -b,R&#@2Hf$@rmmMkXjF"VC6eAqPeN1`@Pd+rfi2ia@#pZ#L)P!BD6Mi)KKljX$A2 -k%eL[,KMA(H$T(phpf["+V6%&-Lbd(Q*QGrDB0QC#qqNGeBQBCa2MVb%15%&P580 -S"5MDl(E3,Q`JdG5XjNS@pK)IJ6@),1f",dfSI+MlFAM(@[IP!b'GKJl@#%%q$S- -kU*BM[`6+6b2@ae%VpD3U4)KB89@8R4qVVZl39k!Mi8Qi`i8$r!(0NdqB%[pdLUZ -%0RQ5T5`V(F53!+8MIE#"K%HVq)4Sb&)X$i4S*pLeFIUcbU2-kV%TVDZQ'&Kj*f! -92$%)SQEm3*b[XCZAPceX[m*ZLF9F3HU1I1@r(!4$Dd`CAY5@4S3YJMYji&q!NIJ -SjTNcVP5J&L(`NV[FH`DLGjZhDb)Zc,KXAd0%Zp3+eFdb''9#[2-B(9AB2ScU,`V -SP"cPJ,ilbXBpBVX&j)c90P($SN$%`a0"I4dTZjr53b`$-3aJ,Y3+C3`5-"GZ@13 -+UVEP28(Z*RDFMBq#A"KQa3Z4rZS'F+3%*#1+$53'%3)d9l6lirmAejHhKi+TQTd -U#--26ZrJ6dDU!Z8(!NL+91k[&pp(8mD4fdeEleV-B&rTpp(Ed(2L(PT!Q3G'#hq -RN!$YmNZYL0*VNAPjhD1&fkF[m%"b`ia5hH5pV'bSK#KE2jKQ1E1JPHQfPQikFKb -X4"5hY$TSeNR-hUI,PllFP'"6A#CZD&0j5)(UJ03h'[H$a6K&Lk)"PLB9IAH,3&j -X$HZ+Y,&"l'3bmK'"4,iReiqjNEV"I%F9a-0p9*S2[XHGkL5kQm%,VN8@%Xi@B8V -9hcj0"Q!m,%A0VS65dCF`L"HpE)MTFii($kLV`,*jUBYi[V*8G3i0Q",VqJHrTU@ -r$$AMpJSGYqZajd&8+'F!f8m@,-"1j4N6`83&"Hb4`[pb+Z)B)9[)BVjcD8U&h)1 -&L3+%Y*pd1BfEZ116($3L`*E%ZGXk3Zc9G+,Kk&B@Mcc$YYihl%)!k2*VcI%c3G` -(*'UP8fjH#i*m)'p1!!fFU8@m6mkc"fqlZiB0[U0'@3C)8RX2MJ4d[#Pd6iI'h3M -+m`"!3b9Z+M0H#D"&qLcBa2,+0iBCb*2(f(ZEDL#a96jlLEL'61Lb&3Q`N62+!1d -VZTVhCYHd!h(T"2Zc9l&6IbVq'pAq8J*cl9*G@c`-8[!9B2Uhdj5ZMj,B*[IY[SX -k6,KdG[)r[r`l6C!!I!(b8J4P-ScPaTkCj0Qa!YAf!QR3M[&-203(R4UE5[5d)(# -2cZ"AkZEKpP#Jb*j+,!Ek#TQ*+ai1jVGFaflI(UX`P8MBJe)FE,`0KpV5e3U&-YN -HMUb`TbJp`'ecfYJM2XXHRkkNIJc$DT0(YViMS'V4*d,3[3A2Nf*J8cBNUVVPGe1 -BRkb#"-k)I(Q$F%RA1DC#@6&lLkcCeCd4mBFI0XmiIQN#[[00[@f"Yp6&V"1Pl0I -m$b[5%*KTkqAa@cqeJEGDr($jQS*ViT!!CYZLFJ*Vc**4Y5G`jPeSrAFiaLdf1&Q -jMhIPTZc"S`r8'%H[)Zjf1BV,6ASb$XC6LS2laVH(m@U46E38mN#r(-$qmh6Che( -4[TZ(d2l0mDDi94pTBA9b,C91)hAeTGc%AIC@0Hl!r@#c2mI**f$(-F$h&pi`U8[ -(Hh3ci&jP"cqB1@ITN!$k03abp*S3jAb&P&iY$*&%RS[HD88*ZRTc&'`LKH-[e,b -@e@rHX4bZ'K!-i8L)$Sm#@3JL(Tf6GYD$4XM"!(@NE!md5KR[qB06XdU&%iSrAD$ -jG4p,*Ci3KG#YT[q4VrZ#ICNJkDL2#VZjHAJ@A*jY#qrK%8V12MZ+4a1T8mSUGXE -GJhbUS@"(3B"98H2D"JamVb4PLA-EMHCh*,VVa,(&HB1U*KebV%@pS@LZ+mGSQ"Z -$04+U8l#!)0+*Jff$(&"SEJFT-8Z61R4RDL,c#c-aq5cddM&%qNDYS!iF8)@TPMV -D5'AH3IrNI29%l3L3!+B4"-H!Pf+fLh0%r)-&e@h*U2kj!ZHSb%k5deqDhTbDBU0 -!hA3)Lj81f9D5idi3f[f8@ML*FkR1$mN9S'K5BM(KQfhhcI-J4*!!a+)$R2KT*df -@V[$MCdYe+ECjYM`P+mrmP4N0`b36U%#4+`p$6d)IPfXa@k-,+B64'#q),%TQpbe -p0VCeGX@4mmEK%ULlp%LR9@ZhhTC@aKUrE%KN,kTHI'&mfhl#&a82EUlMK-R"N!" -&U35VS9L6%c8j88Ab%UmH0A$$IP[fb4[k$$MF!"rfb5jh08*MeeeVlA43!Ddk@Nj -D0l%8a`RU#)jAN`8"BKRhm!+4C+Cp$pLYNX#$*H)Y`!NlJJ@8rah9KYLY3#Dp@B0 -$&*pF@+bSMHA'qq@T[N*l)"RPm'EZ0K&A#rA5SQAqBCrIEdLS"!0-8E2adGj*bXI -&Br#IY`BFik2T'r"l,IKGc0P)k(daC%'Hk-#AVY,065qmpT95Qb*RpIJ[$mjqJCD -SKL"[fNHT*kBeZEIVlj3M(9%&mqJr9"d$c&qeYG$FBM`eA*bG$RM!S8C6ZT@(V-$ -8DfrQS4jELcKmEH,*Cb&R5KQj0lT!MNM,5G6aSB$fpY&fBF9@j'3(Z&aPkjMqMNB -RLScmT&*p8R$ah6#9G`%NQB)emi9"`pJ`JRABib$VD&QNc%Xb1L2PN53P"G+!(5[ -N425&*8Jd%q"`B9JQHlTFrJlCZfGQpRm-UACcM"jjbAm&a`l!%jkqT&d+Ep,CpG) -89@d95+i4"$,6BHN[Ki*ib$@CT'qK("")9EQQ2N@`l2(!%[4Xh$fSGJ!8STH(ECE -(9)3NdEQ8+(jN$LmKLI"IjdbjGbVEc,XL5Y#3!2r*q4!ZBlKA[(Bp%%LdedQBrJH -DJX#YEb6TE0N)D8ad"rH*4JaUbABG2aZ'UKbSrJ&@lhdlBG03GfX$Gf*iX0bZ-)D -9Qm8$FKj1)X4CXR['XXBdmDU$8"V4aZ2G&3cdA'EIcHJNLUElKSl,j6mf%A#HT%T -m+8UiI0BX!j`Z42VHV'Xb&QkNJLKI!3,p2l5p+4rY"D,jKPYB8HC&G@D%TiSBjYf -fS#pN%[P8h92I8iY%@p8kkGM'a#PCQIk9TTM#l('50CAK#!T$UR#T-XMaNmaiG#S -PV$VQd5ip5cR&8ZLFhC4+bH+K-V)4VGe'U*j1EC[KZqGITZ4kRb@TmRKLhB0bb@` -1)PL(0(+E6,3%XR-eA%$645&H(Z5-XXF'akDfp'D*6ckh[84*jm$Aq(cCeDeV(aG -8q%0#MV6K5e,4+(V*Y(VbNMrl#MBp)bk(iX%8P+N,8F,EU0Mmm68fja(cqE(@LP( -%fGiF3GPC2d#*U'U3!1l&c*)qYb3E$$ZI0A["""kjSA[c6HlkLU,$Q1D@R"YQ%G2 -6"VV'i3ArTCHNC0Rd(Lm*EKRmGm[#e6Qkrib26Z@Nri'NZ@+M(lEU1#AIQPNiI`0 -RA"`B%)k+a+pdh)$3c$8K4J&JDNJLeC+ljTlR8LX"DD$,5I1Cp9p`ZE,*(@%[m,` -3($Q)[qa#jcX),&cBr8$SEf4AdfmH+(VMecF9QRLYRQQYd'(9BUT"1ULS8XSJ1+# -&QHD+j4ajMj!!Z-@j1ZQ`pULD*2bkj#3ZRi0YNkSk@jhmaJ2HU*ZBqAB1NVQ*aHK -(4D-HV&D@ZS`"GD"E#fCB$058#LH$0[N(h15qJl56[*ei-2GZUd%BD1PE0Y[q[CU -lV4`dY1"%@dklFRZ+h9PM"3aVZEFeS'Rd`Ar80m@"m-A5BH#S2#!640!kVQIj(Zm -X),Mr62jrB6[G3-l4*64IAjfdU,R$Rd!5X%ZjfS!qTGJlcQ"&YLT+&Z)ed`V91+q -AfNE1lpQL9&RK9l8"i@Rr%IjB)(HBf[4GTG%,DkpPfMS-+r"3$Iql!kNLPF%0P'k -0$-%8lKe5a80`)N2&GLqK$D61P9lV(A-*&a5%l9H&@Y4b*!&eSZ,mTSLi5,&M#&N -kRaG!RHLbBqLrJfjIch"PGd,BI@R`[3pEDL)[q0U@C(-'fE9DkVpK2`G[#*[1@B8 -(IRGB'p1ViDkm2e0l1I""*PU!UX*mj!D0J5MHH(@*fIb!CQB#ph#5(D3ri-,6"(b -ElT%PlMb)Br"kb-d``)V5QXVpj8+U6AP+kQR*!!,Yi3UDIr8f"",-$bFZ$bq08+& -ph!B#)'36e'CFL@VQMXU[$8N[T$f$l@6ei*HYU03c@m)V5ZFF2PS5GX1jGd-EZ(h -ar8%9k%+93)lIE9C'HC+bAVdm6$Nj&p&9Zk!NR*XSM!LI'R1P19+E%GA'E`LXjV' -&mcBNpmcSJ)@LprS$GX'0e*3U-UMK"cMeTR`)CH1DmmNJcF52SU'&ilFrHTAASAG -I@GbYd5Plr)N4VX`Ma+S39drp*-QP12d*H+JA,A5+6)C)jpNkUp,G%V1d$QqA,d5 -Ip,$%5YGNlekNrKDD`F%Y*VX[Am0-FBU6Xpe0kc,+YY$b95FXI8!QDhFYGfflMLD -p1%j`qDjqChDFXDQhM,V0(bcZI0AAkTU8fd4h8G'A`J8*`ER)GXZ&)--0YG[Q)f+ -b`%M9iQL1&&J,#eQ#jbSif*1AUm',,Z$UU'pXT[JA4kk**Zj+pfXr(FZGXZdY%mJ -'h$QDq3Al,bSTqL[[ML(X#aU2a5)`a@rI#bDVT@G*MCFm,PMIU,He#j`0eAAi+HP -)5dc5qCfXpMkr0hI(B8NE[j(lBcjp(H)U`+mbS&Tj*V*N0@9G6l'p(qP'PiMGfM` -8VQ%%3DH@,Q66R(ZcG'`Y[!6IrREZm4JH0m&Xd8&i0*!!kkcN!f&p"j13!'l!-Cq -"0bb#9AGqTR5Ri)Y3pUqSCG+ZldH"$m42PNa`&$*@m1r$f"'9mH4P(Mf+!YI%dT+ -rdBFp3X1&b-i#LJ$f8lIFbC!!!'[S8#03'$hPfk6U-F"H"QTP2DjiJ)hFQL&%r#6 -LPcei9r$Z%6iY8`cBHe1&#Q)V$emSXH0ma9"flNh8HeEdkcH1[EDm%%5SKb#0QLi -F*UFF6-1(0QJj*fb&8,V)k95K0`(0AAm0+C,-Yh"DQB#`ZK1*,fG6*@'Z5&fPS9f -MKj5@$91!J-(,U(0h31M&+Jm"9R,pE-rJ2mi0AJMqll6Y-bhK+LiaCFY+*c'b4T3 -qZdrZmMI@p5N)SdU-qM"&q,Ph@5!$Sm5Y%3VBDeLS'Rpe3*GKX9QIp+rc%Q`6JZ, -"j+4EddJ&SK%,#&b"Pd1`cfq5!iVES8R#A6HFK)Rr(&JVip6Y)V,4mF%3hP4H8$L -R[G4BHMB-3jejYa31`3&2UKFAj*,$6#T(QYr"B,S4-hVKLf@%PQ*'RU6Lp"i4`AQ -+-`kH[b('f8X+j+0'1EpX6Zc#`$&r-*VIRH9bMLZYBKShH2DfRCU"A4&`%X!lHrf -k@E1-(*U+D@4+i&lVA6BXQ5mZ(aZrcM`UFUp$,``AUF3p9XrqM340fSq3!,D)`%, -jL+M'1SYNp&&2`8mNp*J"f46!r)fQMI*rXTM(Se5KRe4((*Q!#X%Q8PlV#2BZa9K -e4@)MPbCXp*mB#CTY`DZHPZMBFPH3!"S@N!#`I-h&bFVH3G'h'!HM0ccBQdYKK@` -l@RpPpXK5BZh%$8Um1'2)!S(UMHh99%5K#qRAJq[K-caeHl(a)QcX'J(F*makXL[ -hZAViEDkBN9r[JkX)(fiMml+9!M&9+BcEdB0Xef)EPJ`3ka,`QrUP%3pGY6#ZMIi -Xmj4hNb#pAD1R6*5KG2Al[N@IMSPr"EBDU)ZC#iqpFEr`Id8Li55Z0NGPqlKSGk# -jJ60qehcLUmQA5SEe$&X6IQNSdVAF%-iP%X&eNVf!5U9KNATBaqqN2NdD+fQ[ie% -0(4jXLLJY`,RDRTa*`dN"E4eUD8AcZI`iBp!3`rKjN!$ELZd4P#8L8bKehrpA,rS -aN!!&4KAe$!jiL1L46MFJ489ic2F'%kRQdJ-NCS,U"-&lJ+$%r82j*@JM!9CZ88( -"9f`Bkb"Ym(J'%2Z-%d8HHbdh1%Pb*f29iCUkqTqVe8k(G2XVpMkV$QBEMfIq$lp -D"-1B(Bi$5jhfLVip+0kCc`SQjQBcDbE`i`F1Tr`U%S6LiR5P8,02cihjm3fQ@KS -HY'1!ZkcBDRP`*4jVa53NeqABk22C(+C!mKh%NlJFTm#YR-2jh@@B4d3A"6FC[BR -Z&E&+Vr`Pr(fNf8XZ9cPNI@'qPNTJJh!QEC!!V,33(*X)j,AYkMpDUUiIll$!XA* -Rae'+"NVpk``CCNeCVLJm&6#SMVk6l",mGkKm%DP!eENL,#D(AB2Q)"VjbX6@`I4 -80[Q0MB1(V2Hi'BkhbCm&kr4De%0lGDcS#EefJ$8$IK&DmR+MQ$"!kR@+cIkV%B3 -@%D(+0j!!NQ#RQp6)Y)$RcC6-ZR8C8eihNq$1JXDD9hpam"EqC"XbJeY[pC%+M&q -H0GK[b&9CBJicVXr9jGe91(Y5AMhNNR*BM8fl&8H[-J2mK$[@kp`TEBL[TeX2Z6Q -,4R%9eE$L,U(&RZ1FGmab8-@@R+8!8+bD%%KGqL4a(5IT+'ja!X8iM1b`$5pQr`) -H4Nb"r(!bllL43YTbD#U6&P9jR%a2(%bR(6ZJEdJBaIIdU1C5"$2Lij2hA0Ij&La -BLXaZQ9hq*3*@''3GCM%F)-"i$EAlpT%RI["J#4'&i0bDArB+VPRY9FYjf(R3aM( -lH(b1h,6-A--@mEHYcTl6Q-!'Z5h6,[MGM,TKfdN%HT%!Dq,B'pPrM&9c)Uk3!#V -H9lVeq2,J%c)'!!MEXK89@98[+XLbD9p#r6hfA2*&9hPfPB562bC"N`B2Q3AT2*V -TA*2aELJZ%@1dlqU*l*V)phQ%K)cFp90HDf,h+%D*1U2(C%S2SphfbK'*$d&qrR0 -c5JYIl)B$X1@NSc&'iBeQ4pj[DhP6%0,a30B-2f)08[[bZU2&kJ#qCP#BT"F*89b -iP2#Ah'C2KpT(p&rGF+Nh0dTabGiVU!,m3INq)H*5(R'H0aQ2m+j5eLIm&S()G$c -hYH!TQaMSa14!X-5,&0N+Uqb8#YG5UTDJ[URe9HNh[lm8VdH*m#ViPS5(6jG&A)6 -#IU8@(*-QD*Lk6CNmD$lR9+l+P1@a[2NQDDU8eGkqZ83L*$,*VG,KR[FHC5rEXGq -I1P(Zc4YHYk*5a-IriB2*da)UK#TFpV(ZKSpQRb@m8D#3!&&3lf+#Rbe-K`VQbJ9 -%)+QkYrCkm#5%X,mJ2EA,Vm360c!5BC-kLaKI8Cj8q([%"kX9!ia6Z[Y,&i2`E22 -*BYUaRjf@Lp#eMTCB8U8N$`Sc%lpl)GZ6$`(%8*+S#bj25br-BfiN4bGdj&fM*N( -`20hIk(2EIG[Ni%2#YGQeX,iTcL,S3`ID[+fSlCmqSjJ-+*DHf5R-231A"VkXUcq -BX%NY*B0T8r"Q+q3E1fe0rXL*@%!%X'*[Pr6&#@crIih'QN4EZ3[3Pjb'G'S)*T[ -p@Rd'Q+"feEqM)6ekl&QRN[IRda2*Nl44AqTQ%HXDrHP2hm9peP)D%&m$P9Z-XJj -6hm%!j*!!G03`0E$5NjMZM`K"jCCm4Rq5@EJUfTlCHB8K@SVTfDI6--SF1Y6Fijm -DaD8&@`lp!mf`4`kEB1*Yec'V@13jlKajMY"&hl$T"L((@"6C#`#BTCkE+-NKk1% -jbJCU1&QDeeG0"`K!,"K14PDdapX*Z240*$-i60cAF3BY26fqF(LJ1EGk&EL0$B` -3'06`SP4"FA(4AX8dk)p@#84h'AC!rcT`IGmGeUb["%"$(kQ(1(8lQ5&-22mHfL% -KZK#9r1JCf@"TiP&))KT%j!$p-'qf)kDQCHFJlSH&)`@%NBT,UVdIZ%"m2%erIJd --Np[NKPVbPK-4E)rL$BNEm@!'X*URM@6FPZB"Ur`C9C1T`MAPQ@QkZ5)h(6fpDR# -'i3#4TTNHahbfP3Qjd`&S2I6L-6BG9!0Fpbaa51pUB3m2e1Vq6e29aUi"Q1mc(f% -*3+-D59!hT2CZ1'I#GVrVf*DFNpT%T6b9Nq6LS"`304lk(AhLjM0Y1#%5%-e8Y1( -ke9$J%$dFQmBV)-lG1dCfYGm02Zb@l[!4#@XL&,bV`b*qRaX9+Krk2frA2Q$,50V -XGG5DDLj*""%1$`1[F4pL&jT3d-'p`)!&HFa!$*!!4li%BFeIZCfGa0GI"BQP516 -m!Z`-[`pNb,MmI8#dHjhq'H+i+P)QR"3%3*k4[H[pq6`Lm*!!1,bh4B"`+@#`[ST -f3YCmGS0RLKCV"3%lENL#)QCBRbiR5hh9FVA)*EpF*6Sr%2NID4HGSJA-RCiZ-N, -V6"G))+$0RXlPZ3'-cTMk(05fqQ%A9*mjGBdA2K2'")`[T"m`r6Q$UVXXISiqb5M -B6ZPdEDpm%4@VB5X5@)pUZUqbJYd!'3#AAj(kI#FbGDr8%0V@McfCPF(@1+ATJ*Z -hYZ0M$3mi98qkXb,RrY[AS*2DN505JU(Z4Z,p!-46Q'FaQC3S`Aj*Xd,cYhY[eBN -9N8j99#NEeI$QMNR(,Tj1@X8NN!#amA8ljKd',V6q!#$KDi)6qX#m*hTM8(bPi0G -)pBY[KF4ZmI[F+HQ![))e%MR+Sq4Ml1SHa64G(FLJFPc'aX[,bH'G@E@)P`IM3`k -FKP4I92@rB*6`iqiYq#'Tr218MZEl'6!*rGUJ[ZQ#bXU9MEhT)kL5iH5ciZ&$N!$ -k408Ee!SDMX5RXeKdjm6hieHYMEqdRHIGiY)4FM"brFaUJk#f9m(DaS#JXT6-e4, -992%'p29DcCD)0l82J5b*A&cNZ*`2pk4p0j!!FIJ0GrRq)9iFRYX)I-Dj"1Q3!&U -i16MjL,%,rqQjVqC9ZCDLBhRhM!(FZp0(QAiI0rS*J`I120AClSF*J($,LG#h8[Z -GBh5cZ9c9mLimNcca+G9UF"3#bGRd,XIL1e3*S$a6hfpR1-IqpJT&@49@',!P8Fe -R,ZQe0BQ5PY!HJ4%pr6A)GT%8Ff5qqF1PQmN)rI1aI)1+*PrDlAQee'r*TSMehr- -ZQ4&2G5"d-G`VkMmEQeX2'pL2,N$UXNLj9"5FeR&2IrJ[m6`)qq4+)KNAGe1lReM -aIpS9e``Brh2'"1e`KIN+KBQ%DKSE@p%3XIipkNpLI8IE#GGd5K1aq%rj04kU-'4 -cDUSlp"6qde-1B[ac@[25U)K2I!)&mV[c,6CR[@%TImR"NbJEprDRZ#I-[2KlIAm -Kq'"r`5IGP%ekVM!1b+`hPqaLp2@,mZ)8E0jH(qGBJ%R%&@6)3Dqpa(MEC(8P[cK -bR5j#1(GYj"PN+P)C*$1#Jfa&`fT0L`c&H,3`!S,,'&4$GKkZjk)1L,FDN!#&CM& -Hr!0VIKrNpN)GAZek9HcT-ML"Iiq)jq49-Q+4qI5!R6e`mFMR2F*@#-DF'MK`GMU -%cdm`%rdmCmreGNZT9N8%%6@fRi"bb'f*kVJmR'#'23fR[qaJ0jK,6&22+0ReiiN -2(fh)PM2&-L&IFGc4q0E6XRf'rUmkj)ECM5Jer59'0*B'LQ0C(``2DPQ19*3F*GM -fjU8S59SFJRIdP'DeS2)6l9e3chpZ$)*M+([DX5iLH5%1dS!Z'`4%%#!PZI(,Y@Y -R8VSG(KVl5TAmMP'TpeL)3"`dd9(diHY'("1Xmjlp2qmdMN0V"%Uc4Re0YG-FbF4 -TqQUI1HB-kF[GSr%9hU8fNCIVEBX(!2hVqM5&FJmX@d(6XN)rl8``qeXTRjY2Ue3 -J0(-pJ#'h"+iMMh"YS),EYV,VCYlXQ&aC8r15TaR@BKY+0MM"$A*r#BqbRr("RRT -C*Ifj8)5bSi$CGGLYLID$!ehP$+$j3U2Y-5'YJe[jYa)Hd'i%jTY(35FR&EZDVl0 -q$,SkhpF-@LTF206ce+#l)4abqT!!$APBRBiE'(5b"l$mj'FG"QN!VqH(5GmJpC2 -#cQ@qRH@&V2XU+#ZXDBB&[T2"5Hi+[dTV@Y`jAS$AaKYLB)b)I1rJZT@lLAZ"LY- -$irR!85[9CrP1dbLCfd3&Pkq&N!$X&2kqCd#+(5qad`m9$jqbp90qe"@"l2A`Sb- -ic&1h,Z#SfDemlb5`@(jMbjYqJQ"IVPa#&A)IUV,HPT[3+C),!#qhG!r*+ZfMDY[ -C9p0`8&$V3%d!2`pT6BrL"@!Ij6"9[pL9XQRPA9(h-[30p8"b)Qr(1Em"Q[i[$,Z -r#ZmH$8'[@,&FP*mDQD*YIi3Fp(9MaVk'8J649iL!fX9i&IeGpjU,#$PdcMf4`pS -jfH*4hEQ4SU@[,YK2K1i0EJqU%UqC)G,8p,$MG+Ql%M$IKF&R6'US&0KFC,E2Eh( -XcZi"hQ1jE!(&Urr"l"$D8Y[,c44mb8Zp,6Val"ZMdBQq`SXA0K'eaarC"phrpB3 -Md%Tq6`R+bE`mKcV)[T)&#MTV*aPZrf1V)QK5#05Fq$@%iaTKjUXp%#$U%hmaD38 -RCCHe+[@5rS&RU'+Tqq0B88LGaCXml20MpZbF,pbFp[H-)a%QFa)pX5T&)FBlHHA -`2M,P6!k`+-BUBllRpN(h((kc9i2RLVC,DbXCKZ4AHr,8ZD!339P4rZZH(Qa)$BQ -3!)k,M9C3had6T0Ifj"jj[C'8B(B[li`bfq1UX+6+SqL5Br!%3+'*9drZ1f06!Br -M&rR6hbUe69,%`()k5+9G0$DTA3&3J#EE)QZ'8"K%a+6lUiV`0E5-aNLGCJHS`9H -2J)E*6'2)p25@h*mfKIdU,UEhia$S2S-T3$k$RNCS&m-![F&6f30Jf'q[XH"Md0D -D"!@Nma,%mPXh8L09YpM#9CFTc[YipBUk#&Ch*hC`)NC("-00#XU,dZ2bh)frIGK -`-I3%[Pl@ZBh[0hTp)Z"PK-bNM-#a,@j6[ff2r0`EC[Pm5+%(q3XcUS15ZBBek0B -m9+Xf,Aq4&fVIr12-R1C00M!-m'KN(NB3&(MV8[eQ"f34Z`ZME'imH20M*+REk3k -p`plm2@Zld03+qaJQ9S9Y`!KEl',dGM8'c1f0S*YKaYJm"JdIJEVBk14jPR%,N!$ -!K3-IMprE(eU4eQj2`&CMc'E@Y+Lc[U"F'GAG1jE#afU!-i2`RCC8(NCe!VmjU(m -r2Lj[TAXX+1i9"-aJBP)S%0(KG4XRTj(-EQ58q4kcU+'NKXZBD29$R5#*G#cDq+$ -1Iqicb4TI)iBH3-(rq`BcYQ2+&I),k*fR@GDjRPIEYRP[N!"5b[IMfFG8iCDl@@9 -+q@B*iX14b"*023(L4H#+G`cM`H6RU(5kHY9a-iMMZ93'2d*+c"$C-4X"ehp0aPL -eS`MHqJCh,H+YbqHXm+YGKib2JU3"-[AA)GFKb)VpV5$(!X+)L,!kqpH-'+QdLkh -rY),hET200,EHSHAJD4hK#BB#Q0"U%&jkRUa@Dp@2rqXj+ZfiDbE+j)U2Q8SbFJ+ -4M3Nr0ZH&$q*qLB(`Q3p6@a"eE#hP90CBMfkhYH11h'I5pfA(emrTQLp"KCcf-jP -"qN3381Gj-+T!&q2&'V-5`YkS)9E1&jDMFl*A6&f%J[-XrdqlP$f@%MZ2`d6XNG@ -becPX`6UI4re[iD&M(bdA$XF%Lm'aN!"aZ2dX&&h-P!JIQD-eQ`5,,pHDr`l29-T -ai!*N(-3RLM5Jk8JQ[PLB08@V9Sc5q5k0-,,%SU5S1ammr(6-E1mbkVcY+)j)QU5 -aKH%CQk&QiDLmbFq,FrN4q"GEF$p9,ar5kU#YUU*p"`QX+T,E(S'!,(SRi%[PKT2 -j%IjUReAd`pd+391IfZ6#ZY(6ia#ATc8hmQbhGQ6h@#GcF+[)r!cikBZH!)[q5Rj -,K5#hF!*`'LmXLE*F$XH9Hm&9F54ITd%mSU5XaBV@($(,!9QJDTB!b$DTl+-`[*2 -6QAAUBBKPl2JaME3jFB*Vm9#eA&E%f-NI&+UDhbHki6qpcIG0hk1Xcq#2ZU$UPL5 -EfacmYUd6HX-mZfh5%@l8`Er`Fli-i8&ND4(cKXT*6m2fGY39,12-TK2DG5ZQ$-h -N[)4NK#(M6U&adUZ2JbkqERSJQHre6P$KFKepGHID,l$#TUfdZKFe+(CIrR&ee-5 -6F9$$RdTCBk5A-J)4p$JTQA2L'-4&4Y9U5CP2`F$FJ!qS-l&jeLK4"'8hM9`jKA@ -&aMCZ@Ll9f$m"UYmpFc$L!%T2YG)$+i[NB5Z&21!AFQrI`DlDS(+$A,F1MQ1mEIH -(DT2+X@TFl6XY*)rj@C38'VD3!&kPekIEkFXLd@F0Q8Q'm%[KUKZ2l[*60H4CKJ! -lNpAKXJ,$P,iS0FaR9#Q`S#'C52qEbkJ91&Pr81-m"HU@G*rP%A"D3&5`Y"2TFm( -%V0,N(aP+CJR"XZKP8CkPEXqP`DK&iT5(Q9Nh([p@*iPq%kSdDU4SbNIME[I!bZX --MBi&BDlkNZ+$KLT)+DXi(SfXA)mUephpYDPKA8eJ0155,E[ch06$m&0TCX'PCrb -c&%(H##a69*h`T93MpGNNHU*8i'A0#IfFG4dSG6,Kr1$JJ+rDSUrA*&M!#cD0k2M -PK5ibSq2ZRV)MQ9CZDR(j4-EDjUMa`UJNETkF@dT4M2,"p0le(6PTmdZ@Mhp0`d1 -4HJE"61icJ2j`a$2RrahmA3rCilK)30kMerT&Y,Vfkb6%,dFT6mpcA#!%TZ6`fQZ -,rk5G2eP(cQCCjYF6!4dDlQII9%m[j2BZcj'kHXi''k,*HE,((a"b6jKZB++UPqQ -KkaqP3ViTd+Jq,EX#PLHkNpeGID&cjQ`J&iFJ)T2qpA[LQQ9ZMZ(bV3Kc%E-ViPX -CqTDGhl!&F0DVb9pNiTp"-@9#R5#FIE`h+MI6(4i`GP%P+cb-GTc#!qfie%GVa!* -RkNGC'd%cJ-pdNN[$XKp'MC-!,Q*qbdk[)$lDmBAi&k9#rKM+lbXMjU(NP1QHc9` -LflPq2R8P64qqiLb-,R,,#PlELJZZ@jY3aPf9S@alc!h34qlq%#$l'bR*l1UG6rl -**$$BrL%&hhSDC@YG#edZAMHLSXCjq,K&V3)k!'B%+@qlN!#K'JV%IJfA*T,$(dr -,Krr[VEMp@32&*9[I'0*(9%lM-!Ab%J-$,C*CI`@8fK&r'-##qL'rphGj!J&U%iG -dchLBCAI,Uj(aXc3-BD#J!ad#S5YcT5Ki`8#YeU[SXRaBYFd-"rQ!!lBB,BX%DdM -ZqQ,pEB(!0X4Pd8kB[TqB(mr-p!1DC,a5Vh@NkLQPR0fI9@[Dq8K`i-CL#AN+6CF -#(09jKJirZX)@GPqkpY3rD936arkcN!#MM$Z@Aj!!4QG`GlDUMe6'p0K"kYDI5*V -JETD*Me#I+lMlbmfU2E)p"JjI-S"hM16SIYbGBHHj`Fd8MAJd2ia#V$$H&4''1`e -"Xf'a)LTD`QaPl'%4GD#LMUH6%@i'h%3redUr&PdQLe6lkSY6k5Nf%@b9-e)mJ1Y -J#+bPFrYATmA+U3%bYVAE9)hD#j(J%SAh42DfC4[-+&lX#``VYZ3NdMI!)T,Xk[S -c5JQB)Rd6"5AIbJ"mq`5PM$e16pVMD5*iAZ4A)$LVBj'Epm1@PB%$m!-3Pk@TUXm -1)d'"MSTE&RX(,D(c"Z%IK-Iq3+#M`@,(GDa6URT8"Nhc*Gr0ePH[Ac@k,1bj@`p -l#1&pFKf@'ACe`D'H)D*9M5"GACUMqcq)-qX6PfifDb&53E!fcq'48ShU9#%KQl5 -`-mB!p*%Cf)J(lRUr1-&Bkc4$#I$0DGd*%aDE'61[UF2RC[BS+CL[P6R-Th,HZIT -B8`ZHEHAH(U(3RF!eP'Vk[TVk2I8i+dqdR+BMXPqr&Zhi[NLKAi&A6!%MLcZm(FL -R5daHBYI!'$3bY8EQ-kc1MdAlIBRTXemGZP)4XDbE(2NjaL4m-"b2hhTplj+EJrj -Fq'$4fKY8aZFQfApXVZS"jUT18+AD4V`YcmHD+8GCRcJ02%Hb1+!Zf&6[GSXp`'@ -5mUQ-+B&`j#$1%`ccdGA5&ZAlD!MckkKh-")QH!D9icA$*hQqjRJ[@#Q5QaQJD8l -1r(B5V9Dj[$)iipi!pB!)0CGL+i[4N4qNX3(Vac6NM0m+BPf3!2T0MmGd2(&8"2Q -I!,Ch3ZV0[jYfDPaGKE&`HP(I%&E)H05V+b-B0N!Uk'ISPiEL%i"96&-plb!"*PZ -LGA#$NV%`EfB!VCPbGYa)qV16aqhDEe"m*j61h8fq-pR-$pmmca#5RYX4%1G!4S, -"flf&N!"kcQ1*jiB"@P0qR@S@5r4%mZ!rK3bjX&Z#Yf1-Nl54mh3J$kdJC$8lRKJ -@`#YGViM)EUdqaq[RJ$3ZiM5db`C1cZY0-#m+`!T!b&['YZ5d54(U(jN)Dmp`p-B -3IKF&F[QFD%B8PhB&Z-BTXrT0(fk-I$'$&!eEZ4-q(8FM[LHqmVim08",#*Q#$dD -&+cVXpDSZXKd,Hc[KT`*FccH'IdB4r*`m)F3%c6j'U*hBBQYbTR[Y,Q4%Hk)I+Id -&+YLZBVNm9)aCP4TMeC[LM$Y#CNGicH4E"Ck',Y-*-QL%E6)GIpJK44&Cq!RYJ1+ -qlXhF8H8B@8')Lk9m0eMDR3ZVZd&D2Ib8R#VLRBfP05BkVqEU4)EM9"BkArpkI44 -aUPchKNPFD2b`a@P"$&hL!Kf&"MS095(GL%PhP9Br@GNQei5jI#RlYmH8QHGamMS -1[GAbUabTeLVQ5Af)J5ledG"!RR$S6,Tra$&))d(j1kp)hpfLr!q2J1,XJh6C'i2 -V&J)Q1-Z'%2MQFD#cckr`K5`N8V`0Zr&3'A"m5Bh`F9ArpjbTr@+"+Hm[BLm$[UR -f,FTBA(jmJ9IM66XNeEKNVhZmIN'mdJ-`)ed69ik-6d'mhJ'Fm9[rd)df)*3DE#e -fF!kr*,R*IprMAJ%hBP[Je@lCI6T'X!Zi5N$!JMFBjBj*[q1LSHL3!(@Yk-QiYf6 -q1r0&kM%`c#4B@1T8E"cRj)DmhbciII#mhML2NCIL3$1HjF$2MRXaGL(kb1HINrD -"Vqf(pVl4JR@ATq+X2R4!0jZhKS$%Rd,Y%c-%fD$k5P-3$+F8,%hhBRU@6m9MUFp -L1Fr&e#LqG-cXeE`Mf%3)faZcTNe"%c2(qaL(`9I(e6jYr!(NIV$fdA`M2`iiV%[ -F)3HSD,fSZA,9Y*lq1'Y%N!$J89*4"qdc'+,*4,[ahIlS6S1r5JmAT3QG23@Fa5C -rDE0bBjZ&CEfCA646Y+4B2$H3!*[$J8`BU@LUbahmE@aUf4#MpcEK9rQ!&158`44 -SDiU0-(Pp4[k*Ga)VjUK*IGH#aRQmM#Lkr'N!N93A)81j@CQ6aILj0i@1[9C+TYe -Ler1bPMqRaL@Y0q)p9-3,9h"9,T91U!SC`BG+VpF#ZNQ1D4-)H29GB#IXQI9Xa"2 -ifjp`j"jU*-4J)VUVPb-ZS#*-*[)8m4-&0IX*2ZmZS,825apmak[aklkfcAJ(ka1 -I&6d*"m,#L'801jkHHVfZ#h3A,*,rURY*e0-'4)Sj%["#"E*Kh"UIFR'UP+Mf(a2 -$P#aA%25HIkM3[NTjECqK1625#[(mR($GLq4*SK+'8rY(rr(9XdZ@mbPa)eElh1l -!,"AG))i#MUKTdR"EiA6KHa5VLq'SGl@i+iYH`0H@UFFG-Dd#0%5d+2XD8YQ+51' -@[jcT0KAA`[&UEhG+)"@I%1F`VF1DHhPpEV*A4FPLD#r$qQ*2[Dci8S0aT`lA0`E -6eB5c*@R3P@$'RLZ3!+58GXFc5FJ-a8-G)0epE9BMqbTm!Z"PKL-BMKC8-K%YM@D -FLG*P0JV5J)A2ee`K09@a0@*QZdY1T(Sq,`4J@4Pm+[+dYae`SSF&IIENqdkJ'94 -q(d(V*5e!Ca6PT2ampXQ2VFABCZ3a4JBHkILm)-kdC-D")V+AMGpa"kEeqXp@-6E -,(fI9C'#d!ep*Z4K!ZMcXK"QM"PJ3iqpSqh&G#ZU2L!kmY0U&aj3EpCM)d3$S1Xe -$YM1Q-c`&e[cR,5flBLafEYGM14P5B1B*V`R-,0[Nl$2NkjP%G'(EH5LCDpeT"Em -JI!,FVek%EaUI'RCThBX5!fir-LY!EX#e`Vc#K`pL-aI8$@LMe8HhpVXC95hCNmT -9DfVQUfrVjh-93emC6+3QBiC*#DaS`qN&lHS5!Vp'AeP)!39fZZGar)C-Q5+5pc1 -`ZE)kZ#QK6`aeTlM2G2Dp-[4R4ZA#'(Dp4#*ZhaI*$D`86%I'3($j[kDNL!)[G#$ -L!"k&T*'ZN!#mS2@d0fMRKS0F*JbNIp@@0f,L10qq(0DJI%pN9)rH)I"cr8QB2#D -,BQ4,0F,pjX3,S9QX5J[H6UGYIY3XXp9+aVpe9pUd3(BDT"Q'`eqPpIPPIb+$b!' -0Sbhm5hP+%N[H@[0dbY00Yb"H,@[$$RBlAJKH340Lp8N+d41PprMbSiF1JAeKQi- -23B5IGF9#DHfd9(Bm+4NY4K3@K+E4j&%N'lIHIX&&5CMLJcedEE-,$qbABlS3pD& -dAX(kTVSeD9(9r0A@K3kM05eBc@%!&QfCZH62f#dN["Yc0!D!0-F#HrPe+q6E`Ir -9+@8d@c5-SEmf90a9XQV6A-$*0FEB3Ve$E6e9"IX-4iF*@FD(Q5qE!6SL"qiemDK -p(*2hSp9)T'a,XP58F@KV'hiJUAZH4l8"qANVB)GP!(H4Ded6LeF52G-LF-2(-+* -b16ilA08&EdAKr9Ca8209"IdNQ#R(ZZPSf%'*3XYTE@,-Ud-PGk8b%GK!8j[jK%" -`@aT(LeZebHCd@hJr&r#Gi2KNL,Q95Fq(KjpAV`XF,mH$IpLk[HC*T&VPl+ZlZ,X -%Pm0Gp+ZP'+Vhfq"ZR-BT#0M-r-mLUQ6U6GI`J0q1YEr"98Sh#ec`jP[m4@jLPAS -@Z4UYNdmQENFJ*0hXLd2JGG+9Z-hqZ`me$&&'6(QlZl814Xh2*m0hRk#,Mp-0fXB -3(e313hkK&ECTTELpS3D@+TJqCQ061)NhU(Z@lRh[aV'bDjZ0)b,lpaKTl134F9L -i-R61"6AU5ZR-pY!cb4cGR49J[VABEXr5)TbUDQFdK-kqCrhh1BBR#5&&pI%4mCY -fpir@b@jYP9@j#&ZE5mM11,Ri8%BBb2Tmj1PqN!$l95K4+ISFf8d(5cQ'6HZeZPD -'3YMr8lrkb6[kL6A$MZ6KC('*%PE,0D5mE#4m(9&i!hX*h",96%Tp))BZPF"9mMi -rTj!!M`QdFR@$q-a(e28j%eUqNREC`Sf`*EXF$Ch4hh`1maTJ&$b46S9[d!$%L0Z -68`Ep8FMSYF-Aqb[EHXMc8d![([ic`0!cJPeX%`,"IbZXLA%UD[#-FLhU%++81(H -ji"'q!$+2A8pQ!,iK,3lVlPXZ2V9d"Yk-(1IR3Z1*fC!!L'hD+,a28,LcpH0Bp8H -lN3m6CA&,*$3IQA1Z+U4K*@RYIiN@X8TV$bkBhmeRKF[Lrh)S8#!TXk+d`6iS'S9 -LKRFA+T3T['eYY9dl,BIj(PliYB9+9fYA1`+JBQTV2aG"2S%(BUL6jDf+09,PiV` -)CG3@'Pa[*Qq6'q+Gkm$U+XfF$1mIUa+dXH8(k`Jp[l6d!Bmqeip,TjH$m%frDk5 -XN!#3!)%ZMYPJAJYi9ppp+XE$JBUJ)M`+c)2PLN4-#cC`@,aL*LVMK,',4i@A`1G -(H+9l52T`IHVRkC%B+[!rAXAjlJ5DK3h-3Ak*rS1S!8@EpKcX!VaKA#NC2J4Y`H0 -0qTA"dQ-UZHP+8@DlheR5D)JPqr%cL,%(D!)UhYM,D88Ge8p2pDS+CG[4dB+qLZD -I5qApE2i6eeTDCE'3!2JBBdiqEU&I`E)UYa4mEAS"Z@j3SRGh1liVSc-+@kK-kQ& -Fci@B4jTC5Im0NPrl3TU+*ReRmiN+i8PpPkr!$pF+&p4,IjJNEI43Jp%c3ki+4N( -N&#P"JDXJQTbVMX81BK8r!UpH1A'cXGQMU*a8HS,RZM*LZ1R`Z(KA1JR%ikTX)NI -kr924YMH$3a3%8`D"HhUR%eq9"A)$cr"-HY10Dj!!2d@'R!JYT&f@i90ApT(+&R* -mJ,MH%D93&&8D1I1hFFRX1SP+pC&l3&N+%jdB%S*l)-,BeBF"A$ID!K3"UPkG0N5 -V%RT"*T3"P(*cUMA)b9ZkRBd`Q-,!bX68i("$0lX*E&V6XVh1aE%XkYreE6EZ0pP -rPKAQS`[)iCCI4,E6'%)a9cMXdS'LJ5F&(%h%HLCUM3%PNP9aAIHr%'q@@+k-142 -8qH%r16Iek"lMNlYqNaRa%TrUhS@&-"@XF(i`K!F+&`6$X-ZkQL8`U4$S(+HURpl -f@rrr[iHGH5eY(e,4Zq('N!"UN!"M`dRXpTc9NPk1)-Kr-!JS!j!!N!#+!J4J'qp -%VI8X3i-)AZrf%E14jN@YT),Z$$l3KXp83GP+&NHZ8jEi5iKaJE0RY$+N$2VDd)@ -@[FN,N!"UY8%[9$-mYX$qT%"p$c$3'c#@ZPk68VCDI*9USNM`2i5EPq,AiM)X`eE -`b%3[3`l3JK"5m(DJ9)%"qMLD,LUD`bRX*Xh%9I#%9i'F4%'jNK6[G0a*q'4"#M' -Me93qXbcpmKS,IC!!)-r+0ZBd[PFR(9$MY+EY6+,`YrRTfKkk"[`ij2QCp5-BVQf -bBq2ib%%df@MaKdQjI$%XVmdaIDQ0m,'6B'mS`qb1Y"I-,,$L[2f9[*i8aV@a1T1 -+L[Teh"TmM!'V"U0ePPBfPIKe@"fB0lld(%*`9-LeU(raFe,*m1k&kimLQ[QC+bm -fa5*l8*efKPrE+,NR8pi$*)q5"3SF[0`PrbGeBc[pU#lr'f-YPff5QhhhKE*ZHM, -,QheI53C+HYe'@4pjEQ-JP5r5eNC1&Y@fl[T!*-pNqMd1EbD+D3mQqCS-$c@MD3D -DHJhDM&-1k,VM)(YI@fY2Z[cL*0930Ife"eXHdDmE-r"8DXSE+rPIm0,[,SH25&0 -MES!pDp+c0Qr&@QBKpbpYSH-30Bkh@(8*ZIXLp#K'6fNZGZrZ9M$F(TR"`HcL1"* -F3,T`D9QV+Q!GU--Pc6k(6Z9rZ1dF,'$LcK%PFf-&iiji9HR!a#Q@N!"JAD+dI&A -FTL%[`6acjHVNF#@0#lZr8aU+QdHZf[B!0(8KFq6m!MRR-NFSINIbfi#rNBY%#Vc -'rPLiCU!TA@#(cbNq"cdS)1M02Rld6CHABmLp9@+P*HE6+!*l*("k9X59+Zh`$DZ -b)m3)`J(0Cac2re9RG92k9-jaE%`8$@Bj"XZ2VS)P*dpHNdcm4MP6%pdUqdpNTfc -H%hjFd@F21Xh`[NkqDFTiIJ8(b&#M'l*BP'ND`9qApffIkG!R[bEaTAVr(hXeqKP -V$c$5Fk4FGYbpM4BqCi*!drKEA'%iSQU25c9G9YaaY)Far0A@XlS2dAA-lCc2m#q -&,iQ1aa-T[(*SKARAC'MXRDb0U%`-jPk"lXGaee%P)j*B3'G8KQa'@[-3h*q9QIi -rZijj"0-,K!(pkrcYHae*&IpY88qH6!fUE[ak@BG"[)`K'R@'&i&"p8+pG)[(mkH -HVP*[pl$3RB3d3E'TYcH5@a-U5[hU"!eYdS4LCT5eU[!Z+l+IrC[*NXN6UifZ!c4 -(N45E(r9i0RaJa"cM5['XM8d38TA881EN%ES'd*U3!,&YG&c5PcLLk(SX`J*#`IB -$0)1a(,de1d0T*DbVeplc51(l&'0H'YNpmMTGFGD(a$a'!U1#jdefD$Ya)CH'FJm -)BDI4FV-[mKk%U"aGJA)r`9e1ZJ-aQ0(k`f-Y[[`P#+'-lTQhi$hEEb!mQ,AEmj2 -q`'J+qe1i8*RL#E2V)("haTk-b`2qQ@!k%ISBG%V%@G(*6j2K(A%5)5b*#64"I5Q -Rea2Y&NRG8Z9[`"V2X%6h$&!Ae$LPJX8ajQ8SQDmF+C&Yq*p!Z3H8V4LcQN'dfPq -bETN(59$A*hJ$9MeBN!"H*XN*BXfADfc06D3)Z!J[,a"i,rVTEjS!%-@L(TV$PI( -!Ak3'$EpCYEUdXC3VQB@e$d+"Te*E2SGMk8K'$DcD`dLTQBRVVm0DJGrl"S[T"1% -Y(r[5(k'HS`XH1`fFQ#8Z!HPpiGP($h2D2Q#i+%cKaM[*r6G'@)ISerblHf[S6[A -KTCPLJXMh&Gj)cY&330DS`EqALD0S%[Qfk6pUS"j+L!mZY`*,LqemL!#0!cZ,V,G -$`UhdRRYi!,ckZ,@#XS,jYqb``YI-heY8(!1h+6DL'fJLCZq+0K!`49fJp3,mqEr -S`GIRjZ$lP2immCRa53A-H`KcETrLEP'0fKG!-hZpa5B5'[e)Y!jqUal5(kK-ded -i+$MkQ%MU3!,d[1bB1IF9[GCkUk*6hhJ!TC!%!3!!3`!3Z#2D-lJMfM-!!'pk!!$ -EZJ#3!mi!%m$%!!XHZ3!!)VN!N!32!&4ME%aTBR*KFQPPFbl2J#jiE@`!!I$H9%9 -B9%0A588"!2q3"!#3#S!!N!N"QJ#3!f`!N!32!%,"e3rPe#b3!&*+4D!8p3I+K-V -9ll6TRV"@)qCMmGmb`r!)he``jaX+iPR!9dI@RL1XBF339QP"'4Tem)R%C'AQBad -afIKSZ*-Ce"$r%I8VX,9jm'2#',&JFR%kAYmA8%$A8J-kfqQNeDhA"!"#`G5P#m! -qrDbCHA8Cm*d0@T(k1j!!IY%QFJZ&,5r``@Q,bZf95FVFdd`hY[a*(1[+`Yd`&qh -1h`1Z-Q24eF8Ei'&ZR8IqEDINldPDbA(ikJDKpi4YYiS9lQh$Rfp6rKbi)`lC9iF -V3TX#4)1ei49&1,)8"+Z*#Hj496lJXQ',$hQ@-Zraip[TA6M2P4'C"0D)1G[I2Nf -BXi2iZ'ap3HmrJ%m0RP#B!Yl*mPbZBDRb-ER`UDRdb3rG5EmX[Lb(,BRRVB0Q"5V -VaX["ZS%rR*Bc#N,3G(`8fPp6Mc#dR,m+0[djK&$5jCXm!"Maj8fjf61m`f(Je[U -",%@qAGbCVmQmm##G*b"RK2QY1RZYa$KQ3i@ZLFJp'UbF*fqA&3pQqk[iCVp"83p -@f""CIG*KNi1R9VLXAKrqF%))D#P'QYq(h(eKGCdL-4,R[&l%D9#pm3cHY,YhjZU -FXN*Tk6'rQF*$Q,'BZcjfY#PX5N2+UGLb)kM1#`Bh4`e**`1(TUB%qXHGQ-!*F6P -!h*)GIhb*S4`8j-bD2cke8UR)6"DSfi(keqrCpJVZrBmbbQ-FV6qFk'TZ`EacG!l -)CJPUTcD[himj-%V99V@3!169mB5DafX4@EEdIa!1c*5[M"`1k+eFYNFN"2A($,A -SGcq$ff[*K9PFf'1B-6NS*F+0b03j2iVV!H*1kHEr`LPP&Y9mIYFV40@`#pBPHaa -2rbbf)[$)m94jM6JkThp)#fPidpj3JlJLG"QfABCVdb)E%ELc1QrYaFkT%lU3!%2 -l-Q%,0@l*deL`D)l6q`&3Ta8*qS,(@i)X!6J,D",)UJF(2eAX9mZV`kmKR8AJHS[ -lHN6ANYKmqMEmBEXEEA@B(GZ1pD"c5NhHLQc*cBV(5i86X%B$ARB)E5ak#&-!Dr1 -6plGj`leY(aaeCmf!$*1)`*JFDP$9k2Y&2)`)f@YQZ3ea,aN5`bGNIELK(&0Rp6C -%AA6()@DD(d1e16K(#0-1r&jJ9QVDZ[5G"*&%h3YHP#Cja&IYamGa%Cmp(#$-0ZJ -$"%YFBqr&DIMr[`EDQ5*%D*5c&%qb+NKJNDmN'Vq1mS(04cE$5N!idD6@mMKZRpp -,0ecC6VhiD$J*Qj!!0FNbrA-&-JH,f0di8Q)0j3DaTIYJ$j!!Me6Y40%m+LPZ!E` -&8d2#T&Gh&C5qDd`"9J9CQZXf4$P&Hp!3#(S@ffZ[[eC(@&8LSUGE9K""FAc)d5, -BC1rVFb,V512[+r(-#P3bYBYjI3+mH%de+M3Yce1X,i+eU5`hm,,qLA$Ep8GFQE- -&2D(P&SMF!H)PGTZiHDM2C'cbA$Mh&qSMB9qJP*8&Jp06'`VDm-eEiFBmUHY9MEF -CDi`Xdj4+445L3iRbdBfBl-mE2"i)IM9i&MqIPiS'SKaR$#A3(01Qb*jlZCji+mF -T02S9d@MkV`H*b`!1"$@fNEI4Scd2YF"6a1Bb+Si+#cm`G9$S&,qXKF'c4KFp)"M -I`edfk8QP5)$)4!qT$UDd)"qZ+681)2NQ%efjb[13!+iZf`AG8i``Tr108Lb0GEU -akY'Hqpc5"3A6B!$X@`&KTCJ$G'@R6*P@[&*,%2qVXC!!&kB(rE$%&'HmDh)p#Lp -h`FZbCeR-98CR+N@PGHGlDP3$P+X2E8khRkIlB*PLe9bV9IV1ek$-%-V,c'+#9GF -ec3)ST&KN#p@d1NY6p!NMXQZI`dJ!AmA(`pFf*N1e%YI-kG)[CePRiZjR6GTR$2X -'$c,$P!%P#0L*@Ia%Lc*Zql2,H35$i-Rrf)+aRr4F6`C0&h2E!m#qUZL2(8q+X&` -DrM&0Gi"5qqhf*`QXCmp`b,`0[-MEmhbBVe%ff4VLVN#"m&E6P(q,JFDK`HJrLK6 -E6am$Sdlq!r"k5hDibSNFjXl5Dqpe,,c[3PTT%r#IhZ%Nme8lF0P@d3k`5B5H+)4 -(c8Ikra$ebS*3CZ`+P#dpBSPMPEMa&e)*RTlG6FN99'K-PXQZ#Y-GR1Q6UFVRP9@ -bm2*hZTHA&k#R$eBVUET0jQrdm%T,5K@020hme!I42J-DJm`iEj,6bNI-JLMeBE' -H,4IFYGa1%(lRK@Xb$J%N3I,P1cf1iJRQ#6SlL9k4!Sm6Lk*,fPjP0TK(mGj)P(l -Q9+5Y@[9b3ZmRq!N)i(5$JD0U#2A+JDVPTJLh'p2lPTdA2$,b+PiXLqFe&fcP&F0 -i$!EDHH%l[586'iPebb-X[(fiIf+b'Jm+fa"2@XIEk*0A4(TEUU`4cUaT@#*IZC' -d4J8RKdV&%3&I'!$HH51UZLmkK)Pa,lNID1T6S0jb4H)KYJUJ#h#p[emBhFX,0Z& -e!0JZA$QF%VFX1VD@K#P@hBH1BeI0dBmaF$bbe(J5Y+iZHqa42IjY+VD5Mb0dS2' -m9a#[04YF2cX)lperp-%ea&j&bm3LffL8T(!&Ba)eq&",N!#5+Qh+8I6+IB063+$ -BeARhqphqM2,'e&P%E"!++&j0X""Z[L(RiUG1JFJJ'&0p3UY'BK+%iPAdrh1)`(& -JX)Yh$8k)"XX"63ND+q9I8r!YbY)T!D$'bJT*S4lFmlIT%h-0,p[C(jm8EK-6U91 -eLHarG5I3)E)8dU(aXcr-D-T-(CHVaZ,#AhU6hlM2errk!D#(VhMXP#,a2'!#Mp5 -5$EZCXd)hHm#SfD6Ph2UHR$FYqRKS9X9hQ3Pq6Mi9KX&Ed91`UK5((d*K*ND,9Gl -NQMddr))k8[,R!ZG#+&G!-aZ8X(d#3fNKL0Z59S#L,NE9P3QQMX"N8%F6p'#E(GK -kK8QEDLpBr@f`rQd0-+*I'l[4PC-T0l95l@-ai[*$PTZ`Z+9BUmS[k!Bj,a466#P -Z!4Z0-'Sm`Z9`)TQ9D(qpUH2(E5'qrP!PiN6ZBY6&FG0r*)r+hpVZdc3l5a8YPV! -!#k$Qq,l&jb`H8Z)M[YpDem$,lA(Z,(ISZ8i*U0ppqUNd1(Z5hT+Z&Y'c%ibTiAR -BZe"mcAK%P@SXQ&HUlYkKdL%EZqrTqi2[&YM`IpGrE@kb0aE,aB[)m9NZB0@fMST -h3A$A[P19IVa420&T0Jhc9$(ZpEb19SHPP)8PV%QTUa"ki#MPQk$k"FYf2rMVf*P -"aJAa,1RU2lC4CD0k05qI03rI"T+83eAZKqqVa![HJr%bX500jSZ@+l-mUGdh2i0 -ZAU6A,CGJJ[EG&8,S&)Nc0EmSpB13!(qHBd,H3Di#ZrHP`k[cJ%-ri6A2JDcZ2H5 -Q(S8&8p`08FSK`,Al,aZFdj!!p18hr9$ZMkZqNXmB[i,1K+5mj$)JM#TT"`6REG$ -eek9&+3b+RD5m0EH2SN4@ri6&9%VBj3I&dL*KiTF'meH1QGi9C(e#S)lG!m@Y,ZL -rUFh#M[Hm2*-J'Mi29`5`*DRbYcFEMr"e&,-"p!!PA,R#LjrdbK-c@9Zr9-5S"4! -%XcR3CQmcc)@5#cc[%25Cb-dY#82kKI$%P,X5aj,,NAGE)TbPBpKNM8BR+Y$5$26 -X6`Q'Ndb&M-C&l0,iZ(drQ+[8T6k!Sm-jj,!HX(Iehp2YYe#q+Nrd6DHhXG$-"LJ -J#l8US*lYSAm(3k@#M5HY`R&ba9XKraqi,f`5b5mii%1D"rfN0FJX%-0`&'eUr4e -C$9M&h[Jh4ak,,(f-Zp96S13Ah')IDC[&f$ZTQd#`c*hkbN%)'+9m$DpZ)*b3!"1 -VYU#-[Gm#G-5MF0N%DZT&%1lDML)-4@hYm@lHh4ZC5D+9Sf!#2-fl*KL(,1`p'SA -rAM5+D+(bHlk!Hab'P&[eM%TqETiq4ZmpZ`GP!9VM-UZ[[dAeP2,P@**J&$'F!@K -#Hpq"%!X4Hcm*`F&aPV00*l,C+[LeCShA+k!V1$1rmpNb"j-K)+i96m3,*)Bh!Qb -j+`CK!E-pqM5H-#(5e*!!h8(jjaGYQfAeA-0FCKGJef-SUBGh@1Bc[d8*aKY#5Xb -6R%&)k*cY4qZ#[%SjP4RC$JA6G4MmZ98a2e8X#CXD'lk(RLDDJGpS("XZBlA5iKI -VB+GhZXGIb+"T(f0r)0Dp"5(Je)!!iGkLLDTLQH$i9Aa6`8Yf!4bqc2X*5%cXq)& -$`3KkA!"8J)-)AjIG0,)f3#H`fpmc6AV0iLpfIR4Xhp3`MR`2"UZ8E`D2UI6e3mG -4d@rf"5mTB9b`&0+%9F9)4!UN4KGRL14(QFM-KIr&cj%E1r9`*J`-rGG2dGp0ZAG -!-$,&IJRk4[qGFAaU6d'm9lH!XMXdX0rV+'PZVe91hlX-cFc+0#SPR@p93kl#G(q -K85p*G0!p&r09VLSMUQK%1cTb"aCN'"[k)6qkK8"+Jhl'2$+*`N2Mr)-GbfQ"T,Q -L,C,B&ZJXlKKUl+3k`@m1APC+$jI"9U"Yb&0$'(YDKa$P00H85Df@2$VhVqmD4a$ -9AL+SB)l`YB9TqkVRX4Y["iIM-bI0`@KPrEN@kMJSbbL@jA#EIZq"@Hr9`M5"FF) -jQU*3e9*N3944*M%`22aqV(&%d8"R#1dh'%D3!-SjkFP6jd"KeKe!q!N(0+D"0UU -KDVkYcm1D3ad4iHAj0(@Z%fZaU3Ll5JZ*2b`H5eA'8b3TDPaQLa66kUA1N[U,f!p -V&,lm(*DK%#6KAABY,(-rN!!&!eh!69(HiDUiM9"Sj8l&N!"LZqVV51`iQ,'3!!b -Z`H&"+V8&6(fDr-+dm9N4X'H!j50GG10XG*`h&bIZ%6Q`R,kfLH6Via0-"NHK0"T -$m9JqqCN-+`-k#6pF"1-5TA8Qq"#B(RjQ,i31&Q$M5M*KIA8Aa9Kpd#$@B-NZH05 -LH(,RXfD-E2Pce#Pj0#V"d(!$kjlKPqXfTEqFUlafK*N$j*[9S8eP@a@cMC[[D+( -JadiBVdHi@G4F4lB*H``j12'YcUK*Nf6UD'EGc2a+YI'Y'9cQF*c*1C4F(pYMB+3 -c%Q*SV)65[%e@2pEfrI3G88HT1+346-Da#JM%,NF+[8C[P+2EcT0m@%pReb[H+-J -82TUFZ2eY-UGC5G[*-S*pkcqJejD#X&MP"[0(AZdqBb"b2EP`D+efrV0b+$0l88k -#dQeSBU2FFHN!P2iDYMT0V)Rj0Ymq"ar`PaUS*3!hDJF5)TI&b,(&Fb4M+pA!UpP -0dqDfFr,*9'Yb(-,$SqAkRQMA)YS4$8k&HmSI(AAaC4Q,J@!f@'$*lXC@T,5S&*4 -X#*3&%UXJNEe,@!ijReLiJSYf(U0eTChhKC-Nqj5lafbaNbi80iMHmTjL6!ZLd)Q -DN!!@LS5%Y,S-H1l%eG)KHS$ec8iFifTBD!IYLVGZ(3LJ(!Ql`j!!B@fSd+d[3"` -LVph$0ZpDpREMkD*KN`,S*#DV9&j234,c0kjiKd!@1ZeT6"#j&m2X&!I`K4k1a$L -GLEHPTTfMrK1l`E(F4G)!QR,c#-`)Dbrr6+G*Y&4IpHC#)rBYES##VR!UAfSUdLD -RMbik!'38%9mH%cck9J)[hR4VS30YHE4YTQDBeKp[-H6[piBei8@HQXY3UVe%+cV -+akqehS'[*1`lX0!Q%BL!-e*VQ+,$33YQ-l%d9Y,H&+c41I9Jfm5'dVm$BR'UUmb -pdMHrAk84RaqKp"M0)BPPp0+qh58pZ[1P$ce2X`reEmL+BSm`(2l$+aRifS*-UX) -3IIT`r4@2X2p#Ybp"q#lMZE02GcIC,bJp2M)FZ+CAdU&DCm9K"H`B&,kicQ!4H5@ -p4lP(HG%258%pFJ')-1$Z#*JIXAFd2m09Sk4k-A6-Y5%aq[bePKb#aLXE,9%pYAp -)8i[)Bjq+,58a*pm,e,`Vlm@$'q2L%99XK5eSTGKLFQdUNlB'Aik2YjqA56cc4$J -[!Sb,T%8%9QH5&1(ffd`V$BZB6c[,4K8bj@P(Z`0fUB0C2Z&el[$*[`EP&S(%PC9 -PCG(hTrb#P9RXkBEb2dr'T5dU$R#9Z"1b&$*!G3iP05k0PeS*@r'U+SF*k)GZL8# -*2B[aX-+fjN"[Vr)Yh*f(mMh"[`J!UFRq15E6XjZLT$M1V(%@GZ#99MH+VPmPU6q -l*Q%8AiGFLJHGU0`8TMmGIpe*qPZ[j[8KYBCjL$3pFG@(KZ'R6cRX&m+LT58aiNA -HZ5)JK&*0q(5$(G(cI,"CR5SUHE343GU*U)+p`rE"LFYZ+Va6raZQ!T!!$0MVAJL -XKFY25CDLk9JpTS49iMdKNAEqUl&ec8DL6M6R!%+Fr-P+HNIld$fbqr)!HVfiiZ1 -#3Ab'f32MD@U&P`,ILGh0""XE(DK+`aQ+pSp(U"!Fj1$0AeqSG"hDEUZQ!#HJ&K% -Q"3104cEdQh28hD'JkFB[TcTp,K"YJBQh2PHH`NQ+2qGRb+9a@30MAEf"*#'HMHM -!UbKDS0JdGAq#pSTp'+!Y6fCAh)+jbeVV1-C!FBD&lALUCq,l-AVkeDqj0M+Rf60 -H2GPp)E*JFp(Jp+9amRKDRGpIdL%i`1lbqpcF-2aEXX6l)RUP1j2"Kb!Yi4(E -AGEGLcr4C,#2YZ$0$P@BrAGTZ&&5MI51-fV(2`Ra8*,3)d""jG2ceq0R89iRHF%f -Y5@f9SHr!!HCT[5YV3JmBXeX)K5PURafr9abCipRE9Yl%EF)X4Ta8S9BZ8kjPZI3 -[e[5,P@4Ee3mBm)5r$!IGB#irUSKbqF3d2$c922()rb3ZfP[AYhaR8r9qLPU9P0' -B@83#Vl3PTiRIT%"Ui)G8+d#r&m`&$8)J(*KL0JF+d@V8-`Ikb$88B[Q['0rJP`r -6$'!6AZr'6""JYJN@0YfXA`,D0''qCYY#4ETZfXhPCPcf+Kd[0#aDlc4"4mLBRS- -R[ie%8l1k#JC%rLXF,Bd*lfV&h&Jp%X0af[r&,V2RkCCDNqHKB$+4(Dl4a4-'AYN -&(NX(()(F)I#S[+4NpHSAD,l,)0*-c3*8e$BQ2,*P'JM6qA#'Ff@p-BprdN3kMP1 -5e5jlHRBa"&(aXmB+F3(%`$fFBZ95d,pahhQpKiIEE8&d3&D9kd9peqRLdr`Z5XM -@`2bF'h8SHABABf2iXffB()@`kkYm$S``SP")i$PFGkN9!fZRCjEPfPj`Yif'FJi -fF'T*cdCR$pY$DVY@jSl38k*S-Zh5KjPd#LF,DPkJQJ)UDA9b30P2Zh-#1A'l"TK -QUdGqUHQU$3k6Rj1--'EHdJV6qQGb#RV-Kb%CLFB'XQ*5GVc+KHAe&a'!cm)UmKA -1(hH,Z1$Z!U9dh8SZ5[%*8MV5V9BFY!8UBd%K&bYY)V6,!2dQY#93B)0'2RHP#,$ -`3,bCEJrNl2`9ZZ-2mYe"e2[3AB4Vh39pbYXjVKar9Ca3()*``F33C6Ikkh3VP%a -$1)5d"FKi+Qa$PqCdEPAF3dG+SIRHA05%PfAE!1"EhX3h2'$EN[XJBLVY*f1"PS9 -(8f#9CV2h1Nd-4(Z$%AE(+'$)6)Jjm,i@@RBEPf83(Q3SQ'hKUM-*qh0d6N[DQEQ -*d%1HR4bCm(pQB#jYNMfl)PDIl1$H8a#S9PNKH1L"3bDfVciY80`Jb3p$LFlZHUR -m)ddCKG+#QVqV8H0JJBCe62#DXQFp#bhh4QZaISZ5dkZ"%'MfbRTUXJ2KA"Vcq39 -F0(*c6&b251[CLpP'M%hmH#5j@(@kPRj#*4$4P+#H"q25LIL2m!eb-1F3AV+HmK* -pBpkk,k``)6UCGd(rkKGK(1dN"KUj&eV0+JiIEC[$LHp[F6NKp'!pBlp"`!2kLmr -C8A#Q%fbSQNYT-&X`J`)(G`I!3l023Q6[qNE,kaAPmqM$qL2"FZ8`AE[ZE,A*!Um -r8(61E(&CjaTD$fA*CX'*9j0)KLqMH,,LeJ$GXRbR!@eU-QL%-L+@RF)MZlBhBL` -AVKd0(RpX(hh5!SS-d"dF*SY')p3mTNcLXIJph3$"qPL+fCP2@b-k26154%[Ya'P -[+H,Fb$Yl$@Xb2`CVZECSLhA&3MhUJZF0jSRXGpS48-*c!lJ)d'TATY'6kqL+2Xb -r*Si#DK!0lMfdeX2[+!AX1(rPSB1-M6SA"`'Rc6P%`hXJ*adilX(L!NA1NI+$-&F --'JX#EQ%MepTp#HF18EaqQm*6L1SVhLaSb$@NX@V'YN2LiKZqApl00UjdhCeIPT& -q**0NT"TMd"IX+&CA9D,'lJAXTikPK3*HF'+*MS*UL#CSZ9FH!,BMcCj#GlRR9NA -'Tkc&+4$XqMjLEh,*PTCD@DT%(M18i"[&-Q*T'EP54(fFr[`c&aq1$+I1"eHm6H! --D6hA`l%m4#5lhZp3KSc1qD#3!(RYLPb2Er'X(#IqE8!#&J*0!$"q36hTXSAK3YC -A[&3cK[+PaZkFTC-eB)-r%Q*MrlV#l&'V-q"VqC1m`$(L6j9+([hSSZiC&l4JmE' -Q#ieI$Ej4&Gqq1%RX`L`@[H1+Mq#1[J6&ckRZQJBDHk1+U(Ap34Y2BiF%-H&-e1I -I#96cMD@3!!8&)3JM%!C6*-!$3ISDqUbih#l!M9%Xa""b`ahHH"j'LC9L'EpH@5a -M'@c-3Uq14,bGr)4N-e3R9-*XCA"Vl9Eaa`3Z$)m9+6fBC"+c"LGE5A550J-Kh"8 -b'DkB4eKK9q4h6pSBr-Ih1+Yc@$@#rEpi'F)`+,Qqq"LJHF##9d3kRRdUPqNQ)D5 -KNb"&@fkERd3B&&(!##)`T8pV!+S+aXhdRGi)r3(Rk#+$X8`[qkZTmjZEZ,S(4j' -!+E+#kDjMq$@4YCS8"2pr*U%+Y2D0E@'C)TiIAp)1$pRL+*aAFI+#5d,VXA"+RQY -X+!5qiJMe*[0l"!Yd,c2[QENLib#d2T`HGJEpR8pmZYHcB)P8!16FJV8[PRKr%f( -)GBl(5bbEPTH96p-K`"[c[2-IMde,D+`p&A2'-88K$0CBFN"Q'*fPE1b')"DMe$F -HG9[2ljm'@319$5+T-Z'*hFKpBYB[0VJVh3UG-h2QIeGB&9I(4H`))MPc2`NL@m5 -NEb&bmrhM#c[LJ-Z[mX'p5q$-B8@+SS86h6KL`12Jl)(RB@PPf4@8Ke%Vq[@IF#& -,a*9f@hiqeYPD(YAh%Dl(iHe`)MKX4%BPiUr#B99b8J""DUrH`q"6V-[mB3MMrkD -1)qYZCj'#(Q62Xjk,K0D![8DMc8@!FK(HXbIJH(U0,'jF9hZGpmHUJM&CEShHS40 -8!Z(@KVe`HH6T-RP,abU(Z*&10`rf4!$V!`ZH"hGcCT92V$,Ni4h("m'$PcK%#14 -#kDm8UBV0*"D,05&[hDe84$QaATTU"S&[G[f5@0klE#Z`@Q1h2Q"crXp&-MbDdcG -1&jl@1dD!lYT)l6+@R20N(2aM(BHlV3Sjc-,XVTHZ!EP9`FM31Hf4F(KBNl9@AB8 -4ZZFLl[YkIl"HaHja0GVh(FpX6%f`,*pf0b#C+Sp%FU33Qj!!``a,)q8"P"ArNVB -XL&*le998f&Fc*jEhFE%iB9ekNk'*R'L9T1T%m#1lGrM(@UKrPA04eCIMm5[@64M -LM8lH3XP1)E1h-&EGE!18,-&C%QZ`R'&Cl8TUCTY-eZ#-m46DEdLPLd*))bc3-pl -S-GHSDfP4[cqM9qj&l&Xk&GVL3bLKh`hp%`4JaIA-qCaU'eNUKlqGUS-QFYCVjUI -qX2T,!$50U2J'49*1AmmBMM+8&8E,[ahl*C2-ZGV5%RcH+*GE3e80h6N[(VTlVAr -[ID9UjK-S6LUKKELRHk2(5bM#*eYm'Q81D$@KHD8f)'S*K)@2Jf52iiFhTfR"5UD -RHE9+!6MVC`jf0RrSR+pH3"Y8b"4[IedY$T2eeL00-BQ-$,Pq6UATh0i8%[IFirQ -[d#50b"Uh5K`Al,Dh5+Rk4CI"S@j5[,DI$%`91cDpZS3'5*b(d#P8rbPYCjTFVJ+ -e[!bcQ6VDbGj-2Mf@X8@5$JGfK8H49ILN$lD@mS*@K8b&B-+Y8Iqj)RTYa$J+SdX -,XMm[14!5PEUTDGK2c6(DEk5X#Zqa-MVhAJf(lhFA@E0C+lAPrBNBiqX(IqHVBmq -ST4JAEfR&!6Kbd&fdGp+FkkVaUR%d+jZQdLlHGZCLPbT"AR,V"HdQ'%+XYj98'4k -pjJ#3!*4V-kk2i#$ifYh`LLjI8lP@lD8Y4@JPdj8@0RS$E*@kN!#NG"fIZGQp5NV -k@`a'1'6@dQ%p9R[%#)Gi`4Nlk%"eF3AMLb19C(9V8X2a5jN@*9fTe`5&--&UR!M -i8m90#c*HRI#1LRUqiS@N5Xe)[PN+3AqjkBd-@VUEj5fDSr&`,kj&br4TM,pkG2Q -kj+ZTZ6)rRiI[fV&I,dr["qTm#!UJjm@KL,m-BjZ*,%eVmdhXBUSE1mp5TeLI2S- -HFElSNl#5LJ1[RZE3e![%)A#2[M,K!D$X-JJp!'$CXK0(&m`B5GXdHe@&3IN3-HH -@5C!!f4,JaIX!`1LC@%R8U$Xf`!Idc*-#`*@P(XfGFH4)AQEHh)5!(B98[L'l+f5 -II%H*rYqPXc6K90ELAGQ@KM2,'c)XFHJ[@(Tj9K2+l4)Z1(dDd2b4`4ek'"kE#r` -&rjR66%CQr[C9M'Rk99%*[CZpB(0#V8@&%PaHe,@5[Qr2*N*l3$2mJ$`eVe5N!+C -A@33HD#edF%dq4cE9!adq'P0amh-6[8Q![$3I2@2BcdCi9KhMEQ"E4HEU$Y$,0`T -[Ym$5!%TK3`C*40fk(CM@IL4GpUph2I@!pSd&eGdr4+&refYEJEjKeVMKh#0-,"9 -'2*D[jQ"N'Gai'I)'[ChdcGj1L(K%PdZl60D4'XR)"29USRQABR8PHa1dUcLZcVB -JDq8Q'M&*#jFEbHB-m4-jGc)3NaUEGIGAKKMjSfR,MBaf)G(K3Q0NRb6NSV"'8cD -Qi)1l9p%MfiVEHR*(QL$F-A1*L-qj**%Je9Mi1L@aS,&R'UCqDmq6VD[aIQK2)3G -1ir6"SVb*9+Q9TZR4FfSIIq)U4ZmqXT5C"dc4m&QD)ch%e2'(')M1FMp&PET'S6c -!KE&UhSdMB8V`lDNqk#PM6cdL"8*8$*%T8eTRL-pQ3cLH5DU3!(#6M!"Q+d9YMm$ -N`q54ZFh9JNFH2%RI$Fp4$d-U#BTd)2CX1P-pmZ#TL366L**4lQTGKM@NF3#3!)m -*DG3-R'FD'G9'AD4T5H4ai02S#!8EJLr#FLd&VZjpHB)T#el4a@P[C)5FL+51F@( -JTfR[h*G#iXl!jLrGr1fr"*r$KIB*"@SBF"&PEI8H3h#kr,E`NB!fC['IJKhT`HL -eYlEr6*Xr1@C(6ARhSKP[[dIY',rX4'$M)&a20eP*V@&'i-4Q"KffD@$H11fmkC` -@&fjM'XMBG9rC'FELD2aRXCZf("&(ZF94"aEqDJZTm'1Pc9BkiQF$j,LUMmae&YQ -*Maa+1`0Z`aV9LGHD5IN@D&X2-Z5@L01SkdDP3HD0XR"dHjE$KM*RDYV&EeJfe$c -m0[S+d4ZB[5XX*SV4e+'Mh'lE4"[HZ68@4l5aqiXEG@Nj3`4aXljP1#p3Qk%MLH0 -C-C4[,EcVA[Lk@q8H2rNPi5m!pAQDc'amhS&(-Pr12Jf1SCG8&[2SC&'(c-0cbX2 -U#rPbp`SBNSBqGBD49F[QC@3ZF@LH9HC*Gh-Q9JHq%%remL)l&p-hQE[UUZi$f@- -JI2"92iF[pKU9HXEbEIi3+)[`@QKa+(&Qkq!N9m@J!YA2qhJ$%6Dr1&#dZRG1h5e -4Irk'jC@BYEb,D9`p1!m&GJL5e1hHDkAk[jNM[['V!RV9b1kcVL'HNLUSJC*TeT) -2P%Y$5+VqJ[EFG-S1HLYFN4KEKML+bPZD1K5@)@@$j,mf&Q*`VMLRY0$mb*E8*3X -GD0I+([b%'qaZ,l,KRr$mEpfhRekXLES3!LmN(Teq*,FhHHCj$ETl*[ZDr-C-c$- -RQrf+l+R8-9DC9Q"pG%+0a[&4r@$QFGr-Fre21'A5)AeB)'eYl)J"Y[FhU&`&8@Y -JEr5""*N5LYN%@"CL+k#V4VrihV@R$##mNf1PXHc"T3%&Um@HK"%c8dpCVJhYcl6 -42H"A*p9%AI0k0@Jr*iC!BJ)@EB'``k*h1A5`EJ#PN!3"!!!m!)#dSF5TYeNKK!! -!Z#!!!3jV!*!$cJ!-@R8!""l(!!!b83#3"!m!9'0X8fKPE'ac,Xq!!!"!XNe08(* -$9dP&!3$rN!3!N!U!F!#3"N,"e4rahBGB+p$IhcA8XarlKIRL%&4V![@Lk23Nd9Q -!5FZ3!$XPbE!!pd8Sd3U[HaGHml,03e2dMF!h#`P+6FYj+IYU6IiVf@,5S@,-fm` -#lX%3eS#-pX(1G5$44qR`L%l,CrK*Gi,($q8G10YMFVJDD5+p@+md"k`235Mr,bH -U4h6C92Bm,-jhCm)@5bQ25h$JQQk8H@V3TR1"KmVGNb3hee(N&AF30#d-4`NBA$b -5Q6H9Y!RlFJScXX+0aMKY91pSaYLa!LmK@2)XYkNipNidb1i2lZ(VqaUGJjUc0Hl -Qq&UDic9T%%J+8miTCbN!TXc1#-K(k-GYZGia`EQE@3U(&`,C$GJ#RJQb9[r9R*R -BI1XF-TUc6-Nm(B63YpG$N!$R&(m,8I8aI!#GlNAm9G"68@CTMX*qIb*BD&8Nme# -kFF$`VUC8C-9h"PV(QA$h`Rfb")lEFI&F4`RU,$6aK1rH3JrLVBekVd,36EQj1p) -S48T'X5N`qjYJSj6RrIY!Ja(p353F#$T*4Fa%`kGI4X)ZX)%YMLQT$Z81RH%1ZA( -ZNLFU-mjp9m%UpY2+K+Xir5NQdbr)p#qdkKQaj4![dU1k+2#hMIS#4@RBj2Tl+%A -cL!SreFj`HlGZdEUH'V!PINpZi`hjiS'H`F*3dH`*iRlC1A@C,riSMYZXpX'pHfQ -53C@kpiaMk56a%'c$@md2%cLk5!)#IrdeSFP+[e8EFraa@V!L-pI*lalb&M*F#N, -+4PAhRfh)BFiK+qepj5ZIJ%5qL`eG&e10p,J9qA@%%,lB5F9qH2UD8P6C'Cm+@Td -P2RP*lmb%T)2'4Y@'++d@V4Gj'H53!%@11CCHdI(h,Fq5hEf1kNHH1lKR**&+1[- -iBBqHS!NZZ(HYH1Ge#mLrMpliYcDXUPe@N!!bH'KN!ZGkacb-2[XRV@[*rp@8md, -0BCB(`FiP5V(%Dk0@TqMC4'5NV+`$dm3!Y["89CZVJDa[!KEV4D(kDV(GjQA+T0V -pc2#Q)*fbYAc&@ScArE5maffabS0G,1cbbPP#C!UbT&pNECASY,L50P!iQS06N!" -FU9P($KY221+0R'!+Y3CTr8qReM-6Efmi))ZY4qF(eG"l6Se@iaedE"@q6h-VSiK -i@Daq9JAQm5H)@508pVhI8B(2Ik3-BVd*p6!jJMBk*Y"VJ`j1M%`i&VmKcG#hFIq -%h+p*4909a,Z[a2pPKkmmTHVCiAFEYSh(@QReLRDBGU)0J+1p1*+"klCUPPf,))j -8%cUlmR!eI0*ejNeQ&Vrk&9(3F$QY0'13!0lK05YrNia6(eU&6P+p2EiR(GJZ#Mk -+4D)[5N"5h9B0iQ[Z'ZmIkR`[-QB'3mdQVA(G,fI[1Yb&RI22Zapm8dM-J1T(J!V -T*3"[5i#Kb5kR%YQ*$ieH$T`erkVf$Af5*CjX&LFeVT4@$QhPi+ek`GbmVZ'HY5A -#L!)h@(ZrcH(h0#fK8k"bqiX1rGT%j2p4!"EKM26[Sffl&)(VI#Rh!cpaETHX+P( -!U*&ZD(N"iBr!J6LL%Pk"J&-VSV)#@JeDf,`5&cQH'l[6D`m`SMk"!%4Qqm(U[V" --CG'9Ak$b%Z+J9@8Hf6FR25J))Q'Cmp15&dPUB2XMrYT,jp(S,,L$+9(*EaD%YH[ -$jV[3TAlkG1C!DU&PV'*VKC60P,`rPR9M+RM1-DVaH)0mlCePa+9$9b+(E98*JQ5 -N*P0i,Jl@PiK%5kI&-(@2m,"c,N$,Q"fI6++,$-c+4ReY+ReT0ql"rU,-JM92`hU -IAjJAk!qlCPMCMIc4,mTj2#[Ca,`r2'[N!PMrl"lX$9H@kU`YPl%Qq5c1641j0ra -X$(U)H"*"NXdh%XcdFqC8G6!aV"9KT!R$HP-$,,cHicc0fSKN&N)rR#5H4GI(#i! -kfV`!L`Srq)FLfJ'ql4+T(VZSi+#rZRGE#-&kqN-SUHjFUP6I(%K"0#"`r''@Kq0 -k&VlFC@-jP6YbKUd,#el'$`3Vh*RRlM+9KKRLX@+[56#P2hT6i+QN6)j8i!I'bAq -85&qF#U601dC*T([*pb',ZlfL(*PJ4h%M(hRG*MFLR#dYV$UQPX3KfGYfZi1mrrD -pk9)Sk0[H`S+qb#I3%aMFZT!!LZq&(r[Ka*@,j0RRL)ai8-2F4T8XZKQ'Jh`Lqr3 -&NLR*JE3S$1j4"#T@-4KYjeZ'd$'ch"[2M(-['$Hq+Yh%3H8,kV16FNK$ZB$%!r' -C4ph99C-B'ckLT,FZDied6DbQ'+[P0Aamk9`fVS(c'TEI3dVKpXd[[rdSC3Lr9lE -VZkcAES&Z'-ErHR@$C++9VlC8*5!0`hqhY"iQm(rZ3eIjYl)`"YMNP#82rlD2)GA -'RArRJpV"(jqHGD*R'pFIMFFchJGQ3-L'D11QE9Hl96S'&YIRk&R0dB`dQm$8[K% -9*RQEKPAB2QaL4MN[#$+CMVYraPeFpcND,mQ8*(fM43[cbQ!0h,pK-8Q4bpUkb`H -(U-Q4*A4$i3`M[-TCm&e'T,cZkIqpJCk+l#GP486S8@jZ`Jf,cTLDKi"c'$K%`)D -YTRKr(X8TdQkVKL55d%XhVk)bF#1$4i3FKLbm"Iep,*X1F3$BhUi!h3R!PK0edQj -P3P""0`2kj$A#)Redi[cQ9KjQHPp@kS&QdPBeprmqXNq8khcZL81)L`0h(fRe0(P -fi0F4`J#Ql9'm2`0C)R#pAi@l0E##lE"+KFTY2S,Kc(#!j['5ZcDPZA,l6S9hE@q -X(90@I1T"Y"hliIDp-9bhdf$HKpjpj6hRlBkhD862q0TiGDQ&,50l"!VpIdPF'Lr -KC%JfL@B`&!hDU2BGfl&KV6(D4Y&QXq1F[FRG!0@A(Le1[iF1iM*l5&8[!LKpGSl -e2-I(H+hCRAdM-`Li`)d6fE[eHlF-Lh26Nr3V#+"!X)365C8Flq,UZ&Zj[KJ$jH` -YMPA)E[c'bVdRXh!Vmk%LI$RZ)(hTPd*KRQ3h*H5&8,1-*`F!@8h$p9c9JB+6Y9% -Yp(c#3H91V["NLik48`bXXdlmhX8%ia4"#K-kfj!!bMh3qU-MrC`8S@@,lhDd9Zc -MT&*Im6'VIakTEN#Ne@45SIhcmGHcBpGUd!1*LkkFB$05T5,6Z'X-f`-,3@HP*L( -qF#Kf3Ylf,K!@Md*+Q4Lh#q!"%DPNjG+r+a1G'DXBe'-*kNdf,-,6-%J6NY$K2-M -PhJEMk14MNc(-pXS'rDVhV[FRaF,N*j!!X#JiR(,M5%H(b@-2*R$9TL)$pkpCYhK -a1!5jITb"!@@e%8leR%"S$`D3!'98Rq!8ET05c-B%-A4LrbQTB0c!ZXB@qEd62e& -@f`6Y%(9%F3Y'j0pc(H"h@1"fQDe%1033"dAH'GMiNl[0r`qe4LZai%L%i8I1*,& -%UebiBI0Mmfrj@A(de`2)!6pG8JLhUf@1E9Ah))GJf1*VhZ'kMjc0Im-CpJbN$KD -!lF5l1!G!Z"pM1VF@b-p,[hYGapeRe2&kfmQl[LKI`2a&ji9"Mac!+9kAeI`f8q* -"dVX8TBNXViXeSP&#B90C,@'q"Am$dCa(K)k#Rc'+L#+BA2DHGIA3@-)Zk%Mfqck -K*heGTpm$djDSjIQXi9"2piHM!$U2jDh[0*jAQD!`MH8`Q%lA0bSC98$SVV#L"Q( -0)N9F+)#Am2c"1Llh1*'d(EK9H+KeE)!#0PJ+*eV-TX&@QBKN,'EI%[!-56iCj9H -LXC*bCLR8al+e)5HeB9`$HSPSlI`NkFbXL+a[a"QDp3VVmIbrkV$I4b)+&"U5$(' -MC9lEU"PYcL)SJA+aPXL14*ImXQN"G2Df9US0V2ep-ALId*ep2M2Re-pd2!bDXq& -!bLhcQ`"8YJklT$J)fc(f4V9)GDBG)&-C#c`j$r#XaA+ibmT20hkI2XeAp,,GGKk -$"(`Jp49L,!6%SVra*h"[XX4#)5,-eT8$Z0UF&kPa2jpKBU"P@4-,X*YUCi1K-j4 -iV2C'+kRa(BHEATD'9`j4J1(!*TJ@@`-3BFNAG0P9T@h$l(K*ZEZ&VkJA3EbQBXU -@6r@4K6%1&J#&mf%UT*V3#!cl&+i'qU*'a,Q%RaDL5epl3jDikca&1$G%1Mq!TDA -!Kk1NAE(AVEb9ePp)G6fc%e,B-@L46M5(9SP5bHAJ"pK54H,+mhq4jaU9*3K9mG" -Dh"qFl9-'cbM&(+rcFP,CGm2%F-aA)d5&[LqGI1rM6HK3'TP4@rEF@`Q`M5lcm", -K65A88)iSrT*,$4-VHe*F"`@Q%9,GRA9P+)rb+#AjC"2f5SefL!ddQT'T@-r2bTa -ckcFpLdjmp3hL)$Z3!*@(!r1UmZeaeUKDe5@DQiLT@M)MI4"QNRLTQJB)JhPZmAk -Kr(!E0B0il6c)1F9rb1c3Si-ii,T5%Hhq)r`BI[A*D@@3!&ab'VIrpMLcXTXaVA4 -VILGS28Vi852K'$6NCGZ*HNH,-#GkqCKklb)lqR*CdHa9QHBV3K-,35HC2BD!5,m -XQ6UC-TF"+Cl)3,K*qA@lh!H*&fZ$X,$k-+Jm(T48qibR10J&p9V@EZD4M0p%P$C -Qm'lXSS!BA8NALSNc2L+`3Z"I8#1!4#U#bVc`kJ'h"JkQ'5"MUdCl-p`[cU1FT'f -kCQK-I'9'!3Z'Q+$LUJc98Q*ej-5'46+N6ZUNkTS%qdGZ-K`-3M#AUiRA1Z*IQi' -DF)YU6H`0T0N,SD8B,6bA*mGd06E$VDS**X0#UF@*+ee++!Krm6Y[f#Z$&9Zfa2E -,h,j`5Im5%%Kq20bXD,3i#JPi@EUZ*mGfIF1r-"El)DSCKF(Lr$Yh'-1H'QcNrVe -%$A@IGK5ePlm4M838cB(h"B@"lKjJ&bfG+d#`)XaRZ5V)FQD1@(f)EMpXrK)IXLP -,(i+iLC4V3PAk,S1Nek1'SLZ"a50&MH,')K)"RC0))AmkKrV*A*`I)ZQqqL-c*bS -8cXEIHm5GBiNlE0-$j!Q*X5JrEZRP#q4)`p@SAIL(@N!*pIeALcH!bN6fQF"SJZE -&(jV0L$Lfl&K*hrKFkkd@#KEE&h*R%ZP(5(-`UIYC2$%(E61M[GR5JcjFFYF1IbK -`5m`VRYVj+1RidY[N!K`9FYLPMXT&RbBfaR)B0IF-cl*CB!Zem&iK+$k$@DK90)L -Nj%Y'4P4AKK,,*QAQNX9Aj#HT9-Ferr"1V[hCI"+eNSq@d,I8IHHe&C)K4@U3!-U -N&fV6Vec0F)L12RqXUbT,N!$-)BR)6eL93+iDUV#PFB4k0D1*(&!C`!ZVXUk@412 -V)B[BaF$D(K"fcFle#Z(ieFMG@UC(`5eLY8X#PXiVHcEj31RA"EGm(T`rDqCmN3V -emFJFBSV-QIUE85#BmHN+Sjh(q+iKZB+CMJYcQN"+"-QpSj8'fZHCf*VqeR0AN!! -eCQQelEK-%!3jL8lB5'A`LQG#(Kj%iF36Y)alI`6C@86d4#CXbYbj,JBiphCPD`@ -PN32a4rfPRE9[JUklPfl8iB28cV'YdI-T,($4iaeCIAJc$m#'Ck&LeLZK6U5GH59 -)IHPcNi![li$),b"E4B9M0mi5&V!L$AS%YLKm@#l[*,Eek!%rGG)0kh9"0TSbA$H -6$K#j$ZCSDLhfmM4E2m0DpE9NZ`EPUL6INbQU'NpBR8!4J0@'*BeG&R@&8#@P-aG -l#EH0[,l'E(B(TG3PHm0lR[dI6LC1fef)[NSd2Gb+1h4&'dYMBZ!JVbpKD+UQ,X3 -VLbGP"FHDKpKp8#V`KeD[YM13!110bfa$b(1cFP@BU)1`F#U2#l61%VRNiqV@qSB -EVK0IGr09KD`5`+d#Up[qpILfQ#cUK)d5HXc`1F'(2Pj1(0UC0'p@Y8jjL,JFL(e -F,(a4A,pSDNERlU8!mBYAHF`0IeaK%G)"(b8`[-1VY!'!i`A5&JrMYB!TkJIGp6a -l@PkU#'KM(RJK8JZb#6eJ-C%aPhSl#1qQ(b08V"IS"rSD&M[,GMEAlNH`m*J%0T4 -2Gj)IdK`0"R2R1cjhk40K`Ifa5!4CpAKrAc@d+!b&$kEB*jP4l6LLR*-$hR8fSkI -&2R`3T)YNL!EAT`!-dlSFJ$,F*)G3DXR3a4Y3i4ThiD`AZTNHDm!+C*XVqhfU)Li -f(,e"R1X5ZR5c3E'q,JprX)GJJ,[E5Y&R8`[2`e4j9@B9b`8h240BNI#51&d8irV -aUH%&CQBBP!)'9e&pUU,%[A1aG,!H,GJZdK0#[qZh[HF9CVP1(MAR0qJ[9"T4j2X -lTGf9Gm)L+IN-X8Q[V%$@##"k'+CP%ErX[dZ$p%bh#aB,!qE0U%TVGrIfPh*4)Ne -9BZB,e4ii!CNERVfF&R@Y%Da6B6-!E'Zfb`NNG3MM$*N$TAHHXef-`#968krV$Dd -`Q3M-ljBfK8U'Qi)TXk-#q%cV%BBq3[qIr&C1k#J6e,(`8+*NaV-J3HIj$2JQ5r% -A5(&3h5MCTBp6*9X,m*X,Gi@)+`8b3ii`A1Z[%%CfA0mZ5I[`R4KlVVmqNml)XN# -$ch+ek!qERfMa8-4Lp'ThG&5LcZE13!jIp9HFE$L'cGmi0`'m9)JqYK$eq-ZBD,D -Y$Ge*($E,2bhTS)+Y@f,AAVD4pJ+Q&!%YXEUUc6%6P(8pHR#8V%XAE1qQPe$+,De -8cL-h#@,eXArmMF`N2Fda!qjf4I3PiU)(F&0RNXAkHFE4@XK#E9*N5ZrkhUA-05[ -(B%0B!"*r"69"EK!H0'KiFKmlp!(A#"05(pZ,j5$Imerh"$+R6"TE-eDNKc)aS-' -i8@IT&A$E+hK1Y##FcL1p`&1prXf8i#UCadUq,rfRHNJm'UCVNCXqiPGMRU#jiF% -M'3Jij'MfV9QS5PAl'RC@[NdGZLSN[`qFai5%"$)F9"C`[3Pl&4H2mQTidL!"F,) -3+PT0600$Sef"aP#JajXk`-[A)J5QUXLYpMh-5b0'A`l(#"HXX1k$qGd))N",N4q -rFhb(fUQI9keJ!cJ(4lCTPe"%P#f3!#$pD`3%G,DcA*[K+UkLpb3qiQ6(6&%2i+e -)Hc1@'0K(I3f`C6jlS02J1-cAbS3ENFFpE0aDTd+'qTT@FcR@H@CM`!H,$LpMAJ( -YK@6VRaG6#DlC+fFILd"lDR9bQ@-Diq@cEqRmC$M54MN'0BV659C)ef)f$kRkGKe -fd#T4Dr2`(rI6JThNfEdmV$d#,pZaSf2Z&($UD19S*R0elBHf'clS$9l0HfH&DGH -i8bRF2MAi)c,TipfDV!()2$@55BCXNe$ERJC2L)1,mBDLF+4d`ZeU++B2K#ZZ,dp -&BlkYN@Z0*qiSVNeEl`801*LGlM0[Lqa9Ba$q*HK4B+ZHQ@-1'lHFY5H`RMFVaVZ -9JNSp5'Qde-1M@N@1)Td[phq19ciilB@pi`THjN+0%)1Si8!3H6+$45%6X"3&q6[ -H(TSe3FqTaAl1)V*fkR@CPL%Y3l*mRVCGB1i`JU368BGLL)@*X61+Na5k)DaZFdC -UJ%bJ@emq,)!HG@cka8D-dISlM`A4q1Gk5@mRCKD3!##6GAA4%rR,4j`QjFrep[G -UULd+M0G3pG)P5,DrqkF`dZII#+'qp1RmDlc-8q,2N`0)Sqa*'GB8AYP8EPbfC&U -l@@d2&rY6XPZh9TC+bcTfCQ&0Bh%5b@-!A%LIY`ecd)ia%aMq9+0-+diR0jca#P[ -I9cTL9jFSRc2mblpYmiZP4ZpDMQqF6Y1C2UI8FMNXAA-$aBU&@X+V+QhiEH9E)`@ -M-Zrk+Z6eC`)-@HVTkUi-5qfVb&M0@abk'UFAQ*A*2'0452-4RCHiA6hi5d9,%k0 -TA3AbQD0i`"hS*eUfQrkSXm66%ep8C%U&jEq5$4,FNY&kjHp$0@QEVi1X@jYR!86 -dJ$IM0$c!1LrPhd6[`YB(B'0-(AZ0F"0IB"kY'L"qD[Y4E'leQZ,BqNT`&q+VBVT -4H@a@DDheFX!j#U(%pe-I*R8![%H%1KVkDK2B8bLcH8XS+KlViPhcI`FJS1LH(5M -RV9e4RNSB@!`U+*DX1G'Qi`4TJIdU*ZE&Vb(5QZhH`6[j8T1IH8DG!ZND42"`)N9 -ScDIG8+1aGLU+0C4,c`'5p#!,(J&KlYAa,YUlGQR6Bb+0H[l+fPS-03Xr!NRRF&N -G26KCNG[Z$MRDerdV,hT6FY+J`%Q`X3Q00SV1qVMU+`IP"RaNrZ@N),RbiZjFRT8 -T2l&Q6bAN5#Zi@d)la2fQ6hIEV8pX0VDJP-6-K[C"!mH`G#P3iYDAXV#0$4p1CDq -bQfmS9Q"m3!jGG(GN%Z*[,ipf2R5Z+Y)UGiT`RhUJTm+*@j1U+M@PU`iFTCI9ZDb -RReIGSq8pG0&Id3`KT%i%0*jf4H1F0+[,*"8k526RKb1il3US1QNi!8lk9QE,'-m -iZ`f*QFl'FI@D'CT[)FpRfQ&Lh02(*$rP3eK(TA)hc2U'F9$HK4iiN6e$N!!h9K6 -S"-9p0Xf(ijNLe1!X34@-G'$4"DUiBa&#Hr9mIC5#YC&4lMPK$pSe*B)PkI9@2F$ -VG!X'Tlbj$#D5m$B#022Z)%hP)'0B(i`1PQD)rTj"0caF',")#F6qk+famXP"#`I -6+QV3*6%QmjZ%(Z80Sh#4'Tcf!G`M$r6ShJITQh'3!&4(mq4R%"k!b`AarQA0QNU -dV-Kpib)YCkFF6ZI[lhTcaUIfDj9LqT!!`&YKP"f'52d6G-,R([Qd[XYXV'G5jdc -%A#Ii$m4BD1(Hc!4&IMZJB%eNSX*emM%(0q-(DZ(mF+B"S&jFP@!QdT1"'M*iE"X -+4lcb-I(fMhZmm%G[NF3*H[&aD1AbH`12C4q(ij&#aGCXVmM2h(mfkQ5i`kK5qDl -rTk$U-lQN+6bNhQGU1T`SE$-BHANT#6)`IJNKT4GjhRPC-D0bAr1lBrbr1A$j-bX -&T5E$QJ*Xb%P@mVI#3M"5k0&)*3pX9MSSErNP%TJ*,a%I-a&h4QiTL&Yd3F)&CG$ -36KC8rf5RHbC0"ThN6c8dq(LQk5r8193Mj#,k6ErQ$S1cCSl1%+k"Ml0jQBGVh&F -Ir@&)eET$F53ZVY`baI8GINe+JYqY"r!V5BBPUkB2E`-CN!"FGiX+#[Q!3TZ8YI" -%0&"[5UaYklda!q$d5K93fXSc,0*G6drc#2kLAeF21UQ(IbHMM3hJr+fm@*a1UiF -r6k8%GL$iE"Rl4leU#bNQfQQ5L0,H-A)('6T*c6&0H[Rj$bm)[,MVF--L[&T0AFR -%Di[`4f`k-kTcd6M#e12P+bh[k,1@C&Yi,rbIbcVqq0H&!GA`KDei$K`jSc"`bdm -+r%Nk-RcA&ND1SJ,(Bc#!mpQ5-*UkEG-VFID#0qa!iQmV'bf+[VcKSFbG,"Imj4P -%M-J9Q@NbZ0RVS,+K)TVB&Y82QFpU4p+E+"T$+,ElJl5fAC1*eYI*DEUB1)*8[rb -IH3V4$8hZ1A,IlKaj%E,fEV6@rdT"83MU[a'Xl"9ArBrU@9X,ha`R8&8b*A(5Re1 -5FZ(``rXkETN5FC9)4YcMB#&EDFCPrBBTjd93!meK+rBD*0ShUqA4Vq5*J0&L4*F -A@!Y-NUTjH'UFPc5qj'Pej8l1B4#m-6fRpqbkMDBM"(QdD+cN`[ZdXUe5[bIl!2Q -`Kr&TVp)KIm2Fe2$pb5Pc'4`kaRr-Jq6A`UM6+d8bL8[cUq4*!3+(6(X,d'Z6H9+ -)(D6[i2i[%pcb+A8V$%`L'+NeMThlPCURkp!L-',DE*!!Hmrc@%1aBEPTK#ph`mY -@qfArdjL6G"$m'*%SP9@KaMMF+-Tb1Mem-'-JqCI2k"lUL#!ij(jDK@(@+c-QjfF -E%,iE4j80)2Tj8pYHF)9"2P4MYTQJRGJ9U1KZK#P-Fq"XBREIh-)KIG3mkH'k"Cl -kl95miX8[86hTEA0Xp,MS#AkJ8`Gcc)SQ%H-RqiSc#ZFYm"JI*mdFDFbB*Yr#m61 -EZTH$!TTr3'FCQq0`0ISD@SS)HiBQ-I-&+db--hZEH@$`2AUUajrUa3IcaPqcRGa -ldYkK'*j3r#hkP'Qj6J-SLCldU&V3iXJ0C3J)hZ6DZHThKc!bcRHqL5#!chIZ@1Y -DpDQ[m#Z(jFBIah8r6bqlB%b4!H!2FZTNQbX3%!-*K(e0'YJ"H&"kmZke-b9hlZa -C@)M"J$1-Cq`E@BPj8`GEC6lN2l6P3HrE`pbrrTbEV4AAeP*81L&c3fK&DV&DIN$ -9DEK(i6laMC6$16XQX)qA)eXmQS0fJbE#8rJpKX)J4J5MC!X%@4l$)`r2Ef,QbhP -j8`J"peC+0hkEi0-NRUmNITU5)Bj#99h',[9c5Ph+8TChYVJ6'8&#*h&+5hh@IPc -ST9hHRc3'ZLpC'`k[TDKHQjr3$qGl#P"iKXjVj'6ZqPLjM"iSLmZ0a&,@J#9#BT5 -920ldJH-bV9N''9J'MF&NZElcICC[ejfkDa2[4TcAhaj3Xk!k6A,5j,r+cqAKXN% -d(DMlQhLGr'd"CSd@5[['E!Mjlp0,eEeIAI*(Pji-3e5*arp(U[V#40IA2jQ'qdl -P'a0bG-b9j)iLpGXmbF38ZH-j``8D"IHb1pG0b#qCNA3KI[E@DZf%65N4K3fY1!# -U$(eKZJQEq93R!(dB&#GHk(("MBheh!65LJD4+PCpQDJDLHQQp$9M(8,`h2fbPlc -jCZ`AeeqILF5'&)Q6T`QY3d$5eqB-59`r-&,mK`3kreH3!0aq6%E!ENq4L39JY)! -95&jamjpUG9MXf(9[%eq&'%K[@H#fNhY-p2B#Jq)XAUIk4S"$q`Fp-fRJF*U`UK[ -5[&&!j+M88#R!N`Hf4bTP0q,H!)8Q5*4",a%rIGGi"09)VCeT(I59T5a$#m$RU,T -Faa55NlB!"RYX&Tm-ljcT#,+B8Gf"&[+))-)SEMDGLNqaNVGk('455(mYFlfBSE5 -DUlReGF91jA6C38CmY!#FV$5AicX&3,6`kTIU*,!D[m"hE0MTLm(jIqj'M8hUBqQ -L@Q'TK%SJjqf4TSVQZkDDIejYG,+eK0QTjKMFk6kd*)KYrkTL6CS,HlrM4b2A66( -MbccZ!NM8fqc%BDkCEipJFDThHVXfU2Zkh$#l'q8UrC!!kDL20SaR42UVU1Um8E- -pSmA*"Lb&EUS'"Ji*2'A8eAQ5AE0Y)RK"VX@C0@20-2$(VYD)P2++&rFJH!EpdNq -A5q9B+$(SHPQ(lZ24qE(#jkb0,VI8i'S-FKEDdL(U))!*IJYcj!cidK!#QYqI8pF -"aYri8H'Rk#BIm%jbi04D,$SV5!lb6DB[f%YYk%%`Di`TK6)ii8V@-ZKYBT,0d'` -3drT5jUdH1ke*cDVqmb`iX@aG&JA"Ze'H!8XehU2TT)febbP,r-plpfM,%1[&@UP -V'NbSAQfIbe(*YjD3!&rqYCf0a2J9q(%$rRNKklIAkPc6MK&U6&QE0GX9jX`E[@3 -mmFlfl4`M0$0LbjV$cjGJAq1YmF(%PUGjp$c6DebNXk)piDK&3rir42Sl8+$m5Cd -ZXI#60LDeQc9+K6#JkY1'XXQ1cj!!cbEc&!UbH',1Qd8iHad#I#6D%"ENe$%([%X -1&)-jGYGjTXI`RR@Jp9[J-q2qkIRNaA8Sd'1[[iXp-0If%!3h&R3G,R$TUrVeUq% -UUKB+@U53!$(II'GZh98DMD%`rNfY[(c4@B##T-kI1$pqXM[,I`E)#A4!$'(fC3p --Np(@+0KXY@l9cI$$9PUQ2r2"3`H1K"NDAG0"C'1EmB*SQ)V1fhrcHNC15T&H)fp -T*S0MB5l)R`6cT@4b)cb`[B2(b'M)K#kH#rYUl1&$El)U'&ZPG3jC'18Tb9)4+,q -X$GPhBkhJM'aSRj+*JMmarN$lS"5@bBA0$B5)4k@PYFC@HJY6MC9H!Vl)b&E(T9R -Bp9C9a3M#BchjZD"28,MQ"PMT3q-6(RhK@pdlmAeD(ApU3-',1rD[kSKXAL5)1(6 -&AK`m!%*MU4m"p3-ikJNYFda#!-8XK1eI[feQJ2M%M6#STbm6P-I-f'X5PX0IC[' -cEY2H&T*+pk8D3FLeQaR5HNcaLeR3#b5XXqcPF1QPM4h@LMXdehMA-#NK'+h'G8K -DHQ&b@qA*lq3A*jIdD`ijVZ,(lB4&ic%f)H"8kH0ENFqRC6PCmF&Zl4R0haV5$-- -H%r[ram'e(Le-YFR9CiT*f#hH%0d@mZ-Hbd)M8P-QPhl,,1UbCNeAhjNqhi,hccN -&9m$(b!L!9eVUURl"D$Mb6e`&*+[F3IMD3$-F"'p%*X"1*f#$94amVe%rhZ'd$C! -!mm)JAhGGJY`1Q%UCY&djR2CYqXmM9iBekcRA1kQ5UU(+[RMfEC-HbamB8%SqAp# -(qPcZHS$fbA(eEXmRkMjSCTq&6'hkT4$MDkZXphU(9[Q&TEJ&0Ce'E+%)cmJF)B, -LN!$RYQqM)kc&FMKJeVT$FNGY"hV*HCKqjqIb+PYh(,$8+ZQX$GIVqTPPffqMm9b -PYGa48A!*8*f&$%4MdkCr(f21*Gi+RSSrLqmIY8Mfqd80b[NDD&cik)T4[XFh)B@ -2[f(3Z"Cd!hS8$8RaMckX#0@'Q@&)a1XVXX#aMUmFEr4&BC6%Xjj3Z[%a2**jlS0 -lpZr`J``"E-`#q!TTf#0$p!*h-%YjfLY0,GZCIiMejlI&H(HdmlJlCdH(8mc*eG( -b")dE"Je,@*62*l&BY`Jaf("Sj62b`A!QPi*I4!JH)@iqA!-qP#IkNB`Qqf1RP8h -0fe,RN8p#[Q'Tk3Zc&kPGVPF$%f,UjilTP*ZMqlBaAST%p23'3G+kSj!!*T(,0Y# -Q"22m`T@eUFe'Fj%6Yq6D#PF,c@a20PGLN[8@Uk5M2Ek-8`VXC'cd%"aC!J5Cm$4 -RAZ1L8Pchr-ZqP[j,,63H9+l"YNU5lZcM41`D%`[T@KaX3L4cQ3CSL[JXF4`N"6h -cY6j+VA!)r0$L3XbTPAdFG$dAD%RFbb@SH0Ade2'd**!!'A&"H!'[45QY&al4U6C --IE'%&,,jmPT*N!$D!Kaj0&)VJ@IccKLMmS-K!,Zr%@+AFIKj1CTZDE0K#iZ&-!f -,5S+#k4[IMBE+5pNq$SQd!HA4`(N9jL92*HiH93E"dKjJEQr[FjC4r(BfrY1EQ-d -0CcB!42YiCRlr&B-V!eSRL"6&C39db!%e30AMeGKmHKHFZa$6&k2KdU1i5-B%Pb$ -m&l*6r%f*a%l4@&$,mc3*br``)DTKV*Cc(NNmq4Y@r+T4P"S5Z1'hX2IQCH,-#$p -d-5dT5[lD8bTQJ&0`65&B[Z955!M34b5Lh"5cPYG4&MK+18YXSc'jL%`3V9ca)r% -+a`*1!fBIa1[l2RTEfa11mQdI19Q6VL2lfP9(Dh3r-KJASp&UV#iQMe50(b@!N4J -44EIp%KMR!RIPNdL3!(DGI8LQRDMrAYBH8!RfJc3'4&*bP,)Nj(j"$QjK,Z8PfKF -`HBH5Se8rTdVh-LPb3b(G+c#)P2KKX[NV#$C'`lY1TfcGl0hBikPF0&$-JZ#dl)i -%m@*[[JiI[`UFRC[m@1ErZE"LPh#&VXjMADD)-TB+ZKL51EXc-ikXFq63U-J+"$T -AS[`#kqpQNhq&*4k5+GTPb9)X4E3#+b68XVTjj)TTJ*h-khLf-Zad@QYT9fef2@, -Q`Z0m"K82)&AX`TE`"c6[4pr9mCFi##jF5E@)f3-9S*'c#q!G2&6T1ibB(+GI)iB -V9S$brq6G3kZTT0[0A!j[e"QEE[QRD+RC98e+',[T*6p+LA(NSISHe+-Z$FcYV`R -,,94804ekXAh#j&kqKeej-Xqm5*m9dF`pqQSDj2lfI)%'5cRkYYU(1YCTc9qT*S[ -&UXEjBVJ8X`3af0DFX8VL!m&qmh%%V9bLjhf`6DGK-CSKR8SI63M+,[N,1C[EBI[ -kVKJ6cc)hkVPq'Ri+h4D"%qX&`l39il'V(khMKG5)5$Kkd)KRlRfV2e0NQ`6QjRh -#q9#D`C*bZj50EU#r(&X+e@r!@4[&dkRr`%[J3@H9hekU@LSh9+96+rND@&Yd(8a -%LY`9M[h-4dD0dG"('RiiL%QC'6*N5A9pMZEPf#$`,@RK,JeJAAXha9RL+SK,'Yr -L'SSRjRSjN928)Q#@m$Z(hdrPE+)b*6YKLe5R""JJ,IV"T`j-V63,5m*ebTBE,RU -QDi!Ni4TDS)FN!6XT@*bI4221N@lCbpXM+Qf2cPAmZMVIcmHT&r9D(%&G8+VM3r) -R$crrcN2-%GK*)6MU8E6qfGS'%CjC@MYTAcpIM)BM9V%3#f!'$'p)j`(ScN)j,2X -ijV[Z#DkFdSLhDiPR9CLQDhK5+TEL'G8a[lEQAXbrAaaX44I6HjX[J%j8F"ZI,Bd -e50qID)Z3!2,UN!"0GprIDR4#6$Ii4U[bXj4Q19-JBVAieU[cGUkB&Pl,0rbFH+' -$6Rcm19f2$(R`4HjreH5lF[cTJj,+X%BrP-GA*53&1qSBBD3$5$kIUZH$i-iYC2F -*#2(J'TJNGm5cp!`ET1"ISKXlj+$,Nr%Z1qCbqjSA95$GFqXYBqi+$AcHHKpVZED -L9-VaHAT%F+(AXZ+9b%`Dm4!eG9fDM2j1`I(Tq(5"ID3&4IJ8+a6VpG$cY8Dkf0S -"`Y-6BjEAjIaTAf#r9Jk'mhZ46'SB35j%R$plNVXqJTkqj6p+9ea[p!VaJ+24r'f -ZH$klFi[pdSbA#91PC,YD,9-0K'B5&K6d'$M*THrYS"J0CX+Q@pK)j@3F6-,[d6D -X6jJeSZ&6"U@jhHFjL0eq+CFPaT6$15pQZlNUpL)IJ[e20l-m[r,Srec+ZQZGKU8 -0K1#V"@XppqXEF8Vl6ra"KS#%Q3F01"NS6&ET5&kSUlm61bVdEDbb()-SNIcjdh1 -hVV'%9!'!HRG9CGLcf4$GK5(qe$)@J$[rF1El(A%9L%eMmliC!a26bfrEMXA-e*E -kTp"jJFG`%G!8V'T"J8V$HqTVeN,MSNqdp$N`dqdLYrDLK&#YXhr`cp",-Pecqb3 -)V6cFLq3R#E6*Rk#6fK9ZmjheaBa*imi+&CTb6Z6Td)C5AfIDf!mY!V#Sq8K+RDh -Na'9@K8Bb4V3@[FI1#M%p1XmKIP["I%`R5G(V2!HI*%Q1mTl)(mj[e1%kp!A$9iZ -G2phNh%X3'QJIX-Z*mK,hA1jCi%4hK&ZVVJGYqrjREU1PAq`Z[l(!SBTlYE-Fm$D -rB1KTRc&k#'bmH4kYJMdjd!j*(1bER06HT'qh#L1GEM2f0)P`pS9cpbDSNcb$&ji -r"m)SJRlMX,LDICMhmH()qT!!JleHPf0l5jfL&bS**jZ&-&e929H*)NYN3#bpd6% -4[e0-kBc(e+-f&DM2"%fEe`BKfN`'jLKdX#1PG#[bGlhH2QNQE!BF9hl)Va$`)I` -`1XdMfiI``P4qbj0(eT4&"r9,%PFT'5cpM@!flYJ#,3'ALmTm`cH(@LT99MGc*h& -%5FFBf5d%[fM6-GL'U9eGlLhYl3@f5Tp'0H-#SclZC5-b[UR8mSXEJdbVU4Vdq3h -&+c*1)3f9b8pUhGB[ZRQf9S(f8%em-j2SLK9"T%0)CX0aSjT@"LC35hE&akl"`im -PFAC6X)!rcrkRNP*ZYC!!A`3L+3SAj@0'RHCI)(1S$*PhdP%-0@)kZY1cJ)be*Qp -dS@LeTSrKRT+"95ML-jjfH4`G1lPXSbmZP#+BU45S9d5,BQ5$EN1JiDJA!6CjRHl -l1FqBrQ"rC82RMShpNlZFT9!!i-U5[RrFC#5$hMG"EfJ(SCbS++VP,Ipa5$PT![N -YXEDaU2@c)ffYZP'AbQc-M61Mq*MNXGPm&&%5N94rD%e`([#[N`0&F*V'*!DXcRK -bejfI(&#C3!mr"qi3qh9(RiSK"M)2EJX)&FrG($Q5AV0Ik(Cl'#F*BSQVh&,E"6F -AC`krI#R1-bkqk[d,G&DE6l0M5HECR+UBb%Ue&1R[e,KH2Fq+0cVb+"Z0hNLJk[2 -khNPQF*4k!c-8+,5m3QUk4N[JfB#blJ0S9Em$fZ92ApN`&AdTF`!(K+F'RaZLI'` -Ri1abBQQX@)8)@5Fj!P9JZbbR"6R`J-JZNSh!BiHG1mpMk,-4DR5BeV,&TCJ"ITl -bU9fYQS8k3-"$"2GlRYNSPVdr!TmJ,CUF&`J&dTX)M9-Bf+4c9G(D*VjQaHIcdEY -rC2b"Gd2jEaIRH#&$FY2J5%L8k82ZMIHQ[VEDjZe4Yh1!,dAc1aCLPFrBd)HU0e! -40rp&V'0$QG0&raGf$i#@Z5Ib$6(aA'PXN!$4C#ke-jT@ELmlXY$IpI0bSIm$24, -+khIdqU`kFKdl-1XZF$N[,3d!H5J5Dk`Q%5GKKY@m!MmR(0[c!YFPK3C"KE*6-Y% -%6K9!$)#8bc6r`*8LQ5FT1')%C2R@PH)M#,V-Bj!!D@%)(9A9DJbd9Q,GMS[aKaC -5%$,2U!-H$EA+)D36KQ8RT4RlHNiJ"-4032rXSE$m#J-*hM-E@1")--dpGrB'S9k -3!&m*d&J)0jAd(aa[MaBY-0-`PXYUjPirHa)h'6$#-MH8kAXURDPJ+A%Fj'!J@G& -&Sm0Ye2&,#,dZ(IVFr#k,YiTFIS6!IVr[GC-9lhG[-[-J-3""@"qZkSKb)Y&FI`I -(@cUQ4CR'Q`,,PKC%mi@&Me!h982),[3`%(qLSCGD)LE0(!Gf@9KAUr0I#K"0efK -KK85A1rLS[NUk+0IC4pdTVCN`43'8'ZR[+GlZVm)4(q(ef2U-JRHQ[b%IANlN64J -L)0`YPAMTSUEB5(&d$P)kKKV#rVcD+RS8A$[5IBA3,qKe'KYH%e*M"bZS5G68CL[ -AYB63`kNQTZ63-#-VVQ)[+LNIGM&*rDRKr$40N[VbGqZ0*A6*+0HMTTa*i8Bm2bC -GSqL,K-Ze2D0!#ehLq9"p*SSXq0fVHdIA%Nmj52&Ce5i,aqElj#kePMf,P%ChFq# -Er%Rf9F8P%hkU+@!eHXTr9fB)ejZ&IT&"R(Z#Z!!ThdTf"&D@lEaKpSbS`46,M#- -KB9*kIG+pFRV"-2jGLXBA#af"Zf(Pafa(2Ff4@Y4GP+P,AVcc%qDqjhkkC@i[MR+ -&85i1T`)[bD!6R6RNMljLE",Gjd2Z&'A'C)A0f53b)f5XC*8@"BMGKFpTE9YSjRd -)*!%d"Lk'*1SpJJR8pE+2,P@9!L3'KS!a+2Ahr%GPkrV()l!cRkTKd+Vq1kf*3G( -0V4CeHKZA&S``0Rc(BqZHNUUNpMDcN!$e,T!!X)4-i6YRXrF4-aM#*#8"bCB@a0P -P`!p6-@VdbqrV&1@-)E(C-lN4Fj&T'bcR[krEMHUNRS&'fLCZrRa28Ca!b+FXrDc -b"lb&Gj@P9MRm6`m[HK5!H%8Gb6V&20UGH2XqiSXjl9pa-S!Y0F@'cacIe'+Y0TY -84kkJ9#9S%dM+jl%FjDq&C9fYPfpV9'2EX3RLN!#PN!3"!!"!!"#i)pUlZ#2DZ`! -!flS!!5[l!*!$cJ!3+2m!"U'Z!!!Fj`#3"!m!9'0X8fKPE'ac,Xq!,RKYE!!"0cC -849K83eG*43%!rj!%!*!+J!#3#3%k!*!$0`#3"!m!3X(9#he9rJKeEik-8V@kZdU -V2E5CM[,Q9SeqceI`p4Mi%Ir,pA,iSf5%B1aAJE&LF@'3!1AE"6"#`G654D@ifia -X9r5,'ZbL6H2M69`9C80S#5('%+Q3!+GI@2k2@'Bm`XqY16I"JB[%c3$6aH0SQDI -e-5JDF0rb,B*1&m9Me-8F35ZpjDl`(&e$24+i'EL5V#q$pF8*QSdXH'*bm&`!-#J -DEjb61bcPR+2ZI[e*DX#f$0XTcKTVM&A+dp$Hhm(rk"BFYjl'IrRqUr0i'+l"(B6 -II*&kU6ZGZAc!`!2B(Y+9q2Y"JmF)FTPBCL)PG1dec,jNjFmeK8MR"qcHT3-9#kH -V9,@"0f2h@i!KSAK+&VSA+CVbkfhmq)3T6%e9YT(2$G@IkhUM0-&R$*[D9@J,ZlR -"-Bj$XeNBE[2UrkBdR4UZaSq9lh-TiVfUUclI5V3r1Cc1-J3V[$'8"K@CZA$*PF& -r"%6eDHP22F#*GaC#04lpV[HK,9m,2Eef0Fb"HRkmq,%Ka5$m+dGbFqYCR(E1ISX -HTdQ3!,(SPL!8rRcc)FaRF@aR!PPalk6IMl6RKJcpYBePZ`2h)8p,iMX',[DVI9S -@+6MHHE(mRTTmVESc,MPZ6"i"Z3VrpTPpJN@XZ3XRN!!hA4ME-f&h-A-8i1aiaHB -8BRdbC!5Dj6aE@XMdiSljN3aM+m3FKpPe0CK35Q&F3-5kIhD4%&p@T0h%3TqGpRY -P003!Hil3lf6c-Gl$TPc$%9@J+C!!3&MMZ98V3`eS,TPrj#JbrQ39Nk#PjGFXN!! -r+aE55!V)X"4V2*mM,EfQeJ,`Cd&BUR&M(1@lACQP`'j"[TbAUD(&*ql6,5FT'AD -Y52kE&8&ICbJ6Af&rPGBJUjXq9CBKk""iPA$8!mV-&T16U$,Kr$*G`SdC55-4F2S -`6ca8ErJe*hH`bHc2Q2S"fpmfdhmM0bfhF4iPN!"T5Kj$iXkVb3!6-9A+De'`dC! -!cKcT5e(k"Upe%MmrflHQ$50f"lR%DFLk*j9q%QC09*!!HGa3&TT#U`$!91jfmqh -XDMP[-N`&KD58Sf[iX2kjD1a3Zj',AmJ&D#!PB,eSJ2dJ`QdYlbhldX+$m@q5Ali -EfHMiFrfG(NrL!TFY,PCHj6rbU,G)BBB8fRF)K[64YSV+eBKjrQA3F'Aq8d*@DVR -B[hcH-EmmAmKjp%DDFM#*D"`6[*@EqFi'kPcb399EKiS$i8qLkVAXP6'0,85P5*d -ff6(fp1*fqcYci%fjR!*Q%Z@%MfaIr-V,LA+q0+l3I+BDa2,FF`J'bIcN!,)iYi% -6B([1Mrp%D`1UB+@hqdE%LA1)*@+$&lEG6VAM8-hR#I,h+ID4fhf$M!Nl$9#d-M4 -G,lB9aI1j1,'YT*p#YU1rc2#[%d@aa3P$0IS5S1Q1)JY&VK5e'J3PeK5)d6r[f2T -`YG3q6fPk4#mYL(rUM)ji$L4M4SVE8mfaqfB&ci,C5"Cb5[[`DI-d$iPYfipS0[- -RElMD)'8'RSXC+2Zp`-YP@jS2UKqYMTq&a!cLLR&NLk!)@9XLj,05@#3Rmk+dUfD -R$5NY)iYAK0IeM"Ud@AM+H5FHPRVP9)f,R'#%)!'L0@[dY!I[GY[I#!CQY!MSS*H -X2UEHLIH!0+(a)!'$4(NapQERC6j26AZ-h0#R54%6V+aV%S*PX2EC0aTVh),jc+q -dp$S66!iid(P8P1!GZp9-X&kZ6h3@VFpH)Pre9"qCqYc@(E6R8*ErbFcYI2TrR,I -0pp%'GfJ[#ricAV@bbH-p1)Kk+RVX4I[!$BqfSD%QiZ0N8AC9hG[@mlqYeHX($r3 -c+A1@-DLfP'kHU(#prTJj8E'kP&$d%iBbHLAb$XI&+-$dIYFVdd)Hp"N''!r"QT5 -iA56*DU`#+j4,iSa8QN#frGjU"rakZRmTDG@rRF$N%Cm)Xe)0['U'bmYkL5N%ET' -r3,ceMAM-3VcK)R)+qYJ)"jT#`CEl,%3-21hcp3aTbBGH3q#PCp0q%51U'-bR!lD -fP8Pp,SLr)-F11D!13L$rI)VqfAr"$jZ(FSi6RAf1m1pM0,a"p9*1hmAkj(6l,9A -m2da9E$qQr+JqL`ei$F$-`-RffMjV@Ib@D8bdQ*ZZe0'&*6"HrDNqf,@pq(VldR) -MepmBAipq6QY2("5P(6[h-AR0,ibdBB8e,D([i00PZ86m-2e%C0[MHJDIhJpB1MT -jh-%`d&X99MY9m&pl1`DKBqi**FpHmH-J!,#VR9C1RH#BVIXIPBKrpMalA)GfXmI -'d2G#,KEdTEAJ%+6C8QbQcU&*%HQe-iil'NA0HF3PUhC'3SS8N!"U-[EjcSE+Il5 -AKmH(Z92Vh0q['@(''CfFRCT5ff2NhkKd0-kGG`T`$Z8')i9TBi@(`p@%(X$K`@$ -U3l[L+m(C"CqC'9&L$de3mG08S+B!Xb8hpqPkBk9Ebl9Z2i2cH$mVMG`U66h*N6b -YIh#3!*8c8jbhm%$`5AqYr1@%q9&EK2`Y6d@2!T'&1%(dEE$fUNdX))3Vq89I!+F -KJQ3LiB&i)N6Z&+(rql%iXSiqGFAjPpM'UAbF`6h@h6X"ql(apHfU`r,Dce+mf'm -lT0&M-mG+3%!IhR#@Pb+GmQT8mGqF4De644T-TMDL4icPilF8r`VUpA-cZq3UBf` -k,kEB31+MTr2`8,fi'dcffFMDff(SQId,eJ&C*'LkPM'@A#h(r3l)N6c[YKEJCMV -X8"pi6c&SH",)`3k*jZK20KhH-dfL61a9(Tm`B%qH2bp,P+C1&+b12GpAk#F%MN0 -aE[d5-PGM8a6*Qm#if%0`arc1hArp+)FGAEH*Q%[-VFYq)SSESJmV'4)bHT&I*IE -,MkVfLPlbh@(ZT8Eeq#Ybe%6YTMYjDhTIqh[HA+X@YY9h(MC2[dqJ8jPUDFE6DK" -TH!a3L"'"!%4bG!JIikQV3SD'-E)dEXRrpF32H92lm10dYAGaflQ#4a'mq5X#SUN -G9[FY'KebhrpQQ4NqA&kYjF'ZKKX[JF$9N!$aUU6a'"13!)Ym)efA"U!ahaL6T3( -$`j[b#9)qk!4kqc,p,&)bJ`@,YNY8b'SH,Xh[fL1%6q5jj"XZe*ZFelm-NpGYUB2 -IhG2@QPC`ENVl63F8`h+UCP0Lf*!!LlDcYfCJpD@Qief9l&-,+)0'!cddj4$i&28 -+Xi))0afkpLP4j0b8B$&9GDNG%bEF34R'cMI1'l,T(`Y@JrpS`*a@SUj(I2`PJll -"V'C3X2Erk3X2k"NlSk8FHF2pfpDqUe8JN!#((S3DdD8+iJ1ShCcJ#V'L"#5d!T[ -4mrT-0l25c@[fA9*dYYR#hAF-2a!$K%AKc1lEk"(R-K$4mqXfhJr'PDjFr$i8,%8 -15dNr[,[BGKL'P,*Ne-BILYmEU"SI4+"IH5YI8MTp[6U$`mX&QEj[4"+GMC8p6(A -SRlBNpb`dL6ZV5Ehd8FiNTKQCc80,KUVX@qN`@qeSY&,q2,q0p1TP$j,Fp4Y0,6i -d'[mjGljlPMEiY0lZRp"l&+NX+AQGmZ%URUC2jFX,4R+26`+YY$5+@eS[+h4J[*U -,FhSaGKHAZ'-80a2T'XejS`Zf3QPMSE3jp+2Afp3+QeUVdQXPEIF8'!NachfCFQf -PEL[,r26JiEf$c)k3!2pr6EKIPa8I6V'6Idp8@XHA6K@YR12l6"`BT!649jTL4VA -j$9D(YpKFEjb-1e5CrY#5q45N&T0lq#KjGRh#Z$6m#`FAAbE'1c%Gc'9k"%'k[JR -2QhM2X&i-B@iEfJM[%qMQ6pCKCpIMY6ClD%D"@-YD(VI`hX$Y9$aQ2$Y!'#Q)cip -bkUJRHTD$(VPk[h*chS%($3QiFD9+#,Mi3$+3!$VUbZ4%!aIc6bbS'`jYRHr@kjZ -9`*ilfbI`GXF)m9K#l,3-dd%edPNBadcM(Re5apE@)hmdC,IaIQaN-9`0*1Yrf-( -c!4HlCIQ+R@a4PQB()ifI%bT"Pp*q'IYM4iIma)kC'm&MCNQ,i,GNfba#ZXIFj%a -r@E0)BIq*f-llHSD"TVCl2[dFh"f8qYdN)eM'N!!jhDN6JA02'Y!q5BJi5"!Nj,h -0@d%%)J`p1DDlJ,++jhee&DE9`YYp$88B@H'YUJJ,%5DT*`('kNZEU6T3a"B#X,a -A"Eh8@cI-`dl&)QQQN8Z&F5LlJR!-[L[QUa"cKd$UDrN6Tc*QPIjVEQdkEN4V!Ea -RIEV03IHS0$9TK[ke`#,+0`[I5EG45#%0Ge85SJrT""KZd*9mV&(ZB@DdXcHZ3`6 -+K"48#qL,eKZJP6BJq")d*5bcl6AQDSjD3aPZe[+jMI+TS-N(#0dFhUj3Z,K+"i( -2DbK(Q@Nb##ZDEHTdG*-XCX81Lk[X!1eYXcVhRcZ6Hk$8*`&'C%F@6`jfA9,YB2+ -YbKc+(fCh'I0'k#eL#l8lAp9`#+1b3PXi$!Vdh5kC6iJYQQlkX3jG4UqNNb!!S4e -M2iXXke#3!--QUJ9`jR31EFcYqVBL!%B`5F@kFRqpY)HHU9G`%E#$fb(,4J$jDV6 -qScbYrIP!lP&6Zf$p(%k,`Nd*3U1"N4'IXLeIcJaFl)ZY&4Z(DVf,mr4-+`Pi-le -&C*!!2!T4QN,jN!!iY,)"F@-$#fUBGd`'9LpYa+ZpXJ-Ql'SJm#bkcR$Q%i850#Q -#XZ#e+Hmpl6%B0S!cJ,&2DTj"T4[(qabZ5RV&!(Cp29Q!#kT`(eZJim$MHR5pUcR -VF)H)J'[U"&'4a%#QG)"mr$NfriHT*ADB0YA'qAQ1DT1)3IEfT(3Khc8NJ-TX`X, -4DEF*qSrRQ)CD#X4P"&IFmZAMDBi4*e1HR)S,+U%TM0#JaLV0lA%6p2-e+H`5i`R -km1Q46'2)"jBHH3%@p"[N'"AYk`qq2K8i%f-K"q8*d(d)M@SS$Y2cLEhdc6#[!&m -X6Y`S8D[1CeZeT3"eq!S+iDf"8#Lk&BfdqMC3[1(KPjhAKX2H1iRe445ZAfd8KJ9 -3+KI``ldH#T2U4%Rk3FU6e6Xf6Tq3!-h2Q)UPj5095'p[$9EGlb4T)3UdD8r+EC( -ViH0$Cjlj4)F&X[)aYTHZP3QTj',fPc661'1BANE8"@'d85cCC#,[)"pVY3`RF0, -eH5haH!`Ir$MANkmHJ$*h%FNJVGl!60@b08`+QdN4HAP((R14'r!eBq5-+bae-fq -R8jJ&#!EAqfhCE%$E3SL$6cB5ECKV(lm)31$,GH[I"Qr&@2FKI6V1kcXpV1Xc9-f -JP'[Yd(B@dUN+,8UX'VR&9&',Mbe!jEphkI&b)b2[Dab"&f9P*bPXZA2*QJ8G'e` -)8j!!L!AC-jCJ'm8dV%i0lq[@R"HBeENT)N8r[6(`&@'["#IA4SJ1%3VeKHcZJaF -!%LfdI0@5)E(cLEiJU2Uql+(IM9*,GNqEb4hEXEe["Yc4iH*h5H6Z@!*P0q[6GP+ -DMNf0A2NHi!M#h18A`bc%f5(IJT5E3TIf@@,rRh"iadAHLBKJfZ3BHKGa($#kETU -A8bUCPcqhVeL9$@PhjQXeN[*YVl&#Ce+1DLD*aih@c4hk5Mcl1ClATlEYh(18ki# -8,+)piH8i#MGf!)%edCjGX5p)PmY`#)0Cr,5GJlEUCV4rjJ3U'YBC42rd+T,'GMT -1Hb*a"f&DGf'mG8-@K&@+PJi0I11[Bqj!#lpIDNSK*(NBbSCU`J"bE`F+8Sj%ALm -'dfpb,BGj[+#TT6CBTfhq#"hD-Z@3!#Jpk#HQ8Z"@bFVr&5d+E$@)`)'JV#UF3-P -!`a!Z64Pr1rF9Sc[)F%)QLS+Y'U[+q`QhqKPH'%J25TEML*'Q1Vbh)L8L#Xh*qmY -)PL9hh5@J1"`40lQVb$h2,0GCXh+h6k99-'Kq0bEi2N21U+I+#*lDK4+k"X%pZl9 -K2HpXlV(BiDLK1[*cS&MC6I3"IF4!dBBl9QhVHQ0lbRQVd[@&6#T*YqLqDB[rRh' -!P"%88aRGIZA54X`df)+2L)fklq#C0cYjPF'b"*YD64Gq[62L53Q8"Nih8U+J!2Q -RTA0`!b5"rJT$q$J-(YSETLTUcPr&k1C`3qB$5HdMV&9)$Uc#m(d@Si1D`k3C#Jk -KNEKSABDeL[a#aRiB+FYJ6!JJIP8JqaK*HVqeVc[5G"6bl,2+j8Tr9*U"X,+%ep4 -%A1,@l31CDC!!EPbbA0)rE44r#BG)0Vq)@lF"Ri10*@6!@Z&A80Umlp@fVi-'@(` -TjM0IN[qF#)jcNb)"r$@TUXaHKld8[3$+@2eFf!,'D`RdFVT2RkEFEK!6%TCU,R$ -SR6YLQaL5T3a*IUFk5Z"k3CAH60AeLGbYT(HHLV#bX1H#!Ukk+r4!CNF(-3h*$#L -ZQ*12M#fYYrEklYXV"p+,qbE"lk`0ZFdAX6+U-L9l2,hE!(3lP)M#M10il*Lb,`1 -XLR)M&L0ZUT`8,jHcCPN68VJr1RmPQX5Xr2%Y)CrqMDJHc#'fh8k`Na#mEIP1DQp -$Xcldp!jU#$d308ha[lXGM!TYUk[0@&TFKR)AFfRm68&Zie0E,h8RdClK$+DUSI` -re*-3QZkY&N2Y[')H`rdG5ZG20XF$39!qVpAGqdRkQ!Mm4+M2RFT0#(d&,b-jBZK -A4V1%,B58c$p%Z"E2hC`PD%-KcXAJ-jr`X0+G+Hr9M$-b#IC`1(aN6cL50L65F$9 -rB&X2UU5ilijcqZ*p-bJHajSMH&lmmEFZ!mSIMeChiXIPPaKIi$hhMm,[4FeEDVK -qZ5X5XR+4GQc)Ife4S@+jD"Q@cjHl*S`#@rl+NcE`@LBFPG99,8A5rj@E!@G5""I -"2M[HIeM$CB91D,6*CM%j(!BcQa$'K%DkQ,NFN3-)P!NPe4@1A6P"6X[ijmkl90E -lIM+LpX29Rbec2iXFb,IqLB+9jUf!K1(qpE!0UZl@*['2%,-JX"LSM5Mkp-M`3GN -p!CU'*L+1"0&-,6ce#BX@c2f[rq6c!"Z)A5c%rm&',[U46d#EL+&GcJreil$Jpcp -CShSf'KRb!T%hZN5D,qVPX#5@1m9EAR98HNJG&C61kJi9i6cDDdk3!!)'6YdQY&S -bHG3$I9ic9m!G[l,eB8krA`9d2JA5,-[2'SV$f$ET3NrV#UZLDNqG1iRDX'jf%Iq -Y(fYG,Ge$%DpZD5I1F1fX[`R(1I$G`)JPCFq$qlK2G"!%&GU+5pI!GSjkF[T)9+9 -5J8l5j#BDNRYE$6N0lF!mH2+lf)qQ[f,+1T(0@-a`T(kJm42j(I`)bZR"E,fQDGl -,+(RKma0fJL@mV0BQZrF38&R6CQPmI"M9,NS0PYah3ZCc!6QPM3P5Vf6H+jY34KT -[3R9ZU840XbGaq-Z9lF!JrYIf"&D3!0mR#mmHd5kaUK0'BNUm1XQKQBVET$H[)!k -ba[d8AhlSmR6SGjihUaG+DZS)4PV$0+!5(b`Q,BL3!([)McDU#5N)@JF$+`f'Zr3 -Qcj[rH4+DfJ46I"A*LHKT8-P+Q+K5CJh*h5!952j4H&r@YMD,Y[V2)1bRq115T@Q -LIjDHkiJkF&R4ej5Tel%k5$dmVS`d6HbCP$1bcGHqYpHr4DD8(FA5K9CE&4,&&EK -'Y[GD,A[E1cI-K!FH()J9c'mX2[80Ie33!#0h11RISBAb4b4hN!#Clia2IT8[AjF -j9-l&3#8bIrCa0ff@-0"i-+5FmT*f,lcPeUDCF1h*X`Qq3GDkd!LF!bq@LD8I$9" -r+dVP249[hJGkVS#8Zq!+%`r(P$8*Jfji1%q'Tm"!l9A2Ubd%pN'b95i4r@5M1#K -KcJL6#3"dXfAqKYD`kcZaMXNQ"I*J,eH(AqJ48Da$,KVQ"q0D(B*#3D%#`rY"Pe! -+"fqJNSC[rA9@*!b(),Fh+qQF3)cdNM5"I4I524Zm`(&C26m*&9+)`j3RmS-a-r* -cX2+E4,1fa2&T%#f''!X4T@qK4aa%ATkkjHK(r#h%SGZ&I"'KQiL2,amGqE*jeXD -F,8cpB!@2*AV$rSm)Z!'Ffk(&JpA!cQ[RUZ@!kYpBcM((qebQH0*CLhZ"IIJCC5@ -cRB$B(JN4#q8"B0%leNqJ5TDqRm9eD0mK4G@heZ,rilAYGT!!r[[Gcb`jE''bTZk -Jh'Va@MPdU$m4mKJ("#ESe%j*V(4&[80A901F,16,J%me&2Q[*cpfh6aaU[(6%l- -dhQmqh+H)L-ZPK+-*GJ+FqA"M'fFE6Rk-3VjUYl19AE#0*br*rl6'a1[ILC1EM+0 -GB4R&*),P`RZeb[*)l%MamM+$-9V8Ji%2N!$kkUA$FH!(2C!!R4S*A)E)NEDMH-r -%`eSX(DLHKSiYiN2drN9m#`MY*@`qUlKmQ[@(T9@TFpa,%9PI3+I6ZY%!&95K9l% -p8dI6b0)bJT0B-@0%$$pGcS%rb0LmSLF*&Jd4ih12iG!-2TD(e))fm(j@iq2kh$U -Ud*X!'05,c$fMYF6%p0E+6el[+Y5[f@k(@'HMC8hZe6kb'h%R'4I+Ma3"Y`Qb#1d -c0FjiP'!jiK'6U26,eE$(jTcV%A1$VP08rG!PH,'SY9iPEP0iU@&*`AVbV"m23C@ -H4#'Ir5pKe`EC3[@*PBF"d8+[6@`#e,I#@)9p@c3e!Il5c9q3!!SI3NK)+LlS3dR -H9ld*%F-+jZH[)$#Q6`"Sl+')AXQkLSrCpeA`HKdJiib-F39-X5-$RdZ!6N$30r$ --rj[jQHji$'fS'L%%$R!9h[aqNC4cYi0c6f2j0c'"%ci0&-V,-jZIDAcbFd93j,T -4C4e(*fpqh&(UEMi&j&Q`Q%YA4++LrL28r[X3@+L!mITGUNQ,(q+p9B4*0EFG0UT -#cmpAIAi+1+6!TbhQK2B+DA9@e*F8U-NH0KK0+qrM)+63`9iE"`jF1V@B!$NN4`d -cPi*fS)hkJ2C3LK[ekqT@S5ccdGNU!HVH!JV)PTkLG3d16h&$5D(arqFL-)XkFUh -6RT[baRX!iU-YGdhIB&9-hJ*b53("kDXk22HUaPDqJmACT,0aDJGHLa4G53#"#k* -p!X+KFPX3i$e'AKhCDK!+5fNhUQ@,Ia@CbC52iFJ-**b!f#K0TjL(08dP*h)Rje, -9A+h+,R'5clXRSl(mMrk$`SQkBFadqI-cYELV'#aAAi("CZr1Km8l"Yf1KC@Pbcd -3DYij9eXH)1("()@*Alaqh)6c%dc&q3&$j%C,HNJ1[PU@SdPEEpZI#CK(#CGNB9H -XpQ#cJIfS@E81LRPI+2Yk25Gh8"UIB6`DSQDY'B%[[LDF4J-c@pRN(Z5iYHlSm4& -M#853!)ZkqfpijTZjm'N4!3GEih4ihYQT0f(8U$KqE8Q4G2Y4,BkFa#43TB-#A), -LX)i6aaqdVKVe8G#)SV$R49THCa&hYqBpeRJ99aUIbMh-ZUkbY0Bc928jfe+1`dc -rJ5Q&M6eiAJ8jipp0Kmh60e`S@PXc(q@,EkqZ9GNbV9--Ue"jT)k%P0"0QMJqH@3 -I`+CefFG[2elb(9*PHD-LfX'23pJVFUS9fiU4S5p+Xpb'h$Lj%",)E*ETbrr$'PT -GCKrZm9G!C!fJ"@-JJ,6591Xc&#RYL$X"%K-BFj94KfHl2SDq+[L2eCqRPGPR,6J -*l0TjfUL&aCp2,SUr8MdJR,HEI4+HMY8dQk(#B0khqfEli"6BS)HmYQ!2'i8"1h- -YEX%"C9JppQjh8mUjj#&Qcb&PR[,'#2r,&I12"9!mCqLcH''idlcU9e0fID`CAFR -pEF""k!DpXkUm"D"[TKahSk336-[TGElFkT1H9,UQ9dQBAU*khdLJ41#`+*Q*JpY -LZj8aFj!!Y)FXif0FZ$+E(m8YiDQ'f-28!Ji-)!3rflhmZ8S4I9!(2l$(h*[4k)d -4%XCIfcZ5i3`*aFr5KEhX)RECrEkI4GqR)3Zq8$5M#(%#K6G$cMVq5Y1bUF$b6aA -T%l!kpi6(IIG+$-ARqi5LCqeX')HJ#qMj6j&bDSK8'K+lZp!k+'B4Dh%`b-6hkX5 -hX$*!QVYcTS)AcJ-Xc11jE!6@dEMTlhBF%EKL`%r,f!9IY`dTH`a&YM@&Udd*C1C -$fE2Y9-UjTl0%%TD%-8M-5hcj-F+4JN!1##'264%8!+@3"!%!!$!!3!#3#3%1D`# -3"mi!N!0"rj!%!*!+TC!%!3!!03!!Y[&1mlEa6[-!N!21!!%Y%J#3!h)!"3lX!*! -15@0[EJd!!4)YD@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",#X!N!Gb!!#dN!$rN!3 -!N!ULN!!!!!%!!!'MLJ!"SSS!!!9,!*$c$!!J!!J!SJ%F!)"993#3!``!+!!S!+i -"6J#e998!N!--!#!!#!#L!4`!JP99!*!$$!"L!*)!m!'B!)9993#3!``!4J#Q!,S -"eJ#'998!N!--!#J!+!"e!6`!Ke99!*!$$J!S!#J!`J'N!)K995J+!*!$$!!S!#J -!P!%5!J"993#3!``!+!!S!)d"&`)"998!N!--!#J!+!#f!4`%!999!*!$@J!"!*! -&A3"`!(%!V!3#6dX!N!G+!&8"%iJk8fpbFRNZ)#"*ER0dB@aXBA4TEfiJBf&Z)'p -ZE(NJBQ8JF'9bCQpbE@9N)'pZ)%K'8b"fEfaeE@9c,J#3!eS!!3#3"9d!F!"a!+` -%!Np,!*!(5J"9!41)1P4SC5"QD@aP)0*H-0-JE@&j)'*P)'4KE@&RC@3Z)#"3E'9 -KFf8JGA0P)'Pd)(GTG'JJBf&eG'P[ELi!N!05!!%!N!9Y!'B!J3#L"!*25`#3"33 -!5!"R!31)-P0[FR*j,#"LGA3JB5"NDA0V)(*PE'&dC@3JCA*bEh)J+&i`+5"SBA- -JEf0MGA*bC@3Z!*!$I8&%3e)$!!"q$9-+Ni3"Sfd!l!Yb!l5b-LXVieY0hP[[D[H -QELEAJ$%!3!-!N!1kY3b!!!PT+[lJ!985,2Y+b&X1iq9cZS94MV)rcirrVL!j0k` -Dq"(+KM9jKQ+MCf[`V&ir"HlX#m#`U3BL1%aA2VhVbkfM'32&(&P,'cJ,!*!$6!! -#!*!&-3"R!%8!V33%8A9TG!#3"3S!8!!F!4#)'P9Z8h4eCQCTEQFJGf&c)(0eBf0 -PFh0QG@`K!*!&#!!1!#J!,U!#!!%!N!28384$8J-!!4)08`UE*!!lLSL+&Fm@d(1 -X4'`3p5`rIcrXejfrjql1$+GBf'%P+PL&999LjEra",'U"3ZbC6Y1)2Q3!"m"9#5 -BqM@mKDIGaGRG6G,)HT+pI4mZ3pc&PmHP#aEjM6KA6jAe#b3m5Sk53ElSG,A`G'S -9QL)q"HC1abaeLk9cJ@A[I"3FZ$A+c+Ce3%m()3a-9j4CR+h"Zf9c)KIFIJai(r! -m3+*2iaUXL26-$cGj+&$EM-KaUkHFa@0E8ER-cGETJDZ80pr*q`cTre6rb@d!N!4 -Z!!%!N!9S!(S!I!#f"!*25`#3"dJ!AJ%PL%j6EfeP)'PdC@ec)(GPFQ8JFfYTF(" -PC#"LC@0KGA0P)(4SCANJBA*P)'j[G#"cGA"`Eh*dC@3JBRNJG'KTFb"cC@aQ,@9 -iG(*KBh4[FLi!N!1T384$8J-!!,B08`UM!J,[j!5Gr91a$mmfHp2E9(6Bajb+k03 -*LRTfFql'k6J3$a8lE'G9#9C9N!-KhQd6UrS"#j)2B)QrqC!!!Al+C$IA*4T0h,, -0C$41)9c$S80X0Nh%l40&LQIS0$'"1Rme"P-qaQ1QT*,p22dS82pVc)-l2TG!Iei -&[QEeiPFKRRa,frhZGP$pLG-c6DU+j6&M59JZp!+6*N%5EamGV!)!N!-k!!%!N!9 -3!&N!C!#6"!*25`#3"3-!4!")!1L)'94SDA-JBA*MD'PfC5"TFb"NB@eKCf9N,L! -!N!4)!!%!N!9(!&S!@`#8"!*25`#3"3)!43!a!1L)*eP[G5"SBACP)'9ZG'9bC@3 -JB@iJD@jMEh*bC@0d)("KFh0hEh*N,J#3"#J!!3#3"DS!K!#q!0`%#%0[ER4TER9 -P!*!&"!!%!+)"BX!#!qJ!N!0m!!%!N!9T!'-!I3#I"!*25`#3"cd!B!$cL&a8D'9 -bC5"TFb"ZEh3JC@j[G@GS)(*[EfdJEfiJdPi`db"dEb"MEfjdD@jeC5"9EP0dG@C -QD@jR,L!J3@iJB@4NDA4TEfjKE#"H-5"LHA4PFb"KFQ8JEQ9PC'9N,J#3!ai!EJ# -'!0i"j!!&!*!)!38'8h4KG(9c!*!''!!d!"3!r!&k!!%"!!%!N!8$k!#3!j3!!!% -I384$8J-!"1B08`VN)J$IGJ11FDG1aI+XhN5ajMb`KrLXhP3XTk#)Ge0Rp62"!"d -')Xj5G&B21kcbrprhRKcHfHed@!),S+0`'6QD'hf-e6-0EE0JA0JYVCTKMLqC4BD -'lHI%rAFk&h,ZT!UE+blcrR5$XU%CY3&X,KdXDS#*9HPJ06Ki%J%%4j'$aiQ$Lac -80FqpJqd)X1(#V")%h"U$B,1dq1`PRHQNP#Lmm&%MhQUjjlm1[0)NHb-$5U,$+hX -*C!STdVjIpHXJf$AMJATqk-M-MAJli["V5jR)&)*,#QKAa55e-8raq6Fp!b1H-Bc -[G-40$Ldme)!l'AmdjamkrMTV)lN-NRH5S0Q(&[jUb4G0pRc!Ah1RGIC')T3DMaB -!!!F+384$8J-!$#J1A3ZXJL3qkJcIlqii#D&+Ke!DU9(K"%G!H9m(C[1JfB+%&8p -N1&D8a9jY2,15NYUHE9KV1r(lkN0S,@5Y3J9V6Lk3!)3*Hi[IEhAm2XAeqmM#S&Q -eT-lX,V86@a55-#r*XU4,K4$5pcZplm6LfR2Vp`F0jqFd-3%N0#-e(dEN$U81T2p -Ub-pQ#-'`@@PihV`qI-'pjd8RLm)IBIebRc`+GJ`A2SQ9L4kZJf(%Ki5*VD(+++J -iJ(KI*!L$-i6RJBMj%"Nl8-TZX#ZTIBcBlM$p%iP6Rlpp[)(p[2VZF,crpQH$ikl -L2p[!0f(&9(QT2YqjNVeT*-pR6bI2K*@I,SDba8$G!'bC21$jKIJR0ihTKH,TKfI -'!mcHfQh&j`f`,dKaB5E1mjd,%'aq)4Z*jC),+Ar)9b3$Jkf@qrR[cF3cPIATH#J -bR,XaXMLik5Tr8bYLC46q"Ael&k+"C[I#"GZ0$dVBebMX4XC2jR%5'B3rL8[E(JV -icPi$,iS4kXh`-m@V!Qj4VaQ&0c&()JhM%r'jCe8ZjY92Rj`CFTrN2KlHEH!EPj, -MZ@)f9CDH+hEiTDeIR%r+[YVcfk8NpmZjEFX%I&6"VhJSqdSP["kj&S,-8"q$@hF -lBJDqY'mm1IR$qG"UHHkj'8cVrDQ+IZU(8IJ2r+`9X&j(B4F5)P5mR*i%J3j#-[I -S!Ke%SY!0Uq"LXTMRC6'h+)[kMf34jf3K+&588$L%#LRFTZT&UP5Pf`02Xq6d+c& -C4[ZF[#bC[qBB@8U[jj+bA(kpjl%XDpk*lM)`2ki`-+8rG"Lmb1a`'!50rN3`q#! -he5SIaJ[hrX5$@Z[`iXKI9Zl`5KXQ`c"*KXNc6+SZf3Dr`9YX&JBq,H,iZ,!,elX -ee+GlXAa$MkVGC%f"T8I8PkC42fLe%MV,KqS+VNa[B%P[1H!S&5jI@,ZJ0KaG-b2 -TERM4K(bSPGJqL-%1fYE-M91k@m"*3&Bfi2X@YjEZT3J1QVkL![(3ed!b4qe`$N" -`QL*UQpdF3bfdiT(4$1iC3,"LM'iV364RaNi2iGC+dhq6$j%`!`lI%Dm1d4cTqeI -dJf@e5Dc)M)LN2DTPe)hD2YLD3f%01I++KlAi[L4ZHA0H[3qE9@qmSGZ%rZ&%Y32 -9Ah[-dRZ#A%bCT+TF[bkE+VPid8'PRJCMVrr+36c)[N!hp"D"$ZC6SR-ajP5(UD1 -#Srmr'"hLem1#8fA[AIR(b4fMd*Ulpcr3#[S$MSdVKIiDdY4fD"6)TbKXB05T[[6 -pc25K$`8IcSSJ9#eGjIkb6qhVqj4bp@,!+Ab0p0iTlF`FG5,VRGTaJ'J@Rj[9MJf -V3!i!FAq$hT(CD38,fJD!CimeQd(*"%i2DEIGVcL4Sk$&k5BM,TrU&DPfNAS0TpK -l&Zh2lXZ3!*&TbdZ$GVILk[[+Cr""B06H3[-$Gid6'FUFe4b1$IGCYRQXU8d%bl4 -0a"+-P*,$T29Q$H1S#A(5mGC($JcjNmKbd,k#1UI#h4RE+2SiVp#F8U!JIRp,rIY -)DeGDL'&83"i$p&i6,+a`1r3(fS0K+SEKRZ3L!9lL)*B)!F#)rlQVjd$`pqi0RQp -XY&@pYrVNk85Irrh[M[qHrBjVrderGGk6cAbck@*X[5*13r1q1RcA*r(AY'c)Q&a -50kA)b(ETcGab10R#2bU'XLNQNC!!JpI92ER&p8MDSSMMNK34ILGadH5hd4EHcS3 -HC4M,2P2`GPqGP+L8*,m1j`!2G%KF,RNDJPmUKYS9CREH&0cfZ+k@Eqbaj91VBdq -6rDUr*a,[PG+G(H2qS1G5+C5SMZBED%SB&0VJ,%j62X2L6Z[Z$dVq'44'F4e3rYU -LJ[-me"T9J829KkaerSDL$)`VXIrCdFZcN!"TZ#A1de%Y8Z*-EUE1dB#*1lE,NrP -R,ZC(qHd6E9H292IX,&qq)8rXQ'mG0F'TBQ-`'-U'0bZ0I0fldUeC)pFB($(0mYM -#MjS2bLmArF&Jl6B4IR*,dRjZj2c")G18Mbhb'4BS'bV1cY1i#FPI5GQ!DIUhaYA -"UlBK+ErTQSd''jLfK25XF6Xh*!9-C3%qf%MK,m3U-M!)K,fk%TkBK&2brJZdA!" -'E1f`4+rVE-pq%&fdrE"-3)#i`R5j*Y1f-B*N'$,XS6dfZQ''F-Z(*q,F4ir[4U+ -Gr`1)iAJSBjSKL8*IMe6rHppArie+Gb2BZ8Qf+l@fJlHjUXbHLI@hl5BUN!$pc,J -d'qhDFE1TIC-BPF@@5VlR@LJNK,1'9*eaLB1,Aa'&8ZNr!CA6DN)ViC4-AD+8`[# -"#%FTlJFYPBQFIc(%k%*98ZVB@2@VpFN46eGTXP!p4KUi4pA(qEEmFUJT["bc*Xf -"AJB*T)e!-4UU4"bk0YZ"#V2#JX&#@U%EkXVA2hjV)KEh[3!!!E9"4%05!`!#b!e -9#j5La1aK"%pReGh9)B3UDfd*$*Ld(%PN`13%U$)jQ8J'!5,ISD3P(j-1*6FFH89 -q*XQCr'eJ`6EH6TpTGi@%56)6f530b#IEXf2Z,82mj(Z1VVPMNi+EBlfXU"!$l3c -i%Lp1N!!m8H53!1ai1[jprBcY`1#e3A#i[$`q(XH3!(Cdp2`FU,0B$5dZZjD$j!q -rA0lJBYTbDI!m1FqF&ca[H@Y+QLp4erP&b0b@U#3HJ2Vrr0lbcQQNH+&'MC)kqK6 -`ec9Z1Z2T1Lha1Z$H*fQXlZHZki&[&YbUTmmb*DPlkrZZK!rURDDm9"'9%[kG1*j -6[@R1UKP8hmmJ,Pl[iH@LC)-'+SShpBbB-p32UAVkpLLF8Nl5&[!0f9E$bq-lhJl -FT+Tq8F+d2Dm'e[MrUc4&)[-RAYp`U+Tlk'k!,'B@$N@Xe`fED[H!5S[L%M*5IP, -*a!HF9h89CN*F*[55Jl8T-$XVQN%ef6PIQ!X'`cDK&**3Q@cfkN&Cf@C&LH%X1S@ -1%ilU&29$c81F@AbHjM@&!SDq&R@'X%)VM"[r`)*S3B0P#d85Yaq4Z#rf[!r14`! -!!E9"4%05!`!#p!e9#pbb`+d2"#FRY(fFYXSYA1K9e1X5RpXqUZ,qI8AV$SS,G6[ -'T3i3Pq29Uq'iApffE4qJ&5%[hdYbX9&af`F,kc%+A#4PY&f[r*I5qN+[D-[p#I8 -P$A1d2aZ8eN,f[I&"VQU3!'U('"FcA9bIAV`I3"Ue`D,Pq[VKBEZYAEB4'cDRM5r -#2jfRVprmaie5iqHDh5GcCR`6r@[mMj+l@J@QB"Y`9!%T2J*B'A3!6LE+,LC1QE+ -8-&SVe!+P$Um3U!A(#CJ9k4A$83%$KDQHMhj%jXBb&`NVADe#far6`F+R*%,5pUq -+rhVVC%V-b4S"k4*C[hadMbkXb!Krkr%ZUc%RU@9hAq+E(drLFq%L6G8r*frLF[[ -dHdMRE2(A*4lI%R,1Gj94Lqr3HdDZP)X6Ia[kkhIq2-C(H+*S@fD(Ah[[8&c[IEb -mKi*QQI"!D-((5&*ShIYK&j-dA&4a%dke*lAH,h8)LP3&jJl&YqJJQ"Ti3c*VCf4 -JfY@3!#MQ+4"5RUG`%Gf3!"SFCM'HZaEKJ+I)QUQ$H5N@j-iqSi5X5#(['arhL'e -hL&QCN!$fA1ha&!)!!!'+384$8J-!!V3093ZF&-Ae83$I*(P*'YHDE1qe@Dh!Idk -GbP6IkAY@IKAB#V`+E!8![PD0YV@jZ@rZNRAA#J`6f4%$14$09`ERpmcaNaqj2hG -2l%TfFfar'bK(iZPCq2Tpp3,NLk)cNXpm(Iqqr4eAC+m0)VI2X9Nb0[HH+Hc6,md -l0#SpEeUab'PfiGccV3UT2UPTm8[1A%pU&"kKqRrqk2Q8T$)m+&9UP)9HXVlEkLS -$VQ@45GHXZjIS90Z`,!ekA,J@Te[-*E4TDmXN(m@6&,Y*K-3NrblFca4A-4-a3+d -0!&BlJeH,B3S,*!4hDDb&Fe,[j@M"Z9L*IP4[j%9S(m!HJq4)d,Vb-9',D"1U))[ -fK3p[J)R"ES9dUSE(@$cNrd2(6ZiJ@,9'+XJSGT!!!)e9adG8C!Mf"cdX-bdCZ8m -)c)TlmT%U%#b,A)T6N!#BGA"a3$U0f8#KH!m,D0Z-er3+fSNkMY,#E4kf%!UBjfU -9!3H94f(GrJmB9-d@((SB8VMqM-6Vq,9VGM3#!!!%-d&%3e)$!!Ch$9803b)5%HC -HEK"N,4P%D[*%*!X3@DZQ*LHh2BZ-i(ERb%Qh-e2bQAph[qrELM`EhmbhY8#5eFl -XbH4*f,ilNa'5j9ENLDc)laq42j1IbEcCeRB454B6XMFYb5)S31)(rdjCKT&84$L -S#cYiiLGf)5c5J1e3aD%@GK*H(mq1D3bR6lpC+R)6)mRY[@4[%r6@hmf'R%[)+8F -IZEr5&V,ejRAjaL3*5bPTf0kN&a@6NPGC,a$mi-RK`KFHI%V$*QM4BN6+hFfqTX2 -b,*5j55k)jb(*(2h&i)XDJqim&Fee*9$cG*JIMZ6*i#SGjViNe#Xq)@+3!*h[`af -,NK")heX@$ED[(5XhPA-`LA1fRcbNbSE0RBqrZ,m'l)YVm[NQUD!A@)"Ck2@aqND -T+'b%UlJKdF4%D4j'8D8QKLJRXm5(8JQR40@4X8N6+L,JmB-'82KL!,85ECR3J#8 -d%@TbLdfC`eLTT"qR$+aeU)[Di0J#T6DMFe4B`aLflrdNJ-)Z!m3jBTLiESAmcl% -RFHbLl9fAJNh,JDRU`pD$+ZFdM(GdeX@!G"Z$#pDfYBXaSNc2)HBbh"2bA1lEQ20 -L2d(0f,[Q&#I)A'ZQ2(KBb@@qIDUNT-rSkShVZbh3b(2j4EE#Hi"%aD`5%YXK48J -Pi!JpjfESS#*')G-lpU&Zma9#N6ZP%AF+hP-PhjBJ16hDlDNc*qDmR%1jlK@TB-c -EfPh+FK[jplG1#3aZ,GrmP`rLNbG@J3Mpl)N"@`NmD#E1Ye,'NV,SJ&0-'N"4lGD -H(L15jV)kGQArf*KLjXEBBNT+ilSFVqIQ2L6S6,2!-qdr5A,SM5rZ8%e+qrrFIEa -)TAK+(ePf3"KU9mH96KeiJM&J8-CCH2(UplHlTpQ8&pIV!mfS&!eYS22Y"H59K,, -GX(5'$iDUN!!D1!1%4[Dm+R'd+EK+q$Ll6eBP[SHY1Jm&+*f0f9@c1LPl$U`!LB0 -EA#,N"l-#h9`&eEjM4RfXIVf`GZf$Y!rlJeGII3NEUUX[JA!5-Xp,Z*!!K9k#PFa -lib#6LH[)jR!53fYB8Y@+#cA4e!fZkRA5eL(bC5reTB0Nq+`1N!#ULm1*SfpKL@K -A(V8&MK(J'6fDpK)ZJ-$X$'lTUd'pQXb1L-Hl60lqhlJ2YkIbbBfVNkBAI5lbXT2 -6-1CCQI@i%dADZX@J'V("P$45$f-VG@mlh@!+D@pipZKGMr,CUC9ZcXXMqF'dI'X -XGU%XA8IkajQ+#fPh$2Aj@FVRjqVrINKT#[0r9hl1a'Bar[EhjGLF9@FZ6fPZ&[U -Q90aX9RVbi))fT0[hNY60m9Pip++5qIc2PqqBK`c8pE9GaLXRlhFHm(""&mY9YB2 -CTqfiUkZ$G385RX(1bd[ERX3qk'4JZaVPpDGj!R%'T["3[!PH+Gc$PhJ`"hHqIVA -3@F0Eeq31!*!$$!Y9EP0dG@CQ)'&c1J#3!`J()'C[E'4PFJ#3!c`!"33JEfBJ"b" -TG'9YFbi%8h4[F"Y*G'9YFb"bC@eKD@jTEQFJG'mJ9@j6G(9QCMS,9@j6G(9QCQP -ZCcS!N!-Y384$8J-!!$!05`0EE!ZhDJ#3"DJ"@qfr"JB$m"(EmRm)@%,*M`E@'c' -A%`#3!`B!N!80!*!$2`B"J!#3!`8f,M!Z-6)f,M!Z-5`J3fp`HA*TCfKd)+NJ-6N -j-#db-$!a)%&XB@4ND@iJ8hPcG'9YFb`J5@jM,J#3!b)'!B!!N!-&0Li`,M%98h4 -eCQC*G#"%C@aeH'@U)$BZ-#ia!*!$$!!S!#J!I`&`"+p993#3!b!IU5!a16N`,6N -i)%&XB@4ND@iJ8hPcG'9YFb`J5@jM,J#3!c4"9A-b!*!$!8P$6L-!!`#3!i!!!3# -"!!)!JJ!$!)0'8N9'!!-!N!1!!!%!J3!#!))!!`#$!*!$('&eFh3!N!-"5801)`# -3"B4'8N9'!*!&K!#3!aF!N!83!8S!!!%!!'3!!!%5!*!)R8&%3e)$!!#S$9X+@N! -#GrJF9R9RkF3q91`3He-hGAEBSBqh'hZkhCY[Kl-IE&K9BP8P@&9L2BBG9J8*U#Q -Qq![JiFY6!'CTr+CUIJ,Z--20MlZSKSY&HKKK,qfj,(1Q,"9-Mmrf5(RXk-@X00L -!E*!!DjS5jK4TL&dh"9[h4!G&YT63ABX`ZFQ#C6*"-HNekEYI%LZAU+5p`$mR$b* -V!*!$Rd&%3e)$!!#U$9-+R!)#lpEP$+#qS*Ea@aQI@CQPV4E2bMUh0hHehUhEXm9 -[R!'!!3"S!'"NFeNC!!-*U#QQq!X8kF1E,U4q(UI(l#YZT(50Qkh9NT084ZTSlpY -69H@-`L5-qh0p3'iE[*J9S`[#TA#'fNJ1Lp%f64eF0J!,&AB`dPq682G6"-FSJiV -4Xp(IN!!QGReLkGYZmL[kiaM*q`i!N!0-!!)!N!8)!$3!'J%EL"Y3E'9KFf8JD@j -cCA*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)'4 -KE@&RC@3Z5`#3!aJ!2!"!!,3"Q!!"!3#3"`%(!!!S#J#3!aJ!2!"!!,3"Q!!"!3# -3"`%)!!!S#J#3!a8!9!"N!)X"KJ!"!3#3"`4,!*!%"d&38%`!N!B(8f9R-J!"!*! -%"e0PCc-!!Rm!N!-(8f9R6J!$r`#3!`G"8&"-!*!&!3#3!i!!(rp!!#!#)!!L"*! -!!#B*b!!L%q3!)L!#!#*!!3!JKq#!)3r`3#)F-#!N'Im3+"U+#$)bLL3Q-[)b6M3 -'15CPp$)5C43N#'Im#!4``"!#2q!J!3'!3!#'`)!!3!%!!#!#!!!6j!!!#FJ!!!5 -3!!!!!L!!!!&!!*!$J!#3"i!!(rr!!$rri!!rrr!!2rri!$rrr!!rrri!2rrr!$r -rri!rrrr!2rrri$rrrr!rrrri2rrrr$rrrrjrrj!$2rrrrKrrrr`2rrri"rrrm!2 -rrq!"rrr!!2rrJ!"rr`!!2ri!!"rm!!!2q!!!"r!!!!2J!!!"`!#3!i!!N!F"!!I -rrJ!)!)-!#B%#J!T#!N!)K!)J#3J#%![3!rJ))!!)#%!!#!L!!!J*!!!)#J!!#!` -!!!J)!!!)#!(i#!J$r!J)"``)#!Crb!J'S)J)$+#)#!`"L!J0!BJ)'Ad)#"P(#!J -Cr`J)($!)#!ri#!J!B!J)!E!)#!!!#!J!!!J2rrri"rrq!!rrr`!2rrq!$rrr`!r -rrq!2rrr`$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!r -rrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!r -rrrJ2rrri$rrrq!rrrrJ!!!%!"rrq!!J!J`!,J3+!#%)#3!Q%!L!)5!)3#j!!!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!!!J -2rrri"rrq!!rrr`!2rrq!$rrr`!rrrq!2rrr`$rrrq!rrrrJ2rrri$rrrq!rrrrJ -2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ -2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ2rrri$rrrq!rrrrJ!!!%!"rrq!!J!J`! -,J3+!#N)#3!T%!L!+5!)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#3!i!!!!&!!!!#)!!!"*!!!!!*b!!!%q3!!#!#!!"!!3!!Kq# -!!3r`3!)F-#!%'Im3#"U+#")bLL3Q-[)b6M3'15CPp$)5C43N#'Im#!4``"!#2q! -J!3'!3!#'`)!!3!%!!#!#!!!6j!!!#FJ!!!53!!!!!L!!!!&!!*!$J!#3"i!!!!( -!!!!$i!!!"r!!!!ri!!!Ir!!!2ri!!(rr!!$rri!"rrr!!rrri!Irrr!2rrri(rr -rr$rrrrjrrj!$2rrrrKrrrr`2rrri"rrrm!2rrq!"rrr!!2rrJ!"rr`!!2ri!!"r -m!!!2q!!!"r!!!!2J!!!"`!#3!i!!N!Kh384$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!0A384$8J-!!3%08`,FeJD6pp*'c886E3#dq6FZ[0Y0'fE#E,kV#pq%hE$Ej0e -feG9eB3!*1+@)rh3&qKSdTMBHqm5GDpP1JSQ`da$k`,2S!'L3!-@qrJ5q"J#3"J% -L384$8J-!!iS08`UE*!"rKN@`h6Nj%l$&$Pe,6NmGf`%9!pZaqYJ-9[A12LLS@(e -X`@kXkXE!2f0r925rrfq2mhC@'FEU!!ZC03eF9Shd`Bj'pkj6'Z`%Xr-S&0c&iM* -#YY5j)-Pc#j!!hfq#GS,Td84dcbPjXa2G[-RZ+i@%-ma,@ZUD8SSG#ciIQp0r"2" -krMRUbY2UD[qIAfl(Ujrp3rrlNCBP!VJcDU1#E9E"5#Dm4DYXM&@eAPXqBTZhKHe -K&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-hh6j4F3 -VE-XB!*!$-!#3"`3!!2q3"J!"!*!(!J#3"`-!N!F%rj!'!*!$"J#3"3m!!!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@prEf+rm -!N!k"!2Afp[hrN!Em9[D3!b[r!*!-J3$ep[C@rhrhN!5"rrIfN!3Vr`#3#S%!pID -3!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!!2mV92rrp[C -@rrIhIbU"N!5X9+Y@pT!$rrp8q2m!N!6r+e6rp[EmrIC@UbU"pT!$JArrprD3!rp -8q2m!N!Er+e6fp[hppeDVUrq3"RrhpT!$92Mr!*!)rb[fpPEqIrH3"2q"pj!%pT! -$prMr!*!+rb[fpPEprj!'JID3"IIir`#3$2mVpT!'ri(hN!2fN!2hq2m!N!lr+rD -3!rrrq2rrq2D3!rIir`#3%2mVpT!$prIipj!$p[Iir`#3%[mVpT!%92D3!rIir`# -3&2mV92q3"96ir`#3&[mV92q3!e6ir`#3'2mV92p8q2m!N"Vr+e6ir`#3(2rir`# -3([m!N$&E18&%3e)$!,l@%&809835!#&LlPE2IEijMq-)4`KT+X'mK*!!(Y%NTpK --4U)Q&`hRN5E(*8TN,$Nrhp`T*2%f"NPGrja6SJ34%(%Cac)d&3D5J#&BPQ9FP`Q --l9M@CF45aP+@@NZTCF@aeV%faYchphZHpqkp'%8kRErrc`!DTDFNbS%J5))J##) -$!&f6rh(9q9FeSM-)I0p#KVi%arMVLJqCQTm!+I&hMrr!(6IPIIVIDLY'Ee+ZhRm -E9Yc`MGS+ZNV%3Elk"K'ee3FGGqPqmaN&j&$YrPGl+qa2lphjlZb4hi(B@6a5qqj -X6,!a2JpDqYrpJa0%UJm(1P*1N!"lRaMip+GKfdFJ@EllKe$bPfZF3mh,2acBDhl -h0Narcp-CQ+lNkIhdHV3LIZEcCqMeD%@LMDFV345ZqrbCJRm##$j)Rl36)##1@2Z -AR![(,@'J!M@HZIbUjF1#I`)G+3p%jZcQPBVS1dLqRmm[2k@bX%5PEYlcjk+r8%R -ma2'6D$ZPp&rp3pP(jTHF#4#VSZ(#H+rkjmjIC2CDHkXAZfrKjV&`)8mf"XE-HEr -+FmrLVKkfBA"4S(II4fij`"3'`8jGHp6Hq4fa`HI1K!-48#H1caTc2UGL"90"N!" -d+j[+8SH8T@T+CjrGcMqrk2`&*Fa%dbp%`eIS0Z0RHFB8DJT-iHB-V6N`43i9,iB -f$UPVQlm4f1cBV"+ebPkX2e+9cb5$9cV5cZH2R&+12IpCG"k,2ir&ReH*dQre+(G -ZpcG059kkBhV5P$4(cARh4pfZ28GS+,mD#cZFhrU$HHiB[bV8VVGpk`p6jNl66b& -ck9#Gpl5l91BNkk6+GReR9AjT%4&0fhCfh09KSkJ3Hl5MrphCSY1$LCa5G%SE%8V -Pi-hr+Pi%D,LRZlR$jZNdD&IqAi9bqH)8(DLb5imLX9(llQe@,0%A`A3')KPYZ6p -p8QANJ`5-IiL@Up"I,hLPpiG+G5r-ke1QK`G6b`YHJFL5f2DcM(cc(fI2h[@q+JC -#&1[plpi5YZPM'd%%,eLDmDTrXHd6c6Y4)hNSAaQ',8(N"d6Z(HUqepT`ji*`4"m -E2kkr-IkmAU,lpG6i,T!!r901'M62IR(%I-mUKF8dcGC,4Rlhme8U!V*cI#6PGVa -mT3!-rVaCaIe[2EE)[X3+Vd54*,pFJm0Z0l+8qp2GZkd0bIj`[0R1bk$XH"fLFQa -B3-Va&@hN1qS!!9r&DR-HAb31Meq`M%M9Uqi!C3`HYNl$brYV-YDmA+P(2BaKDDA -)Q(B'-EM1b'"E5Gf284#m8MTmAB5m,`,PI[E)bbQJT1HQJ)+A4Z#l1rF'hPfaFFK -Zld!%K)i)L)+PPr2EDYpGSGYm0e0`QrrS9$haJUNMbQh,65SLEcX+AQP6CX[mUmZ -6jYiIj0hIDlCB,(PAcjSQA`CG'I9F59SXCSX[Ua&*2I0B1"DpqJ!fF5CSSXIPS!2 -mdQ`T6qCFHrqdHk,Y,p9(PVi8L$rf$5aG$#ViSGeHi53bA%H#SK@66VhNRMjl8e5 -0pimI'lhTh3TNPYHh9VBfG5"`l(D+S'MZERBf,d3NarpTpCp@iif"Pd!8MYDZd)G -#1DH1)@+QljFc4`BEPFp%"4%)Zp&`,"6r)1T,%CSf,h)l#ZD&EdF'6*0eRXL$94f -*[E8cr9hhiT24G@["c-9j)1Bj,"rLfL#b`EQAmd2*83$HidXrUV6r@pFr2!IJZfZ -'2Z3lTq[DXGBaAbS8c`0"6i[1qfLXkcjRIpF-Fji$%3'leH@mc3U02cqYC1C1dCh -)hQFLHepRA`@Lrp$*8#K(fp#FTd8CJ"P%Tp,@iIMTj%Hp-kr(dCA(FlClp+rdSA- -pahe"Jj)e"Nd[Q2R$-mpGZ8jeAF1I[1HZf1eGmbfeAGFrGd8jZKB9c2bD'q+)QSI -M#T1PZ'!b$k0!U'h[`8qSB0ihaja&*&a%KAIL9Ic*RbB31ARR!JaIK+K16F3V1LK -U"S!-NLd9&)eUVVhKUqEA1cLk6pQD[dI4FXS'GPH-2cF5T4FS1VmRVMF"&(*U"28 -''"kX#C!!Ge`+c`R`VFN+8P9iRr-"FekTFZj9%A2HdNQj9e+8Dm9Q6A)IS&H(Y&H -64p6XYqK[h9[6Sh1210(BTQC2SEpe8qk2cJ8S0hfb-pP)&q,Q[$S&B+f*0UKaFDq -+BEXh5pAXeqP[hH[h4ZG1@RhNhMF2S"LFYIRV+,+q[N2&R@RQ[&Q6dBfK'$'3!-- -TQK%J3Qlq-a",URQm$C&Ib2#XimqA"iMKrF6ZGeC('p,-m`p&$[E2p*Z[2Y!r-m0 -mcGSMDl0GmGN6k'rGK"R6jQERf'BFf8rXIZFJXAAeXNRQUqZ5qrYR"XcI`D9,Z$4 -TlC(5Z)I9DA-R0@E6dQG0eJ1(`5Sq'V0[FP1-fGZCNDX(0VT8Gr0iI`P(PrH0@bR -kLD,+bQi()0AIp3pKPbY!dF6+"Q*4rc@(LJiTfmC$#Y(")0NL3T)#Xq@4mK+hUla -E$%c33,dA-@dfE"mdY2Rr,bG4P1U2H%&K4!$DL+(4h%"'6A%4mTRKH6Zk!FMHTeY -4Z0Q3!0e*39I3F'6D0m#VFBH1EjkmTF6HK-98M*G5i0BB[#aSm*[E(H`,'M`ThF& -,#29EcaNm`"+1ZUfd,fjqR6iG3rBqHepV-l+jK%UdrPNf+T-bYECMNP6*eMpl0S2 -`i"%SSUUlA(d['MD&8XMHA2!1K44&%Yi$BjpiHjG+q6T*0$LbXd-bHpUIlci65R# -@Q)C,PfQSM+!X9cPh)3)M4UppQ`@VRB,92Q+hqA8+I0d2X0fPER6`084c`Z-jZe5 -RpjLqXP$bFVk-Q28%`f)R!YLF"r"p-9p01c(NI#iZ!ER,bS'r!r5$4,U*N!"-QIE -kZflH#d#jL`$r2Rp8(d26HQjDlRB9eDPp1+kX5"jV`['&HQhl$'BZBb0P9-Z""LC -Vrr[e[MC+r)5,cf2CQ4#AZp"Ffl8H2cGMf#Tr2S(8A6rcS"N#L"C#!fJJ#SUB&`9 -Cp#KB91FYEfHq9,Z236"a"4QMlTq5q4)GA(f,Gr%8G8hS63Lb83jFdkJ)5AfE6Ie -Gah0-#,6ZM[kZda+PNUC'"3'kGZ9VD%AABI4aPE2SJXC2'SZF#5f,*5#pL#2!3Eb -hA8`1*jrEh(9LlikZdmreGPdH[HPphejc9pAS69d$SH[QZ&%F+,AD`m+,Km"#4ib -McMq`MPh1$eq4AEAFA2ZqMcXcIcL1+*NdDX$KQjJK6d2RG"3$%2d2cGBa%N*i@Q$ -c48$TpL['B9qQDPalHUJ)%4T9'f0dp5+LlM,bFFRXh!d3`H[j%kH94i$cl'A-B)' -h5H8bNei4Ml1JqVYDa$(,2-,c0SiiLaU9C*NB$KCNPYS[MDjXPTP5D(-k[jMCGGU -h$m@jcjah--empB+Scm(&j@8D-2jP4f4M'VCVT3!-&p-bFFb!XmMi`VI+D&)!3"0 -&fN0!+N31Ym$XTj+mJ@i0266(E8!J(NB$b'X!(-ER)Er515Xe&FblGY9$*DVY5l# -LqZ8@$ed*RAbP@M9JUj'JVHk8Qr&9mV6&V8A)E1m-0r$fMi`rre!QEia)U'ZAmED -9kQ22YX5Sf"5$5f%UmN4E5AQ*3@`FPFT44f#YNE+3!'&N3BQ1SCfp"3r$D#U0)rp -1%jK!c@H294r`0,[4R"$0$CjQ+jSMX[QFGiX$D%i6cGiYpU!j*TUp@e"dBMDL6ce -4[N#RfccJ9aqQVhj)i&FI3'mbUY$RZ)%B[DU6%D)(B25PL4SKTP#hpUkEf)5-TMX -3R90h49Qkl)AikGb#UrELdA86EmDQ)k&LC(AP!"IM)5GY&iij%fi9cp(V*Yj#'Dj -*q4"TMbBhVM6KLYJ!'D$0IY"5DGr$PkmcA'i%S@6%IK&!E6N1I"!r6r1PF5k-Tf# -Kj9Y+*[CC+bIfq93m3S2%jNpM`kG!'VX"Qdi*IAZ1QiqCKkCTP+A*ka0cc-0**(r -'jZ2+%M,lmQ3e0PL$*9[hE5PTDU*TmjqGG8d!KbLb"`6'Y6$a'V)8E-jY[3Z&RpT -#*P9A82JT#I+UC+e+AMS["L(#k!T-b%T`b'3fmJ2aeMkC80SqZFhI(l"2Fl33UU$ -`+RCCr41FK`KJqm0JMQhkK1P44',hZBYeUhq3!!21jANj1$hU'X8b+a!0h3IL4"F -G1"$B-D$[)1#L&CQaEJ2jC@PjS1i"Q*Gpl63-B"U`ZAZ%J-L$"'KGEFk$F9JKQi4 -pE8[2JC4pXGY805A35d!5QHmXL*kDEXAPF#PY6faL1B[&jQA8kGJ0m'@D&'JI&8# -&0h6C,iD,R6%KM,&U"jDkC-6rm*[(9@#JDK+)XK98V%*J&3GG'KZRP(f-"91+$5F -h2i&K*0)V"dQXBNK6&eiZm4iiGFC'"%[cDMDXa#(M$c[V*[BC5)P0R!%@EY5+UhQ -1H`PBf3M6!YA0L*iUZ,6N)Xa0RCDZUGFF9F0*D5MS$8MeQEQb,f0MT2ADddNbrH[ -,)&0"`i$SH@lHQ'JYE#[TX)'e*P`aiHG!FkZMLi#h[JcI*JP1ml8hD`X0hEG2CAQ -lD31eRBCZC@@-M3FM!2QXJ9iM!b*i81"S,"q-F*1bqbd!!E$dr[DHM[lfN!"jq$S -6)6%"#dKDMN%-0hZ,VBcm-([,@$8br3SDG"L*('9j%XNFY4NA-J!bc+!APPCeR"* -"+%iUX2%-[*JPLVh8d@6Sq0kaVSTd"cKm+QfZD*V0@lQ5M`*SfF9J'!`F`hXXhkD -VB#PP9@p`F[(pqXZ#YE6TeM3JmV*GqA3Cb$f'4*3IjUIA1iY#aaqIHB0r,aUk9[5 -2,IR!1iM!3"$djNfX-#i@V&3C0UTFmJ%+4Q3"YV)D``iqKaGG6IM%ZeBkqpq2Dd% -H,N6LF"(B-SAXHmGZm!qVmSJ%`aaR!,5qk"["0Li%Ia8Q6LTfdIQNB0il(aa0NM$ -J96miU[J&!JB[%-RMk&H4phhqr'1AN!$*pVr[Hb0+J-XpHEhVqJi%hJT&aZ[J450 -p"bMEkcX`HY-0'@DrjGY&6)#k,JjMaRfH9bpkAk9@`83ZFKiENZI0c!MS'iIL58T -%d'"+1,`cJJ2VqJlN&#f,(NV+`pZ2q20246iDB-B25,$KR6Sr$PJbVf$H'lF3Dlh -VPXcVr92%*Up3S3#c6!3J'@FZQ@HZV,LQBfJMrXN2VJfD+kIqJ)T&HSQ'2#X"JiI -#Kd6$q(-Bd&kjYh,US[D[4YG0rF(P35bqNpLEZT!!$UM+GhH+`6d%[,jIMbD9Q&! -`,c$!B"!P)U)3ah(*mL-h8-,k1P-[f-8f$GHCD"[jFXJPVN6ibN(CE,NSQY1i18X -fMeVheVCre3jK,(N0!ZNXQ(Gfh5L#KB$+jfVE+lXZJfK`!XZl"UmG!*i(#ZBeV![ -Cfi'@4'kXcL$KlaJ1CC,jGPX*G3YHU4fJEMPPSLBpi$,0k1TcC'ER9Sj&qQ!`'1l -8-`rkbDal8cF*$41ERj'fh+8Z!B'L4K5c`J1GUNBKqrQXVUB[CY&@dGa+TISF-a! -"-V%&c4[ZSqNRm'jM*J8d(J1"VdaXd'$1UmSR3q-YRd1NCFK!Ab0[1DCm0RRiPYH -UmSf(9Dke[K4@mF)[N!"K(YZN4jCLNPY("hBS+E6G6fZS`b36r$5r655P#,ElrA% -CI!$f9I*kk`kIQm5+c1%VC&H9P%cJ,-2Q'`Pk-HrAAG4Xp+,*#Cc&9G)J'Jbbc&F -)Z&L`4dlk5&L@$bNVH1iT+[LAG#%E'[2R`j3kJKmXIAmM!RVKMR9p9CHR8(B'eQ, -@(H'BTAr"UqjZCJ3J9AJ&XElJ9I)+&I!+Sa"'4eh&$ILCT`ND)UKF-KN(0(J2300 -&0#N%AU4Q-1#i6Ymqie+&U+ZS)(9[5cLZB1%X@4BXR("+#YPpTU0ZiQFGG8dr51F -)3Xmb&XM&#`4bT@$Hj[[mqCb3!1c@!VpFFI#VTPXkkTBX`%mAKJBJL&[pq8$k&lh -C+T`CG$Q,#ZB9[)ZXmJ[H4T)8hbbBpbmE3&)%3G8aE$$8C3!kP#`[6FEbAJV$Q-C -8QTJN%pZqbk%8'MZ,5q1eb#JM+Z+cmL60Cm'N91f19iFE3Nl2a@aaX5d8SBYPTFQ -r`-!%,REc*)e-iHPL%PQeYAr""-(FNB*jkaCGcTHLik#H)!fY!85cBDpe12lD1b2 -1)EAdLB%4-bB!TAql+'bLD$BNGkiEAlS4"+@#9a#T!E+e5SkBhE(%!hI#[3fkTVP -MQ@1@+K$!q`jZ8(%i+1Tkq3U!N!#i``@lYZ[#&LY!YNVpC8V1a2NSjm[NX!QG1dH -qDN-R$VJjbh+@Vm3a')8ZQL0SMQ'58('mM$JD9$cC8@Nc053l!Q-2M+RG[&PKUN& -&lK`*aakJ6911iBhfq'XRC2Fk8d0m$k)irZ)J-X4frBe[)&*hp194CE-fa"prTlL -l)6N9DlM@!A+-c`E'Eh[J$#LkGldm($HT3ZY`BNAYCKaGL1Y$PM$)h(ekrZ&K@j8 -U$UAQZ(eYKmq!b&%fClG[hj0Re)[+qH59(B'GMkLX8"+[BbqI8@@U%+Ki90mj!U2 -`64YZcbkiKp##SRTP0#"0afGb4'!K6$`G)1S#A8B'hH@)eQYd$Yhq'%`p(3[@K'2 -@0H&ZpiVH#UArI"BL0fPBP-d@6'5bi(qeB"D'"pcV6YIRR!15Z'Y2(MZ$bI&chcp -h'T0")U9MXX`AHJA'#HVCrheFTmQUGdiFab5jlf42p6ZB@'TVD8$bH-l*@TS-9Q0 -'%bAq!A'QM5#)3a((@I8+R+"e1ml'6`1mM`6'h$&6Jq1hPbNbh`eL9N2b48bTf1F -J3mH+3)`N1m)0)Y!1k2P,J0+rrVEc@h9QaeK4FEM--EDa1'c#Tb&FL+B'Q'`SGb' -1YB@!$U%%S5ff8M+J+l0NXUq04IPHiX-"MNCAR`hkBVLLh$%fAk5)qUXN-ULb%A0 -hF9Je69qJI#XHriDH`XX&M-bahC'de(8`@@Ed+!Y#Ma5K"m#kh4LH,9'aYSb@j[M -83B#6!jp%E54c6$,Bj$Bb4XP4[5'CqQ`36UeHKBFXDhe9,m+`rAFFM3d[jd!%*F4 -J+MD2QEjTlB#M[8*mBZ()8d0ZdrL3!0XKZjm2)C*lb!CfLS!@E-ELB#Fi9`&YJ6" -`1J-$#Q8MK-N!`MafY6[Z[eS1H*)'k)H*(&!-j()mqCKUXja4K`!@eeQ6[XKih"d -I6q"k0ldHDB8KdLFMG)5080UHae[B9$FI9$Eq*BB@dT!!bkrb!-Q#!bcF5+mBI9Y -99VT$LJe$kLiB8UL+HH!KCVPZI,2d!L2N"8KB%85jTK$*X!kH!Xi`)1#LZLJLBFB -J3*-lBPUPNXLS+L`Q-GcIr"1)0c)bL!`Za9&cm+!#T(bBM$UDafR*PK[eS[!)43F -kLf')RJUA,4JlJ8`hFc3F-aAINqGHB6)&aXEV0-m)KKGf**MiH5X5k3[RG$BUN!! -L($$$Rm[11K"Pib5"-NR#%&J,FDR3ILX)!3llh(iL"r6a"L65EM(8aN1c1a)B9QC -IM@(GpXriiS0)#Mrl-9hq-CYIM10bGQJI%4hS@"cr0"pEl$R@G2FfQf1lSke3j+N -YC"khQSLU)%PmaQ,JlAJ,q(fILmd*jCE`66iLNcM)`"F,*X,'CrcU,MJML1#3!(d -JX"@,BlS0$(Fb`bBq`N(%%5`fTLd@)[k-@5ccX#JGT'9[S8ZVqG*RI+5AZHXZ&20 -fKSrHVH'@#iB[C(,2A!VJ8(b1fq-jmc8%iNA1C@(G`S(!b"6D,4B*-Mh-#FN*8"H -6f'R4Up*Gp(SL!L#Dc3BLAL()S0fD%cV(@%c90P*QpFX"kA#VGCpd3M@e4cVFBV* -R'NK[GaC4P-FqCa'K,Ccb,,TL0liL4iG)N!"qePMNFa"KJVT6XaZ,B&D8F[6Drak -Nk5QlT!1hG@6N#),+E4MF`i2ADC%R-K,+(XHV&fNi(B#KUp!!4[3lahGe`&%E(GJ -mI`J%i1Eh'iXFA5LAi[E&[NkqJZf%mi)&$8AZ3Ud4l&3eJ"eI["(%am-rYEQG-9U -+"0F-AR!pQF@`8`cTI-38*+c5)'&p*)99B4E#FNL"Y(k%K%bH*KiNreNiI@Z-`UN -i!pCllErbGAX'-L$IYi'%jMXD,+bTlEMX5dpB%qr$Ueb[X+CL!jm0K0a2YbqHU@Z -$a91a2eJmdN'0&edj@f3b8m@l-0j)%GJi1A6`f,QH(%@QLa9cb$%G"0F0J,IX0$N -CEL-(`jCPPNG4I#YeZh9Qqh#B50(plF-8fB'NaPa%04pdJH(bVST9E9d9kdmRV9f -+#(YVVH3m'-R5LMNbBL6CC&Aqr("!@lTiKF4,-SF6h+D`Sa`HSDh,[[KddZdC#,+ -"fq`A3meLk!($8&Hk3rH)S6E[8*K`"E!NKf8CQ#Zf2)V,hCJ@PQr)f&'9dEE"heZ -9F6TT5NKRJ,)S!6MH4@3#!%L&BJT$(!LNh0&&eq5,ikI1R43[#Ud8cCI#a`((LNP -YSr2j5!)1SeMDQ9'2+)JiLU1B"3*e0dU"`PNpNCMQG6kV&rQkCD-NP*5C!'UBC"- -'l0H,k#)Rh!pQI*m0f6cNIJkLBQh`YkVd)Xp&(%R"$d-fEp3!Ha-pFlq*R'TT*+4 -U-N3``aJ#6DFf$DZfc&r0cjM#8@S3V,U'Jl'6XLqp4F8`kF3%KK$ZcT!!D8B8a0N -dMIaA1jm68`E(QSjL&`%'b2+'9A(RJ3J4FNmGKj!!$kJkAIN#cMJC#a#TF&NdF+6 -lb(#b22FI[K0ifqebEQj,2I#Hh6kSpKef8E#NUC2eK6`jHL)@13aRNLV`GQ!c`)3 -E"DPa)3'GQ4EDY2*TBUABkBPdL4#!3PP[-4P$4J)@ZNLU#"C%fEaMa"R2Y-$XXCM -!0VciTRKKNbpmUd**PbGUbY6IrS)@N@%*G`cj6P8IPjllerGE5iLF&,DPkXKBjY, -9HFR0#Nj0fIXp[V0hPhRddSk"R3@E"r*c0qm)X!NaEh+bqZ`jXFR5l@hbU0KN0(I -RD1E[4JY'Rp'fSH9C+&N[*fPL%Z2*'ERmN!##NJUEH&8SAK@)"Mp&r42T'Y(MCa3 -5d`miTEQ"FSbZ8XZ3!*3T$kAT2k*NSr0a+Yj%8JE&hq$1hN"QaQJJ3kPpaEdjp5G -lk[9MTbTpCm1[j*cXJF@dI[,FIQ+cU@-hPX[C8Z`3%33[AZ@1@jjalUD)DH@SJj! -!#DKlNcI-pr25AU1L%LBT&5-c$Lk&L@i&3!k)bRk$"(1f)*PUEi'(UX63%SU`f43 -P!M4Y+,HEF!RLfVajCb$6[k1A-crlP)lGf,B`D0Xj[1d'1Zib4@mmbd"G+fmp3GY -k8j([%`&3cD(*NmMZ94a"&E'hA-SE3D6%D'J"M0J[A4e&XZ"LdZdNdpkQI9KXZ9` -kHA0Xq6C&'S3FV3p[+VU8&kfc[`hca'3iIM'jj4R9AFIJ`+epP*@r0C!![`X)Xc0 -h"l1qa2c(h3bDDXcVdSZC3+6mN`U%VT9"a'aAD-+f&`+TrREcEY0ZApf9*&dKe*! -!JcE'j+#QfdPXTBJ8#5AE*iA[Y8kL+amr3d@ZQLdB3T%l*E0hY%$$AhD3!-k)8dJ -,+j,'$L*k`c65Ab*"+,N8H)!!)Ap[IX(!cQFm5lVGr-FNQFqR5&4pld*8HcU'+'r -UJ$PC[BmflA#BUa85DL3ZY`YNd6L4XUJBA,FB39*Q#D03l*2$m!+QC5Y#QiSJ5NI -Z6de4BU%+D2SDRHj(R*5"II[RL&ENimRak8A&ASmFFRH$#1)RciG!ZFVk*VrBBph -m[DZ4[1UdEVjdM68H,Lah[2&hma26iM@([8%Abq$8e@4$BM3[LHB8E*J+DCKP3"[ -iaF!R20$bS60fG4p-KRUS5*KB@&G%cSqYEk*![F%bB%R$`,cZ0,P9f-Q"fZfpJJ9 -rMQZhl#Z5M@3Je`YcBIe(cXHad6@Q0%TLiX!'X'!+(q4JAi)!Rd`"AUGmZYa5'*V -3CU[h&I%fkf!QL'hN&Vb!%AL9pIE2i9AJD)E%K%([)RX!iSh-)-3lQM5Pq@*e-)# -Fq!Q@B',Nk*BE&`l@&E&Shk4)P4Y"S1TrKK43Q"B,*!(`Z`C)mXb1JKf"dGbDZ%, -"Y3,)8U`jT,qSV)H8AiVH0l3PdlkLrad#R4J3@`'3!'Pq(5)Mp&cri!K8,fKCecH -*d*4Q1D4LNT&[5NC-+$#L@SDfPM)Jj"Bl"mlAB%&aBJ@CS6-856mcA)E,QhF-M1l -+cD"V"D1r`p@bcTf92I8jPI8pZKp)ACp6AhQXrKa[D#*J2*S*%dlmf0`QLVk&)`6 -(&L+NfG`45k8hQ6("[b2`ZicmJ8bD'"JLC)9Ki9@8kB(SSVbChpZpjKfpMq`Xb0b -j@ASh',dP9*E-k&-@3[A#$EMq4Pj1I!&0VZj*IKClijTViTb"+IFK'X)(C!Q2$[2 -EZkSj+&05K(#`)i1m(S,X4RD4jrAdE`rN"hThH"Q3!!X15m3!J&(i&$+*3X&dSDD --iIA!MY`GSjP"&c[)+@b+J[a5(KH)$QZe+JL6N9Y"mfS,1JK8[kY%@hKZ2MBBb2I -[+1#&,cErm9T#'pXq-#"4je+H0Hd0bUJP#U9-L)lfa5rqJVdHLK3fRi-C(E+93L4 -LdZ"Tr-iL5N!Xq@5S#+$Bqp),KAl9$N(Nr'M"QlaGT5R0%k!TYpXb!$'q',aG"aF -8mP-`ErR4KL,MD`!"THNG2h'k22lhXih(Jeh(A`fSJQrZ3"&q5+8jGdI'l0H(Bhm -a&Sk,J$Q*J)'b#p0b6F"8B&Yf2,1c3(UV#Ji1C0N6fkR)eiU0TLNIPpLR8V'SSG0 -NA0a4X*Q[0C(6*rD-PVUQaBFHJ,&CP-$%N!"GMiD8Di`h,CE&AG1IX(PfAG%EHH4 -3c!UJJl0)bCk2-d3BX(&f5ijh%,R@Y*K!6FXBN@R-H4e+,b,5fj`k(S`$hlMD1[P -lea$BI5NS#dE323AK),&%4b%#S+"jM9GBH$dCM%(`!6mGdUUl5Vb[GBI2`a)+P3m -lB*kmhP4D&)Ud6cSPAah(Udekf[NS&TY"aHl)8QBLcrSSXcqbiG(U&!mpiBiIHN$ -[V)Tf5)1fQ,D%MC(Q0ESM(#%&,d*)G55J[TXKr-8i)&)(3`B%@4Db*#eVl%6"beP -M"K9J5[2+SZ"%3P3[qZ9)hD$VajE`TLrLZPKZ'4r!jRR-"#)-EEkk)XHEY%KICdF -RA34"Xdd#KhVdSX,"a9UKLB0"*&VU2GJm#J-5N486)-,(Ab6"3IJ-MUhN)2KF(La -!R9mM+dE@$l4bi,#cHk*C44Lf,jJjU8J(8@DIe0(V26biP*dpVj4-'TH')6S2HEl -Q%X8faA9&(BkLQ)QZILABU@0@,TE5!I'k0*f#l8d10TM-DU)3!TMY&B!'YKJP))f -K@I`NZ!b6+@m$4I3%STY8"aYK%NMV49[UhV0@%b`9%krhj[[2JfDjXq#Cr&dC(T' -5KqU%mCE*mSaq*i%*2TIe8FT@I,Ted[GS8Ya"!"H-`rjdHJ3+Z,jhC!'rB24raKG -`lIM4cm@!5iH+5)"J-HCPKB1kV2f-LPqLlIH-Q%PYcS,(2U(0U6K`($5CVpj`K$H -0E"Ub2i0YNE#A@c&*e%8'fF&EbXCC%i!#5aL3!%"8#M+3!(ZT)a-85@UihYX3TiC -jhSB%0E4i'b,8X*ShKpSS1%0EXQc#dL0-0)YZi8!U0J65flX+r+1pMq`Sb!LFei4 -j,3R64%5KG)5C(5c-9D9#Q0P"`YbX#A19V93+-e9$Q+RY#M0&`T`A,-`"Z4%R)Li -8T@JmT'kEd"%M-3+p"VcSj4fmK3(ciZ9H`(c#`'KQ"RbUN!##9YL6',MSY""DMCN -HX)afGbiBUac@1NY(K`$dAdbLSE2pQGS!R+#0Q9jf`bc6@B4)NT2e5K9LmRrJj$! -@!Eba+FT$$S5f-m4Ce&j#a3qF!6lMrPaZr6eCE"1JPDGjJpGfCS+SXJ2&I(l"T9% -"NU1S6U5%fJX(C5mFH1A@Y4aiHj!!mG1NM!-2@I3YP44i#bDAH)[bBXTX1MKK3m3 -LC+jcC-BK[(HH&h9HNpREldEpAX%eDHM$bMG3[294`Q$N6XiXLM[Z40(44q),,TS -%Spf#84Z+U6i$H&&Y'6LUQ,%d8GLqD#haA@)`E!`49@8EaVj(bB)'DNSK)Dqqj%, -543481T*H#)p9hSdPik8%iJDbF0f9aZJ$ch*[e,e'*$%+V32""Df[8f5BV$a2*X2 -VLU4B2-J%XIaIL%A)C1H16#mFLq"CL53mE@+#Sm8-ME5*52E6!,CeqDU$$2%mbF! -dC1R8K1ceB4c9k8RF1U6iFC!!pi68lYr"mFhCbM!G*4!"@D`V5N55Bk(+(TR"ckf -'m'Ja3j3Y5d!Up'4VUH[(eV8q&-"4&3@K%!-i-fEM'K#4@N[VS0),@h@'8UfPK"+ -(&'dZ`Ap6RS'Fd5[)'4T#bN3ZEB@NN!$F5S**hUfi@)ReFk+63'""b1Me%$+d!YY -"M'1IC5Ldpea3D-0i5FrS5!N3V!)X&fS,3A+hQ)T(&&LG%'H4JAP2`B)M"Hp'%-' -kPTa4%3"JGpB9Z@h5kk`,86&*@r9lNXS#c*0FD`Q-3LLN41$5Y-1N*I#aL"JRbNX -TQHq@`)E"Z2&IEJP1rJ13!%JR5FF(G1-!&ar3h@&#C!(p&"S1XUNpiU!bpakCT+` -j$'$d!4VJ68VqkmlHED3NaE%1(*[&acSk6"j%5BLM61jZ54#6frmqQaSe-B--Pdl -kF,XEhlQ0MEZ-'`2BZ#$Y+,DeHEDeXC!!8N`'542E&STYE8@mlDp0e+L"qd!+!Hf -,cBSp!LpQ&Vd!P0cBT'*Lib`Km1+D`h")%`h`!UK[NF!&I#S1kX4"EAa3*apN2-5 -KfX3KaHiD`+!mi0qHTTG"J'K01'cV$YUhrB0@IK"md+ZHKAM"2C(-AKSZjQ051)D -b!T[BfZ%Ze**35aC3Jr4)NhEfFQT*E'$bH#06Kj&&425,M6U&0c+`9r%D[I"QQDr -[l!h+-EG+"&RE&m%2#i0&X*B2Z5$hhlV$1VGrf')pq,$A@GcHmPFiSA&#TBD$M2d -TJAPD$DZMLS$S8kHcN!$3G-682jp)`E&iEb$EA3@5IBbM-QBG,iHT4T`!YZ[fGdE -Kd-0"6XScXM0kMpVGcX#83(E'faQpEKU@i''G2+a31MfrP(f*"UCSi+@h,rA5J5* -LB`TP6AUf-mhVH*!!f0cM($+`1D`3L4+"fVZB0"#[9UQRpS&G8eU%$BZCbAmqJC' -DXbY3p!U6@FR5C%0b)*Q42*%-*5mQ*b4A*eZ6(b6R*kFRCbIA*I[LYRKa[$aq)'k -*qq1Ia+[M4q1$m3IM6m8Aa22Ldq1ciq[LI3PE)LY4QQK)$#3b%Vj%6f*DBQeL6U) -pF8eL9Q*ZBQ8N(M&&4L)()J14M)J[dK1C&PNDH6EbEQ4HC&(N[XLUb)Ud90Uq0&G -DBjSjl9,DmE5FY'MDDfP2Th@PjD906lXjE88X&5Z,Z@+0XFfa5l%cXD1a#E&RBqf -aDf+cBR0M+hI(GRIZ(YRYh,eTGqlZ&hHIfAekGrEZCE[(GbrBREIlUYfhlEjppiT -82&@BfTFU6ae-E8TC8jG5*cVle0rK*c[M*EIDl42G5GbY%YdhZ@X9hEHi1b5kMh1 -h6R3Ij+iZZNpcYeYdImRGL1L18cHf3R6RF(H9k$l&hAY&p`RZ,K6GIqIZ$D,l)AI -E4EHCZh0%Yj@lDd@hKEZ64IFplJk,lNcZIL@klh,hXZKfFEG!G0rRlTMSIXVGJk, -l@qkfLHi#lTD*lQIF6BRZ"p40Ua$Grm(GpD)lMlZhLZirFAH@k2irlPiMZKZiqaQ -QFr%6*D&HSLB5!!eUj`&V4CG&R$CCG&QSDF1Lbf*-qmU`e4cHUNS-N!!-D`M`Bqi -1LCFXS,3kdH8J502&9YQHV3V&!"C%QK*G$U,)%M(m,@d*NGRLU-NmB,VSVZ(ZI$& -m%$r2m[!&BMX1MXK6KZfHiJ(,$%hrcNe4FB@4+C)MZK`3NH1'!kEam)#KkA&Z'M- -d[FT0*)#r*q(a*VTK`(Xm3"-!Sf&%%`!(GS)%F*8Q[-60BVQIFrFqdIf#Zi[%aAr -NlMc4CBq9H&Gd'Ad6caTB@%dX*#CJqJ2m,1-"&`e#'H3"eBBVNlRT4E%PHjC%VZJ -b%LBf'C!!jA-HINJ-B)qGf#-BCi%N6+,l%RIMS[YrU4YILHPh0-ELYiMZSpbGB6M -Q86SQrJ0$deTZ-RU!TlPTMU(T2lKTUD&T$6GG0$6p*cG9#lEq&arpL4M`VrLC`J0 -ba3!@IRb6B*3$*Zi8`im3d[0`%X#r%2TV5"eh')lm*fT+9KLDjR(6+R'0![-)0pe -RD'*d6-ihA2XP0fNHJ&P22Q8B`%'IA'CSBLq6M"UDfVQT8La['QrL&YdTh!f)lK( -ZEKEGYlRE+,U$h(@*lZ[Fh5HkVh(A)EU[8PFeLHi%lLiAA3jfCSfkDlPl[a$"%b4 -mBPCT'5#MM2T-G&Gcph24r60heiMZIh)AUR$8I*&4A-(NIiSX*L3k9&`G&m+NM,j -+[+#-*eGdD+XadD%M$iJ,K!JZmH)rd-N5(@,%*$T8M%Bk[a0i+I#f%85T99pc-fJ -$93P')hMKb$VP*)IbdN`NlP14Lq6NNS'CDlMaVK2)Y$a1b,0J5C14U%`m&AP4rL9 -Zi%PjK%`j5e@5Vilce5)SiT[KZIU"HPDCP9pG"5fK9kP,UNHG8408LhS+h42U'MK -01)VT9DT56BC$p89U!cV,9$XhAUA@P!fTAj+3!$'CJmNd6*j`(mAR+AF22Tql+r& -TGCr"TpPp!Trhh*IaHGGp#Cp2hAjm2R0EmINIlXhir$rh*R`fZ"[`bA-Ia1GUpb& -mVR'Air1hEKfI4Hjpq&c[lX5Rcef)cf*h#TqIZ'&CEB*6dE3F`k)Pk,IaK)Ul2+$ -IjmPC!2(HaC)(BDUp0(QE@T1m2RPIFQ9bER*9FPemMaU2aj)9FAJbe4VINe`+)0! -4leEYm6hS4P@HqJ+LQ+&QUGR*0@U9@Ub@!ja-*BZKjdK2ZM$)Q4`$B'P19LApb5q -5imNc56F!c'(Hi!B`#k2[j'T-MT!!4m9N'LBN42)b*-4X6%L-Nc$*`@3b*PpKmLB -Q*-C"6&l%j#hbU*K-`B6%q$BQ&NbJeM#j(j2A-5%a[SC*+5D[BM+#b9,bU*JmMNN -h*XX`X@(b+#Ca60BL-#X`qEqB,-(N36**`q4IbD0LXJD6Hc'"QNme(C29Q&b2bCr -*Sf,b0#Ec-2N26"CJmL`Q,CMm'*-jQ(b)#3QJ#a-5`2X#L@i35252M%6rNj&S)52 -4If-NZSq4D!BMd4mBL@jK*2SM)p%U4U)r-4,GcNMdhaQ*eM-5hF4)Y)k4k&mBLAl -25,5%NHMAM%3V054+e%NNB[6je"Fc$DPrNmEUL8i$HLd,&j*+"Him&!BK!*YFa4[ -q2@ri)fh$q+f'$CIaK[2PK[(jKJdRKdH`SCNl0h+R$6rPq+R$$jacKA@h%aZ[i#9 -pMCId3ej5"5pT+LpT)V23a#cB25aF0V$3c#cm&m'#aI!UbUrq5Eabm@I%N!!C`G! -`ELSMpB)*ETJ,KeAM8+'0$Alb0Qm8Ka1c"#dKqLJF1*GQ8U8STHITdjMTr@6XSNp -aT[GMTLDeP$Y1qUJ*G%h0I5c+JqXHLr,,P2b`N!#Z*h9d0%hX#4rRb@`dCI2&Tq3 -&PBhV`eS(Vh)ILrj&0*c$'rcAm'QH&)IVm'Sr"QfLKV[q3%D9C*B+%Bi,C2jhJF` -Y!TPR#Q4Z&mLm3#$cE`8bIb#3!2Pr-6*r`FJmMj(jlaLC[m2)r!0'jQm`-XpLC,k -(NANk)r22'CR[Cf6q&52c2h$3hmY"IaX(rArPS*r036qAJrjR(23hLk!ri3QXIr( -jD`D9ib@PhTd@2X36U%kKb42r',E4C-iiSY#,XG9bh[`A[2QY[2P2aHBa9U0N9(6 -5a`lUq`6KJ946l'&P(`kI3aK,NB-)TeICa-6*QYU%rUpJ6VpQbeF`V5FRqh0dkjc -GM44YI"[8(@hHAkU!U(#Z[SQ0Z+2FU@26b#JFqkq"X[@RSHS6jZ-6*m1!l(05I"e -ApKCfN!#rJ,S4aDEbNmIM['dfL"Q9jVe0FGr41pi!ap8e4FKaim698,eB0h&1aT' -Hkrl3c)lb2GZ')e"98!H(Nj1PGc([$8G1AqAHpe$Pa#lPP-ER%cpJTVXQ,L!K8Z( -[8Fa3d@%Ecd)dAX95Q,A#fDL[XK`#["@4#Ch5R*JFP)1!mR%V&+1j5FPpkYp(fXc -Z&%erLDPZ05V0%1CRVAKKJm0UNqAE6#L#BepfD'8c$MIrX6$9L8!MJpV`L4'Ka#) -,*CmldMfI&2,"D9&Lj,TVSVlPa6&h,(25!pP9+P580mQh%LqG-$'0kj'I$!j'pBK -jc$+'b8lAcKppjlF,MhIUmi2r2PeB[ai%lj!!YQapk*4"K4M-pb[-HA"J"U-bUM* -(8pAPA4J-El2$"f"UQphm%XacXr&c"6p`I0rFaXS)8P*P3h1@YArQpGLUYRf$ILC -TJk+jQHe`9)5VJkdr`T9"0'`)mi"a-[6GJ&G3lpfr!'TDqLcplDq(9&@q3D6p'-* -#l9p"al1*lckYZJ[DKThCh2mN1EQC3BB"AY8iLjfX--*8E5DQ`SHXrHh[qmV*F@( -lql[)E$K+$JqKZ+2bH$dlMUjYIaq1"EYEcMQ,2#Tj+QQVVbeQTq01hUL80J*"X2q -1Yb%'BA"k'cZd@-b1,[VF1MQ0*j96&%R%N8Nc&aI6d!#'FR8$(j*clLLFlN+TRRI -JFJc8bFQUakRSc-8ZU3$!pbkcYNNbe(b#SPE)-5aI-MJZeEEcAZ@JLF+BX+QjAK0 -V4m)Mf)8Xf&RpCp6p@-!C03-EZ03-r0b2ReRi@HJ9p#Q6['KI6"GK4$1,f4UJCN6 -chQE1fkLdDi+jiNBbf*8$EYA)Mb5%X)NC5c3ISpH(Hp@Y(T9Z0dX'b32HdkVQ3qK -2YTjJY#[ZVleKf(lcPYSEVV$brGYEpP%9B#eI`SN,)iZe95fU,4iaPcq[&Mf)bpD -ADU8b%MJhZ0k(J)(4dBhlS)U4[2hbjPGjfaK[pH8f'&K8Ji',c-#dZmr!0fk4$*K -@h`%$keQeNb4!plF[`mpV3,VAb*%c(3,Ma)@Na0Xcb"[ikl9"@a@J$4F'+(X`FDJ -Ki$1qQ`'061%er#cc+NEb%Y2YF6K[hb"I0+e(P#i("5+*Rj)$RTp1T'kS%ESNKGL -dT(NTI63cC1RJi'rpTL+3!-'9ZU9'i'8hV8IJ$6BY*l--#VbQp5eINKH9faCfS8U -XTJGK3JceFcq(HSab8VHNX8!4YY05pYQYrk1K+(b'$2q&`SV,Zr,KF'1+fGmkSD' -)R@RcKGB*cL)5"+Y@DAK`-iS8[-TdUDI5(e3j@fkM[F4bLrhjJM8I,9KlC8#F*B3 -iQL%r'E"P+6(XZ"5CDjbL%,"&Qa$C1KECZQ#4r@#2%0PdLSjZ*E8QfDhRDSM[YDC -9%0qbT[9NU-cL@q84(iki+`5Ph"80D5c%(4SEY-4C%'Q!R*!!0HeAUp&Ch@Zi9Z8 -0J,[UIL'91#jZGKQD'pQB[3Q!",pXI8*F$4L%FP`+K4cGXf$@YAa*KPC8eCLQ'%Z -)K`!QA)*TZ4iDJj%$1J"Di+`HbZGM0ek"$3KPi($'j&ML&4QTrkJTY2Qh3c')&0Q -kEBKX,BYX$BYX53f4d4'EdK'C[Pf4dE9bd8&QFQII"5*$Xb15MXMSUQi3Q9j$C%Y -BC1Z-)P1-6-)Kl-+(cb"a(M%8cGN`SUd-lf1Ji8[q&0'RB0kh#iY8FjBl*KX*G0f -'J&EEPd0!cl,*a3V16*Hhm&Dd2E+AiZCK#@l`J#m"C%fR9f$Ie%aUM2TDchN8H3+ --NmFlZS6AM*!!@P4cP$1HX@5Ff4P"*Q2KkF1D%N%@N@$35UDmV0kK[3Z'b[hYA6, -Vii)hQjD#SMp146r-GpMXPbXVT1EGe1`Zpc5NZ+(-`l$,EI0fU*!!pM![Lp&#"") --N@h2NUUkq'NK-#Jc&5qk)DTU91,5Id-e-YMq'd,Na+L$c"(R%K$!*KJQjFhqEqI -XIjf@rAZbmcfR+R%mP%cBjj*b,N4liSSK1lmA3de'-%5!-#Nj[%-khlXGcG0V$Ud -"p0",&`b&2r4H-`!Qqc8fDM$!KfNAdYdbKD6&BJXj1+8Lpd`bMS6PKLeA#R6l#[k -Xj-m5##qRTC0%f2T,0LL9"`@,`e30i5DYlKHPYdK'j"@K(V0CBd#+R8'ZkF%JPa# -CSN`&kKCL5I8F2KK1"mmKmE$RkR`1`AG$L+VJ#B`p0kB0)'8cNNAMXGcda2DC"[P -Smfr-AXM!(RY*I2Dd(Y1m[9HeX%R9ZKJp4d3&Mc2E(k`[)q3%LMYDcXRQbp'pBqd -2HT)p`k3q8&0`DFmMiU[HhliDe5+NN!!3ba0EGGRckP8L4Yfp*HfVq4LAjjKRkeA -mpR32!YNV2UZQpiLY0!U`%3+K+Kf$[!Q$bL63jmiNe3h9*&lf++[BSka2ak1!&+* -j+e&Kf#S$8"65UMT)ea[GIiIHL$G%mm+YmNBUH8JlF"XHKMG-rl*D,MaKM898+h@ -9c$#5KFD!JCD1"HIc@fH3!,UeeU22p3Tdr6m5`%YfcaV,@6kpGrVBFk0iKH$QcCN -jCe)JiX),%*&%SQU)C$ie5T58bdVDq+J912Mlq2Q4GU3j,a#&iQ8S&eHT`k2*EQ, -e%mlDRaa,&NUP3QUHPM&Sl"L53eU`1@$m[jb5D[D9r&*kS)4JHri&E#m-CK'S&3* -$bJ$LGSE($[HLhQFcCd9l121jK6mhmfFZYVQYjCZ88B[XD)iRiiVabmiJYDkb)#, -eac'CK4Q9a8U3!#Kbe*Z8fjUNahqTPS""a'*3R,d!"I#iI6D+PDG3h9VY$CrEld@ -RaAiV*G*CK8RR,rIX0EG[!*'*Zrr1A8lbiJ$m,-,23[c-`Xrpq)(D1B$**Rb1idH -(Yia`m6e#$YA9Y1B08+Q2k`qENcCpTq9-XY[5QLaN)S+9b!mJJMU)h)$XS)A3$j0 -"*LkS4$GYN8bMC,2GhR`&Vl,j5U'Al)"XB6f@-FCU$rXSqi)M5VX[*-dVpa#JPih -%#9!**XePP#e39CEQ2&4G9!%eeY'e4qC1ff+a0fhkiXi@5Pl6"3b&ZI-"&l**+-H -Q5R,09b-,@q!N,jDhp-M5D4jPi&hf"3$AqM,bGq9V@a`N4UlZ@6ppfS*SGCRf)SC -+IQJS5'#G%Q5Ka$NjpS0kc)mi'abLM&aQE2%X!AK-4q,JYfCr%5[G3kEN*dH+c4N -34C5'@-,1S85NjBbcL*hkNjRkE-i1iae$NB*),Mkj%93(mY'Yb%+r)+![E%&&([- -3T*ma%d0-#*Z&R`fN+J!+e%8c9mE@hriC0lp'(dR3bB,+1Qc4MLhDaH$Vm"UUX1a -Ii'H4Ci[VX-82d'RRjYGNT3l*"h(a#L165mdqI19['j)4rX31`r&V-TA"5532-Me -&#"@b`kQ['cmHa"Xa-e!kRl*$!&EhDeNmN@4S)dA)r,khQ&"A89%C'"-JS@*!Me4 -PIb""ahM2YN&(H%S8B#bk1M4FB8*9#AXp,-&(`1k9jMF%F$eE*ViqDS0Ul'*Y8&J -1UY+@l3'$hlAR`HZefqH$P9XB$-k6B($cPjk%hLfLD53)H+f3!!JNLCMNp*A9KEr -Z8HTGic@")L*J@"8h%,"1A(SYR8X93NRh%UQN@mYdf&-H0B,eL-T)SE$p6#CN`hY -!VTJMP#TI*Lp+$DdrI3i*L4XqZjc[@IJ($2l2Za$mTdX#p)p*d*qfU!(bLd59TTk -CVK0k'Y5I-k*qdbF60kb-0-C,M$#"4EZf3MJ6a6AfIL!,XcS'N!$k!(`8Y[4!HB% -I`UU3!0kqA-N-CZP,`@VlTlqd-GRk+!P9$R4T!l0V$-c'`-G&SPfbY*c89QL9%!c -VPNc+rU8UAc@[F3-l19S1BGYDci'%[p)LQ9lC5L$)mYCc@kJ`@db9H909hMKfjDb -[9#GP-UJZ!)4r5NDHcfpjRXQi2PEXZeJ2!%e(Z$KUJI2Nc95K1Mc*A5hNK,e4G+r -PVNX2S-Vc-Yd2%Sp1VbaKHZ',@c+p5QbVi`fSDU2$eV+AM['YGND-+LL#*e6"Q)b -F1+e)h6a()Yf+#+A6q-P"0i#*AN)48Tmp"U8&!(jZTB04HIG(V9!M#U8A+VN3&C( -%2lf*LSeNRN"$SDUH(&2Zc'0(M51RNj5F5MjV',j-$SHKm[@me63AUD[2*ZFSY!8 -TCda#aBBTXP0Q"RAK3NrR)f`3N!!9IT!!CqDTV'##R2-[j`SQm))UQ*!!LZli#"* -EUD*%E&rcSIe&T&i#eI&%II[1mi[Q,A!QYj`U,L1RTf88l1[)`dQ'e9b*pU()&e' -I%`EdP,hLd3#qGCR"&lRaUZD(,#Mmm'0"S)ke`JPQdb$869D'%VKf"YeTL!LbLF6 -ZrqC%kQ,DJ&A`9h[8lGTm$Ib5`#Fi1QiqBhLeKb[XApRmSPj%6GrH"e8c,!Uj9"a -5KZ8HC19r+(Km"-bhk5@mM#`TG&36dN*1Ll3!@Mk0!XMNLDl4(6XV9-b9BDJ@D)* --hP[r5UNRIqpVfj9298QpF!@)@5`lVc551L"lNbre3"m1aM#2+K'q&,D*JD3b880 -%003k%3@%K,M5mC19VN%iKP81)F[2FTFC"[)JIVNQ@*@kCpY#3PIUjM`&%N#M*I" -e+SaLr%PC%'5@dL4qi[K*i#H#Rc5ET59'2i82%6VG$'F)b5-39LM1R`KrIRSeIIk -42[%@3$Ir,#G0GMQCD#I(#c89[&r)9Xmif#+&YPmTUK!r3Tl+fS)NH3cHa$6qX#I -DN5)+T&2X1%FBK8#iP%jfBT)8%YP0Pa(aCb2&J93PpLP@[H)Gb-*%C6ERG+(LCL8 -lY"P@!j5T1BG-0V'&3a0VlD@UI!,)b6-B5-43e8m"fRdp,F5$"(&5GU-0DeVV-I- -"Q&HG3G93R#U`3K@h$mTJS!)#JJY[JZ1RY8JN32&AdeU+NQ4P'qh`(R(lr#d"H`Z -L(GG+&HQqlSH)0"kRS52@bfp"KAZG%95(JbHISI1DJCbpED5D0c&U'%J0HF%0631 -'"X2&TT!!0c+B"2#15aE"j'(j--hC3h'(9,&1&h8DHXl2)ZlQS5DUJJe)%+&'QE9 -iSihYV9"1k$,lm@Nc`cQa[C85$XfhLfM59NElqd1FN5YejqCk(qS$k#Ni@9X[(4@ -C@"d2950L#AbCUH*I[J-[Q3$+4r#6p[9h9#iL[i"Uq1P%`-6$*dMj%rkq,C&aGdb -JJjA8[a2Dk)m`ZNQ%@H`F5MdNKVJN!V-M@lb)A5GIb1,0JpDpB6SDe8)j8Q+*3Bm -Y!29`TY$D"RViJ%I`H"43F)K2T1dPE+,)R$jq'@U"(r'E364p"!i$(2b#+Y2JD,S -'2'#&pP!#UdY+M[@8P"`qQ2RpfK1RUR02RAVRPG"QrkjMZkU9pa%A@&R4)dLUTF, -`J'f29&QjS)fd[!L!pa'!X9$5fR*HHkb&"dY+MPqik@Q23dL6"fL3!"AF@mDJNZd -4I31TH++)AMMB(),UcC2HbUZF#GmK9XD&aj1!TmAJfXD'Gpc&3N'AD!bp%$VQMM4 -#P5FEdE(SSXmr8pq6qIec2I@eScR(cTcYU6r@mdT1I6T,PJYZJP1h,)qJi@5eXja -99IIh0UfNU[3G,e(AYdH)2J,5q%UZ9U(FRlpI3@e4"1VG2RGd%B00+hdTU1Fff5H -kbaaGa*jS5U)TXKq-XP!M[P+J$G#qD@8S#8H-Me5C1CTY-6Q,Tk+Uj89k2!dV+4' -`5LG$[V&G8[!4iB(SJ8+SfUJdcq!8Uh%SGTHGcfmMadAG(4%iZjiB8LhRpD+f+$Q -Jb1,#+lUhpe4P*H55F5Vhl)QFNcRI6`mI-Jl[U[ElMhQFi5R2`a``b!S40#(4)"G -1#Y2J&5qjc#12b'SY5F@fQaS$9&@"X9PlY*2S``LSJCb6iGVk5[DCkA%"+[&G"5G -2R`fc)L1`#q1F'Jd#,'Af3QZ49C!!ik$CF#!j,"6RI8!4jXJXPjHEA@CSVNTYMMi -Hh4a&390'cF3J&6J!(9-&5mPVSJTC*5i[34C25K8Gd[Y)96DV#dB[`Gf-F#bfHHF -S+V$+pfI!'@fQ8PRl`##@*V+Fc@G29Tm+jiH)hh1H+QZeaeNKaqCJ["0L*@9G@D' -e3l5!DqfdJ#X5I*Uk3LaJ&9@6M*r&3BYS%krk101%`hbUiU3MM5-NaC+'P$1f5FR -YqR3XD6H@e'DS[MF,#Jk`+2qZ$1Q@cQ($)[b[p!bFVDiA!XjLTVRD*@4$*13%-9N -T&1i&YLRNBU13!,e-NE,+r8,-8bH!UE3Yl$`jUd&cM[FU@1V0rjdr&kkU-k&d5h9 -I#lDS9Z$UqTlkc*1RklF6q09bkiTj[hRJ9ka),r#*VFdl-rh3Ea,BiFmp,pRDI2C -Fk05jqN"pU2VldU%ZX88XKD"K&3aGPX5GLP,"d-SfFhN`3ph8l#+!T#BcG2%V`8a -+bmEI"#1jqD1EP@dh'-JpGI*iZJGr)MIiiB,Il1!I,UPjm&XiH&F"(qfi$NI[UUc -@$SFU5"-I$N,IqT!!L4N3#2,$JeT!A-"!*c9l'6!9i9%!eZ2"$GE6SiZ)kp99qI5 -)+Kp,4U3k0c##-,J%9hkN%LZ`Ud"ehJL'-ZYc6Tq>rHNj@"9bSp"C!!([cS*'& -qF"+,mM`H55j9ZlVEhUMNijR3ik38c2Y`[1EMQAciQRJmNj43P-`+Nb2UB1*!dRa -0ql6+L%@jkl`28[,K*pS@fU1@I*JVY[!ml!b5&,bNec0b6SC'6jmm@hhb4(@p8%l -(931f[%J9PQE3Slp!)5BbhV8XTMj0+(4pV8%JSjG'GqD1@Mb10,A-'eN-1Dc2!S& -Z3pXJ+ME5eGMAbDM'pA95&9ckG9*SI!LIEP@(6kGbiP1Q$Rip3ahi1T4lU8Cm)UV -KkjPU2d#NZ"V#*i)((QN"f06#&63j#'LL`L&fVfkP5Q-pMr(6*i&m*1`253CS@2` -i`0NfHar-df*FXGl$dY6d&%bi3#,c9q8('kPj!3N`dFP-P$%6aIM%e$l,9bS,2hZ -SBX+PH)dU"dHSbX1PQCMU-(NFi`VL1T&m([Q$Q9qA+TfR1K)@%9mP!fX4&+`k*Te -DT398"41#ZJa+XcpZK'VMp)FKDX8cL!%kE&Q1JDM'SHalU&*+*kI)hhV[BjiNhr[ -B4)QCP$Jd*EE,fZkK&`a,jp!8$NeYpe#(105a9BFkYZ*3"`jeE2G3NcM8a*89hY' -K&`a,je!6$M9Yqe![+1fYpNX%4p[jQPILlhd-!N@%1j(h2KC"PpV1i*4KF%SXIeZ -$(BE"$X(fYJDE$)00hXV&l+55bG([Ce1T#'H0LbQ+SE@9`6&CmH"YB[!Y9'#h#D@ -EZ,51,beK"ERDTAAN!IYD#!@KBV5Ed$rX)15!mR`+,L*Q93LLiqdk1C41HqpM*J- -j0,CG*GaJdKV+LlJKiKNJ'e+H!58`lMeJVm#R%G%+AkN'')fJYP+kC,MDc3**UGK -l(k2UM8C2KE#hL#TFflJ+ee[#@FKBd`Jj+DU"M4e!!#82fIS%9G9KV`!aPVXbbTK -B-6"N1-BBXDa[4[,T!IE@P*Q`SYM@pE4X`q+hFCQZY$i"F1+0%Ir)@4!*(RHP1L, -F[))%C4$AGVG!jFH(QMHiLJbAYi*eU+AS&FaRD6qYhd,#H3@C*k4lj3'G!KJUG'J -`+i)5#pD5#N5iTf+GN!$T`X"c)I1'-Uh1mJ`Qk*-Li0,'Pq03@HYZ$$&4Q8bPl4A -6SpaYQR9%4%)PU"LffiNipmrfBl('8N6p4[!TTD+6)YqdBPk#0#C1RV@pJq0XBDV -qkQ'1jQ[rjFLhc@M%#jHI+M6EQ'#b$C,$b8k10Ud!`AQa[@RVQ5'ck'1a!qm43rL -8CN`*[%5Qm'T'l4`[8pkL#%cAiB&V@P5EZjb8"1IfCPL`K('U1,#Fa(-RSP,ZE&l -Q6R'5m5"ASqlC4LVqFTTbKf68(-M[4pBG)3,mp1MX)l12r&dIU@NJT86D%&651fh -G0+UQprlSl'QcThd(+LI[(q9"N@eY-phL6(SLB4*1UVicTDI%mY[-H@5ZV881N[' -eRK$4effj9iTT3Jl@4LfM@KH2Cp,R'A6KbkCBjCHll"AmkH02Ne#kAR'BUPU,'%K -P9+f3!!8&[9QBU$Z,$-3S4(TdEa49Qj+LNBdL)S4%qEA50UUbFTpZ-a)4fAKpR`! -cZYQd@I1-UB,(,aY-ZAPSYdDb%S-F"Bm($A!B&%&i5@&hMJJ3T2a(3Aq2bq"dQ&6 -4XBKTJbVb9JZT1Ac)JF,U!#@%66Gq@Jaj"Bk3!#*N+%qqh@X+6a@0e$#&jmF5)M5 -08e9"S&09"jR%!l4#m8CH"#Lf36S@D#P&j%DJ[&@0I2Z-+NFeIje-dUH([1K$X`R -0R5UL4I6HNfNSD0BaB3V99R93&2jIYEj+&BG53B$ZhhLl3YQk(FeEU*QUjl*l(VJ -*"QH1X"!H(NmJhbdF)b54N!!*+HpbM49iLq9#UBqaJQiaH(B(2p!89$`9LUedU[3 -,([e+j5[9e8JBArRGD'qQI6D4imkG$9IbSjB0%lN'$ql&a$JSHMr)a$SFLXmV)9) -E[CiULjIUlja$GhE5-&lJHLpK$K%EA@5UX8YcJY%(Y8-2BcXRJkc2dkDN3*Uk(5D -1HJ$SrqG,C'kY(Fe$5l&C1@qrXQ1S(rrNN!#BL3lL&cGlMU9UcJ9),+m)3'L8!D0 -KBKU+DiIZqTERmNVYXSG%QU%4QA8V9D&Qcf"(2c%L`L$4PF%NCC!!N39"QBR,AT) -b+YhX4@8[Kd#-lV,24h$Bh6THcpDrL$X3VGIH6eRVI,jJS`Xdh%KbKU*4"d@I&'R -%ipZ$LIh`SZ@Mp"!&UEC"FV*"R4Y[EaX8#3!E43$Bl6@6!1`aG6PB9[dM,SKS%(' -P8LD+H'#&Q-a1lrJE-ql1m6c-@Y0EkirM!I3!XZ%68l%RNGP!-I9CUY)C6DM!'Te -Z929b&Z"V'6l&U[M'XfUIfSI24qSM[-j5@ALK+afG%6@LTrlbMVL4Mm$RBI@`IL& -iM-2D(Z8%9B369,'(hU($m-&KD-*Kk1!`G-Sik9A-55mFTMm#BrqX%5Z-PE2SXG$ -Nhm%CP%9IQ"AHR58pb8Xkc-Y!CirD)`@&TR*9MSp,ZI!"q)$2)A8)RcT9Kd&19$& -e&P91(8"6JfT!ClrDMmiQ1#(l,JYCXRFMXiG2N5Tk8J[50Mb@i(DC2-a-SY1S'Se --SS0(TX"RXpU-MeQCmFP9ZAmj#'*Nq%Q0BE$k*,-DI#M!MG3&hPNI[@R@kEC"1$e -!dRhU'HQ9,ZHRRj5Aed3e"c1RZZ9PVPiCfC8r[qC3HF$I,rFFB,jE"ic*bhGi`1G -rM3-qhiS$0QN(6#cHUJ0SU%PHj!US)d485ArcUaD*cHG9c,L$c@@ah%QAC#DUCCL -FbGfNCDh'CQT#49r2UjC`mFMckR-pZE4CcAPi9-h4Gm,MlhRBV*kpJ#d3HUi+Y!h -5"i2Dm&#)RA,j&FZhab+CqQM1jLT@dAA*N!#f%A9aB+HX!!!LhmH+'&[9($(jR#B -hNL,[&TS5Jq,5Xhb*SUfMFVLCL)icqk)8,8qQ4k*a$L*DRJ9"FKm44-P3aM#B"F2 -QA(2N8B,YflAL&Y'&,@%E%Y&cI"5Pem)0RBL`IME3STlpf'qhClD`XS4a$0VRBa5 -U@%cJM&S6SNFj@dQ%(X&@RrE`!34XB41`e%JXpBP"JpCH*0mcL,6*CS3r#TZP#Rl -9LLST8iL!bHAS84L@9K5EDkH1LmKY1,qDZXB[Kk!#@6JVR%fJN!!B5XDiH`LJ%ip -')!Tf9#eaA+r2b6Q9SjqYe(F-F`6"cXV3+cfC2AKCZhmr$A%p$f-'2(A&r[he`mI -U1HEMb5GhH1Flm`dpMhShMi-b)8B#ZG)9CD0m4),b8MAR!`bUjJG4)[&b9JM4`+% --2[G!f$4jA!Tl(JZlc"046Gj@L5Tijj!!%QNBpMb)LBNHTP%HB3L'#Xh%M0A`HS1 -KBV["J'U,l#-L'!Bi'&BBJS&"D%-`["J8$#ZdB+"&h-d!1(EQC%lT)IhFfD2e*6h -2hkh!)$#AMIR*#p0$fLbP#L(`#)l,C28S8r2%JNb5ADi'#UaGF-LZFr8jaVf90!F -)-K5B1E@UR!-K6#U`8b"5SISfUP#((5SlB")X#Apdp&)SL2C'rPI`9V5&[eb&l"p -3YG%(2Zk&&p%fUL!#'aZBfYNKV,C9"@e94UK0bAUlBG0YXdI*KS4(+#P0+"8AT9! -UhK9#kI3+4G[iEJLQaR)!e!q6!Hd&akE%XBerh@-03SI"&&Id)4G[-JUH&'5baqL -X)CjK,I#&3`UBrJ8PTdhHj$4GSfcHDaT1MSRTm91-MaBKLJdAM'%LT'bCb'e%CLF -9!V,!S#1h@DJ&(5%+Z3`V(($lE*SL!TNdb'cPad4-qDKbRT3lr[JL$3@m)U%"5)" -4CIS8582&aTJ+!S*S##9`dJ@%PQL&XFVDQS)HejbipPRE))P'YiV()bUAQr`kG8I -,PmNL)9BU0RA2X6EKr0b3!#`+GXC+J-#X*4F@qI,eepB4Br+e8%'H%ZcCDQk)aKF -$8Dj!HZEL+N*2`Bl,F&`T[DKjh32)TN`rmZ(K-S-%l6Gf3e$$E5hf94JE1mJ*6lR -B'-T"[)C1A[6b2JSNADND$&kQI8ikJQ%9iTDP04R9$%-0SLK$iHhJk2@CAjZ"6P1 -0l4Z$'QBZGKX*J#6FlUAT'e*j&k"9S!AM0911hRkN2J,cLN*k**U4klTR`%#cBQ4 -8haNNZ$0HlaNF"5FIQ8*Gl"IJ"3HXKR6l3dNb,i,h&pj3H-&ZJ'm1IV#8V!ZmR6N -pY#)P&i`ifa!K!L@4"m4&KEfT5dH@4I@N85bH$VEmdb#M&"m6Har&khU`9,(L0@r -RDiZmRAql@00MhE-rb'1KB*8HkerDYqqa'"!P&E@hdbE5%a#3!!K[N8[SjN'"Q4A -q1r)F0308NR!-J'i`dVXL%4Xl#M%fbme6,pC%rUE#QNd6qbjSmT!!Aq3MaKLcmJU -hj`'!4&Bj0BXb6RVX0T8+Y%Teq@ic9qZIP&kpk6J6B"hpqBa!+IN3+16"'DMDad0 -&i`qEi$&@#3qbh#$JQcYXV)D#(Rr4)ChL0B%LV91%e)MBfL5c883TQ2KKD0'G@%F -EHK0CNJ$U*@"d2)""iaTkQpqKC*-8hX6,kD2ha!1-hYeFl1b&B%U*mEi3)lc,5-! -`C[2h,2!NZ4V[--QP%C)rTiXACVFbUp00"V0cD@j&$a,5r8(fmAKjK%LJIB[+&4i -l12,"T+Vmi`%5%N8pBN%*lh,kI)EPh#NA-r8T6l&kTabfq2U(HP@%(N[!lGF#ach -``D4M&YH&@hBDYK6LQ4V`E#Q+kFA$fTEHk#02BDNjaTkP4HH!X2LH5YA(p%FS+H4 -",L""AmU,A18fML4!mp4EA")eb[&#SJb#PK5T6beRT#X%'%9GNd526'a[TBIe(D- -U!bLMUM$VH2!$J0Z'3+kBd2CS$C3eN3F24PPMe)mZQBHhb$!@reZ4F50KXY1)%Q# -,-Z*Z+M+P9l3[$MS'%38AH2BZJ`*N498d(&@RNm2+1[R8(J2`99c`1&A3(ij2HHP -RE`Hb[jKF1eH(qCmb9V62*TiXLVfi-#qj`U83aCBU"lVjmdqNUUEFYqb$l'1,H8K -#6baGaS)VTX+fh2BJa([c5a$jR9j`6dp!P-9'aa4JNKe2i''C8k@ah$Ui"(2!#B- -*L6I(QNNN&$bN6qIa3M*ZI4#*X0bB%d6r"bIThEZL4j-rQIR"T"0lI[Bf4`alSQK -')RM`dDJV59lJf&bJR!-2#Jc$XFK`F$((4Y4`4#N$PYMfjl04[i-IB"FXc"e%CZ" -!BYa%J*iR1p%H,`J9RD[*`BHA+b6K8a*%pjPP4@kr(a1!H#8RmIS-56a1Z"Z5H&m -&*I(k2%QmK%aQMpjdVaZ9AcT4XcL%p*2QPm#XRpJVC8%jm#"Q19T5m#bPqR3IdRp -kIHAaFrSVPIA$)9KdeKmR!l5lPr`@Q4T%3Sm+!B'1FGH8qa8j&ZRJ3MJc5Sm&S@a -'dKBTR5('MXGSLXF5UG-+E[XU"NRhH-#c3c+$V,S!)%dIF**+L6KTr8934Y)PLpR -[cM&m[9-lc"K4q*GhU'&TXlCp$$df!(AcPKU6'1NeMYld+h0`FH)"K@kU@1cY6&@ -'&m[PeI[-f`6lj`4[0EABd0%0(DHKBp+LIB*%C8L@6-hE9V)NI@'aN!"Gl%$"N!" -8*)IMRN3S9B+)3Q(E'`"mL4JAb%c"!1kqmU$SSfdNNd4b-8)&@-hNB[U!hB@0p'# -cb[%(HQbr2[(+SI[[@@F2!Y,mJhG[@hViX&pGEa$&V"T*hpLf'S),j*U*V+dprUq -rd!X1TU65GT*q-)&2"@CqmCT12jk#XFM$5",'&@4JQGa2NaV-VC5Ch*G%4$m)8Q# -EMbY-"H"bN!#UZEkFMkGIIKNre1eQi,H0M)JpMNYJ#UZH%YRi)5r"4@6'Tmk9R$K -jVPlh`AB64$SLcKfVVMqCFf&'c!hDKIhlaBhJM*J6,EqU##B',0mR3FfjI9Y"#X( -59cA5*ZNPh*F(DU)iUMmkk+f!fm32p)M+8e26SUCNHLqZ-E`3'lbX)8'41+`)Q50 -&%M-aK3C&Dai,X[c"l5,T'6c3Cdf`1jFF4h,'fm1NR8-EKa"VT69#&23`NFTT(50 -eKb!ASb)S&1&aH*!!,f$)["h68M)+iJHCj!8kNc@LZca9@3Z95[4JNp-*dALa*%" -8YfC9hUbC%P0-aZi'i6V*N6Ga!QJpc0l#D&EJDIL"RUV+jfJ#fI!"%c5BF8rM!Vk -8kS3c@`!R%iJ4l@AI5Ma%bh"3%alAcZdc0M@CT"GTFV,`Z(*)cmZ[*!'PDHLbjm# -*XhQ*fT!!ERPpiK*Q)j*qSXi6H!GUJ,)3NMAk4M$)V"@k@9j5B8KG5,,a&TT6Cea -)IPQhC[[NPiTRYBa%223"-MpM0P9a-6LENJ@m9JQR4RVF0LRYlPl`),1&Nil+ZK6 -L,'F3&C&l(CcJrH(YfP5G%)5Y2I)a1VH0`YXJJ@kh)2L0"V-(GdR5PHR6KFGY)dZ -V"U[HJP,2&9$jD33284ai56IH5Q4ecq9MXBIe6aHHU$"H&)HR[*Rmh@&2'RCYZeJ -RJ'AUBJ*BqR4$afAS&"Y*Fm(NUpm)1E,NbiPMf`)9MG'H6'#D19(hHmLR%kZf48! -,CXHqG2[X""hJZZ-$f+Li8dBAFN,eNMpIU1[T%eIjSG%d%Z)f`)1DK0jda+Sj!X8 -L0!2Q2Xma)#Akmlf(H%Qe@KC3mr$d`'Q$dXDMKL8DMV&h"4fcm)+V-bFfE!mJmLc -YXGr1-K3$ICV*'%9'L%[G"T(9!(L%qVV)pMbR(*SH`0MdE2U,#aCKNlX'J#f%hc3 -rR8AlYb('`R3@@#TH(M3XX'aE!*l"NI'UE36**d&XllmMpSa"8+1J-4+P(GXR5YI --4TQ!mpL6d[L#6@e'ZMKU`26N6Lm3(A+3!'*S("58h38&fp!reb$RkUEY)mqfN8* -@lfJ`qepbSGIF&VS%"rVf[FffaHAeH2Ejk3Lkc(-9*Q$E%rA@4KBB+l5dIp&IqpX -+1)1Sr@f6+0*RrVEL5A5$2BjAV$$9L-LAV(`FTP)MhJLA@!G9hBR(NLMP"q%KNYT -)I2UNZ8FfY'HTqNJER)Q9*[@dTG-3bA+,(LmY1P38&'ee4PfLSJkJif'EqXPED($ -K%5F1Te6f%6eHBkL,KMl3T4j)8I&SQMe)eqQ"K9k1lP2T#8RV4,HFUqmjmBU[T15 -aJbmM%A(J-")3Ciq9R10SIhVcJRKeq!$&rTIdj*`mfh-1c58$rKHU$9A9Epefap, -GlKKYGdaZ"`$h6JmS-cakdme2Nk(2R`k5dI[r@K6H!r$HMdNC0D)cMSi`UV3l85c -C`JGaU42'PeBb'm5$d)eiNMYC0'`U#M)mTL+"GHK+`#jpida*R)rqMA5",KPrqDr -NNSK!YRhaR%jh16plF'ZAdc4E@ml2rMpEcVD$jl3)DX0bm1#'Fr0![Sr3a$pB06J -5'"NX$p!Mj$hq2q&mBMmH'p5"a`e'!aJ[aM!hrFGli$q%`FS'6f"Z)Kk&kZkcHdV -Ldad+2iKG2%ELA$-a3*0JGUZ-$)r)*J2,$X'bicGRqHa[`M)%r*1e8X!r@EXe![l -*rZqZJ1m@1N$!2aQ4![l*b0B+Q&Rq,JTi+eM@''kMid8d'apX!()[-0'1[Kadl0I -&XDI1hFdMjlVrqNGZ4CDM(ERjZj9j-%YrC@6TlQ6Yk6(fhFQLYiDa1rCd4&SfXh( -(dmG2PEa`pRKpTECI`l'HliIU-Eahi*M(bE08#S#&$#"#-ekH8ECA(5a1j+3Y1Q+ -0q26'[93@mk+3k3b-@-ASh,De+&lde*r$46@)a,pqY$+ra(24Fj(bI9Q3JBE# -c1aCSUrm#J@UQ%0'KF(e2pDPM[d(!p[lP(,M0CBS$"8R0)4r!V6k'i#[%if693AX -($RJ@39Kj%SD-,k36KLm)P500hLf5UMj'(AHCE2`CLZGe19Y#+F8Ul*Ud6AY19Cp -kS6iR[9fhDY2Pk@lk5LLdh8dhbNGEjFcF(S,$I$Z65ae%,VAEViPq$%GaTU3'fNH -Gf2AXZA3fP!Kef#QEL%4mS2ENZAGHU*&&MBcHp)GXGVB5SiL-l6PDq9HMVr-F48& -%$r-&MleI0cd@[HGp*'AJY1Ap"FEQmjiAlHldKRrDRIl`6r0UXV[UmYDa'rffNGq -$,jFm8epCR`1m1hEUH2fadchJ(EPV1TNf$[PMpRITN!"M`BG3iJ#223r60#3H1'' -c6I-V)T23%3pY#lZ2)C!!rEh(m2marc&$YVCG,d'hMKe,Mjh1V@,Ri@hNPPjZ0"8 -rI6+,j8I8l3Y%fFPAYh6@0hV6l6N803d@NY[hE-FmQI$f0rc[k@bBRNFlCXM8T@2 -!U!ZMDdm1Pe6A9iClcT4iFk+J)03b2UVSTTJGchG#G#C5q',@(JD,2'bV6)K(kl$ -Y(@dCk$dVC8DDS``XlFAPNp8[R2cqZC,+8hM`SY2EjFTiY4aAm5`bTilMQ3[ZB#P -N--HAqR(TPFTcCmlkHVE$keNr3MEJ0k"1X5j*&ffBC)R0$P*Q9,RGIAM&!8B8XH0 -f0R`C'jjkTHGZlUKU1K[jicVfcUDYppM2'[eecA0VL[f181L&1d)KHTcLpX(U'"a -9,RC(b!'VIZ-GSY%,fd3MYE9Sp%*00)T["4UpF2I4k)9YS*%aN!"@ADm&dYCQm0X -)T"FZb(+$5&&4[p4AppM,KjfrUqr*S9cRRA0rFlbq"l'Rj`lmMIEIK9"r[#4dmQa -1bGRDN!"faXXRU`(&R1`jP91bUlU%IJkA$*!!f!%!!#k-384$8J-!8f`293e&0!) -!BdEZ-qqG1``M)M+6%4(KS+K)T%4QC#kpp`lAe0a2CQDZPU+)BV(3K@K@TZqp-l) -I89&3dGa2CZiINTQ3"!dZPmY9CQTUVP6%IG&-cF`)aq(h[M2JZ*rqk[mljqrl2pr -CchI1!4YGJ36"%q55P0#FEhXk-A''mS$mH)a9ITaEr8RhTcYEV&NH`4&#Gh0RfhU -4ZS6!1U559Ab9e$#@kV8YeSkY(5YD5mDZN!#[VK6PPpZ*p+4!EIl#4&P6rU2Tq(i -e5CbQH@`Tp"pL-[p[i@6CUFc9BQeGk&IL-Ijpi@`j6NRMAaCq)DpArUNYXlRSI(' -J9QClJ[j&I)B2+[a@,PC+HAlK"2Qf-PCldPC0"i[EqC!!`U(b!mThfRffFMTF(+( -CEII6(d3VRe8i6bj5&QJ0YMF6kG2L'rb4`UPbRA+4cbam8(j4H9KlbAD'6K(2F@0 -KFaN*39YV@dF0BS*fh[B#E5-qcam[6*+VP"UH@pKI(U!mTAeZUkI$a)9D#eX2ZNM -mQMpE1%HZ8%CT*EC'G)cBLSmVA#`h8pVbdB8MjBl+H+h@jUGjBRXYaVBlNEiZK[2 -A#V[+Uj@P[&0KEhQ*mVB@DPY&1iK4[+$`4rRIbKrD*PXdE5aQDCrC2UDpa1@mCf% -I18bjbPXArLTrU2bQ[@alP8i8CfJRE8IT0q)Vr2I#kI)TTCd@BGY-Ia)riMmAYT5 -[+C'm5H%[mKVP6qeIYSfdUEL&CaIHI9TqAmR42V"YSeI%bpS"fc[dZ[JZ[e5B+Hp -AZQZIf2j'qiTlH,I#c[*Hj5$[9rL@r&IPX2DHl4$0%)1ePEB90%"mMYmV$*(h+6[ -jNF)EmPEPV,E,YS1QLjAF8RK"PT3Jl92E"KSSUTTJ-e'(Ae3FFL'9rBS$G3p0b0+ -icP2i-AkEVq9(HD+@U#HQ*"j,[*fi0T'lR,(Q0%qFYLbjLliqjCLS*JpF,mQ(A*+ -X`0KF'bMLe44*rY`MbGZ6*6N@TKVQ'CMe3"CKiXHN#N*P-!1A9DVV"mC@UKT0Ue3 -pG(fPUK0lM!+C3Ub6!J6"QGNY%6j'E!UabaM[`&K*GN+cCTEmCNP1d59CGdUb+eR -4*Re1ZrMI$YS@ZLBdmPVS+[rEL[T"a'ErdX!9%IkDm!&[qTpAAr`D`9,P&k0fqeG -G@4lYrq$$04'Krej6i9m4(GkL`KrQMj!!0jlhpkMpb0&L0a&+AakpjX-e,G$Rp@$ -+3PC%p1L59XblI"S9kSm1p)ZEed3XMrlr"'PU$k9(MjldDp3T88hdDhkRAe08*mG --)0%N1lPIBpE[&"e1mYLAb-K16D*1dHm-e$M"1N9CFd)rNB3H,#')&-ZG@-"BQ*3 -%*"i81kPQmS%6U*0a%'!#e5SC+%D"i)!f6338kM5T6UD3!$)#-91K,4i-C9+Tea4 -[TUPN54IBc&N*V8&1LQkFFLT3+PS`jd@9!AjDa!R56d@bS-4!4)89D9&P%"2J493 --p!QD++hd+D"&JS1J4HU[P)ZS%14M,c,*3!8c%F)YAQ!3LN39pi+$L)J%JLQBJB4 -k[d$p$>B8S!@k5%**j+AK"E3,K5p9+)KrXKM(U[$S'Dr5krZ9*eQERIT9$5e,# -*+"1-L2qULj[4hIV0$Xb!T'B6iC)))rK&[eQ4A@E4!K8ZcYK9-jQ*Z#3m,S')8QL -#K%!d+G4P)L[4BBjAVK!`'q,KqY4!"(`dPEaiHDB&85C`Q)9+NC!!jS8S%J+T@@" -5ITI$5aPF46EI,a-MT$-(i4Z9$%2`b%9`TmaF#J%U9`D5HmTb'$B,VLAqdpJZQm! -JA[!U)2IH1GP6-C!!kB@+Hc,hDH#RYDi%"#(!+mki,H6k0&d@,c19I9"93Pf!AiZ -RPP!U1[bqcI44ip@2hGC`HQ*%95#*!'l@Z#,)"+1i#%BmD`Bp@(")F-%P1&a%"-j -#6bH5hZkZ`QkmaX`@i1CD*48%#e-[8-%NHp841),+N!"H11Q#6cq$)mMJ$L4F`(N -U&ET&!&S3,$!cVCdAS$BKRCH3cG$$M*`f)U1+G`34Lr(k&c*&kf*3VSZU(p5h -JM3"-m-S!Lb5Q&&8'HTG)(84-FC!!K4!-(CbC5Vr#G!QUJT5K+062V%$8QLi`QAJ -m!3%DLJJe!'Ea!Q%BTN0QSQJK"Cr55JIK&j!!-Kd3*AM+k)LRbH5$CJVfBA$3)+H -IQjhFCCCbA*a-N!$jc8ir&Rkb)#dSf6'c8h!38C,d)#EHBpH-&3fV#KC4"3ZK%JX -6dN)`dd2dQF"ZFK#Gb-SZiV3E"")c6"jlGF'VMM6S6)4S)cTmj!K)P8jXVj1Y"HM -je-*@P4D'-UQ%$JG4LJ3V"N*C%5p5@#2P4%[S,&*B5eL%I!*(S+PALTaL#,RJ6Z# -GD1kFM)&ih#Nb(q*#X$!*-B"a%&-NS&V`UB@Y[%,S1)L8i)hB,#IC!j1&F4"9&`K -iMLBA,%bpPpd%dKK0TQ![)6aH)!KScUi#I55LJf+3!0('Hb8&!NHNQP91#S2CL,4 -GZbCLPIqmCIAZ9AYfqk286H'eiShDAE[$9fb9VSD(ESc!Ci9DmFIDGe',1ihKY@i -,k@V%KZ94S5ZL0fk1q#!L-R6h[m9lELYZPEr+-cQ)M)Mj&010%m5*a"b"ENG--'Q -cc9CjYYd0TmeZCY+qQJYd#jKpNKc5B*@0#Xa+Q#fLR"k0#Gl#M'&%`%lRL(*Q(jK -XQ1kLj9i01f*`D$c*)'2f%G2Ciii%)QCh"[41Q,5$X8Pb3$maac*0f"hqmC,)6CZ -M9qeBMVTTG'LN'*3kKH3Fd`da2#aLFr55H$64041k$&EjqcLbd,i[aRSJeQeK,N, -e1V(RfB@9Zb0f`a84SC(ZcVJC4AaKdVjI"HCVC+&pVf+p%qX3Q-k5(*`[bNFbaD! -MqlC%EPS5'HTIFrI@DVbX%m%f"#BAV#G&qFCUmIU4h028E0dFiED4abfYmVaUdpe -Eb1'QhU60Um0N!ePSmlCKlF6m)%`d)*@+FRB*S!fd@YSNX3d*M0UdC(RiRP"rT,b -*Z4,qRhF%mZeK#L6jlLHL*DHFb3C&K8B[L3JM`ZSQjZ$1fV`#b%q'l(#BBC!!EbE -+1H@LH[0Qch+D!Y`hHYCfNcDV'T0Q-(@5R0P1P#pC4-FY8S*k5e+CKVe@bkb0l$j -pdqD)2CZ@lSRF(EdNP!(3CTf#L!Acbc"CNR`p9Jc++BrIRKcT@QKda,R0d@Z@,iR -'Le(8TZJPkiML5GUX2#fKbR4%M&`6'Vdm22lERRp0--jYmLhZESTN'LUAVpQi1b) -mM'@j%E(D#+56@8QB)jf-1+mPE,6+#GN`9f'SPK!X#hKKHLXd-R59HmBi2T1-Z'D -kCHBCJC`c![PY4(Hbd%Ed`ASejNeK*QX*f,1%2PC(3P-#i`D"mCMCD-6-1f5M(j` -QlBGB62aNSIe3!6KjQ*q"@DNPf!"R(Xa!kqX*mjpYlI#If*)F6r82Te+ER4qbY4q -#@B2b`fA!L-+N-d`6,@'"Hf0LPG[`dih*$deBBp,h5jJQ-$1XGa15L-E(20d39bV -B)DADN!"b"RC)#F$1a+3#4Y(D&"d2eRJ)S"ZmB)FS$'aRG0HG8GrT["fJMEL(6pV -8@,Ze+EYjJiirpj!!VYU3!-BQE3JfIdK,Q%PD'm"TXm@DdqE33dMM3kCU3cRimkh -b8"I-GUd0b'U$l06QU[9XQk6MS3dpS`h&JDM@*[L)@jI"Edk(3m116iG$VjUdS45 -6%,,3KQ*MKRk#16CQD"1Y6AZ5+NhH&"LdI01D2DYhV`P&BPbkHhR8jNMLAUCK0LD -,BDC+mZYKSU9$*Z1i%,8TI$Hq#*bh,0dG(KS"kH&Tf["5k@cRZ5FFGhLG0K`(b0A -D)#Hd54,S3S%H%#KQra&SAi&f%fKMJ9B)p%H"ILA3%SEYK0FkJCB*p&H"[Lj39D# -E"GUI5EmVd+8#r8bJJ3,pPd!(#p6#0&jQiA@f[LV3R`9Daq4dJBiNG9YUC8T4$kN -8U%-NVj%QGPFYd!9-(D3r&ZJaa[-e3pdRd*G4Ca$S6,ch-Ef[-KMM"ET)S1RX)NL -Jc`QdYd"(#r3MJ5B)Y$@VZ5pNDaXlc`#"[+DeBK6E"CV()-d5k#Q"TJNd3+#[-%@ -6'BQ&!Re6S(m)Y)U4%LE3C`4k6D!I#R5Y3!F*p"m-GC%4"kMKmI"LfH)H)a6-e`A -kPN#r%qJ0JBi9k&5"[XCS5QHZIjl4p!XMb#V31(CDJCd6Qc&CS&F%qTj!jc13!!U -MB*9!fl%0+"CSCi%D",T(S"k"RK1Sb$`b4+"C!XeJ"mCHhQCqlm210N+Jl3@D`ki -A-9VKr@HCGbB*p#PfK[i-4NGfjP+"0K,S1`,0&fJrJAi[d+-#(523L3cB-2Er)L1 -PKVN'KpR,FXa1jYBM!Mh%GJ[!lM)k!2Zhq#bbJRR`3hE)4jMS9S&Z%fKh*[S4mhi -pFaa%j`RdX%"hJA5f26(3aA,2CVC2XjQ3!*qTISIYam-#E5E3c`8D)Y"[f!'J`L( -3-`+G)L6HakPLmlH2b5[+hM+[SHR'"DlJPI0VqS6PPQ8F'PM9qQU5de)jZD6$UP( -E-rF21G-ZBNTXqSkj&394FkUlIc,ih2464V-U6'VEGI9Sqj9Y)qUD4%j0#pRhCAh -@Cm1+qahmp[c%9a-mJ4ZQ0HZdG((jj32$,lDm0M2Zb-lC,4T(,bcY[$GrhBb6L3C -0&JYVApmphRVhr9P[r[Q[TjF&V2MRJ*l,qcpaq,fr22rVKimRAj!!rY[SlG!a$ea -kGqK,2feqZ-[CA9pprH1rRhfblpr'r[hh9jVV$Y0r1Vi@2[,qR!pqH11A0BqX[rI -F&jrhq[LTCplkkk!AIRZj68V3TrpSeA[*Z2ZZ[r2GLcprp1#a'eZrlr((TN@hZqf -CX2DESd9RKH84Me'6(E6aeKhN)26iJp$M$lT-&YUJVPLM'aQ8"60$-k)KlpF8MIF -KdcE6'hAZE4!rS8%D01F1IH-Je)d(Qke"JmZC%J!GA+m05N!9(khdi,Dq53-!IiY -*&FaqEI"qdUL*FUGFQ(N`J`N#r8`CM0pk`9MMkkN'"fZ$MfM'UTZl*A5'fFD`QbS -N'CXLiDPGQeD&4['$SC'EYNDZ#SeNDk*Zq#fU-)'E6JXXaPN@@Z@aK16&fPM8T`D -M9MS@PE+a$CSa!f"cB8MA$1S2$a'c$eqqXm+c0a%`0P)EL`V,@0!r&Vh,f-ZDXFp -05QmF[R`cj`aYl'c0Q*FUI4E5hYSpUh)4QBAD@+2@h(Apa&UrfdY"[Pr,4hdi(le -m2ZV%qHZdjQA2ZEmej1r9mX1djQ&AI-IDX(Y0a+1Sl19RhX,"hTTa2RVqI26kq9q -5KCBr(1Y69MmkmrbT@R0IPE!jUa*L3UfC#F%q94p%EIVS84!aSHk14%cBBG)Q)1Y -0##-,E8)%eX@BRi,*eTTRqkM)m&(4hRSM)IMi&mjE9H-Rc$qqrM"K)26Q@Fp1'1C -Hlb!AfJ5mINh!keGHQQqYjC8#e4SSe2Rc"+ej8p&bbH)&%Pqh!'rH35d2qc,I#ri -bd+MfBpY)%M`A(VBlXX,2VQk3!-@HL-MGbb2@X![rZRL5hG8epP9IV[JdE9Vc2fN -"eh56PSIAQVbTC)'Z#"&G@Db@"rH0pm!85r+I0M+aic'#h,UD5%L@*T(Z4'pkD%4 -lBELm-&cDH,blM8IH'*m1'(BbXG-NdG,D`c3F2YiI(hN9qY4IF9I[Zd[ebUA6$RK -)E&ihM"pPP8HATETKG!Pa`rJ#6&'((Ue)FY-B-Q&Zq(NKNB!E4VR6ZZR4d*VU$!, -*TBh'+m,S$M#Y*IQ2*Q6#R2(c3+BN``["#f$ejUArXkG($p4'iNRC,`HXXU&'P(q -FM`R5Kb&'P$X!PJ'9I`2D+`1DB!1DB!1DB--@[#[2GprAT@LY(a+iNE%QE54Dm*% -Uc"&*EJaR'T!!i*UM@62JRFf!pY#!PcE$3"pF[&8C#%df,ea$DkEpV422q4"G1A+ -%0SUF&Y[5I!&1qbV8"X13!151lXH!e'&!4M2!h3BdNJCXXf%M`2VGYbrqY!m4k#L -FH4612!U3!%CPiXcPd)Vc0Xqc%iF5Z![XY)D!YP1rRCEC+B'pdGlCPITfiAZhm1- -jC(K8k1j)ARY#1q5[[H-,LEqfdRYj0ccL`ifKmF5Ymli*K6"XI0-`jSb[DEMj2@A --$Qe-*FZ)Bf*-fKLmp)e"2KPc5T*r$N4'"q99GSTFMm)$,HID+EjqYF5"$SPbZd! -l4@jUHG&Z#D[R*Yj+kfKZ`"1MVede$BeF*HhVD)QV*+C1DHZLfY'MkLh)@McjMQ3 -Y(QabCf%jMAKpm4"'kq)&*QeaNY8b,Se*YGrc+HRSX)RKk&M$VdAiFU`h,)q1L'm -CdRd#m55-fkQ0LdP913k0p6LFIKa1hcVMVekHM$[T*2cac0Si9-I'SDdBKfj`h'* -*RVj8P+IM4IUhb6$"-2YKLN9jiJc4-M'BDHj`%p@T1Hr@8%aD,[*B,R*AlRj3H-C -(BEr(i"IGLFcG$a@S-ZELNf2Z*%QHN@DR'AD+pplICm2dJiN4kHq#2*fFSP4,T#! -BZ`rkImfe8hcFl&b"H3M-*qJ)M"[)DmYfpSTDDC,6k2[Dlhlb&0%UrqlIULAQf5R -B&QMp96cNX10kZZpkqR(A)`69A)6VhhcA[lPI$fYlG%ZLCYDGbCi8el+dpE&GiSi -9@HhhEhqJr,kb*iUIUAkbp,DrYQh(NNE0@Y8-U2qmiZX@24VHV([Mc%XAAkakr[` -,jrkqEUfbHhAiUY#P5m+@IrCae,qM0fhm&lUZcGFqZ[VKUhrpj'plpm6F@H$P8kq -F2"Sb0rhXNF[pZJ8&"i6F`ra'pYdV1CQA,Pr210c[VHjp1hGVrhVAecUmhDPhRjj -C[3TqR2&0dcqEr0,ZTjBrYrjeiQr6IjraMDe`dRmQrhID2qErmm[JHfrj[`qD0f[ -%$d1'$[r12c$afd'$aqC2b"XrHZ5SJ1bJZcHZC&l+ZAji38EhcRdIR[PJdZ-*EBc -0$BRmrkd24-&8+@hiG1@+IFrYf,9ckjEhYhf`rpd$laaklj'$ALIF8H)JF`+99BI -P3Z#i,mE3ZCMhAj`ll0QRjPJ@2VhS`PG6Tc`5H,`2'[pa[!mDrq(QJbrQIZ@IIGS -(Ih(h`CM&ih,l$hYUcV-,&beiHZSM8ilc`8drFqT2H`JrmJ$SPMmPd6YVZ-A[H0R -fEMrk%(rZ#Q,FISVE,e(KGrl&FfXRD&BHpHridlJMi))6LAAG*+rFiHSd46Fcd6X -S10&0AH1pG5ZrqAk9L@62GHaN-[HJc*+,,q0TI$f2j9ei(%S`&A%VaLcFMc&4$r" -bIKm[idr`B[i-VqC2mP+8Er,c@Yk@Gq3P["&[aP[a'Mk!er22H3Ar'Q-%HQ#lhd6 -"Z6F`'ZBPM,"kN9IajrPjrJ*+a2kGVd2T+'c8EVkDKk0XA5KIbTI`-,kFImBrjP( -mhcbDEm*`XAra5,k'4r$0r"VrL&rP(r*Aq9rj*ra[I#rIJehr[e(`-Mr&Aq%R86J -VK#HQml2m#,r-qr&Z2)J(m`"Jlh%[qJE2jRIj&Cl$-rNP#&hR'I``40rLhAPIhKN -XlIRV[#YrMAIJEr01[$I[`h[b,0k,&r!Iq3cq$@r+rq40q#qm(Iq*Yq3rmpEm9ck -4rmDRmpqCJ!e&L2JNrKmqQIqA6q2ri22j2rQAS1-HS(b2hc`qLirJ2r!KI#JIcVr -M!r(lPJrLJrPBRXmRm$`qRSrQ)rNS8*k0%p`&e9FB[6QJpc"I!*UlJpDqr'%qNcr -)NrMM2)'hi8EHR"YiS[$rI"B3886!a#Zja$I`6rP+[S,[imra(A`AhmQhmLhmIEk -0Im$hmhIj!Ii12m6Ii`H2b`,r0`T1C`%-(C+jbKhF`Lr`3$k1Im((!$ZAHp(pq@+ -HbiIaCrP6I!k%&[+Rq5+)IX@RmLRm%E!m9KCSc2pic#a!"'`mm9CCi![3m"@IMGq -*@H![q0dk#i`"YH0!Ehp361Kp&[3Z3KCi'Y3q!RT[Q3@iYT-q,MT5GZa%F"dNBGN -N&KD5N!"fKB6e+ePB3%*X*3R(KT!!813L`IiP#F94**4QXp#CK5BX6#AKGL`,45a -%X(#CKGBXj*2JCd,qYLc-*k&f1`Yl@CK-3YX@*$5UBZ%3#FdBi'EY5'K96-*D4UM -#!,c2VYmY*H%!#qr%XG#-K)2XU*m`e&j'p0l"*+aQLPDcBiFa4i60C-&!JX`BC)% -%bd85,T5am#S,SdN)C!i0C!F,kNG#-'-,CN3%lfIK*!Z-p'!Q'X!1(,#1"HDQ!-B -F-)q%%#F,$5a%NT!![TU%E%C+pMB@Q,VXB56FYE2!MRUAEGL9lLc-CS%GpFSF%R, -fXF#f2iHj,-I#!Y[#(1DQ(,E0Q4YC1-8#!jDC3-+PD"Db@*M1!J0cLC&bR@hYG8E -Sp98XX10PN!#MdJ`rbi1(QBF1Pl"`MJAQTm1-PZjR@!KNJAQP1i2FPl(eM@'"DHd -Ec!)lDprK,,"6GQCjV60MkmCfV"YMkmCSlpDB"8Ce0lBEh4KEq`-X-+VE-`$Y94B -BJ+jX6lT@Xe$"!YZ(VQaRZM,4eeJHkF!8GEM'!Q@"%G5"qE8$bf9[Gf+K*3XX(h9 -Laq[%9(4LZp5*NGZTJ)8T*241Bb'-KA3@-PKJDDJh1dE[*",k-"9pf$(kX264Kaf -lclFX'%RSbG*S6lB02GNfp'5(lmPbDmmM,,#ddT-4fR-J#bc0CE(f))Zj)iZe%eP -X#l0BRXTLc&RXN!"C-eKJa'8a`,eBZZr&8RB[jX4HE(YkA@@"Y81p@-lU0CF&GU3 -#jU!#PXF,Q)X,@(BTB-39X$cq)p[X(dRZNhq-eRQX@HIGB9UDGFeMeXdlB+,-ZNj -K4Z#e)-ZX*d-SZF+X,pY[eY0+c(UA3,0qc'R@5jUBp9BfQ#5cAL2!4--%`d`fkr9 -f'&am$SE2&CK9-#V-&CLQ-&2-HN8T6!--,LUbB5DDp4DjCVe(-8`pc$UBR6"lBD# -m"j5Edh6G[&MA2B+ZP`h6pCVjZPia8pGEe1Lk@+lVTP'k,N&J"4ElCZMkFiGdI9F -C6)QZlcbJke[VGAh,4CM1Z[iH,[C#D#mB9YPeI@N,Q,d`'6"6G(e*NUk(PF*Xd2A -U+dkp)G#T[e$Te2pqhUQ[a@4YJ91[h1[8T@bRrJk(`3@26GCjFE+ZEi5a*H[1!TL -TbATb3M+)KX&&#KBZ#,QQ*H[,&LIVAF$8CAkb(YFf@6q@NDcESj2eqfFNkqA'C,h -X(%aZX[j%#8bIC,ei6V,q6!6-CCM*bATe4E,qT!Sc+9N[pF-FJ!'LG&LbIRXR$"# -hSI!f''ihKKN1!mAq1TJG-,MdCm*m#30!Y@N`96#"-'#SRCHXYrA!Y%M@1kk$!F% -P!&S#SC)QbASV#J2#@N&a66P-+3`30IR*qS#9-$M3!"!h!%$V2i-a*1X9eFPkLk* -N[3H!0B$TcHR*HPd8$"MV)2J'(2)'$[2'h'6pM"PQ,`b)I'PLX[im'*lI"a1FV*p -h`X!Cjl0JmT,e&cE!K-&dJKN#!mHILi'"mR0ANr9eB&bl'JBES)"J%3!&1%D!X+N -'"J5D31bRf,L9F6"EB#$d(!kcS`&Q+6Dhh+2c1JpbS8G2i4lGe3#6$T2VdCI&`25 -"QH,4d`5Bb4jp[4d'&qX(H[6B%TL0-(-mHTFUMajAiG'2&F0NH[5L-SpZ,I,SGJm --pHMP@4kp'%UI'H,4Udpjp#FAHr6E-cak@c"h"*!!4V%H[G8)Mej6lp(V)cckj`" -5%HI4[clTdAZ%HI3h30LC0)rq8SK(V`+bDV4(h`'PZd$mVRBHI5F)f!R%eQUB+"J -!HVq64pm'JVD"BGX`Mrl"!Bqq(i5p'qR4$dhdk1pGKHRUd9IM-Kb+`Spip1@622T -RB2TXU8H20RX`qKh9AQ)9LpqmJC3dTbQN)+,FB@&PF%aC-jj@bP0)Q@ZVAFfP44[ -`p5mSPrYMfr)ZFD*M1hI9#6,&jaamI'YMSfNSfiY((NPEa"[RkVQpL+H93C!!qi[ -iN`*4NFGNdBp9mIXVDB-lKYc2Td![Y3I0jiZF86cj)XVYHP8'*fdj%4F!h1i$PE` -@C8',P4[[lZGaCAaP%9pAcYmXiUe%SRN+dac,$[6,`NUDBUHN()X0j`'N9ABeL`2 -X*$H4qdfbjMNH"j&[h88UDCilL[RQAKCHfZPSRQER+Fd%jLdE%4eQ[fIMDi[T3Tj -@a&1fHkm@NkXTpRZ,mAIRe"f-UGTleBi3B0j[$fR(%mY+'G1kH0q$UF3HNXZ2PP@ -b'lrE$8SFjSS"CHAF&BGAS94mX6dMPqrH9X`IL-2Ie1"GY[0RLRLpRCF8m9T42Xl -eM3P$U@qbe+lQ%q`dXJSQ%kXp12r4ZI[!rqMZ!cHlqm$alMj`NlX2T,UlNRlVlZl -T4(5drGjd1)KFRAChVPI*[9cLELGM+RChGqcrLHi1J,[6`RKD#8m@6l1k@1QF@&& -Z-NT)aeFDQVk$rje1iqI6a*`@[0P1ATI'DfNf,cl$lbrRY6[B(Z"jFi+rNXCL0d6 -CNQjLT-`8rHe3a"TMTQ,XkVc6++[ENTfi08RcRH`"V4qES%JK`!@4Dip&FN$XBiY -%NRJV[pl"hHPSKmTDR)#[H`am60QU%r"KGm+h4(D4YmY,qCjBrNN*IcH@2eR#cmI -b&dYi3bb'K2+GXIbj%PiCbm85[M5@ejI`MV(F[pHE6ET6Up9KQ%)FV([B&0JLBPF -aTa[*c'Vh8lDF5fDiV#",FbFb`h)P@elccE6Z6#hE%#bMI$2cF(Yf%BmjXj0APh% -VQYYLhR(lkC6(dNqJh6'ANcCc[G@4Y)AXCcql1JT*m@Cmb#JqXZ`!DE46iY`br#T -l!&+#aD8Zj*jcT,PR46J#QV[i8DGM-[kUQMG6'DhT`-A8d!bbb5QahP5@4h5hY'- -mQ+2k21YI))Y(FVh64(qe3Yd`'4J!eH$@!rA1U!cdamQRZ+Fi(X,K"$*+jcarXCJ -h&2-"aE`Y2ZF8mqdBI#F`0K5Ck#1SIIMT4EVEBU2EBVrESXTY8CfU5,,%+6bj@2! -"$`E`fT+$[%Zek0M2AGAHLbNSFPVNl3!$L-4fDZ'HDT1[6f4-4@%mZ6TH63K3QK` -'*m9"859I9ZheU+'*9a1Q,Ae5KkJ+AEjlE'J#5ZfEek'iIMb*9c'f`,G)3"%m*aQ -*3IcRE5`l&8J"C8AF&HZHYEIEJh0jEHNkAR5HM"55eeHEb19S3Pd#HHAMf+k9UCK -dB2aPk+0SGjlL%NlA!N+3!#S&YCNE2%YkjB9DI0"+,NrYSNNpJ0&3j%j$@@U#EZZ -1Ef"iqhiHLqDf'%1p[3iMASPPCf`6*MhQr8UFGrX*@PYiJGf-rc'AMl2%e2!+&fp -9aMqUjQfVHAJ*appE,#[Q6p)qI"q5r'Vq*PB0[#,@a$,pA!+2NfNlmKE2TUh*1cb -EMV)kM'9-F"kQ,SDFrUKCE'#THNJX&V#N*Z"(*HKqI32AL88#Mk[RbqKF(KGE'Cq -YUeM#a10VebeGL&TJEG`"Y`4b&NGG**I@Fr`TAqXC9"'93'XP,brQ+$a*X["LVe* --4j2[)GbEVH0cr@M4d[f-@ff[9I9+hU@BM!Cb&FIA-(e*MD8&3Be)cAdJXN("Ac1 -c+rFHX22ee6b1C['1,PDCD%UHXFrDJ8H*hi*f6PV2XK24%-c1jH-E$[(YGTj@$m# -mVCGpRPF3"4mCp`Dkp`3NT1#*F@8#6ki#REkV52Z&A*jAp`Rhfa@,Ui)-*#,UCXF -,K2M8V6i"#5R5I9@Mql+RZKZ#GD3UiLpEbCTQ9fTPh-ZjNf6b3(-,NM63XkBf#"J -jRCSdMia[f-*19mklY$MZG&qKX1YP(cd(6N"#+S6dMb8mVGSGm!CkdCZ`EQjH5,0 -`-E84*e@2$5Ff%i&S*'HQ0ZSc[HeQ1@fCLN[bYAAAh(BiBB&LP[G@+,CALrMQ)Vj -4i#Yhm+2PI'8FrkdYAhQ'QqamA4Tr2TDI+H)pl,bqM$GU4X+C@)*G9mNI2-JrAXF -hPjN)M-R)6$D1f@$b6C2-XUb10N9NGJfTibUC[3UKpQ4fKAcV*,21j%-R*ajUL[' -A&FaY@0Q`USTIGFE+%Vp+akUl,pqCfj-CbHXcb&G30Zd8$bbDI$CP#D%V%ZamlNd -)*-(qEi&Erlm#cJ&`eSFS('LFlaX()fm+&f6V+NQfS&M#K644YU,SJ68+jZS+f8T -00aA98imE4J2qq*%e0jHMFC2bef+-Xm!DZlMMHkb!h&4'3ECAJ**dmBKP'Z&e[bR -$$BV$@'D)XVd5"J8Bl"8VC2ZC1j'BIV`+5akH5MR&Ha4rM!m9ZV3iR[+*@kSVYPY -blh51ieAK+,i6RhJK&MNmG@5S(l9V'q3C`dAjrR1Ll-&3XlUGS[b%8D!BNV@mE*G -mU(bA[+1$+"H23V&H+XNE)dAjpLTXH["l$XX@$-5%%b5(C6DCANL6N!#---@6!4C -1XY#1KA`5!VDcX)k&#"Ek%GD!H4)b!CQ'!-#a-P'qKk*Tac#m1AfeK%&eSK`h4l5 -FA8M*)-8MqkK'BLE92)LjE(PMY6F1*$*UGJQYP,-&5FhH4LXGf8Z*kZ`1@,FM&m- -Np@jAM2#q1`6,Zc1K(3kiJL&KF6C4[E)Df#Z[5ZU9B-KFk8k@VE%F6*CcX-a*NmM -S,MQZJkMQR#HBIC+D%iAl(!YC0T%X19p5-V!rXaMBc(TJ-hG)DZBT-XZ@m-#"d*1 -*mY*aGP'pT%$UdRjFASU@e%Y%ak8-c,,)E$TQXmPXQ#Kh3HAimN&-4SL@beeTM&2 -!@#j*aH#&5[Nk8XAe#&c#C+b6j!cXBTGk&#k1Np6$F)Ckq"ba"-cK#-Paq$)pCR) -F(N,$6BjqjfN2Nk9I8d+bh!p!BMH)MVIb#)hGNC1lR`'UAP5l4i+jHb!`+!k80KL -BJ356)-Ppii#"jrVZ!+C[M+6f*@lUDj6NcP@i3S'`cPHa3&T03alV$'Gf+`-eh5S -`$,qE3[C,lJDfEY%%Ua*lQGM'a-k!UQkcF3ZG+XT@`'i(ArXDaYGqTD5fA`@CpK' -BG5FhNkNI,ab[Kf%)6Q0!Y)[bki-Pe'I*HEU1NZ6A,SVb-Tbb3`Y*lA!!["fL*0V -"6fDCZ1U1+e$iGLQbcGXl#GIERE"Z#FK[6i28fm1a(%f@8l(XC*E86KI*$&QJ%`j -!1d'9fLQEi0T,DZmd,(XMMeKkKe%bQ,Yh1V!C"$(ILjJM@ASRS9!$hPAU`09RRf6 -T%m'bF*r,"0%BL'qp##-32BXN5mpcl2!p9dPUcj-%H36)PPlN3#!A!*RPNY5X)f3 -'mV1)&l2b*,9A@mak98Q@APF)6,NAXPG"('JXD)DE!KbLJ,LNi#STXSM@S%&%D8e --YSZ12jV3'*1MD3`*IpTCX*(3**)NiLDML+Yq15$+b8RN8aJQJdNa3)Pm2"KTNRr -#P42Cj+GTD$K)FF',NZ9R2h'"iqG!`[[c3-R4qJc4e6S$3@e06[[V*j,kD`LCj8U -@L6-BcEm95ilT,$P2re*bc%JMdaR4Zbc94634'rrN5XRaj'GdYdNZ959(k55DD** -[BrbQ(iAXl$E48S*,1+S%)qMXUd@j%BVZ0J*apN1LT9%61V*'N!"Ef55eKL6C'N' -b$0K1%lF,MRSlJ91I*$NqEdTV6I,R+1CVR5bU&FJQFN@$C-%`),*(&56h9Q36fjR -B!R)rF5G&kEjM,85,[T'N-BYZSaS'3M[E5`jR!C`S1kHL*9$K0239F8Jbb3Q5aE1 -4MSG8bJ,mp4V`GdR(S29TY#21Z'`a%L3'fAC"UGBZ*((1&aeGjK-+ic$`)KC0pE% --60"3f0&XaU,UG$rkS64X6$Q5j(eSjG,kLBkbFm6ECDGS4i4FXRLLK,Bbb8rdNH3 -R-$SM,3*2`ZH3!)YR+L#N2K1"&2(-CBDC$)aFA5&CU[I6F'a+p44iRD3`aj16%#b -Pf&U2S*D5c-6f)BYFPJiM40lH+DQhFD2H*XRp0XRNYaY,MY[$LFaY)pPm2e+#kNG -Mi["(%l3rNk'r*1KF-05LPkQY)Y6@"NTU,GS*4qdmSV`YrTa3faBJ[JE2ekI4m5D -jicUNDE`0G9a-(&e5)6P+USM1%QbfbG')G%0U)h3*PNCcD5)b4LXd++h#!+39P4b -YKT1$eT4,MTUVK+ZQ$i&5Nbr*!cc3'bJk"U`N'JBJ3DX$*S&Y!$aF$`m[@bdkkMm -MPr9S1H4k!h"iakLSaJ3MJeYJ+2`bY%`p8)0ai9YF!a+EDk!S[cNG%j3+VBZ5e,S -mF0BC*I80C#A('h-*l$0QbA'QRY"bCLp$S'Ma'F+d8R5m0*'J,Ql$XNkd9&@beV` -+6Ae9-$P'e96*mA`"Q6j[P"cR+iMdH65D,k!(G,``PDc2SF0eJF4c-C,Ph(6@*Te -E$#V1SCpbJG5rSc4S#SUGVpY(BmS%bpV90!Cr@Q"Y![8MSbVS3&1'LaB46N+l*L* -,#*`iAEJX18aQ3V5TKSA2b-kC*N%H9FT2EC,M8jEp9XDaX)9FVm4iqC3X8AiZAh, -Xm*!!LafXDV"Mk8jDKcZ-&S2E8TU*$Qd1c62*1US*RKfLQS,q3ABe)-PJL&%bp#q -,N4`B0)JNQcBCIh8+4C+6N6l@Sl'*h8M3X@KqZe64F8L9F49d*&afV&Lb&*8aP,@ -)SHc)9IFM&59MG2Tf"42dC`qF`J5NP)0+*m`6%c'aS)i%`-jkdI(-%(5TFMA%G,5 -&6b,&kUL`hNBke"XMEmj"YbYha#Re)fL$m-964dTY03)CVCjF$3!i-i6VdCHE9iQ -1cf1)ZJUdRfEXdGFJ"(mh41i4KTI@A0(a4J0GJVb!(G,QLr*,+)+V3AA95@cpD+, -ZHB`Ca!I@&qT)8RpK#S,PA"1k#%GEKp'FD0lA`Trc4)Z54"GY&ba#*8dX&bbQeR3 -4SK4,&lN%biCkG[RTUqabj44fZ@mRZC5ILm)`8P(H!8I(L)iG@8KhMPeeT'+aUad -KB'H9j0JD4ICTka$*XDfBl13fN!$h`3&5"GPI4QqEe2h)D1UlU!r)ldC+mJ%-S85 -Tl(G3HC,IDBP4Lk,M8![5M4bDD-,c+I1ZL&l'![bb"`j8Y[R-rS%$TaQ0aLQ'")0 -KUXAbJm%`NeM-Kj*jdRMB49124N$)D$!N-H68Sdf#$3C$*M$'N!#NK3C$`QK$r$p -MJ[',%fl(q+l)C9i#8I&Y!SX*KS6*E$Bf&6%QhfKmf-J)Q!N8k(T`P-@5B,&-p8P --(A6mHSc4q!JB%Sa2'ie2UkSkdcL(")+Di*da`8@$9IC[JI&"Lm%id`YL5KYS''C -*mJNpmXTR&LKia%LSAQMdS4qFBdNb6V8B,%aTI`[a9)*a9XJ9Jf880&V8KF`TM`m -2cKj'e[')A#q2PmaFaZF&`pLQ%LdJ[Mp"2mfFP2$J)V*k#Y1(8cP(NYNBhh+8Ec+ -P2a(+L`IRFpD#aqFDAMe`XXKJ`'DrF+&T5$GPT,*)I+RldhrHqhAkiqaIbbYYXN0 -bfQ3("#Prkh2Kb!9PrlJQ2mijr25FFH18Jbb%AmLi'a*bTFf4ekIq-V9[qkPr(ZN -ppIH-H`%&)5'+1[QEbC19SfkQ3rr*#%-4P-XK"N[JVcG)`*qYM(bjFI2r[relH4[ -*aXBNNTX6r[QG,mGrFE6F5,"(dfh'`RmQ')F(IMNPm'Ml`+m3XNmf-Aa[1(V%BMM -kjbXYjKK'(hd(fH,S,aE$b9aeN[UY1Yk!c5dd'#BB$,-0re@rb-kpBM&FV999cTF -Y[ID6)McmQk)m-[14rNV6a['cYi0HIbYT5TqJG2c%P`)#P*m+TR45CQ$cRL-lQ$9 -6q8ijU'c,[+$m6$EQ-,(G9'@&HPEPhRr2+e5-`e-ArP,MCrXTZFrP"!DF63qfh!X --#0RI2LFS4$%4Zc0!f4,J$Em%0!eS(46b'p#I"$3*qM0)kD#)bMY0a$JPAaN"PIF -TdBi3+'`IQ"QFFb3N5+N-8VCQ+[455&r1rrT`qVed!KJ!!"dI384$8J-!-Xi293e -P04%!)Q2Z8lqf,mfM[)R28V1CQ%NHQ9+H*8NV&pJFB+4T#MkDhU3f%D-h"hXeY#b -63$H$Z4`[4a[bq4S#1T&aCh$1V)[Zl!ib*%4QPi-XaeXBR2@UCcB`U)b(kf"`&Gh -)F&J1'jN-rIlphQ[64QD1ZhI[jamETLF&3C!!"%%3")"SIaIQ)p%SARc,,$0"Z4R -BPrcVf!kYrCaT1bma+BR[-QHF19HKiR#D2aa,D6Yml5Gdhl)#*"SiTJU@-F%8Rr0 -l6TMTSe,qB&Xj,Rj)"1iM!NrIcLS,HdimABQ2B[RMFIRM,KM%C-11C2**H-M%&1# -A-aDHRSU-8eT"*k-,42LP`QLJBN5l*cAq(*rqlE$MlpXFE@58kVRMSq)YZ@QZEBS -j$RFkb&3BrAlRD+"U)3h,GFB'&V58QAZ(YG2FSjf%c8IqHHq@k@IR9r*$XdeRB4D -Ck51cA29PD2LaK+q1Ubl[X+#fV9m4'[@+ahLiAfh$pa#Vq$%4XPaK&A--3"'i@NF -[020%DS`NLjaF4GUQC*Tp6,Z5l--iBV#2VlhU1-C(1efLcq&G+$LX,fm5USeKBK% -cK1'),cmqE-3-BSJ,!&JmlrHeZEU66c'#ELp-3DU$ImdVaK2KZ1`dNJAmDh#)b8h -aa'LRP`4d3cLNRfQXih(rEiVdl,'KPXRJ5!aCTpZTrZY`5Y2G5&B&R3NNl3cGPpj -3CSUB3R-,4K`#PYIMr$e`EciU5)I`*iK82U3I419Fl'"U&$Ek"*C4UF'B+&Hi-lS -ZJ%,XKTM9VL4K%0`bDl5$d+X5S@hG50DYHp(VG*iTI[(fq[*iFC[#pBNPUEIlRPr -Rd1F-Z,4dBJGGDi%qm@%HR@#"DdY%R'hkClqL5@b$I9jG9ef6-(`Ia(D[dJH3!-) -D4!*VBXNIBLT$P*ZqAUpE[ji+1Gh,YR)4e4&+2`DhFQ-iZ6i`TZTAN!$Q5`B[VFI -eDS9`,4alCY@`"ap`j@c9#K"!%b-f"K$$kd%D6!e[BBJdNMdq!c5h!i"N#Kd1jGq -G94dY!c#'kVEmJ$,`68R''-Q8DD-G`@%lJZiX3F'DP(Cl+FH'U@b,bL@fiBq2`Bb -&4"N5VD0N$(S&5(8jjVLrEE5cl#AphBZU)d#AkZDV!Pj4(`q[A29LL6Jm(KC6im& -$rp&fC'&B`C!!9(T)plXAK98[-YCN!pDVcLM-diIYcG28F#p%1XPeKC)fA(h[hj5 -"e'JqHIXYE0!lkeTFERC)Qp1fICJq66r6I5M-j(*X(dBkB$HPDYk#+QNQj)J*0XP --,5e4cX"'!LNG9IrB*3kr@f[SLHSVM&'Udp$p5rlLTirL#LUKL$+3!"FI[UAEr*5 -HjK"5h)eY-HjdV`e)+5pp[,KP"$CN)+9Dh)E"-NVQ"Va#DP$h$IY#erU[kH)(hAN -rMMDG'NfeV,r#N8,9Yp5+%ML$JI98Q#DNK&,f1KcGTL%P'!KKF*d0q3%T"C&fM!c -Xl2!Dc'c"JB*NQZ!+cie,5BCdLQ%1Tm5$5UCm5LCF,ihQaV9-HfZ&Z"4T"*!!("q -`%6P&)[r[eFZYDb(&M)dkQ5lQK(j-+68LLGF%*6(Sii0pVNPpjDMr,ja),"9mf$4 -Flc0l'H+K3bXS6!cd3Md4iKhM)SK84Q`3CieSTB6)VQP+5QSREAG$8+fFE53"j6, -Ea&#IB+Y1Mf#3!$YDJ#&Zel32S((*aiY!LG[Za1!#DN5NfGrZJjL#K"iRT+QP)qN -9lHH!,QBS""&TGjLGS9JfN!$lA9b(QeCJ!@jaPT!!!42$&BiN*dqBIJC3Y'-lTpr -Z)fDDB"HZf-daY4#NiY96F2dq0`$5Th0$ZaeEKZVQDjX!kMD[!!H(BlAN@1#JcAC -,9(`8`X4K6*5mh244L#BDQqS@0k,EhQ'Z@k-2I44D"SFcLlk4Jj5HkPk&e1$Pr*1 -T2h)(&29N$MP!'*-0q4SH1'E$4LUSZld`Rk@Hc&ZTEjB1p2Fp3k"lEdN+bD`P*IK -j*ar-lG)b5hG`8E[R*`&#RK%FTLQNECSDDKV8pLjU@a6`lp0%)*M(k6iA!+Y$ZfI -,$R5cQbjeDTZk%dZ(QS,D2CZ(QLjV'llSr+)0AIC,p(ImTIX2PAA1DFf*@UDi3`q -qLc!0[+jc"be6r#*cHGM&MJlkp5#!Nha[bG#6,2&GX-4(L54XI02C5SK%3h82ZK3 -Pb*5('fDI)C52%Hiq2m)3SCC5La!C#lC1j*m-+rQNc'JM4VdA16-hb&Za[[HrmJ5 -%'#ZD@DAZUfLrkXVRKYU[EKPU2bC[D,1TUDjr1DEUCRVZU,Zbj-rBUeB'lf&+l5f -9`L!B3NE%mq1c6BmYmTPCTcHCGDlpZXA(QH)fJ+J[!-8(JHa*Plm`XEbhl[8GPVV -#jGHab2(Si4eDA6mYiccc34J&,LB-eC@8#jNflb5&+NMN#KBh)1F*pSChfLF'SaZ -JDR3'b!dB-$BpX)rlaPeN0#0(F*,hpf(`&`d4PUSQ&#IId1iM#,1C&kbSQmp#*%k -H%6"J5Bk3!&p@1U'qr9S1$"%$,$m%JE28b84rH(*XNCQf(Q)h3K(f)#Ak(4MMHql -)&'XK)JC#rdP$dK8F46"YT#SYMa5k"4FbS3Rb*6ZQ+Kdcc"-@L3fLKFR(CrT``5d -iP1$c5!FcEB5KX'iQI553!%MF+kNafNCb,cr06GCE'4kM59)*!%[MFV2ep'"IqU, -93U9f-KUP6b6A*c$SPbNYiYlqBi33Y0'@B2[0#!G3i@Kj#Th,lL2K3ULGP4L%m!X -Nac&dHaLTdA[42)#KmXQ!ph%&CKaGe-aD"KZHSbCDJ@F1*q8Q,qfJe2(A'aNiDPf -e4*a!XVbhr@UiL+&SEi0MmHK*J#B*d*!!5A3$8reVeebDk82#*Uhd&kG6X%ASG00 -+4RP5AqRGAe8#PEpB9[N)1XV844HR3d'DHDU+UD%,[P0FFldq)%B1XNY##H(UGpT -['P$6jl1jRJF)-"eC@A,NahpNQlJD2fZFI2XIS)*e)S&VVS(KGM9)E'p!3P*XP`L -pdbRFe4hDl8,19"Hpe(0mG3G%`d@rSUlRPkB,d3p3L$Sq+%@$M5iF3T!!`PhbiBb -X!Tf#`[4S'8Trl`Pi8mfak0F&fe%*V4'3!*DYD&iTqCUqa&ed#68V1P1Kq'U$3pb -0SK#`DU3!`*T6PF9[l[P+#T`%2Xk[+K-T5rr06rD@G!ZlY%"cA'[jZCQkq!YM%&I -MZ4(Z3!-65TM%J'Ld[Dh%3qa(jVe@m`q2[VUC$8UQ"e@N-'JD"fd`D"4Gm0(-"3m -0H[ha6aiT-I*aj9+U*Gca$ipkaIjEiF(mVM`FZUqrIYMbhE[d-f@"`rAdee9II1f -*J1jlqG&KSkcYm$AkklSfVrk*YMf"+L(L*T%r'X[lqQq&qX*3HaT#6H!U8Y``!9T -HIY3T[TpjR8FRUlF469LT-@L-pZ35Z,4U@Q4D*&@UjUHCcUmdH'5SI6k)r4jTZ(h -fSK5Fpk&JlhhrM[D-&`McQ&2,K&9b"C[Dpd)G#8ZjT-Vi'UQ$1i(%VS`FSY2)G-` -"%A(eqC8#,B)`LqJTHF&+9#kD+YSI0M@eGrNX$#ApcZ5Q[ARHFmIlHL4Ri'U*(QR -B39eb6SRNa!8+Y00Q6NP$HF)iRjY5*E,Zq5!f&Vi)Bd@UQS6KSf($q1Qpfma*j$2 -c$lV4D0AYQ2,@j)eQCXJC4aK'UFH-MNkqH#NX2$X!e[BbS*[E6XaE3q)!%D"Q2SV -0'J@93Sj1lf&CU4G9@Eie3#''!LLk1'`Ff"i!D(DBflY#F0N6U9Je-Y6HjHMJr0- -Sd-qM**!!QYdmkFKjC"Ee3Y(5cAkHZk+$%HLdK-Mm#mL%,j+VA*9FBJ9AfarHI-b -2Y-rYpDQ+pKX2CF)M8%GBf%9#MiKJ(+#iPVQp(THmX5b$CL`)P!9Sq#J)6L@T)e) -$N!$'SkiI,X@fUpF6[+4EY`9E-16%ajd'9eZSD&3N)a#@(b[kD90l@ApI"AH8&A) -#$daIC4)+1BS9TV4!i[N5pp5iaa+eSGM@rI@$6eV%1kB3'&ZKZU)-,1iX@0`!9Bk -aQEfUG2(q[M"hG+H(2#d0q63lj02fKcd@h[1RZ@a-ZZciRfDVBb519f+lFeEE2Id -Vj`b2VPl!KTGmGF1adC9EbQHiIZB[YqP,Ne68djZ1G2pUL$lSFQ#L#$b2,QEdQAf -*Eerik`G&lTQBdAY(CQ(Zh4UZCHM#0medY6[CiIkG"RL#k15lHA[,IN%[E@c4-Q4 -5LNCr%JL,-GY2AL4N(@DZ5i'4a0Uf+R&R4mAcqRL`Nj!!G4K)1kcYDMGi84TT"5Z -Nl5lNDLHEF$c(4bhH(iCj34iJ22(3Mr*i2AK2cR*[IIarBQS0TP4liAFj4*A-['1 -*R'RB),#DR'-LIKc[VST'alLHZ,eq@FCTQ*b'5"8*m-cKS!TM-f3fS3'EB-8Qb'a -&$GL+V0L+C$Dp!CYZaDE,E%S$0X@+6C(CFJhBFPCX1CPYUJ(EP"AE9-L8FdKElLQ -Si+[RTDZPBP9U`F!,QUUC+Uj@Gei$14)!BH3JXD"fGZhI,Ab1lq1&r#3&XY9+NhN -cZY,"qc['NN,T89PFFBdePfSY8X1I80`VlZ2KN9b[8fqXhjGiS)kQpNp#h),3'%& -6JHIlqb*TdD1B1ScqQU#&8+hp9X8[)-j8fRHS&0*pmY1l@L#XRbh+DIcShRfI$YY -1A0[3NF`9mD1E4X5lAlMDpKbFKkpYk*5F-FrG,phIGK,1BqS6lfeSPGc+q0dhcc& -@8ir@Nf8@Xmca"6%I+i,ELPQhRC`mX9e!GhXd`aJ$ZQK[Z%LR)XKm#U!*@D@6Hbi -"m8)i8)%1VPGALqX92KG"4LUrVBjrl(IFHceY2"&iaAeN-P"8++*Ycmkr$dCBA5@ -"L5NeRZp*ETPd5-CTP9i`$GbfLJqXFX`CbU#"P*NhYf89a)Nj@eCa199`#JUVeG@ -GkidCk0*[r1V2Aa#MUhei3B9""B9K0T!!KM,8#P`8jl"0(%Qc1f!3`BZa&c4N[q# -B`mYZ5NYjImkF10JFEPqJ#5a!TBVfq`SC+QNCaC`hS`R9D+HdK#VcCeGmE8eI8AT -#4BB8R!3U'-XUfZFrRe-jc2Qj+NIZZVfbrqqNQ%ZeHr4aNBB1-!,M5$kIb#ehH'D -r!6XA!UIj0'aD*Aa*d%+*RYYD96,Pc"ZeVqjP&43Y9YdTG```c`ClDE0ZDjhNDAE -VEJ(XpFq92J,f`8kDHTK0[89(3TJj0LeZ6d4bHVZb5rZH1dq$bpe!53c[BX2rkfF -GVN+*"c"YZbd`b5Nj9E6&clA@B#qaS#$beDGJ0,ZjRr0@4AfMe@PmNYRr5Ylh*ld -`Q0L#jR,a6`*&q"`dPa[5jf9cZ5TppT[,"HRc&A0jA2UF-CFA5CmAcH@6p2R-hh! -p*#hA@V'GK@V@jhd2CK3eE0!brEH#kHNE%IIjV-Rj'i28U,8bIE[*9(MpMNe3--! -383Y!l%a+!RU"-e4$K04H[Tj8cC'VqB(Ua"#-*9-X@FM38P*a-3UBj[aHCCb1[CB -Ufe2qZEK5r2Xj,Keq,MY+d(cEMi%dSJ5'Z6*!Q013!!!b9`B0FkS5D1E+3'*133, -5A"PFc"QA`$9A"Kac&NQ!QbZ$N!!j*krI55!NT3%JmHM&cEfkqarV8rk(S*E#D[V -+8+jTTLk@8*8"Z8D9!FR--a&aH$q56ccq@jdec(M!eHddC`kjN!"-%Rjlm[aGKak -i@4qJ5NTmS+B9iS(cr&lQ'(BmF1e3)*A3pk2KG%Jr#V-rUF(j91!91H9ZqX+d$G2 -LNVF9I[dacT12Sq#,q5",dP5ZZh@%ml2ka,)IVDZR!ZMEbP@![BZDD0e'2XC9Q-@ -r9Sbd#!bQPFpaaICfkdKTI[cHeM+Bbp%a`TJV2Eb5eeBe(UPGp30Z)$d[a'c"cV# -Sf%CEelDq@[c64l'FarF$,RV&-$d+%ecfkhI`!0+Ahp9h8$!iR4VTTSRqHU8qE'" -"X#S"V3TQ`N%BFafcRh$qe)B8@Y@&2&BDBZC!"'M+EKr-ck%q9c25Z`AV1Pq[4E$ -Sp!-6!0"dKcQm%!dVkN"Y"qVe`@8C,+ZL#5mmP-(K4#pIACP'jpIk!%DMHcZ!"HA -$Q[TZrDfF))A'`c`QSkh!`S2cTbK8h+A1fC@c5DP09`kTee0)R#1mRDif+IJZKIU -m"Kk9LZ,3#fPbIBJ,"'*A"UjeG#fQqRB"p,mS0ZH@FdRj,5,V2Pj6D29T2-6lSGe -1Sib%i+5rNeK[%HpJU5XeI-&CbckmXZ1L-mNq,XXIXc,$&GRa[,1CIFb4"h6,$(R -jBfb'AN#q(!`&rmJ5(Qc#`ij#Ke3"&S6kTidI!*bBLh!M8b!Gi+bJmGNhm3V3kbL -V('89(k[i@'@#95B#e9e80e"@IdBjcDGd5Rk'jJK!d6e85IRrkJ5RN!"R'b3CJ-a -ff08pKBF[#MhjCk$-LNBSA&h-G,KJb0JBj2TVYdClbrcCG)LMkV"c)02TLK8+*d[ -CN!"*0X5')H*V0IP,''!TQj!!'SFBB+XUdePbC5@fG@UPcJY,XdX)Ep5m9J0KLU( -If+'C2UZPa+TcqM-V"R%%IkKqq*NrD(bP$M41)aQTbh`%!J@3!!E5'PFCkRYIFE3 -3NMP,G`BZU$U8-4ASCCN`'0m)T+Xp*lLHdJ$SZ*Cj1q"+iQFD+YHQ"E3-8ka[j[! -)Mfj)&6dTID3`1(@+6chdSqa3!6r03Y*ZB,$KX,4aJ-a43(Ie1rq(ma8hSY&G,&4 -Ja3f&d&rejTQCK`#a3B(C%kNd'I(*K1ZpRkSMAiER!A6aELi9T$6#ffUU%Glf,"$ -HMeF0AjAJLBm5"BkJBirMF1+3!1eCpTHhEFE,QeI*F+Vh$[q46rhk"(G%cZ$K+Fp -XSi6)-)j`QiQBN!!%kN8ap%LA'pMQNe+N43XBlTjYR1Q6%CrE4'N*N!!3'3P(QJ3 -4L(#pYq'#MRQ+UPX8N!$m(8L1B0%m%J`a"3([im-f'Lc1qeh'el)rqINp4"U21&f -CE4aYQHQlF&`ZMYcaJU+b*5hf5bVQV$0lN!!mccVGDHG)YE-flBaakq9aIH9EAN( -0UhLXURF)!)(C&36YVk+EPaf2VQ%J-,)JU%f$)&'FhTDre2",E--F#pb`R(bTfXp -!9YT)q8#*PE3YhqT#LUCEj1fUaABP[`)`p`)"*LP1Q'EckQG$%M,$m$SlT(3h116 -`riY3IaSp[CmF4lVqQ&cYei&dblUi)`m!3'8D#(FS8S4e2i#4fV24creK0lZq12[ -&6"p6k(P'B$-+iiL9@UrGG4bD#)9D+UjkUGbGmB**%cYZ3Gckm4L"%[KU)8p0K)G -C4ab6a4SLF%ifeP259S$idb*e)cX$&3[YMH9iJ)!PMP1R%EEIKp3H$Gi@2JdP3Jp -AS*Skj3ZJ8rG3C5-HKHdKd@@V&V+Ec*(cicXKI$c"TJhke+#U@LQY*$PET5%E-h3 -Y#UqRUQ+5$LX*Sp4pN3$Q2m%VZHSrJ9KmCACCqU&Sq3%@JF,,@4J,KZU$5"a-2G5 -&!`$Jkrr),9c%bmm02!`ECjdAYJ6E)dB-DFKk5J$'l4kB2NI'IK)NF+QV!+&C9Te -edDX3'Mc5"5%U@'#UrL@#ckiLP"E*RqJ0&SJf(dQ0VP!pa#@03XQNDUKH-I5YI)S -HP58#hp(Q)+PR*f4-[Q@Zd&h0)Nc$&8@SU+lNU0NeKKp(f*!!PE@3!"eqLSD(-rT -JhT)II4$U$8F8Z@Ap+0H!'2le%c`8&[%CXVmHVR+9,M)8UVjNRPeb#*d3d1HEA5k --#j@iAQ'AQd%Pj(,MBN(mA!Q2dH2BqLJV*$&ZX8FdVbRF(GQ9GNZ)J66V,JC@eN@ -[[db-f3-Q'ab3!%Ih+D-4YAS!$SbV2YM&hIQYA0YiLMBA,f`Z""q%+e+hb5iGBaH -BeLF)p"XK9S*"SiFJSZI`+,B3CJiSQh0XdU+(J"!H))4d,CKbdSQ2,`[iS2CY2#h -$Y@p(k6(&h5"I`PG'p[0"EXDVRe[`QZ%DAQ(ZMhc+51aCi-$qp%$6EQl"MiDIl"! -TI3*P$F5,#)5NXif5@!)a`3#kF9FF,i05LUbJa2VlX-8FJ9&aK!Qme@fH,DELiZ5 -0ZlQ+`$"m$N2`HlP0$dJ&5Bp`YAJhMp-N+JDQK@9@did0TUA"+!k3!'r,Z4,KN`L -HJDK#BP,Cc4*2mD&IYrKDACk&KajX#4m(3j%V53bB&1FG`T4iS#CmPN3N4VB0aU! -L9X5k@#-)KG(hKGI`EF1rKH$m-"R8k2JM!P521$5)!JAa,0Ve,-`82hhd`#dph4L -"!ZX)(,LTHkSGpB%$,qMZDXI0J1iq8*mb(rJH#BYTp`Z"!brY41MSkbUp[+CeH)6 -Ub%TRSLC!BEmS&*App5b8[M8b!J8a3N&i8+))I08S,)E!rTrdB"XD9[-9JG4'm*E -6r0mbD'5qMU!BJ39k#IU,+kiMD+f1rY%"(('pCB@P@Xb8'ZDNALKSV1SB#qFPX`r -!`CDi3%-*JDZk-9'%RcJQip)NT5iMER+N"la$c*2SbMS@0)RL*q+(bdKcJ6'r3NY -8VIaXj"G!3JNAIC1,#1PJ4%)R3Vr03"@(LCm2Zm[Ubkk9L%D'$lca#%!-P*13!+) -Dr6*fk)H+`&!c`X9f),6,Fd4!S!dj$$J3'PGb!imR[iNJd6H"FJBaBN(eLpf%YLk -M3L4fBQ&,S3K4JE"$GS1@-XK!k(&'D8+D6TY0b,MUG43Ld'rf%c3'lN,L`ZM[mdl -lF039A9j*CCR3i#,KZfZf-Ab[lUXfS%42X+!UZHX&J@+SXpTd&jIDJqTUUc"2Z(H -dIm8e2pfaqri(1Y-0GTeU!IXFT%r@UIkH1R[QA',IUDC*XNZXUkk5ZXdQ[5[qId" -50A+e9DSbXdA6YX85m2!5ZE&$flDB!-L8`K39H'8r(LlEch96)d,V9!SrB+VccC4 -&L'I9FFMl5[!@TEaP4krABH@ih-"4k&9d5l-Jf+T*Z'VYUV(UKE#XV2LCXA+&#rr -i"8'6-'3NNX*60*'FeYUB-Gk3!)-5hK55bDI)5G-)b,SL6'G*Vr!LP4JZdQhPENR -NP)E2#cL,j`Ab#DPK*V2H6`IA@p*AX5*ceVVU5hUcbqIp`9[8Y39V'J!PD8HH3!5 -'jU6GXAZVL9J"cjlTXM63MY6PkQ&@j+a"'[5Q*+**Q``Zr+q!X1#c9B0D[T!!0GY -pDH,Tm$IRC3TGcrX3Z1'QKh4YcAQY[fr(a2Xm(C*C(I#')82[)cA1YpUM[ZcFeS" -TC`2(A3dFMk3G8YL1(DP-&VRKB'&H61'bB&fC+8(*q@3i1bQ("UG*90+dIC!!#"k -kY@ADbXmFf*jf1fei4&SpGJBT%4D`,E6C$i#C$1%9bhC5j@-+BR@B&'kcCf(ZK&A -!ZF+Y`Q+TU8r#,Nb(FIccT&6HJhqIT1H[SpL*bRA&%l1YDhR9SB`M1&NP8Ce-Q3P -MQN3a`59#q0844QGEb9N3eK@[q[2@"rHZlq8T#)XkR!DFSUrP`VUFacS%9Q!"ZG5 -Xm&&)XMIPKhQe1CG%U-XDAa"TMb3kRd@4JlUI3[S4"P4X9hR%VV,AV[+4A@@GA@9 -2hMpc#eI1jAI`e-ikhPb#"h*i-il6c"la2JJcaPUqTCQ#9T2XD%9!dPSdZ1M"+RT -S[IQ$lShia(%RIN&Ki)Cp!%rkRbQFj-e*Ai`RA&8`J0[`8B+U!b'Y0Qqc#Cm4,)m -IIAEY2afkcFaYS6i`8'%JGSGh$RAfAR8)bh)"Va52`mbJ%rVSrQA(H4bLT#U&e2a -6-361e-N%A9B3lF0T*#'!"8q$X9K!Z#-+c0Ir`h3+KkA2[Hae9[H4S#&e,5LU(mr -qQHAJXmhI-2A8G0Ed[[fpbXmrD1fXHBR#2YriYkG2EqTCfl[9[!eemqbcrpIFEcj -VEZhSZHrCGhS@rI2G[cl`lBFIq0hLaB[rpMFp1lrmUl-G(llBmLqIIpIFrR6MhjS -[2,h(r,fR'mepYfS@IIr$ccmhrldjF2br($jVR[QEhj`erqpIhVVfC5-!!$`1384 -$8J-!D53393YXT`$4A*IrZmplXfafiKVA0)3dZ5c,GSR*CJQ5559Sh-5iVKQ6VUN -0iXM@d9dV5G`MRTc8VmIZ*P'M@*U+YCEK-1)`0!S*5@!XNcV1BM-JBMN4V-qR$V8 -J)+,L"#ZTD2Epr1qpqla41X`jhqF('k5R+#H#)(J5f59HhZPfimAre#`BJ(jj&j5 -VH'N`aQ'5,(Z`hfGY!UT8QKD)Lp'r#q06&C-!fEC*qbHpP,+)TdTI%B[%8j+a4cC -N*@f9%-E8NF(QiKEhr1GM2ZYhdbjmk"F0l3'RD)')*RN`'&,`iiF``cET6CM!*(+ -B5m+!$M0$cT1Nr2QUmM90%G&cX!L+j`AE3-LXUH2UDHq!F[V6JQ"!*'2IFhGc2m3 -MLRK1R-89d45+aQB"9+K'VSEepArd5YF$%kLcP+f*0km)4(fRM,kIV!SjEG'3!!E -GQX4$h&mqLr[hqhfRp29V[CBLI@4'X'S0%JGYk$CNHLV0HT3VamZqeb@fZa#&k+3 -FR86d1KDGG'&iD2KG!dJD89@B-%Hi(aX@eYcYR[Y8QNBjl5A'IUmNe3l6UXIeDpH -[jH35[CX8Be`NSkHdQ&GX$m9T14KZFKa*Y1"%*(8ZH@Jd%&c`lHMQUR-k9lm6Nb3 -$YF1-*Sj`3deqe&+9(l@0NZ#+TX&T`*YMlBKijR8BP22E%0Q0,(A()@Zq4Sb$1!D -%!lCkBpa9PUmaMM4&L1(bdA@k"KbX%BCS2jU(F59Z(9%!+TEI4+GaeQQpEUH53C1 -h0S`9qhNmpar%pYG(mhH`b!'Y5+HY1!6!"'0F&!B&(D*Xm"c%Y'Kk9Qm@jkp+cFb -SLbCENpm'4'D[$3-**4YUmL'8@6jBQNB$3k3QG%1,%,[rhmP#CpSC@%J$YIm1BPK -T'VC[F@%JC1i9-J3XMmcSU5S`HSjbIYlEbh@R4+CJC,BN"SK!Mdc(*M,'YYf`'$l -b+mHIJ&(EKRm0Eq%qD#e$h'@VqhYEi%J60aV32"@S3c1&CRp!4,-$cIm)Y+)jJ1E -aJ!R01*TT!Am6`+AZ`1a%S`()J,PM-4KP#Y8e1909q5EI+CMMqJ$SR1*!q4[lr5R -EZBfH'9*NB$%4C1T['0#),pA4-kbMrLBR@'k5ZcNL3Y3!P#`Hk$683A9$8'(pe1U -&U+1Ha,lPPE`q%%hCM#DGCGD,Y5&Pb8Xe-b-G*IVqjMNJ&Mb+e`#2I`"M!-a0Y[6 -#p%)J3Uf'-Ej&h2UYLHljKUd!jA@m0FB(alKlkUJBY346YVAH!rGLQc6)T1YeHHN -jZX"3[eKhB6)lB('6ECDD$,8fe+R*KN2UfmI,lZp*mI5d825j2M@*a(U@@,p8BMd -5"eML`&+*!f+G4#BDEQ,%%QK*eDRR3mi'Ml!j*QhZ9FrEK`K4(c01m55!5cBDp3L -k3Ij1"5VlFKY(S$N3L#-SclCk3h,$U)KMERIAr3j5T##Ic0qBR[8%ck('Y4JIaA& -1FQb+NKJBCMQ6-5kHYZabD3lQfI+!J(V#6dm)"KE(r*Z+aHM"BQ5[H[&dk5jAMr3 -CU0"lKS1L(pYC%Pf92J-9-8%XNNhN)c$A1Z*jPKRJGZZjk4"[jrld0*MErfMNR[- -%$LNcIR!&Y[&1HR')3$3!rKp!q#qHbLN-fblYNU)X`5RQq#(HaRfK1*m&'`YAPGB -9k06$a9!,Dl`9'Y"hGANN!3M,HZU0-$D2kQaq#j1NaYF"kJB8TLTk3L*@T&4-[#A -Zi@d"*iXka&8@U9!N@e5NMP`i'$SF!&e42!8'qipR[0C"4`%8i4!2dr*ZGhQ#d"Y -TND$fY5`bZ$9[G&c*@[V+++iB$R%I*5eM8hPkVj3N)NQciZSS4*ZY&-'$,-+)#%8 -rQTLP+[%9'+kLMp-('+G+Qr@L)d,DV''ELD%U2U2dqGa$[&&0iM@SeZ0e5ah!Uep -Ya5YGEB&$KU)5@(i9%4I8mhL9UXIa-UU@$ai#2R3GVeje$+q!HJ'[rHSSAMCe%*Z -ke5'm8USCVcUe%Ce&9"+jMl,$2AUe'FEU@DU,I6jN(A@01MicBDi@2USF6I-IV)Q -MUT9p0&$6b2PF0M"Db-8@kPBET3()b`d#U8KC4khH$dEC!'2U++,Uj#JASUV9hKd -dP@i`h`$jSh[(U(S!AHAiM5%A'TImqfPLrK1D&AlZAVCMe*r*1Qm,Y6#fah'pbPp -P9(CFiAjr&6j2q"r5k`RTIfl8Rb@a,'4c-#fJRUFMN6T6VmZGGFM(3YdpT$iJGDF -qJ-mrU8p*hAA0mZprEP5p"%#Tm9a&9eQH*Vc#RK%5)!V!eIfUM-`2A1%3FErVUR5 -[-YG3d#jPb5G+!"TDA*T2N!"9hBpIA15qBe,c)!%PaH!a`YI'YLIJP0#!hedf%`U -Jk'FMJ4$SqHiCF!p*VJ1S"c)qJ9eHHBX(H0XX)1-E3HkET'jV$VJAN8P8iHk+6dM -i2Bq3!(F-C9X-5,XB"FTI89jd,#PkHSU"EP9F89PRrPZdc#,h#h#5@"3lGASa$iZ -R,QlKi9KmmL[SSKa,Xq@aA-A85RHjl4`@0f2l#kBhrJjr)H8Q3%aEKqd3Mi6LYmD -ki%669Xm)*JT%eiNI$Aj-q+(NqieF@BLJZcAN!ZKX46Be8$EGd8ZI!#U9lMN0h!V -L!1*rL#YAZlS5$9a[`'%Nm9-2-3-$dcXZ)a1(2hN)L[rR,VbXp#0hjLbKchp(Cc% -NL`!4-(AUJ)J`'r$[-1"4U31BAqCN+Fbai&hRLc`+3SN!T$l%ikU#P`,!LKIhJqb -5,$2AUbei$E#XhXUbHJZbHTCl!L1P6J$H1Pd%"`(2a0"B$FM,RDYhPlr)`i'N!$U -0cELBbi""LJ'$1NEBC[9kqVj,qr6eki*6JmBE5!Lcj"4,4M#iJc*E+9iekP-lf!@ -m'Y3([Rp8,AAr'U*XGYMkqUj#L2aYIIHT4KbGfIhV+@B+q0A5Ur9GLG6S9K)(6&R -hbY4AE#$[3-UQ"-*!5)"'PKG9041K#F38i*'"'%J*j$,(!15&R(`U*X'JXkSd,94 -28@*Fl)HaCp88-hfQV&XR1MS1Sq01L)'$0mCe'TdQG)UXkd(@[DTA`kB*3+phA&* -&TM#,1pk1UrJ-Xmm`I4SeBRr1[Jr5X89UK%Z,RbS5ScdiI'4URqfS'Jk"9!eeUYJ -e5r8K-XBq`b!'40iH6&f%F1fGGBQYGde0X+41C*f-F24-TAX#NUB9")m4NF`amQJ -(P0KT)*'-c&%d-hSUhG05Sf$EUc5pVAH*Y4Z1UTeXQL+Qf@%VbKSh5FmfBC*dk&i -FZTb"+c3$Tlh)2Ud(b3RV'IBUSCIICZ6q9c&KS$jH"#XQKJ3&iVL%)B'`j'#-MXY -8",BdhQJCYfK!@"6--Q(3Lhk,b`!)Fp`9-SY01+lqJlY%ca6c`AfTIYX+)C0lkM# -GLB%@&Y4"I"[55!('e8EQ5P0K923qDK$JQ-'b$N`iFic+cDdBh+*")"V)Z(jN6cp --&A-Sikk8-TSIl2F8"#Q3!"DbS(pDNkV2PP!&)!V0FXC"CJh*ML*!Li#UlqK6Uk' -B&c*50T-6$rdc)RHbb!Y#*"Xm9bmjKXr9G'3FRpq)9i`&2pAq%j4Pr%FTbrJISJ$ -,RiRAerkUeMVr89cTC&dh8YIqUjJqQ!691rja4m)Ad9%`!ZqJJp"(L8(fie$AdA% -BNbaK$L@#qHMFXeFITDjjjFGf2CYe,6Uk&XGeI9MZ@PbUDa&Gjbc9XF)k(Q2GeMZ -kV4rAE8cZYRj*h6)Jhfa$4b[C-CZ1Cbbl,K[15ME!HBSG"&4+"2aK!!5r@1H -jfP9)J6K3rZ1K$V(1Rb8%`XCkh5hU*3C!b(d94"ki3YP%3N8$6S#ZESDF)Y#KMp0 -H)K)!f#qD1B+Z944!@iqU#K$&9GF!b"TUdIcLH-D+e9C[LK-a,QUdGiJ"Y`Bk!"D -rJ2NP5ZDA82d1A&#l+9MA!,@Ql-AGaa35PR)h6-UV`VDc,02Xk)0UM1@JA*[GUij -R,0J'4cFSei&i3aXqejHQ5F'h('4RZ@I)'E6A%0%a&Yj"*JT5GE94#"JQ@2!1"QD -&VK-b)0SZE[&I"F"G4!$FAa@UPd((`(FaE'-V!43p"d*e&!G(,LB9p#%Y,c!EJ+# -#$$,58@1CXcL-5k&5B3(9+#bJ2["a#kLPpJA88Q%"p4)!V@Am!PSXk(8``'-hBlL -YK'""A-eF1FK*#@BbCj2EYMG8ea#j&Qe3MQFXr$aP&@Ya@&!`a91Nb[EG6STXH"d -TXSd3UF1`b6e$R9$e6RmKYQ(302MN0`QJAJ#3!*N(ef@P#FL-Ib%-keF[5Q+DQhS -p"RZB$@q['!(Ld)b)3L4ICmcKrJPkG9S34c'$b!Sr%`#X+"$YBH3MKJCd2Jf#QaJ -!9N`Ri5fYE9rVE!0BXa9"FG"hR53LaZ*hd!FCF2'c'"([LphPZIcmcLJ@Iaq(9'# -P(bK00!9*EDTpA&FY3J2#i0VE`DcQKNK$8SViei*"cK3MTi`HQaU5C1KHRMI),k8 -Y"5+iZXS&K4d!Em)[lrV9HR6b&,+j$mBC-h9,9qGZ'H6)i%qa$%6QQJiS04[P)*c -cc3L!466@I6IY@K3Gj"`[UhMFd#i&b*MB2Q5CI@5)69R*($EBRT-@F#%cl6Xf4PG -J!&0"8Mik%M)X9T32YJI#FQIl'PBJDXeJZl!9RG%#j6!1p`AfAd!J(cU,TGTd&iT -pTi9L(l13!20M&m,83cF2Faa,1Rlkm3-#$CR&8f4!0Uq!%E3@@kI$!0S2Xf5Vf%m -*06RZG#5Cj#3VBkUC'Zjdr23hY%N-ENLfNmQ#NIkL-ic`B`LX6dfU)a-R1UYM$(F -b*i0Am#''Q[%KL[X3e0HbV@r+@pm%5d4NT3i!T"KP)J$XT*5Y#"3ZH*p-)C3G"A! -NQH$)P)6"1-P-5Mm0GAbrB"#"cf81!1XS+6rcABb`a)#*NLKU`H,d0&fM'TNa'(L -$fBe-+-J+$T8"f41#%l@a5BpAGC1"1VMhB4XR-bN,)Z)5SVSk'!05)%EYKL!0$eN -S3S8L&4M9#4kdJ`5h-!&Qk&+ZF4J`fh#dF#QYEE9k9a-L-Q#-5mNkbm5"I!cSSSZ -PLGZ$Ua-bXNDJj3*qMZ2(D,`UCjpLH@!hp,l936D9CMB9#`X!qaR)2NSSpqUJmF+ -i5qE5)Q2GZ-J@[BLYcR(48AhpkU$Sd68#N`QUF8`G&%rlAZ)DJhV`)M2F08[0`*` -hA9bMEE$#3CL-8FXZ5k&cC8M6V!QC0&%%Ihi@r'h4D+c"!EmeF@E8S!V'+&b0f#m -$3'ZN$JkH$$QEdBQ61[%lJY"0V*193LGeJNPV#MRk0VQrQpEjBI*XFcZmeH'-$P! -fK9@-J+X6#bkfSINSSLISie1-YhJSILhbpHq64Z-3UM%NKD-1`D3(T!-"*!jd5Zl -VlG'9[dqH49E9L8Bf5ZDf$,C,L86QJP1`HlUJe$2!,URe`h3GaViXpc#"U`XNT%# -dN8FHG54jNE6j!S3'N9ADJ6Y2`YN%#hE0iK3dcLGe2FSCLMaIp$!&[G,YKBTZGRY -lLLM`a$!VMQFm53(ZUTL9%!Q3!)Y*%JpFD-Hb*i!bV()[NS,5#k4qR6I02RJkjbd -%6+qQqQqUTKH[p[rjIr%NNXBFUQXpQ3+IBmSU%0dSL5A81[bBmG-)-Kb3!)98'Q1 -,[K99&Z,XC6+DF%NMI$)%Ed"@iU-%+L)-DDFU*-Rde0e`3*mpeNk9$1J3*98l@ac -NdT&+*RYi-lZK'(,eFHQDH(IqA3(r6EJ5cTa-l[F(Gei18B83eYfA"K,%2!X!aIN -N!Ac'fSpG&JpqF!)CXN-mq&`kUQ1F`*5DpFN2SC`KkJ42mNkpjX0JjLfSV"fbS%# -j8Hd3&2M`Airr9UMNp6#0qRQ(N4S40"3T`[9VJ$-!b-IbB#lYZ*4QE(BGK8(R++G -'+hkFq1Q!S+-6,[Crqr(*D)3K(11L$3'clhM'ICXEa[lMe-kI5C1N+5,`UFB8Bm) -%aABX'8C9)L$@h%F!KiHRQ'NCANIf6YG4P6D2ZDlqlfpUXFU(EN419EY8HfIp)$R -m1@''Le%RZ*l#MimaqdqAql5kS*!$&ef)ZPhJUSqZdT8l,rmX8qY++`8H@TY6Y0N -@#89aT+pH8fC1"RVeHDUI'CVfJh!deUS*&iKiR["D[Gq%%D59hp4FL4)K'@1'L19 -FmeF`J%6P,'fS-MNqIR"-4T,HjcB2$25S`N,#$hc!JSeZ,9!YRHMBE"Y06d0fZ$" -dL0q!bRNMGBLI4H)0,,qIP[D[SNrpfj+j#-Ml)Kc1rMS2SSTJ,YT2,Q+8C39cNAr -H"3V3`N#"0M+&p3BjC3#Na5m`C99GimKS&UL,"eP@bf&Cl4)RdfmTXY"qbN,[P8` -Hba!1LSjEcUb0P''K[KkmU[%QB%UmJHSiTSX,*[4BdbQ,d3q1B5+UJ$46%PKLd%i -)QIaer"lS[6!J'6[&r[4ppZ`M'8b3!+Ak5bQk8eqrB4BhXH9%+-YMXN(&*cG5%%D -C5S03bX`X523"c6IMXj&pTPJ!kD-!mMDK'c+9'q6VNY%PeMmQ%@G1--@ePSZ[4AI -iD@6QfS-K-Q9h8,D!N!"1fI'f`@ITNc*'M&09M)*Je8B58j%UYq51-K#pAlP!KT[ -8FqGN80C"S)`*V5NJ)jG+GYbULG"AA49ZFh0TQJ6XCB4[@%EiB&D#Q"QLHm-HS2, -[fK'QqHF&K+PT1d-NFJ"FVIMTr5Bj!Pa!GmLSeUcjjbP3!ATCcBB"j)SK9"*LCF+ -'klU)9F9'#E(5&NpD(c0T+"!qX'$#1c&*0+@jTC%&6'3)MIJ)eANYl-p2q"1XqXT -A,GckUHMI(*6%1Cm&Eh&C"09&e`dRqhmI0mL"iM!#43-kVSI3UH@(Ukj`@h'!424 -FIGJ4!,j2dlM9MLU#*0Cr(iN[JcN$SIL(B23rFP9[MUDLiYLa1d849De@29m@,Q3 -LplekMCFBI88FDkV55VbJ9eR5S$KfpFp9ZNNqSF)L!Xe926d+JK31Q'8kL8UJr*L -58C6T6d8D2*)l"`@EYpV&C!k%JECc)Ir$4@)5`eGR"$1hLdNb`AE!i50J5l8*9mM -p)j38a2(MV`4%E'fcGdlJ1b3(clF3221T0L98ca5XB4",Cqj[Q02(5hDM[3jU-,r -'!Q1+!8DbLJq,pNHK#0Y0,5d0Y3d5dV))J@M,C)!UG$+2`#6-m9%F`N5YT84jU6G -rZ-US`H8SL6UKbQeQ961K)#pj1ic18#&$6LhbIPmLEc*(Q%Tdb)#j,N%P*qFdM4N -,r'Vp,qqLB"f([ZD43R+h*#IRQqVaM%II!I%K@+INV'BSY(X!T,[KrT'aI@ri3,L -`0!h"`L#KcVLmAM$FM2aS)KaUM5hMA4fD%5$3&QI3!!G8S%B6aIJMj$bd8)`r5Be -KFL3#BM3-Tk-qE0L%!%K58b"1DBGLZ[e-#f@GT#d58'a4!2*LXCE8%kU+m*Hj+@Y -T'N8)a`i#IP8dX3fS`2#A06(DB0,DF"0GYD,lNSCD9'Z!8m5$hH3Z$4+BaLTBcQI -9A49bHC%(XSijAT2VqRET)T`J2S6#YaQJCM-FFc!X[QJ%6LcZ"*bG4Vp[F@qi5DV -NA,N$US)`MjQY0J")LH3SmL&BcS6@4fkU)icCaqVJ8$TAl0BB4MQ-T`05"NG9&Kb -'CEHPPcBe4KR)h)D&jc)30aH6K!-)Q*Bj`RfR8$ea(ZYXb$B3m"PJmLFJHbBSUU, -0!N0VcUiTCZGmlX92d0+Ad`ZNRlU@0aB%XbELZ%X0IE%iL3+f6D8$&`ridPR@'K9 -2K@dL'6F('4!QeD%9)P!L%CrMdJfY5dQa@li%d`K8f$JC&EF9dk(K!`(kYK'iP'6 -mYD+VXU*b-NJ@aL20B8k%bS,SE'3L9!RFcUQD,4$mE"Tf9XF)Cq#+qbm6L@lG"(! -k)"2T$9*20CV6#&TN-NhUIq3Y)MA5f$QH8#QD0V&,380[+XiFJ$e2&YCa4U,Rh&Y -J*-J1062R*K`XULK#lG`k&eHcL8#*$!fpa)5YCjG!PQX-[5*6YX+RTTLEF&JdJ@- -jp+VQ"i0d!(9U36#6SI3-DI)'8L`!8YNR'G*Y*2Lhl"+9RT-()IChY4cXYI5a3qb -cNdI@#h)'3!CCYk3-B)-!8miJkciR!5C&k'bSDmA86[mm0'BJYBXKF'f9)6-MIG- -e!Nm`H$b)bPf8E3+Y1!`hBpYdGr#6+ffS3JAAbGA%,"JULJ)GibrD4YP&cSZ0&XE -5ITEYjK,c'QTeXYeQ-Tq`E,G*kJ6CVVbZ234a6+#E%B@`F-+am&Qi[mjM*(%$PdZ -1CkbpA5)*+0-55GV)l%e1Q#$+#ib3!*1-N!"l@&9@ZKUMikH$A$Yeh'861d!EQBU -0rK%LI'BBA[Xj-9NLlV@jGZ*HqcB4plBk3e3A[B$V)(2XZFN4)-p5hjD$j!kDYZ[ -AK#cmGFi3-qj"i"a&NMpe9(dEj!54M3R'2TkcRbA`MBLXS`Ym#h8%CE-&lM2"jkc -Ufp*a$V9,AA$[6I@+#RFFFUr*6C%4)bY9aih'%i)ja@%5mSa(A$Bf$NN'S@j#HE$ -K+1ZQ8"TL`%!AB)6*JD(SF4Jbc-Z0NSJ8D$a8iqaTACA,AeJGY28'P"QcB2Cm'8d -45ef5Kp-$e2U5,3+8Z*P0C5kbEMd#[+5)K5Dp#E6jE@+I5FIjVh0)FS[599`aA"H -kl@e)jVl1%$6jNa"S-KMB&9LSSi9fpCA3L"D(!RXklH)*J)@JS#30YB2&4bL,XXZ -MSGMc,6'V[G#&MlR82qPe60-*-N"`2[--"4IhPp1a-%$Y8+lX,ShZf3*4k%lVeRH -DPQHTDC&"Ha+U)Mclb9(ZFXm#Z#b[1FTlhF0!6'EVRjjLe*jf-jZfA+L!eM3`k3j -bpL46,Y!44f*$cB6UQ5mbmRBL36V!54ede$!Sc#b66!9`9&9SLNDDk+qd"k8cS13 -8il8)-F'NjGE*c*4%#'YXSmK`*#lX6Y8-[a1V'Cjbb$,mcL%)NBDR5-J1`%N'El5 -0AJ,a(1T$BZr`&"468MAmc[%-6DRH$m8rLB4+*"53!2Z(3cbaQ$U3!$FDT)SET$b -XR!`dC#(F@dQJ0pr496d"(rV"PLCXQBZU)!#-9,N$@D#$$9+d!6"J'&A$c`l2`'[ -@F-BKG$Em,&k,KfITlFk3!&54Md6UrHQlR-krHRHr%b#qQ9be#i*-M+$N[lYcX9k -0h@dhhK*6l%0HGKMU#9LNf5M@$$qEI`D[@IQcZ'614X+bXma`bpLM)@0`Km0`Zj& -e4SJN&G0!bXd!-k#U8T5rAQkmMmC'kF0$CVZ0&1M!*3h9TI@4+HCVF+U61k'+S+* -p!GPed#NRhb6RHNNCBK'9mJ)"R381Mk"5lcNXJUjDM#dDUXEpPB%,b!mC'5B5qY- -(`Q+1Sh#Le1aFTc1)Q#Ck+8hAPC'Fl%!DZdP%`mPK$DSLR!088AfqNj5%d('4`,U -0E@KPVK0SL,BZEpK+!&kk1-9X(BR#0EE%5NCf%+-'$ST*!Z[I2j+b%[!lG#SIebD -ekcTYNQ-L15R#CEB9@qF*#4!LYX,!5BFN*CNZNG0ZUrBa!`bIS#9pKG4%B$"`[-a -G)PVHZK)kpbBXip5mjaF[lS*DJ1ENM1hCU!D"TUBaTiNl-5L0AE@8L*T95()-MlQ -lGe*8J`B,T4[SF,bPDFH5E$ZLN!#p(4IFAN,$L'#K-*M'`"6pY941E-AMqbB'U5, -(Bcm&kJ(('M(R,cf533GJ+%mmB0PML&Tk`cNVHRLc"$aaQ+1"XcIj#$q`b1hej8# -aMDC)X@dFDL'R0Ka5ip$VPjZIR*NAC0'[rD%`Q#"$$DSX0$Bh&`G6HD@[@-k9pZU -TU"60cZPNZ"9cB(!KTEpV"%")0LRT9U$e#S'&D+P**dE@`&`#`IJed4,6d$3F`a[ -+00((e5&#PBe*pM&#(mJJ9F26+'0P,k3*R-B%#0P,@4b6q-SaLDpd*['9eL5qSNR -%mNVh15C4,dr#)Nr#41K!HKVV1*,LiPHQZ*3*d)AbM@"c+DS`I$8@heaSMikT5(K -+5R#0@NHPT'm%VGHP5(Z4&iKm!%YhXk@M1er9GDC[U#@(9#!kTU[FF0%()qb+mPK -TM"p4,5lV"2YRMYERHDh28Uh2keUIPl3qcqTmTPmdU2)"D+U+A9pVH%S!*H8J[EJ -JR$#[6,f%3UjHJJ,l%NMIdahdlJel*Tc-#q*B0prHSb6@(ReQj0'%f$EbfTEF@0X -pq`U$kq!iK)dR`p%*4GK)"lripP`H94*E[[M*qHd*8ERUI$JhV&`fdB(&,QiG&Nf -i8!3RQQ*f)Hlq%"IL5X)Rk[qb,5&'VLaER&XGZEcbbFTp`Hhl4!AELl&p,pYZFJp -MZdP*I2VIGbaDR4!p0j-EFqXmPeZI,0XGh!C"G(F`E2)Q`K(jJXEGK3XD*I'l+mZ -qA*F3Sdf[2CkELYlcbYlJkT0D8cc"RHlYf1a8%JIf[&qhp924G0Lj+0GX`Y#rI$R -iD*(BaLED*NqdfEd&fjZ94+kKH`@Ek$)fdCAb4,p`6(32Zp$KrK`A1T6%mZiIUQb -L56E49Tf*lR&-9(4lX9e8%Rm+6Pj(%f8Xpc#@lb@@XfP'jHdqphTXpbQ*9hV[rj) -1L$'p6@)k(,,QEU9+3d$pfB64N!#C(h1[`m@BNR#l(mKR8el'TVb56CNZY6(fYdh -!"lY5lGk%+p9+BYHPYG0SfZ`!&2N!pY!"`#3e&`FJ6G[J,XF&Jj*iU'GPH)N(X-G -a!%IFdl(j#&JdqIqmFCXmC$B90"b6+8(9q4*5+lT4)3N(JUCm*%2ZLHKJ5%Nmql1 -qPaNEPM%f#%Hb#"Ga+'E1MJAGX'YMlM@i0UBN6RmHIfX*"f-#!a4T1kTH,9B5FcU -IZm'1j(8kNRZP)e(Bi4@c69Z8K(IdXp(Ej)&Hr3DE3XRPTfNJiX80`c*4aqRiF'' -6NNLG[IiYGJ!$l!$Uf3%8XS116`L+EGlLB!+QSme+m,iCAmcD(J6M6Bca6TRaFFE -+1,%5A@jA%UXE02r''2ik-IaHLH%5#A[SF,"YRC,`pcS2E[K8M,0"aU8KJXRcee, -a("&'`%$"j'lA+)PeccqHB+`GB+bYPkHdL!4el1MRBa"&E(ZANRMXYLFQ-TDD'%Z -GM+@&K06*%e2S#T[DHLAieKpq3BU00Q2MM'6M-QXR+SQIreIEkY[N`N0NeXkA"Xk -!L`ki`)9K*6(hMhqrKkE)@"ZA@EY2bN)kV28U`A2AR3Z@`&U6R$%P*NaA%M-IZ5r -bRl$f3b8arjkr,D%MCB-d13lrjc*EKD2kA%Q%M[Qh%P1[$)"0a&5*64i(NiVB%-Z -9i%rVqRG[#iU4%40B4!ap33)(rifYq3RTi0hcIZ"LJ,'$!10p2m8NLXA)A`A$#Y[ -L94*lrXqF"$[d(Hc3DfAQrC0SqR%`('AE3**9rq22BFVJ&1#C&HX"e`('Z,D`kE0 -J1-+fi6L@2cPNBXaiQTKaq4Y2[JKfl"%pr`,fXNh)--p-fpK,C$$53F1q6`idIK) --Yl%Y)*46Mrl2QBaC1aLcDKdC*Bk"HpJf-'V1MdmCL9%dT1SfDlHVQc&+#FFr%`B -1NTlf,p2eM!&2Xi$K'd,!i'!5MM$fciIICm2ZS'(I*`1M(`Y-fU`N0MlrlAQ-E(B -`XUN9JS#I#*-(DDfjah"5B&&BX9jdA@6$rN+-riX`E)##D1(h)b`62-db`6INij@ -',E&J[C,BZUEV"`bS%*-mpqdEGl$P5Z,a[rcU5CEeGV#X9fX26Kf(L`cD2Z9+#3f -F(9Ymh,&*6!*a$Vp`ILF$hNmc8[q'RG5$*q9"J3PcA`Vh-MDe%*X@1!Jp@#3c!BI -59qIq*6Zk9RCd54Q!,&a,e9e"kN%dC'D!A&kFrHD[f54@XNNXFi#2K4+jje'9hB@ -I8CAGl8T`rKZ6IN$NIU@@X@k(!h`X4-GllDcCqF"62fI-Db(Q,A!!MQ#ac"JFeQp --kmrF4S1L!TaD'GKB+!eA!"YK%jD2XXAA39abcpcr[m%,!PM*#'#C(@`%ppK*qf6 -a[feJM+aPM0ba"%BL`ah,2Ccf(4Q*JmZZIRccH%B+i))aaX1'YN8*rUhDjh`8J1[ -+5JBZPYR"KB-T)2(MmCA2XdaAbd$&$KP8k,)&'HrqJiIc@'CTSFbb3!)@#KZq!a$ -mpkf+$iLNQPSar$L'pL+E3&4R!L#TZV@hrjKB`4LQb!`VBL5`4bB!N!$j[AY[qbf -aJKeT9$l52Arjl9r2j0(Icq6aY61jUIrhQK*GYBL*"lPq'4RUYb3Q"!dH5ap8CHp -EL5MAY&aGjNfm&6c#*E1XM1,H2X*[STk0T(3*VUp-e9Kf*[M)VLGhR9X`R2h(6ie -*-I*N)I[`LLXf&9jGGL4URC!!mUIRAFmE6Y!L2N-eIh*hFG#AK`(8hPid)9LYKJd -GI0-ZRqG5hR"3hT!!q-2ZNfI#R[-BRPRHF$QjTXLq`HTbZ@K,1VE%,JTG@(5kd$I -rBGE*9rAAVLklr$5Z*X)VlYZ99el0*`4pLD[,I*iF$#PX$AqGbB@%2q`U1S2Yp@` -l5X%9%JJ38C,23p-)IlhHNB4&CKDGb6N*"DrASC!!DDTipMSG9BiCB#59PVG)aKK -9N8d,q1#&ZUj6XK,rQU`US3U9',4(X%T82IB)9+25q8a-YRqmTiXVjBXpiiFJVV3 -VB"U[Z0+ZSY'RS-MKic9lp(Zk)#qT#GS0(ZdD8Z,k3$5T&BI9X1GbqkDC%rDB2Br -mjZ9%$"9lEUVK++*1eN8IqHRZa"8Z4VB8)J0f8!B8AmX[ePrc&PpFF0IKP-(%pGI -#dFfl*J3[,RMhm0lb$Kk1ZLjD,e,%&h,%j@CdKSKrBK'a52LeciUTJr@)d1eJeEJ -1*XS4d[AhTHYYjNKGp#FR,Gd'aAliEU-BHEJ`(,RF6L!Rp5N9!"0ZBam*L,IYMSf -QKPT*I$kFcCa8JZ+Tr2AlPG6@RkcI15peYiiCl@1fK[qL[G8p)K64b+TSCVP(B%6 -aePa4hc`AFTI8A0ReiLrZBFC"4RK29$L"6X1jr(YFa@XHpq2e"2IJ04m9MV,FbhN -%VfbZi1AQE8hNR*idQQ1Sh'q%F`bUd[dS[m2eZJkJL'G'8HerNf6N@kid`5KJ@a' -i!dkIUq6K3'#M8k`MM'iD!NI-X-J-6#EQe!X$6m8q9Lff2T4XTq+SEd%N0K[QKB% -8Kb0$R)S0J+20B6L$q#@5JJ"iRM`--d4CU-"-#5T(FB6b*MHjD[)2H+"MD$VhBcQ -r[04PYJ4-X9M%!+2[I&Y0fDT3+a9+bcAB5-khm`eMN@@c6N!iEABX&!mB)-UF(fT -KaGH#X53SGBAJ#&ilkdiQM#UheA`CJ-YClN%d%$&*jrVVJ8Cfh5GFEaM6rrR11dQ -%K#i'U!Y+Q&Q&LbGF8JG'R3kD3KUGcr-35@ABT`eMeJYkrR`iC58RHA+6DKM,19H -DJkP8c&`Z`S(%AB&03F'"+Y@ZADf!$5eGFKp'S5mP9,5XpN!0I4"iV4#'DNqmFfI -Q6R,5`e*caNe%)alX@r"P`-)U+lcHpf@!()-Ki0QY-j(fBcICiMB-I*(fNZKb%ET -dcVU6R+*0P643pk,-jSpKIb-4e-b*aMS!1V#2GHrHhfV"Ka4e%B0C@3Q5Kq&DfNa -,"cTdMRdH-rC@66XkmkIX&A0CA$Nb38CG$I`@L*N-MTGKX$kI2BF%80RcFbq6%6A -h6SJ@H5X@JS-1LF3pJPPiIpL#+1D#ca%NmTA6qGpa1B)f&J4[2%VXS@iN0jGX$#4 -lMRdJZFr6U`'$"Qh0004-bl4kFi,A8+M%Y#biYU'Cq`D'cR1,UAKA02E"A@4d3a8 -fMX!ej!EVC!SqhXU&S"&$[T-9IAXC45a!I-fF04ERANE9I4qj#E#J5NI80[-9)NH -@55k3!#"DMC23dqfHHF9h0i3pGe*4c3)$K@a$N6LQH@6kaK(9Xb-DBpIEY+ml,TI -)SY1&-hmU4H+!5aTUTPPCj-YSpP-PJjQrPDV,#fki1Trq`$Bf6!-MNAN13KVKEVN -523N2YQ"!+fK!6"aEkElAU#(5B%%K9HrMF)&-cLbL)VTRYV0LVHr8AB6%8B,K1RZ -Z)!CUV5Ql5b)'e)fS+NGaMjSBFm@b9`2*!lLC5SQfQ2T'b)80hj8&rB25&44qh%4 -092XDk9Z824G'rDcXZ44P2D(1KU[ZEZR`p'SkJ5i,*GQl#A6!DFJ%Ce)8J)`X(Vb -8*Qq(Z0DIBSij10L!4V6"aBN,8c9f3h3ffcVbY)B)K`UbY*')c!PAabL5AVChSMi -X4+)c$4'b**4`FkV5ckkA24J@KLYeplfcc0Nb*8e,R8e,`kRDM+`5(lIe#!SKXdq -eQ!4UJBR[M6'EVM)h6!e&V84Q9GmBS8*UkKJc9)NCL'Ka-,pCKrNQJDP'+YRr2E1 -8VhQ[,*hrcXHaP2ImCbbeNa)9pl4TX64T2L)aTB(F$U6U3&5S8-D6e5`)E3eeXXk -`'C85CqX92#4!Pc8Dal48h@PTY!Tfd5NJ4G3Z)!8&[,5Jd!Vc8j)Epi$4*i[`)*+ -TQ!c5G!S4el!9`jT-D)5pd0c1SE%adcC$YaKr[K1&dR53!)LkB5cpcTfA5@`lFe+ -U2G@2606R5fp5$c*%U`UXdLmM-5Fjij)VejDJ-DTT1HdPdeF,UNC+cVe`P2+0he) -(YFGlFM*[(4Df`Bdr)V[j,[Zi#qYd,m3eNEXj48R$bH6ZbiIkma[&IT!!p%9-BC! -!Q[im0'ppG)AAjPmi4)A%Zr0(@F)C*245dh-EQPCU4TaSpQ2chqHRdqCDGlk&*IL -3!(#HQXT10+p6XqeC0-pLFhhq$GUm`TfrRbA-3-)*DXE[4c16QXNK029X%*IP365 -a"#X5EP+cGKHDKkPT@S9Q(YZm9pjF1,l3SKK6BD,6V9@9Gm$0VkCm#d6SHS$BGb9 -h$eG93E24iUXUhf)V2QC,43QPF-XSKGYpb&B31p4A8)eY4ckUbYpA),V+#UMBP*V -bLGDU!K,JI8JG%@P(&0XSR0192rjmFP(@M'Xe"FeBZ))L3e53!0!qV5+(C15BLUj -$`5HN6$K&PkJ*1f'H@CQI5#@S-20`0BFK)Ja46(lLfaFKpP[T@r%234r8Lrbm-&4 -P1(hQKC)2lqCj4!P'rm1l88dPUS@%bp@0C%A1[*4SFN"5MTFXML3@YM@Ej5,fE[, -,2(8JjaAaJ#XhUZ!(eC!!`kI##9'e"0qN)P,8('V%4I8m08bL@NS0MDKHTiC69#p -4SeP%SEYSG-"GAda2Q")%FUSqT-kU9`)3(#RPAA[A"2ejK(L%2k[QhpjEc5dR-b# -%TSS2TEXX`U8Zm3"9,HhrII0Qqi#Ad@#CF!d$erLUSrjBG95")h@Kd@c*NlUYJl+ -plU5rQ$kU$IhmVC2i`6+S[,LA#U)PaIbcee!"FJpFI&Hpj)VkAqU0+M"),"3@!KR -N#H#!JH36r$TlK-9CZ)JLNAeBE04-dSC$*lLa))qBh&#$UaPmM-!ph!rFaZUDUS) -mHK!(%Q0U2@e(Ja`p*KmD,FK,Tk)Zh03N3lHMB"i2246&#%AJILr3pCfSrZJ'-(k -(PTq@(P*QP&A1bB6$-A9(aHd``6fV2,LkV(+H[)d+ZJ$`q5dqQ$15Kj&+66NH8I, -Z"HBbTQ&$l,Ch*,L"8&%qf(DLUbJpM9Aj@iaUL9+hVDbi(`R)dkCH@L!pcIkJ!V[ -E54-FS06cZP1QBSL!G-%&eGdLX3M&Iqbh&em8%`S`%UN3*1fVV'#I+DY(@A#GB5T -QP6#T!aqFj`FT1"cP!EqPEqQV!2LlGE1Ra&+JfbMP%iF9aQ-hb$df6Jq)S%,1#[E -3kmZGY%@V`Yq)fSpJX*FjfbY-k91BdTG#K&0@FPUS@#VC8'+Q"h*)D$`#lrTr+&& -aH$i,!VITfN9pbBqY+#XSh*R#N!"LYTVbbT!!4SUq@Y19!)%8'Ne5a+8JI3U2mfM -``)eTl!PbhGJLZIRP'P[E!leJ36%H%A*66)ISb`p&q`4AS$#Df8-fXU8LY$)lU4* -k)lNN5K(eF-G@h&YUF0QpX8P&`%0S0d$UJkq@TYN2Q$'3!%MR2*adiL`cp"0#B5$ -&3(+I3P&'p'NmBL$#MeZV[Jb!M#US-3jY4b$26e)J,c'GVXQ)kcV"fB#U2+FNPrX -"9P'`C5Q5EC@FY)fGV%TNme)E@U30$,Q"F[RJIPG0`FXJUE++'B6kS*K9&#G#9Em -*BFPH"e!j"&)&N!$'$b'0TB614Li4%GkrPkSXKY+T+#jG3V-&dp1%`KKH(bei@8$ -P!ZqYFfVQiBF&AS&qUNk,,!X9Q5Uc0BcGZ2Nc%FND3cXV92-Q#hMH8pI4CaR6m+J -VE)$VVA@%8-@5(PS)#'bRX"5FcI`ilK3Z*Z9PR$PTV%TQjNHMPHX2(IA[,mM&beM -`6%25&@**$ehM8M9lUH%TNKXRjB4-01kL5Y-0F)YSm&#Pk'LRIT5LN!#41d2+SD1 -H``A2%%R"JEB@kK3bJ1RC5fQ-$5C@94&$UVJ$4SkDbLkU51-r)444%fTN&k[K"Vi -d8B'C&AXaQD28&4cD&)R!'L)dH5Tblm%VM&K3UCCeJ`*(*3DaTCI%PUM%P[RC%P[ -8ka*E9!Za46e1E#&bBiP253a3(j!!'C)R0iVPK1Yia"B$HmJXrf9RMXH2+L#kc,P -Cm!`09DIbEP)i3,JqDV'Y9Jmd1D*cY%YNRhVqriCpM'h%)1l[Cf#J44jk@F8lK%) -6Jjl!`iUJcQNSHper3J+&NP-S#S0j&J8,c%)9Mf&bTK6F+&Q4#QBS+,-*D4!++2& -$NAC2Yp88r"561B,'Ed*Q1([@X8SDdd*K@dhP(d2KZ"Rp6`qeq,1bh4#)C19[KLL -'AY1-LK4TCelS#$*Y)hl-Q)LCCI``QNGLT,jrL*r2-4d66HI"',P'2hL,9Af+K$V -PBVeDf9![b%20%BCDFe4YG@r(Um@pQCDVjYqPS-%c(B@mdB1d8+c'9DJ'l)&Dq!M -JBh0k'V&"F0aN#`bLN!$6QXSeS6UDG-$h5@rfjTUql)H4Y4pR3'X5N!#,-rK%*`0 -6+2JfeM[B2dZUcK&U49GY+&bJAL"JA-6MX13L"fl#J08MZi,h%)#LSN4kFZ'Nc#A -%B09j#6%)T-2Xe---AVG`C"HBb5D'KCj"*8Fc&EV0UZUIFYqL$cJ0@CR$HBp3R4q -6+mANB[VBErLBVdQd3+QE0,hi8UXFJS0JpD-&2)6PdVc0S)rBG)SS%lJ$`$p2 -$2KJ4,3c&2d*4f*A[`mK99INq82BH9dhP)hU6&`lQ+!a5fJK&%&RDpG'jr"Cl&#U -jR%1d39+Ge6G)DE,5JeNL9Up31"H1,)k'"@M@f`M@4#!)U&32K3X9dPZTbUl$'0$ -ZB4[L8N%J+"#4&6KL6Em@`3(P#J%2@(%'V(3DqjIZMMDeaf"@1+(qm0rA(FZbF9X -[8mQ25QSZ)ql)M9Z1kVa@&'YT3XR@q!(,1JYkN!$jep1$T3"XPJ(Ge2bfV#!A!A1 -R'+HQX9AHCSmLKDB&+*03%A`E1912b8AciPMU)DLMThkdrf-86UcYV'*"NNL8052 -A8#6$XPFC+3h!"2`UA"5h@9kaEi0a(SCD4'`MT)!C"lD0G%iHCD)l1*Hk0aFJ-$d -@r6iH[F+50i1B0X-NDHBUc*4bT#9)d4[)aI58e!N+e*+0rTl(f11cULPkJjNpQ%m -BQ*m0,)R(M1LC8A%c$8N2B'"hR&lZ%J55Q$3T'[AM!r[8+#SM!B8JYeHBHc)&``V -BBZEYfCP8l#5U8k!T"5i4'c*Z*L%H&-c,!*UVff)!(33iPYX%),KmX5i!A$jA&i` -#lBJ6q&Xq*q"ie0EbH`Nd"P"pCrQpicDEC-3DH8$R`NBmHNX'BmYR#i[4m"VDL%( -C!ma!N``P*C!!$`6LC3!6TD'00S&KHNbKGE$p)UD0kMc2iN%jXe$`RKC!Tf$JGqZ -BZXbMk4FaUI(!hBEKKK3fG)99NTb'U)dK*cE2AJUm(Y"aF+HZ$dYGHqBi#P)*ZLU -cTBSA@GNRPJ6BrZQ`$0KbE0JD1Si,!jpdClF5B-[Q-Q"V&('G!*XdZH`"LUK*caB -*Z'@IN!#!@lD[jN#f!9Zi"0a`j8ek)0[F,I+`M##-Iaj#%$pHq8PaTPcmKNL#+Q4 -l"SdQ3F($Cda,ZAYF9lPErM(+hA+(FQIf-&GU0YNIhk#T%U[QjNL$mUmIKa!R*HA -Yai9,82#F$8QlH[IMJ+6HM9HU8T`4fiM@jP[8'BEV!K)bUSf)fRS*I,&L48HT-$q -lbQF@9$lc`9k3!0GPU8KP"NSJXR$V3AT8K%VQEQ3hbR)8*---@Q(D)aI#Xim+q`8 -!L!L)0aR+(D3*JR82Ih)&S%q,2"qm*E&',5$#08-0)M*$FI2EDl+@fk4J2#8(ic- -F`AMY#rCJ[(D5&)`[NEa"!L'&Ck&SLqNI6pK,C`*G-UqB,!m4KG8!'HKHrNc0JHA -2%QNLick$JQT(TjLTHJJB6LML#d#Cb`V1K-i5NS!(GMiqa&&XFj5jSJrGLRlVR-- -4)(kX2Vf2JMkjURL&[DTLCMe!Fp5H*(F@JcRN$*%e&Ga9-$A8LZ%Fah$5X@%U"R! -FQ`DJDZ"K@9SQL8b*E-@DbRNS9#q6MPBk8TM5Ap!pE*!!&bS[qE1d$reIXh812FE -366jrZfiK2,*b&jG0B,+!PT!!cAC8MKG%B#MDQ)V,([0XBBqcl%mlF!dIp)M9d"% -5mP!'3KBZUlMTXc*K6mfdANQ)3b)@'"5N5akkFLNYX&kRf*i5UJ`1FTq%RmP!5qk -!%'VRSDVb0HA$l19&d"V2hiIJp"db4,UUbVCMfhPA@GPF9ePPPQl!("Vi9[!"+Y, -`q(ITG4iSp)388!#G3$i+8,IYLPVR%522Gk)+4C`+CAri*+Tkmaq9C'j-9C9heBh -4aa8bh1q146++M[PM(TK'ZaZL`X&3GBZSjGb#bZldhHQlfD0*-qijE"K!aFmjee" -&HU()#1r'e')EN!!!KQBr%ZV3`hd5P89U#RUXhUjLSeq-0V"#iVE-6NmM3bQ*""Z -N)P!bdD'C'8mc)N1%!YL+k%K3l!fBmme2HpA6Rk)!3cbB"9A5)!1(Z*@%d[2)-2Z -MNUUi0!@M[miMG4+G5a1SMM4%(&1S+Hq#U[6be*25*9UN+Kk6,p+%meq@6-*Pkme -4RDRAP+qRap01,8D"8IYX*qRL-FiR#XaJ6*KhVDEb2+E3)Q8r2SZa`FIBd!NfR(5 -`!B@4L3S,B$#FarET-%+4)U-hE-A%i'2lcbdS@kql4"Q!bD)2f4,@F3YSXlQ0,B" -K2eC0#q5rc"CSNb+MIXS8c"f"Cdq3!0MPH9qD[QFDUIlm'@44J)IlZkMb,Tq+M$a -**bJJFdh9phV`-i+I)(i+MjI0L`qfipSNjSia(T!!Rk8ZE(e3R+`JhMZk4k%#hq& -`Y!J'Y-aR61L5A)*bZGGZlX(M3FY+FMp#eURXdUPH[j!!9!"#`!"`FV1Bm41&(3, -P6m9&C)UZ3PS34#pp&P'Kj"3")&VLUd5a)TAdL%%@R'@*0G25S6#@C1k[UCU@lTk -[E659+Y"5m@@K&NI9[kfS9S3JI8'VhNfU,(piR"RfGM,9!U59E$K$EYqdd$'&G9q -LeAd*96DU@$-N"+eafNi"+Jf52ZKaMc5YZR(6SZ+3!+DH0%DTm8Z`J*bI0[`F4Qp -0Z""&CPdJPi#XCNFPbUdSr!R'Jm8"'#EFaNC'8LC@k4iCHP-&MY"$iZQPJf95jbA -80qTi$#`Q-*brS0b,5XC9j9k3!0SD0)D"'"jP+*5*'Il)!$aX+5XITS,+l)r[N!! -+epFeemeJ"dL6-&jbdH[m%SmK+6'+#MH5Lk@DZk6KhZqPDd1i*L0465L1H6iH&cA -IMMa05mpkQf8R*l*685!UHSaa18X9TEMV4@lk,p684$%ieAJFY[MY2Zi$#2,,(84 -rL4F+*GV1@$Chb5a,ekSDKi)b-MCHB1)RKiK44`!9K9Y5q"$B8KR!be4j&!(!933 -,QXUc"0L`42NJc)P%F"ZIcG%aXNV9eqaJ3bjB(`q0f(JBMifq@lGU(KA4p4f(d*L -bTEq5rSTK"A8e@-Fe+'3($r"'l@b4233"aHV`D[B)"+SbM%(*3i)"8,FU(N6*cB% -@4Q"1aZ4k@3#&BSBHhJe@84FY,1!GN!#BNk)UEU38UA39`YCppL[C%bM)E',U4N- -Ilj6G23D)Q-$S*LM`TJd!1(T09eR"fr6J9GP-MJSM1qZq-j!!Q[Qr$YeGm$B#U'G -+dpUV[Yb*SUZSmlJ%A*T*ZD0(eM*3-6L!)JG,b%(009[+d!@jakj#E*2V,M%H&3M -ffJ!Me9SCA-5[pI%K!)0C-X%ZA$,"5S5+l9IF@h(K*K(`N9`q1JJL&X!)UGaV[4Y -Q1e"l'@49`9(QQNFS('0*J%3("!c!+&"2B'#,m9S[[`A!95pY+mMG-"Y43l+$'d1 -*1!FaePH@%RT5H3NIbFSQ(-D0L`J+#88@$RcTE4m"P9jkSldb,T(TT$Ge$6RN5!H -KL8,L5+LK,aYG3-15NRYAR5IQkEmb5S@CG)XfIAIAb8NqUCSp@%bLR9CpGhm89'V -C)&8NMHZl5FRA"9LNR$'a[Ve`Vfi"*$9iJ&,24H"JiTXQIB[!UEq)(KmYHZ5LNa9 -H4#98V-AJk-&(8[EM1Rm!!$'*384$8J-!@#)293eQ4K%3)H2ZBIpY[jDUp1E[ZVk -jRZEaZDkVHUUfHN(c4(C50`EXbJ+pELDcXmLIapEbN!#1kjZjK4$#&HhRPae`bSb -)6Smi&`i6Dj,a21YN(VF3AXr#HS4`HJ-MK19CKp'!J5EGT*Yp-alVlprIrrGe(5# -rZb6[*5mr!"9hAL6c)$)L%L(a!"%L"PpTP-PB$$qbVeN!+5B(X%N)SYRX3H!NXqK -m-qI!,%8XPH"lmrkmEm))rVkc)1-pA,fYPL'2D24)kp"(KYjZD*%6Ym1&LPMXGlp -JaB0JVPf00MpR"2[Er4EIeiZN%86i'PB-T%ihN!"&B5"H'%MK$!,T!PpkJNQF,kH -f)L!Xl@q4T6JL15B1Pj&hV-mjhZJIm!m!E(rB(mI2CA9VFac+SM)DP"EI'%bdX[L -[!Cq&q8!X'3%VZ"`QA$UCK!QE-0hp-"Y%eALC0hZ+rpS@i@)C@UA8J!a16ace88Y -mM)Z2U%EmdBr-1*!!4SZ[pDK,@I4,bDd!L1[%j4#)bSY50Bh3lcYcb[(P&NGhLQ( -2i1a&GGF9mB$fqmk-mN#RrS!fAA,8CAV%CAbFM+MbT!VD*bfbCd1(VeQG-$4ELfa -'-0d-%$P%d(%G3U`kAmDBIp6Qm"[*BQeU58Ep$hZDe9SUrUKYkDjY3)jEaQd`h#S -Me0m&J#$-ba$%q@KjL!6bN!#aFE$E#kJa)k"'&LXUd0q"TICX$i-4`jqb`ApSmC3 -B3C9!bT4eF'RTBNBK#E`8BC`G)Cc9HEk`I'[hC*!!8aF)[cr,hGe[HF*T,)F5E(A -Qe4iMfGB1d(LjmXK&jC%SPJEfhKm0pRFC)BF&X1kjfb&ejk-IU9T"HrlqC&*Ci"F -,cZibNJ,@*`1YB32P-,+3!*-Dc0"ZDfpXpeeKNd8#85Z+l2UL1p*J@I!C1@QfRD" -LbNPlfiP#IMM(`83f-LNa65@Q56'GA1i#N!!`'F#P1Hb`-QJb"S2pmrZNkQiCq3U -#4"Fc-VcLp(3SG6S@mb80+Qa!LbH3!-VU!82kX,&a0kZQ'Qp1@RHH+#ajPqqd'%X -%V$'mTHfd!$UTZbJ[Di#8V(caceV8e0*,X6TreL9"IVUAG5r8ZV@QEKB@8MHD0ii -L#KZLQhQaLC6cQJc$J!+1EPjSCLA+36("r5bqG0#`p1ML3Uib[F"%!I%'-EA5Y'i -EV*p9iQ3%8c-aR4$65DNAeVSAPF+UbU'B2X[UNmP`&`PH22+`)RJTVe-Kq9K!2[Y -SD2FAXh'SHcNmcmA`ZNAG4T@)qY64%'m`Lk3(2I#TH-"YrRi0%L%NX'hc[*@QFpX -Yf(3VLaH'efhNFkE(bjFKB2cQA%k'"5JiT8RCGS)hjTrhLF*m529RFY,`*)e8@`H -,@`d*Z*!!#hi5&qp$*EQi*dedD9DGBCiLP36"232$!CJ%D'Ac!963QfDL9B!PMbl -dZebP$)TmliP%J9IpLBSCRD(b#KHc8UMmB8`8UNH[bX9%TGfMbfqd`1KaZDPVVS$ -8"J["'jL+S"Jf+8+Z429EF35UAmLV@&c)rp+U,dqV1+8e[V*6UITL1N5Y*`BBjRQ -&&3@+!U*Nk,Nf3pZGZG2Rjk3T91r1ZF$i4l[E+IKKCZKH"JN(*I#T-TD3!!,5Z,[ -i1cbD(iNfF3!@[Zl9Q(Pb,Xh&Y`@jZ2cR22C,NIFHpQ3Z4I&6F5Q)(jGkl5S+jTQ -0Nb&5+a"Al'[BY$dMeGjMAe@I9PkY22C9j3VPPA(XUkqkP9FKfYUMMMZT$YkL,pb -!31TIC-aVD%29-#N[KX,XA0M#),)j@6TZDqbB,LeSZqmE8`#kE&Xl#rGblmDUaYk -09IUl82eEDFVQ!`J0T[c+r#*%1,b4KF[+R!$M()((!ka@250Ud98@QMBC),,%iNb -KURGjf`@T[RD`eqYH89lR$rEkUjZ8epjMAJ1#hEbJ[!`4Zr%S-aETP6G&SXp4F"9 -'TGR9)Zdcci+!+)H6%-UCA!kb)jbN)m*RJ1d!%a1%IZ$M3jKNQ991fCBBT2H%C6Z -d'PjL!RT["288hU#l"+@cA!@Am5ik`(h!91JBaP6Iq'4idJjbrDjX2GA`pFI&"K, -1%LY!1%fBY&fB(KCV49&djaa-GTNaMfkd)[ZZj2$IKNU%Z6))S3&I5DY#5-b-p(F -!')abKc)X+K)U0'h(MrRVHe!4fPY)cdrpEGLU"(pf5PcAF*,0HAD3!2!ZEBkZjm" -qDA2N3dbUrR!!55fB3q6-(`lil(5XPBjY0GVG%Lpmk'3e!&4VMI1pi`L`l3XbNK8 -U6U5C4#HcQZ-G)NA"#5$(q'm2h"DQpPpaL&Hm+Jl!R%U,06)`0Uf9C'EMC(*hBA` -qpDaJKSiSUBHAQE'Zr,rh8@bX+,Tl[3K"$22(q*aUNCbVV&`)cEd8UeE(mF(N$lG -$Fj@aGHULAK5c"Df&$8BFATcF@ar+EjGc0M#SeG&m-"E+Pq0@eBNZ@*NQKYHjL#h -'mLB10lLJ,84XL9@+Y-VraIq,r!rqLalcAe$j6m0r!IbR(j5e))9N#Hic,*[KI28 -`rK#d8+1`)JN@&!DYX5(r`b(&N!"VrZ(333ej"kGffC!!r`Z,6NCZ$,FU5EUk&!l -I,UFVH2,$f-+fIcL%"bi1ijLj5+TGbR)jEI$NEf-,eT!!*4E,b1,Nmr9Yl5%XF(* -AU1ZGBU14&N"FfX@)kZ,EX+6EU$U6%QE#Yd'`*`$0P9Y0,D4D0+RF"P4VUZ@[B@Q -aZJAYBNK0ASabQL#f,PCA%3!,%k+!pVia),UKh-jQpiL0R8Fm6ZTF+kPcZDKcqDK -cADE1*H8&N!#l4M$frmEEK'llIrhRMI-8IYI98'VdrrG,*Gh-bL0[QKBm+Kj*G"H -[H1346VfrF,FKGJPP,@elDUXUb49NFMN-)aPp!cf@%kYKlZa%f,KB*UK!6#UFZ0S -Xhd!m*Y8*RN4Bm@-5PBA2T!8mR)3el5hbBhEJL0i,5BBJV#!ER+$NQf&qX4541*B -26p,K86AUL)YAY#45r2(HpEkNRB#C1&jl5B'Ejj!!2V81TRb*6)34c+8ZTAlfF0P -IIQq*NlT8J@1frSA,XCL-UNJmIL'25FJGiFRFZc+kL!,F-1$a+ZPiJ!rI49L,C$j -H-T1cj4bRU,qEPb'`HkD2`ll+)jMbV5!JY*hhQFdi)a&3"Q2[-pR,FMVS$fmaD,` -#K@)hiJ4l,)-,*iK2c&DibDi8RK3RjGLY%am2i2!rq'5d'JiXI`!j-jLmJD6C3D# -5I*`UShY"kRC-"Tqr$f$'CYal4Q%4rSQ*q-5BK'[R4S$r$mGa""F&)-mpfiM*RBU -%TAdXpJJAD0ZjSJJTm6)1X($N(r$RrD`pP8Gia3`Y1Df`-mbfi-pQ@#!1beAj6%J -*V92$SHM5SK$8mVhVb@&`24Ai+"Ai06)H12T4"j0b,h8h'@QPcJF!!N#$1fX[rU2 -'*C!!4er@hTX[VVBYJD#hcH"JKJ![4Prp($'Spielhd8i2QaRF!j!AYLB`3GYNB' --(!kCS%1m@EXMAaba(1b3!+SKKe30285@k"Z4,kC[T$Jbj*!!ZL'(e"ecb"Tp)r* -'qND+Sd-1U4eb51f3!%28BIXJDF@,2&b[0$k%4H+C@E4`XRRhfKhh!@0Qb$$Kp[) -H3K&h&$p4eB$KD6!3ke$6UAa10ad@Q8f)E',[HSpeCUNJYl4[[Hqmpr45V(VBMTr -+r[bL*6A'"Sb3!2SpQ%i*R%K[`M6+fGd6IrEKcfV!J[XirF9-C'`If,G$(#B"E*Q -$ZYS(SpS18pk(QqdrjL3Ch#X4lYD$I9L'X(QeJHiD@l(lcGjc63`(fY4NkKBV-&r -qM!6FYd,0X3,Tj9"P$c0VIH-J9f9-`RURZ,2hRFGRZcY&lU!Pf-b+$6Kk@PEZ9lC -q$F'I8CbhRI1pKSZ[D16A[AThi-2KbKI91`4e!c"J+e(FHMG3i)CSDN$T$-RKi,i -P&*e'R3$"p9HEZ41JL&Z[8X*dFm2)Jm%1Kkj[5BH"4#UHU`$!kq4P@CMU1qqFF[R -9APcZpFP3)I6mI6,eki2GH@+#Zh0'!M5i#DA`h`Q13`G!%AlfZb#YJ'hYH((5Pb3 -!kq4ETj'Q2Bd%8CFahpLem!eqLBifKN8R8!40Z2'LX%iifM0)$J-)fmDh&b1[IZN -1MX`1Cq@VQiD(ml*a#4N*JYjGrT9aK[PGjl2cfbach6$c23!E6K5QA1GaFf#a3XC -'!CZScBA!mrGjBh2CV0``-+XY"XF!N66JXJX6qNZr1bYp@id3#VaHA",dGB$GQc) -EGfm#S5jK3Nd!IMQ$a[`!EPiFhDK@&!*A)SHr*")550,"2E%3S!per!'+1FcJ"bj -c!cZ3!*aJS'+bQ,+rZk&V`DB8F!eh2cK%m39Uk*'@f)Y51VU@BD[6-TBG&&ReGKf -1C@Ap[Aae@C&mkejeb@K`,(KCcSa99a&j0BZ$0KKaG5hqe(#!CCarT%5b3Kr`MKm -j,%fBU)X%"(($S-ZC$26TTUdEF4RIZ0M-5k$H"b#k+FmXL)[KJF((bTGHUUjdQmB -2rhJIh*9KFKcN)2a,S[1j4"!A+`FS`,"UDdjk#Vb!AG&GIqSf[GYjQ4%#3H$&9Z% -Q@C8DH3"6R',K-(RBfL45RkMffHSpNi&Rj#5"U-Z[Xa%#+aQVhXZQM@U@Le$5F!% -`X0V(UXZBQ%a&mKS!)@e,*cVrJ1,-0[kpXl(cX6aBqh'i8-+S2AD#Q5)q$JP6lVM -a('m1#F&a*C!!&Q'0J`M)#"%1(j%40a'2Ld3kVK4[*)*b!q(R18pamFIi+5T1dXH -ZiZAm8A9cN9GAJ4AmUC69GHVML3p4qM#5q+$4KkR%Kc"pU%KmL0#(h&K!cF#N@kT -,9'-Xi)kbb09Q6#-d6H@B!IZG@)CUqk[,(0dQM-4AK"4[@F%")[qi%GM5#D0crIU -qP)SbhF'&Ac$GH6*P#i@lmapf6!DCk@[VQ*4S@J!9h(B5)'Rm9-06XkaQFp,AE-3 -j[HeNjR$(MpQ9C[Z40k"'ZdL00Pq@1V-"pjS`Em3MeffL$8PC#e'dXR,d*'REIi1 -ZA#j#G#&8#,Z-K6dPmjVEqN*L642E!)PYR-3fPFC1pj,BqNKXGdPXa53d"`RY,JP -0*C(eUSk%X%iPa$53!"$3bS4SXJQK&#!8Vb+8RS43c)433N)S6ZTQMpVJ`*iT"2V -E0pb#BeqhTp@J)[*Zh2+Aaeq+p4lrGe-f[A'N(X8`ll6iZh`6U9[X$$XYM[NEI** -bVE(4BH&ZM`BkfK8TZV*DbY!j+Hm,h)N%K!E9`1aLf0'aiYEY&bR3L95Ah*j3)"G -!&&qTF6h!%9D!IKS61H(5$BFFZ+fabRQqN`&SE('XZZEd1GXj5dYeVG-5YF4UBc( -Fe$NY)$GjRGc`PP3VUBci`EVr8'#DA)M*)Bb9'J8(GMM"el%6[(FlXdZ+iJZMZl& -`adLiB4,VM(SCM[*),C!!`cSj,A#&AMU9ZDT!F#2'H3Ch%JqN"#-L1aA)VZ+S"`" -KbC[LYA+)p@!AHAQrIK&2r$[i6%9RrrAC@"@U$f))8*@,f-k!eXX@e`-#J!4!q&Z -#!p05+bD4BqjbIU3N2-2IC('NA$Vm#QD!K!@)DA*HE"L`&Aqd'VfRQJTAe@M43`5 -c$3*Q(%5KU4'DQ*35G'ED'"llNZ5iYT5#MS[dZNJ2PQ)M#QaV3"QVkI!8IXCNTYJ -#&UCS%ZRKM@Yak@fR'MiriRS!"5#eA9!TGlNVdir9iaS,UR1&M9[Zk`ac`86k-6Z -,"")RG!%'$cME,dBqk@BA&,R0F2NcN6@qD2m&abdd5(+ZDTrqQ3MmN@$$"c6hH3M -Jf#+FUakHH9YFr,%qQ#B[CM8`JUB4eq3U)qQC`!-3i'-VAHbL[c$c0P6H#-bk'"m -,p2%f(KQ0Y1"$-hfB4I'-FN,0akD4iHA90Zi1XC%lqq9$e+$RSEi(r0,J`c+bp&6 -$UfIjmV%40RAH['F-afCNckQ'4CYijEdQHiar`J0)0H%RqHZc-LHEmC19#2liq"r -`6I)(r!)2SB2TRqh5Kjq`21Z(dIXQ%KY-Z2M([R9RIf30b$BlqSfiNd5f9p20"0h -Xbr"0mrI&!h(kH+$!0k@2d-HP%VN+(p[SJ@*kJ0Ar#*(pl6`P0VHF([$4!h[%`NL -,B"(``LYBAVSTd%f0mY#(LV24L2ZQD#4&0fIT"R"r0%aL,49-5f2lJTf-c43334m --"#PP*aECr+CR!!c&DQD$86clM(Ka[ZdF%b!$`(RX30X&h0K20HcIVK!M'GPRf"Q -10H`J%qpRQ#Lprq-,B)Zr4H*GcXIK6aZ1[-D1KJJAeQ*a$bef`r5AiF,EF@&RB6l -DcZ!#!dF!"q`mL8T25J!6!QM!`q@8$0T$4jHGDMKFbQ![HR%AUBjLVMSD6hKCDGf -HCIJA4FD15rX-9jDGJfUb&K$LDh"!fZ'1+bT59,f9'e8CGR5D&A##H,qTidJ6"a" -+aBkkG-QD)CFH)-0"QYkcmNVNUXB,$&0D3,NN#Lfa8,K!Ebl#iZDFr0j!E"NGm&Z -IKKX9+3H!$,&PRPjP8a1N%1`!F9BFDH)NC'beNkX8rh%695Tq*9*5IlJH@q8(icb -*lF%MGFSM9H)Ma#dQTU)D6&a+VYX[,SiT,aVaMk*VTC!!("MPV[AdfK(U@NTA6d' -S#p`pRliqmJ!hY`HlqY0Ak01Xk1K2h`4lqDa3'dqr0[+!#5SUTAV#4%jrUcBVV!T -9cYrN%f4f*bQd*#NLQ#Zf(f)PP1DFP4A0DmCh0j1E2a*G%dA'X[ECB5DCM9fqdG( -iFed0lG24'qf&`*El(%j"!F4"c!,2Gh+3!2GG&)6XG(`J33kdDfQ0'8c&6AU#'ka -aXJ'X8iAED,$-cQAQYhFA'5Y`l1[Y61`TL-M)6RCDpeP&Xc0LNYKP"5PUF[5`L)C -SiE3'4kC44-PICrX2lY%'`QN[D303aDQrrj,8(RR$Q#mb'R(*[hm$Ki3(djY@DfE -33541#D#*Cc3NVK6f)6E-$$XDeV(UQ[@Ip!fMfe94`Z9aN!![NafCIRU'(bT)Af& -QrNGSM#!Mq!%`KTpe-UKbZP(M,LijeCNX5(qlccSjIqbPUMNa1X%Nd'SpaN%JA$( -'5Aj1XcTlNA#b&rcZeNGXCj!!(1UhF)*q0,MhVkMJRN*aei)"l5`%GYpR)#)EEcb -pB1HNCH2Tk43p9)Z(RP*R%3)'$hq*#YpX2(fle0KiZ*k,R'mA6#1J(#fIZlAhVd! -+"ar2m''cl)C8SbbK6p-6B"j[SDP$$5h4q$)3fP-q'EZ%5DeReJMXeSA+B&eGe-+ -Y[cc*U!)iUhHc)8k5H`1ldaU`['japX+PXij-!LCA-*NN4pYTXFN"I06#"e$6'[Y -EJ#4r9akVSZ+U3i96XDmEh""%T21VdKJhJ[&cl-J20JrLGk+S-d@!Fc)`0TP&aaQ -618URel#,$l1&,#`3J%SiR$@l)iIbGhmb%"M[([m*LTc*[HP!NNDiET%l@DAH,)J -J`&D`b42rF4P3HQe"G0YN38m#Rk",ISf0LeNddE"$jR4fl96$lZZ80TFqPCPF-0m -paMahE+rCH!l13Naq@N&f!%RhAq#+(MP*f`HdM5kI8`h$hQYTl&KJ!TAVEC%j"1f -e[5G9hCNUkAL$33k%l#Yj+lk#DLD10*r[j'19#kF',caE6JbElLb`Kmee$)@*JXa -G4N(L`B`K#T06mlG3P([SXp0JKbB8*c8iCRBj[&5LfCR-3Z8hXmT2G`d#+1R9LjH -D!j4C*32I@j4N1aV[h'-(N!!E&kL4&N&p-$*XR"0UKAafAN#`F(B+XH)D4B0iRj1 -FQ1`NN!"G#&PfAB`UbV53!02&dK#RCL!QZmmGG5bUN!!Ta+PkflLCX0+)BJqDNl* -b[-pZ1+FDYZa8b2VMh''1A%"")*'3!-QV6LSHXkflmGCYSFCrSBlcaamfUGVL$hr -6M8e@+BAH5S9Q*J5H5JLR(H,'5dH6H+5a4DDQCI@1)3&+RD*'#M2h&TNC(Xffc`3 -a'62E[iF`'5KM@%mMX!1Aai(+0R0#K!'bBH%i'fPVjk"9pK6b*N2i86LqLG6Ulj! -!a+rbik0(I(J8(dV`8"##UX[1d`8YHJU%R%T,5@@Bl+cPEkF'kR!bBrHULNppcBY -SCLqpaRerVqH5)VM(93FlJje$9d9aTml)8UQkR1Glckrme)cM-Ym@jX$'m-NY0S% -0&PpKX9Xjk)iR*`lbT-a4'D'+@e6V$'"C0DiNJ1l$50#!'qk(pIjHA`&'D",EBAG -(&bed%$8J%je@F91*$R&1UPH-RaXbCU"-XTFPQGB+-[LF3HS$C,m9C,r9i1CRF+8 -[0Srm"BbqhXL$i@4JDj1DT!#b(Rmf+@j$9LL3!%CX[3G9I3pEkb%(!XfGa4C8I2a -(&-Sf&$klUMPam2ZX`+Kl+Fhj5A(e#-8&aY8(mM1M'k`bm%!j15f-a6EK6lfHp!I -lmBpS`Y,))5'kR[fUU6M#MZEJ-J(3SLEf(X$,lA"4h4-VKi2ZVPJCZqR'5[$bj9J -0f+'N`SM*5*9KGeJDEmd1i2LAm@FrrZcL)3pqbD9,KPakN5q0#QiRd[*b-lU6G5c -fhJE00q%2`S`1E-"R6&E2h2&V(ZX'c@-I$MMZL+B,B%qAIAFCR*8N6+R'-m`rM9M -Zb3$JMX4Uf)d+k-4E8"!m'GZ'TF+*PTB#pJ6S9VChR"[EUXc8P[F#p-bD"hm3,Z* -P-+EYG$'[FV'A2GD$E@K'!+I,1&6KTU0m#BJ[9iMV6G$L,1$&`F!pp[lNFP*#jF3 -%!kMmr9NpG*!!c&lA3FdX&dT+(5$c-p'`S8`db)5+F#B8MXU[p3Z"'6B(UcCRqie -SiPIQfim0Y8)0@BR-'!N9C%!&'8)&aDT!8$L-UN6cRKV(bB*p`keTZHl$)BTS[Hj -5C6`K@c2X[-*KcRSLe@ZSZf`U%YfPRC4Mqr#l`UN3$p3,4JR&p,iaTA5A&3IT$XZ -S1mMJ0k"8XNUAD&4Pm%0UG00b@4),Y*U"GcB[dl`LV9*a'8&3SUXp&'1p8(Qa&B9 -m(1T05B$fL)DX"0m8#*SE*9$Z&E@2M[i%!PfYhTd*3V9qJMqV9EqZ*S1R&*AIKDi -!8MCGUVZQ",FGmiT0I,8i8%fSe5#cr*piU%XiZL#DPYqc3EEmjGPBLh!lj)*591p -2m2"UX&kY-mG"a&Td)SB3'!`8%KIA$6L`JqR0ir8[P1B!qq!iCcjL3rT@3i1&I4X -'&PVK%"4U(*LfM`+f351"fN-YXI@F''L`$$E@Mahb5jrQlrIp$'`bh(*@FR&&'[+ -HN!!lfT!!plh'54iBAj!!8P-(k#0BUpL"jcPaH`"QN!$LVA$D5R`qdN+JJ#eVNYT -'#[&-0#Z)cK*-[-er$F4'bReR0'Dl10Pm*BK8FjJE[h068re)*d1UqmM"%P85,TC -E,)rD'1S&djI(SY"rM-6DI1&A@Z'@B91C69d'*i#IS&)lZF%Kh2A+e@h1UGkTPDe -%DRkH4QT%dS1*6IL9!"f`65%R*c)-dEG"$E6"AEp8A8AE$f$lFGiFQJqeR)QLdc- --BI-Ipa@iUB$(MNqEq01C+$'a[ifY89-dI3K6'8NTDQ&M3LR-k+!he%!M&'H@e)+ -0e),Y9-2[qK4heM9`E)H#*&$lJZJBR%k8@I@dSKifTLN(FG&Im%APkk3J0JVe`%+ -"FV"ab#qcB#+c@FY[MU-#Za3&BHKQh'pj)88K-lrMJdUJ,Mj34bPT)EVe(ZV-3aQ -r-Jc,BG8"'MkD1SHXj*6SQU&0jke@8KdQUBk8![Cp&Q#IMm#qciR3qDGZKM""MKS -iRHNCS2"iJ1#q9c*"e9R3&,L20k`$INk&UE5#r@YhG$#iKp"eam("[BL2R@5,)VC -f6cK*),@d$i*c2&3-Eq4M$!$%`"q5@dq!AABC`Yh45QV&6r$q4C(FPjYB99ep9hk -UZ15P&-$EcS35Je`i#4)#Umm'-)NNjlpRQ&"QZ#P!bjpPB9eH@9Md*er'$1krD9J -iKS@[r0N@IU9@@DLiQa)-R3CJC!i1B'J#`,"Dd`%-3'&+8bmDI'58e%NE&b'%E@F -(cI'AC$Lf"i6KFXE2!fYFPK`bCi,p(HSB!YlMYbFbJIk18Hfj,NFhJYFH*%2[+iR -4D12afHCF`0(&VrIqPIjU@FId*dEJF#HlDfIR'im[b1"elZL0akGPd&*JKBP%!"T -)6,$#K*U3!-'EV%jTm+9682$PLU,#8$&UR*4pZ6VQI`,$L'9B$G1KYFU4*FU"GFU -"G6K`KhS)#UXFPBVV4c&l4"FK94PpAA4GhEemY`@UG6YB3!ZP6c5S2M!-Fra3F)p -PTBcH3C[GB(3!VFF#5T-K(#U#(Q@M5Aqr4dEAmJDa*@T3TQbT#P[DbqkMM3-,cf' -5"0RBHFc'&"8H93JZe(*ik0BLZfKV3GUDM4S6J3%Qi9@#Y0JJ@V2YHL&r8HD#Hpm -C)Vj3IdG1+qpfG1ep"q),(EkIJ#SJ2NkTmqZplqL['L#q3ZL+aT!!"S%N%'$N%-% -N%'$%eZFhiMI$B*phB&ZZ`8FC&P1UY%-ThVLSa&3&H3bQ8"9He%T9L9*99JmYj)T -Jp,5-qHrif,#6k!0fGB`V1iIUEEL$MFaJ)r('1pM)SK#&)*pL8"-XX2T[XGX2,hV -dIeq8'ArIP'T0-mE6#f%bR01cB8Hh%@rXAYM,2h!-+'%JlQD5dbm-PkZAq%1L3U& -dFaP5)H&B'%&e9LDfHTbEl0*@8@6b(9%FBU[kBYk`fbkJHF@PlP(eF6K*Y,N$'ba -J%$5B$6IJhBld@Ta6C@S&$a#@M6-B0fG"f"2p%4c+-!PL%X3NJ)Q'54L6!#BIriK -Gb0#3!!+6M3`8BUJ@FDRbS5%D1DaEP449#Xd&0$!e@Xiq0VrXPQF#UKPZ@-BU$2e -dbqGFd8fI!1dCQhJ`+&qm`)!I$"EE6VTM'bb$3cGCdq!N0"jSQ'KJ`-M)CeaZmrZ -f+h!0-"RXUJ,c@$$bklr$c,,6K35e2eDT`ap`VlXXNJ`&[lV)MU*b"d'4$%#HG[' -`AUe+dTMFJerYj%%fh(Z1f)``(UjhTakaJ65"I'hP4qla!(fT$SJJ-,d#MU$0HX+ -`HM-IjV1c#S4T))4$LKS!+iDl+NqrR4k('+S+MZ1[bJYJl&ja4qBBV+reMKHPI[k -41iX"q4#1H-IlN!!3j4Xi#q+e%43[M1kC[1&!X[B#0m6!N!"I1'cpU*&+Dea4ai@ -e8M6%QVJLM43A+)EmZi1'0@Y20Ic4,JE[jJ)m,06KFkLbLpQ%RCf&*E$h5GrM8*0 -*hpG)D9BjR`$""j4Za!FX2lBi,'$6UNb'GKL8UAb'did3p13m"U&l6lMrC!2MYX- -@fUU,3r#fcN,q@6`X8`MrF0ak2m--(R(c(53m*abiS-'IS0#3!,E3"UXLQJ+`8qB -6+l(a-@HHKq$#m3lpD0kX4q[($fhE6P@B!'Z6%V"[FR2IJl3QLj8kG)dZ(!G$a!` -fZjNJ9B"!@+*#!*+V9`NJfGI$K*CHM9&PQr&bVAM*d&`iV5(Ni#"A$#UP(imEkmd -i+TL"HdSP&lGKCLaUcb4IY&8j'XRLkR(PXKH9bqS[NGLScLN[AjZNl54HSL&#YDQ -mR%'RJL#qejHjQJ!k+bkjLphFe6DbqjH*aeSTl4aL!D'l3,3B(,"1DMrJT(5B!-H -%UkT)%+GA*P&%[Vi(DBA5erFJN5)qD"(63UlN@')K9mY)h(*&iVcpeKZ&UmUf-Bc -DaN1Z"i-&ME38JmCK0!PPKM#P0K2XijV*2jfAeKQ!1"cX3J5IBIDPli(H1-*F0)6 -*m@,"6*TJ*RYK(Sqc1['cQQ5PYNTjYG,Yr$Y[BGaBlN[pjX%V+k,'h0AaMj!!31I -8JT42'[h'-QClNG!&UpAc*+@C`mEp6$qRRRN3SCiA+A&F+C,dl!Vck4S-k!J'e$H -$3+6@H)lrrc+lKRckamU3!)qIqSfVNe)I!2,6Zh`lmcB1Ua+$([,#YmC4E@dQ4k` -Jf-V0*AdBSY")qJ63r+,DDb5&UZ%1dY3jGCQ6HG,i$VYQq,e6F,&)3Bf!KF-R0+N -4$BJQdEM&hFS66TD4qbA5,Hc3!,&Flq28'&Id0"*MB,b4b0H-mqXrck*6UTY$fLh -)K5IF#ic2Z"lSL5pK$%AbfAZ4$r(RKPXqQirmqFblNE@r4,$EK'!Tj9e+iS8M!Qk -+D2#QHV$hIU5R(q)1[Z9Zhi1$L,f-aFkN#0Xp9["l6M@%,h'MlU-%r`NeE2rNllb -CF50e-1&(1SaH%[jD%[N*%MJ'i,5q4!+[%Ph`bbX8BFmDjr@K'VhEMGjrJX!MDdM -J+,B[IbdKF,lek3,rFTJ%AJ23[-DGrcZ[YrIcih!8#"qp)EL)XcRfcX#p!%"S,j` -)HPK896YTF0%bER#Y')D8KcJ-GZE4UDlS+Kp094)Q`XXMhd#&B&C@Ja`8bVbpp`j -(hL16`5f)9`UEb8G@'5C2j#'i@P-+L6jr-21XXjI*,P`L9NdQ3E)UXEaPmQ0aibl -qZ3dh%0RQ0NiN&b6-#KIl85fEP@m8LEHEN4Cd,6"XkB(Uri&6dMFIL'D&J#Php!N -M"%NcTXJ)Ui3)IP4rF#-NK54JXH@HZ,1IL*R$-,NCb-E2HE5LKp6XUBE3,!KT#Qb -!Jj0RVhBD[B,!F%-L([acmj-`Z[leRqG%&6H#Ci26,p5AGL&QJ("3[0$,6[+SMVM -3@VV3+aK-YT+l+bk%LNDqJ3XjMVQ3!!dGZTq5fL(MTZc"8-+pI0R-#eb@`94*Jl5 -3!$XF*5K!l"p5SA)#66!!`DbYBQCYF)$4eX33@ma!K9D,S@ap)@+0GSNKDIN(AG! -+NGB4)mA`Bjdl*j`i-[hZDpqhUF1$)6dHZ)F0G'1!!3VSQ8Ncc-1#PDT9@+RV#6D -UCLJEG5@LTM!dFEI(C,E1d8''S$Cfc1lATp0j(Y59Q+BQ-%ec#Y08-XJQSD-0hT3 -BJJ(V8*LPTJ5c9(X`CSN,S`L&S@@B08)hi'&ZHi35aqF0c')URcAk[%k%iV%kU-K -0J$eJ2QQGE@HUqp,CErd,!2TZ*Q@HX*T#mmX8r8bSS5*1IV9J'!*jd`S"QJ$A",a -LS5-H`HZQV+D`89@$E"3DIbCT8)8TBRC1%iY@I4!@VGTjRPd)`DK9HjUT`@)BlVG -36C%*SGae9JaGcdRX&fmMb3bBf)K"3bdE1H'`KL'cfch@9$Zb`!mK*CcbT(#FF*% -EG6e3#!'+`ZiNT`S86U`+YmhF*G1+QS%NX2$4eDb'JJXdQ'h58da&#F@qEPB8T%G -PFTfb+%9S8BV36d@SF4(k"jkSQ0-89K$+TDfTN!$RS2NBCY#D+,!dKP$ZCiD`GFL -3!!8F$R(AaS#d*bZZBS[[S*YL@dUJGEVY3LE[QX*J`LPf4RErd3H1P9IG-3#Y8-P -[rQ,akMJ$hTh2"0jmAIrJ'b%`LSGD-AQ`k)+&1f0'L$HIH'`15X8r1IrQ"Ik%SF5 -MEmE`k3F&+93p244(N`@)lUG9$+j"lE%DLLh,Hl4R3QqqhR!DNm#E0p)1d!C6aVU -,Rrm0$,)EaY*4r2R6"+YQmN!2r-!h-CaVE"dZmQ,K+SJFZr1X!k06r4X-8fZ4NaA -69bkGRAN@$eh%RmYZ@Ipj$'j,EL58A$L"Y06&f)F!A@l-m)#0Ri@cr%USM!Y)A9e -'JQZjCmikM`&EcR[pJ-,4)'(p'$m'KXDb0S9%$KV%rHVDi`ZapA"LECNqHlXSYXE -(%$d0MHa"9qI"V&4RiM%cm9L)(i06!Pd)3``P$[AXT-8J-1B&pk1#UD"YEU1(jpM -P0YD+alG"R4QS&SK,"+Ba*mFrmS"G0NGdG5Z'bGA9,9l0L+'%XH!%+I-3Na0@X)Q -KJ[QP1r%5L@hRCa+,qZK&@"#DSjDYe&rrQThlY,5&4YV#m&%,Sd-@TPe3PU3Y6"f -l8"iDXM$P6$5*SpHEKV`fdikpN!"fV2fSBbm0@@JI2*D(EPqqh[J-[iK5&p3r'4P -m5!`q`Z5XJ"3dI$lRLc!SEMDHbNIJj1$b1pShG%cAEZLBeBaNqZ!M2$!d@-2hL"P -Qm+#C@-9'"#CjBJ(I&F903d%VF%*im8T-'ECB$*p+d(cX-4j!0V,e0i,T!)YM+Te -qmHScQZML2+!i%`U!$U%V-6aH$c*33X1(B#Mii@@4V#!@%pX&#D'"H'p+F`50(m% --9ARrZ1p2K4X,G`C&J8*P6T4"C8,T"+qp2B3&j3[bpX9&d88AQA9DGa)ZTjK%bSR -G%kqDh9PL"'IjS+6jYPF-irC#4mPGJ[eFGkC2B85$e`D2Nk[F,L+X,V"l+@+1MEH -("%C((AK#$#!+GJN9p[BMi$LpGJc$b[HM+5H8&c[$mN'Df&VY#fjY6S4"kiLp*h$ -%jE@iml39$B(+FR,K3I@M04cB3M3hC[*UMJ-6CU)VGqN9NKG%-FRAF&4X"5Y12-c -$%d04QZP"Uc!lYiQQ-*AN!PYC-08H)LTT"'6c"hd2qYZ*h,6lpUB(-@b%a'Mf1c& -)2&5eRiH"&a[kDJR"%2+A22cja-02TMr-$%VT)VNdir+T,K&X&P`mp2Yr6[pUpTN -+D9(q13+!B))NVEc+,P14Xi*pS%'m1C@D("83)Ija!`SlUNjpmFPPZDY'k1h5c,J -3!brek!-ZM9&i!m0-QF+3!2P!VmQ$E'#iM5NMP'kmUFc)Jm+*)ZIh2c*5GbeA+Qd -GQ6aFac9h(`qVIGGLkh$Q-i"pfdimQaG0P'K+rc3)68d15fPU*b#DTeC-l64YaG4 -+8`269TSk-69SQX(85G-FTKQDCM(0dA3ETPQD,Q+kMDB9Q#l50)pT"8d(--h6G"c -6!CT1B6T18aHQ8c6YaG4&dcj-HfNk!ZFcEbC!cBAN[fUC`%$(X`25a"mlrPMaTa9 -r$#-`K$`R5BbqiPm*-6SrSc$bepNSm)m9A0$9MDj%UbmPKM6LCL,FA3j-,YI0)mK -*TP3"E!+BF[d&M&qV6AqKNrA9PkD[%&PILcpVQ+acD1NTaQdEEmJG`I"`AhbbQMI -"Vp#pZr6&rr+YflmkHV&[PVG8c3hqfY#pSb#jDf-KFJe)dB#i"TTke,SrAUXbSIA -0iD1"41LfJbeca`kq$-SmL&#p!bQZ)QGHZ2*rl#B$CBLNcHXSG[lm,q)-JJmUf&T -kV'Z%S)*U#eqLqMUDa,h$c%9eda)0JeRGaCHVjQ4`mhqFVEiH'k(,[mD[%FB[i0" -kFHMD-F%UmM$iF&T2%!K5-%LDki4#+EBECk5c9fP!A6FDai"'LhhXr&QT-jJZ#a' -2UIA1`4!Ij!M#BQ8&j[)#P$T$U"Sf-e))6&9NHA56deY2HZm*&3Z&U,$NN3Sah)m -[kVLPI'BeqG,JCk3hNND[!b%4Af+3!*PFFGS6T`ZQdSMF!9%SMV0F60@AL,Q5eA[ -CP@"SL[LUG8`-f4`A`iBJNGYmq(l'[V@MF)r9T6'3!12K`*U45Q&RC3a43qQXXaa -i1,VjNBDZkE+'VPPf4qiaZP@IdFX$r#cVm#f1DQlM13ZR"YdQKUbE-S*k85REV'5 -5J8+k)c9+3Cd8&bf!qAVfZ05qJ-ZJ)5XhD%Nb!%9K6Sr4aF9JN!$EFhUDi5SjVA, -A[(4YYMK0`6*3#!GD'-L(6"EAq`A89J!$!4H*MQPY3mGYmB#E(KM+b11I!CP8KKM -AFNULI$aaK%P-JQ2VPc"bd,YbYV%G$X"q)hLiXrKDfcQpZXT"FE"@pq5X$MD'LXR -mkh3e%&UJ$prQ`d(3l$T"BdJ0CUJL+,qHbA-!6m'HDj6GNLU4q$)jm$6Q!F&$4!` -CcYall*i-i`q5-SqKf1!-%[CNb%f+$F[%i%i9(+CaFQIGCSCe-[)a$0`28q[`RD* -&%eL82'S4`lZmk*1d440Be&0N2[)45!LT38Fp#Q0MrbeQ,')hViS")e(K`#S+-lm -YUKYS(#&5rqERdSG2%S16kS,mck'#,0%&'Eh"8!%*XN34C#KGN!$45r6!-B+-[ND -#"1J8R4@#M%iPMV!R"-N*VC3Zb&FlLmeM"4PY*N'QG""4qf#S),8E#8'@+&#-5'R -9*)3CIP8)dca+Q(DBBC166@#Um"cr6kD@)H!hKF4Y$i4McZ6a%bG"fHGJ!*l4SB, -kcd[rqLX@9'9TQU$X%"6qS5jDeXc(BQRm)%[*,,jDPVDdQCCUY05U,,8IY46NN!# -@IT!!YY6+5q8K@YUM,'dqb0,EY05GYV5(PME4dPCPUI9BJm45XGfjY+@Y@(UA&TD -qm-,r5CIFA*ffX"3,5`'RYiKrBL4Kc'(GQ+YeBfB6HM,GQ+0PC-`P3ieC$&"5),M -1##D'H463hPE9%1B!5+GRZq@El@",[iiYF"!8%Sm-(AcNkL+$INpf%Y3bbUcaNpH -9-+N9c'l8d`a!L!HJ#T[,S-N)@JI"cI1R'B6*6jiLX+[9EBJJaF1##9,3SG&aeMi -+BZ4*B[%Vq4r6N[@!GrfZmf2abac1c5[Kh(NdBlmeAE[XPZme1#*S'fljA+2"hQi -Sq%"4F(Hpbc+N`a3jHhm!"Fp$*V+6JZYmEU-DRlNherk&Hq`qb-`Q(GNp[4m2GBU -(jK#-15j3qP%6JkI3jYBJM!Pl6%ia249(B$$!(r43K!#G-,e%ZJV$b98`NI#-FYF -bA(!bYLGBG[f6QIi*2e1#PAmUKF,3&0Lf5JF5H*!!-E`-8CJ-)*!!QC1R3SS3T2a -c%S18(`,))XFm'2$e$"aAU,!YTaTU-l68cJ[rIB#6)H*bYD-i[Z'IGp,VP2ljRm[ -TFiF)bQQ4K6kpN[CT"XId$UPDlj!!DNda#-e&6-1GLH4J8[a$6)"U**cYrH[r'iF -)0(`U,rS1TGc#4P`-CFC`6"Um%#6BfYU-KhL`9`$"BrKA*6K&Kd2AM`i1b-B2&[r -8GUkijrPk(M!RHSlp9bkC@pkdB&KNDI)(0#q'kb25NX*P+68)M2-rIX309r$a'-J -mDJR'T#`fqCml1GKVYT,LRU0ISbY+rZI`Z0PI,-C'm[,A1G4R)$5M,%E6*1R9dVB -'m8[V-FI`-+NTdA8"$5""4QiQ*KU*S!%``486-1GfT*Zim@2*B'2Jp''i!*!$)+p -"4%05!`"-hJp9$@C8%J!KiZj%ll9R2HUY1CVLA*UL2mTj(+Af#X-iRG,&pK3j6h0 -hR-EFZPfSYRGAaEBhE@NkV*ZTY%S4PURJ1!l$ZLc,%M(8EG4TQPZA03PK@%1Bq[e -K$"'R)ieT3)dMrIkMYIIhrll[lhHrkrG+R1GjpYRR+aeP2K3"m3-!!C!$!#%'Le% -Z$3EmNAXrTd"+d#&0H+j-qN2(dPmPd!!FIRG4qUXKljmL)e8UPB$,CVCI@l9B1J* -JcN@Kc*QZPLECjplL3#JarG13!2I48BK!2`h`ma%Q*#GATRmd15$lQrdSbM(h2dk -Z0+`Ma"jh1T&Z`eQbThZ2$9R%J,'$`MlX@Xbpj6c#S3iCr'jS'F)rjp`P-cJbI35 -GYHM`6blZ+A*E3TP6Jbc8[ZGAZI[6M&hi#@HjRCQc[1BXGkNm'XUFF#IGLYpP3qJ -@fE+Jb@9lfMR,Qa9NNlVe5@&p%M)RecGKdN&-dJqGT6Td@(9Sb5a[F)8F*NFipXc -bKVah(Q$Lh`A8QP$QABZCNpEJjad-9cUkBC5KJ1Xlq(N43Hj2(BHa,!aj(kH*KIK -C&r)qI!@2J#"0p`)a"aFAi')2ZcJ(2lH([,%q@Y!MG+cbmcD%JGY1b%"SNCM`dcA -XUMIF`CpX+)eHkMBBq28*2U$(jr!"TJh2j30XU#@E$l$0+c%qS%3-m!%PE`C1@*+ -&h!F%I#CpfqjZQCDeM`h@NA10,3R(Y(q[&3Y#@fc'rNY`K11iYR&rD&'',BK16qD -[FUe$UIKMELYFPR@1(M2X3a(HKq-flTB3[B,#19PGk1`T*'F-!"6VR9I01jdjb1U -)Uh,l#$YqTqTiDE'*M6241XF(%&E(#TiJ%Q6*1b$XZaqpG$9+$#2'#aM+q,d9C9A -YlEl5'Tqe$,A8[IIqSX*ArR&L,'AG8bJFibJ3i@9MZk-@ahBRFrGi$2N3[MiN&Ge -!lSCB4KfeE0##EI5ML!AF@iT*K$-R,#kEiN63Q)IK(%-NG%M%KT!!9hCD)+C!q(' -9K$'!K6NX1HVS5"UH-p8N)GJK'%rFEJX&f0&efX,%@lS5iSe3mATk'X4(`'hYN!" -#,2'3!$HkNd+aQ&3V!Y-9CH8RLSa+6A%4PXr9P"@AYbY&bVY+bDR5,bY1[1LVa$8 --FD$BH+,Q5epjHA'jM[)9'FXDG*`)b00KHU$AF84cAh-BjJIPL,&rreYQ%h0PZ32 -'@R+3!-9@QF2#ZXX'p'H5fe!KV*0fBMi`j66$lAB9-d$`2Cafk+#dCp@+!q#D!9h -XiTlXG(r6a#Sa'#`)G!5i9j1jf,S*4&8J6-i+d$%4$eK#+CKXjXccG!b+3a)G[3b -)r@!qQ60,D(,@6Q4*DCK0K`)i3mcpY)h,a)L`q*lL8I,F*6Z'G$3"#FY5%TLXQ&U -%e"Z(3'[ZG*I-qX*GXRdq&Mm-C@l[&%p2d"-"62S'USB'QNJ'h-P91`EDFZq$-%J -lrTJ!K'[k3mjY-,d2XbQBfTE,h9mJa)i"3!-LKBe0@YLB*A*Z+XJ1Pkf+a()6K$# -GLH9kG-dABKQY6BLPZ*+0+a4%*&-Pc!6p%-U@X%Pd#L%hCa#B59LG+2l'N!$M@qK -d1m&%M-')jiHEc9f+%mcVXL-J#Q(%3e@E-3E(9eS%(3AXL8H5Z4CEPZA[If0QC&$ -`Zfc+E4H)T3fa!mX`r8T@8r!TMUM#JMEQ4FM54'$b5hCTL`j)ZU!iGF#F2&@"3L' -+9([l+D[99e5P@)XVP1,RbT4LXe*qUXMSZqN#K9YI&TZrC,Id!Q@0kS!MX,54bH5 -6e1bU,LVS8#e)J1Sa-Z`6U%Mii1TG#&&D'B1K""b)&hCb8MdL[J#ZDZ,JUe6%)FS -(i`5m92%%NH'VAT5Cdh56jJa-3#c)68S%E2,4-C!!$aUVHbF&UeZZ%LSkH*U%`pa -rJ5V`!KLr#EQH*@`R'pc$(M`R"Q%jNJ14lAV`fC%Fhf+(+)5p,"P6L3,TPL)K5Jj -$"ZN`",PM+3%Y'*r#B0HN+"iIq#Eae$LSR`%E0AbK'@[J)!Ti-LHKX(!RSH$eR'G -1fTSSH$e(98jL&l,cL-J9UJi!XRHl0f)5lTl(LYh*B6(-2SZ*Ar",1FL`If(4J0( -6c3kk)`'-RP#+Jh)kclC+(6!3STh8-El65aY'YN!YI''hcPkEMML1k-)A%F,ALSl -E(FIC8eNN@Uc!kb*iQ!d66&B63#DD'UYeRU8,aMi)4mc4TAF+KMY1c,e!E,YYD&0 -1pLdL@X961hi[a%"F%F-'%SV[39$'%`qjQ+#%,kS)!R*'M*%%Jj8cT15cB&qj$(d -NCH()1P$(PQSEE5Qr85*V8bB5Qjj1G,KdiEk)S)a6ciE%Lh@jchVJ9)d[*IrkLKP -Bj3HSLmqC%4ZS#MrL9H*[UUN5Cc0#K"IG-VYS8T%V[2VH-%HZm&m&i%r*4UX& -eI6#+QT)'b$)SI$(-&b'qm2"&NLmLlP)l($hKiSFd0d+da"&(1QPdRVB&&DdB#+) -NTQGK%H',CVjSS8A35&988jQSX+NLUT6%4"CpQ$&A-TJ85ZYlhV55,Q[-QeEXCY9 -#jNbVb"c*ZeR4KS,"H!-+q`T42E1UI"YRZjfLU(1b'e0R9Z,JFj&@U4K2@pmEBdq -2LDGl98q2X+FRm241r[5%%(EYkG5iTc&eCKNpl9dRPH,GM9hKK0J@+c$ZI4'f1iM -SFm&K5FF3AdE#pJHI*C8XX'YQ4Me49(MU`)NUTFMh-qANJH+DPj4U#0XiFPqrjLX -p89&'r&aeYrkVb(i[B'TaA+N""IdH99Bfi(KDlLEJ*I-Y0UKd[3[%ZmLk,%"KlBX -m,CA#k0HqM8VXDGQ1E*B&QDcKd+*Q#9+U'fSpdRUTEIi(Gi$SrEB--@)*JQB`N!# -b66SUqHQGY+#-m*ihHCD)d$&-l3XZSk13!,AXDaebfF##E[FZ1`PJT@p)!#XkRi# -9$Z$HG9)!+aeLN!!qN`"@p'ieX'MUKJ%#PRMmU8&'TSAjm0@`M$8CT$-2b00+[fH -CmT+-I*,MPr[cc1ZcJRcDME"%@%&#I8@U*l&VTSr4pH6[qpFC$2X[ipVd`qF08P` -mj-'Qa4-$l&KTD1(E)QIf+edC0U(#"3@KD-q3!2eief(rH`9(![prjeG0Rp4qUrq -"+hmGqfRIMiFI2RG"ZEIY[Z5Km&14CeUIEYl6j'Kjr0'rHq*[Grp0ajqfhpRpEpk -p0$SC[(Vqiq[[Zkmj$qlp5FKQqF#crr3[M[hFpAq2rSq-rrEKPeQR6YC8qFc'KK2 -lAMT38P4XrD2bLV,R#Rp@qZF[rUmErr0lIjCfkmfmR)YRhmjprI+cErcAeriLHp% -lEbhlebAr-[XIA[LRjrrlQ[rhbVppp6prrPmqrHk+cpCpqi[-EImap6ZcPLlrqj% -IM2h3qhrQrBH2r[f@lrrSplIriECr[1-rVIl0)lpkl)mlGfcD[2A*MEqHrlZlIc[ -RSEPr0ILA#alXrH@ZE`jmlCllekjDqIAerlcKVTRakDQ*EbaHQ,mph5#NYlJ3(21 -j)UAU1CETUe)(EQ@GBTe3'L($Ul092S'UR8Jf+U$H"k!'@5M*H"U9M(&i)qYed36 -ajVfV$*Qq*-LA!,)F!4*G'"rQppP,CHc(qmpHX%-*6)Jl3L'HG@#RVG+cGapHZqk -mP@%c"jJa!F@Qe@ka0D&61FbkRFjECY1HpaP,Q@%6,PYX#0dG(i2LB@%dUmL6"k@ -FY")c&!P`N!!bY$m25K$(E[l!CjCCE+edi((9J4qV$Z`MCN22QYF95ZGCXc3dFdD -'C'pB``G`b&26JSM8`kF,A`&c9K(T#cZK)2LjBmrQ"K%8@0J,YlD"II6V'9Y'@03 -#e8I6UCJIBUUUb1J5Qp`0p"K%re%DS2-06"e@A6BC#9LlkH+&NaBEVV8$dBjVbh% -YM1Pq3L6B6NbQ42B4dKk2,(q[meBBkM%QHrPNkLdb1CL[%"$++dM4drVH#+XD4PM -9X2"9&E[C4ZaQi5-KlmSC`@i@2S+I,e6XCTZDhE#T,c*fJ`bD&S3bK4Dp[h*Klr[ -hfrf4JmKfZ&6ELi8@l8rlqCEcmS&4q346MNeFl!mY3RKP5)4Z0$5Z4#KBB9FKN8J -FQiarf!Q#eVL-K"`G(Qa[5mLlrM9DN!"J4(ViTJNp'm3Ue!GC5%BmJ-2K5#AHN@( -*`*ijXjaPK*Z-j,"A9&AT4maKmd,H9EGcKmh$cqHUUR4eR-0SUT-jM)R%IDYj"`& -Fi3-5'5kb*(+e'rJ!iPKlR8+m%&P@N4B9PbQRLT6*mJTIdBND4@FH[LS&4*h[9%P -G,15UjkT5dq#VHDRLZ4+Pj%4&bDQbQSBlLEUdJX#X1P9f5MP4SI#+Ydjfa!Lq4cM -"plYU#,iaX+f9LH#Arh13!&H2L%!($'iQ`dT'i&&)a-6*0MrBNmPL-lYC8#lKHV0 -1(UeeZNY3G!9jK#*H%1'ZcfP-(YhIb9`2P9S9fHIR"r@c$,cl[JESLJCd8["&AhQ -a8P`18X9iUZa%S8mjqCcCl#YR9!FmS`6Cf&GeV3JZfmqmVSlFeHZdDcDe"q1)cPC -b5c)A3X*#2S+d2,a')bd,+L-YQH)Q)bh"1Nd,FX1YXRmNl@3-"DU993TiE,cRd$j -+))%%C')r6Fh1F8J&D*D93G#2Llq*a0pUB))I-0Tr[8lfkpRYa'DG3*YVQB*@'Jh -)R'%eC2A[a`#2"X$)!bD68'P9Eh4B$bp!!9(e5,IU%3qBI,mhTbUXf,-[1U3)R,T -5E(%fVV#XVTdP8`4TFhk(Jrm"A4Yck1(dAQ@)f+e1J(*K[CX,kcHV%GE"H'(YbTj -FYGRb&3PVJbkXAeX6,kb(Eh"Kc@dXV&p,9LHXDL&ParHrA('eX4*HLEbHJF"ZYM3 -@f10REeCJ)BSQ*UijaJM!RHFJ-2[M33h"49)6iKXRM!a!KQhN#+Mjfa-X[4*aCBB -V`j[BLLkJ)(p)B#[C@*2Bf&KHMF+ZlD9Q(+``UEC'ST89FHDC#pLN#%Mj2QeLR$J -fhML%Ei!,iAMP3VJ3TN13!$C3*!rcF&-iVe3Q$`DK!ZV--4j9l0"@!a@%!0'%0BV -3d)6a1K1Jc2&h'3PH3-ER"ENr5-[U%NXHk*h!P!ifaIi$S8ikX5!YmBcCL`BSqG, -ZZZc*#H63%59[X)S9T!T85&'T#hAd41J6SKL`fc@(Xp"R-Q+h+cf$Z9#M$9clIU4 -RD8j2$V'#5-YHqhGblMe[YdFZD&G3K#-mK%U16cEEl8KLQl,AP@[kkE8YE6hIZG9 -cLkl6NfdY`h*T@P,Zcc%[H#C)$d@qM!Hf3i3Z[B&XaHPZ)**Y(&RjcGjN,[f"`65 -*V'PrX"@K"UU3!!2*,e0NrGdT,i$)MJR6TbRTXU%"K(MF1f353KpSd)3q8'RfIc% -&Q3!!Ja"Ddh`iI6&cqQ,"D-(k#NMe@$"0P9%JB"`QpQ+m`SbL'PXbLI!EQKkSa'T -DL0A5S@V%UL1PSiidD)jb6UlDkUD%EhAIP+0#+5m`4qeN""X[LQThqG1%Zikdeqm -ZQ8J8FjZ@k'fUSNp&E#i,bV("Z-@P'qfmTV1UL@UR&5@FYG61RI9*0Fl+9MQV3)M -4eYA*h%2-H+-iAEC+A++)55+CFNBN-m0@H5)EXDf!LQhaE6HDBQV-f0M'!,BRKq[ -H'%d5'qYDA2r',U3mqQ9Y6MGN2HQZfj!!T4%&!B6&6+$$#ia0D+,C@NJ00G[S5Q) -,%C!!*@3q-"BmN!$6)6ej)aGpFb0$LMfqHPpDb`&lS4V!$ZS#a-fjfl"9VpKUTB& -!FTkA1bpcCNApcR-FSDH)D'R,4R9YPrE`#@CJlI'mT9`,Ud$M'(+AM'd"!0ISKZA -af@+liqq-T&PX9Ah-A%Q)0hM(f55DY)(-f)YLX9-9b+S0IMIi&*!!c#4Q+'A'&Zl -Zm64ff8YKZC6284@Q1--Ae&@JU52&aXTS3ck6-Z4*FqM))Qj1TF(*T*X-Ic!8+'3 -+'-p!0[F)EBbT+"cK)'3+#Vb`(N[QZQ`*)kTK!6P%L$5Bj'*-HB`eZ9Y)SI,a(l& --Fm#)d!%-%G-#bC1aeB-NQVX4B1KJjN2UR-Fl4c48USXDr@@1Vh0+)NZ-GKlQAm" -8(iD-!@hUjaPFbB&Yi`l&Q@&61kJqdrRii-fCcL9YjHj+L[+,-1(#I&V9bJSC3k& -*4Z!G!L)cdib[G3R$S6GkP*%IMkS[eL6M*Q@1li+a0%"QKS"N$'Pf2#1RjPj8p8* -KU*`"VL`L8I"JNM2Z"R!$$,4-j)`+Hl!H`+)ij[KBTPEC#fD262EF$"UbCcE%XIX -!GmRH42-[FJ-9'UL,QXc#K(U8#pGD#,N6jRq6iPq3!$DB5rq[cHh-l59'8#XU-A) -ANYI#P)QiXN$Mk95d&kf3!%5HU+XbGI@3!$PGS'VUdm&$p3L148p5mUH(UIRlTSZ -cF26*N!"`04abX,,MD(2ZLJ`5&a*iEj3CejKb`R'1Z[*EU%b`+K`483%Z)S(HZN0 -j6rABkleT6DaBMcH%,5#AlI-[XQ'kBQ*&)U!23AbLZ@#c$(H0RDf"3A8Xlq4L')Z -(f0EYSN"-Qk!+QbqH8iMi1m*#88F&#T0-bZ&IjMC,jH#1,4%SY4$4Phih[f$CF4Z -*8SC%eY(ZVS"))4RTmm3'k,)`S1Q(M8q`-)e)-RZL$8"hrp%0U$(+2M4DY[1YjiN --QKk+%p8L#@iEK6E6d&KrN3XUDHD*DS"f4FAk&Flkpe61q[1PZRVDH*29%mX5-0) -8K6i*dP5K3J)6hk0-Q8G939%Kb,$jGUP*IGAfQ[MflUaQHbCG5350VJ,P#1)jhc6 -fBD0CRDR$dX1*i),(CG3[8prdlDUFl*hD1lRUYlHKZPV(P(*-q2%V6NXe4!'EbSL -#UIEk+cCX[*XRi&Se#@K4J3G9cPfM1TRJEV!$-39#C8k'b0$D665`j2+K[p++Yjd -Q(G)QBqNAT#4lVNe8b00YGC'5#A,'VJSdAp#)`VZFPC%fr"J6NGkXU2A(Nj*hAHG -*ephMj1ljH6AZXB+aT#-T5i6BSB**e`-&iN"8(Gk(0L8f`-3l)Sk6abTed@jk-*R -,f+k6AI(kcfP$2$KrIPhZqB901mlVhqfbAC)F!6DpBE$P3Yb%+kS*8!rBX+Z&Cq2 -59cL'Y'5!,%Fc*CP!%'P1"M22k`K&``MeDP23b)`4T1Ukh"TGjd'cIba"a"5P,lE -fV22X[Q$FLm%+95JP5cH(c6m09kGH'Z)'-DKF+VP-HB#Q(@eX%[[e4JURA'T+Aja -)b1%2HH#!%30#qDlQ9"&&9BZK++5B6aaJBC2V@-"i$Yc,#*!!r1486H1!5IVXVpJ -pAXdpAQXA,CPLVpI4I3Rra"p+V0@Z1Hd&PG1f-+H0`!f+jV34SE*jiE6QY)rLR)E -T'emPTiQM'&"598#Ch6J)$V9HlmBYfJ'cm20mb(YZ4M[!'hF!63pbS+3QJ(*mY3$ -+pJ-TJ&+$F&@CVa&B"2C-!&-pb-rmFDC3bNPDpcj+Q(dG#lS8`Ud#XCS+%`V4BlX -[F06ccUZBXTHEqR8RKr33iT-CZT0C)!GUUJpRDdkf0!iMETe,6ZC93%!RBA@A(LL -ZS!46Y,p4fURV$*1q9Nmk#jEQJf!)C'-MB8N0V!q`"P&1,)ZKmUblBfJHZB-CK9J -'BF0@L*Z,2Z%35--h#Rl(h,*@j4D2VXL`pEVQ&M)%VS3#pSZD@kih9QEBI!HjK3* -L1l!P@ZLZ!FbVK1T,`KZ%2%0Rc0'G`3)j8ZjLS4`TjbVGIiD8N@0)EE-UK!h195A -`0Mf"QmdXJGf'@cb*pi5m2jkY*A'XF4)hlD)N#YIVlZhjX*&llaD&Q96AY50AF08 -qlkBCcDAd#CY"("M4$R`KlN#DAUKf+3[@DZ)'a@8KAb`1,CckXr)6CEicF#TlJ%2 -U6qC*J'P$JK&&HjJ#Bq0!rR@p'1lB'"r)rrTb(XJIE9`%Gf3`eiL2E368kLraCDj -Z&CL8!AJ3'Lj1F2LU)6Lb0@*k@m+XT4(!YI@6[3VlC%KUpM'BDe9%6MP)N9S5*Nk -@A&&I`+GFHR5%H*iGRkCk!-+FAdVKC2'Bi8-,hcJ3KG5*LUpNkC[S1UrU1LZZ)4" -BX[3G#V5V1TI`cKi-d1$!%,!NA0(#AI'+&NJXMG+L*d('bI,*93pee"rmHDK$#qL -9eNNNImV"XV3DX+6'NH`aPN%5QAh[m3%FYSB(mN63e93jf8l6Z+NP[miY,HGEqRi -e@pUL28rU8Aj5MF2L#!mJH3d@&EU(CG1TU!bMLj3TlEc,VR9eS'YBeHAAZNkMUdI -9CG+kV-K+$M!`LLj&khS$ABqTZNDeVKAS@Ll!bVV5Y#idcNPrJBP`&"ql'q3QZPk -fL-J"hZMLP8UFLiqKD13c2C-JVHQi&l8KEHZ!0U6YIkJ0NFadLcD%1p+$fK"Z5hq -#K8A)10QU%HFYPCS-0R$M9DXF-0Y4MIGUBI8BKG8$C#JS1#QMNCBlHlT##p'i58% -E8CFm+@r)*6*92L)(SMhbLY@!ci30)XcJ2N3IZ-+Rl0L6-YV"!NQ2N3*DY*PepQL -G`kac&ZXd@D2mL5j8+-1*6Ca1S`kQ`,B@A4fUl5@k0U(VG+,,NZJD3jFed99ZkVb -PG6k2cMG8RBUU-`fG+e5GSeTR&ETZ6h4eNB[d!aZcp&'GT6pL9bPCUY6VL-L)CqQ -rZ8`XA3")CqB9IejbX[J!XA1ZMC&SJPYFrT26ehp5A18ld0jZp*AGK&TA[KB-p-S -f4M#DpZb6[BCm!Mp9XQKBd#S(idd)U&jk2e3cDQl%C)$[,B`q3"pl(%$`D*!!'I5 -LjLkBp(Zc6'cBBrBV3`rQS[,ZII"C1RKlEQ)U0R#(Q'EF!N23!)bQ[HVJKRkm1F! -VM"9b82p`PBS&rBLcS$qZKJA0Ep`mk@DV+&4YTRZ&fH0PAYF8*QVhTj9(rr+c3j- -LA!+eZ9V&[Mm(JDGKPE%A!B21[)eTSJ[N3HqKUdbTS,)`6bG2lN19*hHlbS!19Vj -40pcJ6cpp!T!!QI@aq9rQ1L4ASr9V"4mEU6kB3ipa3hb@5,kV(X-6I3"XE`3&a!3 -Q'B"bPEq0M$R4rEH3!2K!f`$)BcB`cc3bE6`M!jfI5G0pZ+DF%+'kbI8"L3l6MQc -U6[e-pYFd"6m$)BJ*EFpScrBThm+RXR,$DHb4If*2L%0f*8,Mp'$*6Md)#*'bPk3 -8UERFbIGAiq3XQMLjDUipCG@ZKrrdc[S&K5Z!$1,#pIV*K,RA0I2D(I99bSc0)23 -c[9Fc9fC1Fp2pG,XU(!4#IIU*aL*IfB!Pk9&@b55Z0V&U4M`rUJS#9GkBE)*-V*5 -"i&H)-'YLfBemM[*SlLr53Uq&ZQ)l)85fGAS@rh`R$6j&3aiaT-34dEb@Ghh)ZYE -bVK[-+"-c1RN$+8)ZBq&S6HaC3'5!GqE@mG5`H846p86bp@hUlZ%G'e9ElBcEkQV -9!GDi!mBUfHVYp@ceScUHLYpUNlTK*DPp*!9BeP)6PqNUl3'SF%blf'H+U1-,eM% -J+Lr@-F%(Er,Y5MQ2Sej3,0p"Sfck[!V2hZAc5l4iM9r1eblhSc'R31KAKkZG($" -[CHUEiX1RkmPid(-2%E%dj"YBS0VH((E0C$l(%DqPf(S!#VaZ9I23pETMR'mCL3` -JYGq%DfC8VPQ[FXek96,MYa`cdLG5mV8NXDC3lTFS+$FpN!"bZRP6m+hN3GIP3dj -T6ek1faJ[9Y1,pj-UcASaR++!arT%Jbd4`SaV20H3!'L`*CTL*F+#dc-`I+&51'5 -K#S!EZ6+RQHUC*jXKU+#6dV%LQ-X"Y)jSEcp4K-E5CI&YHFkJ`GYmhHRZNVP(pDD -(8lZC8KifUK`8fjeU5EL'!JYLHe1Y$!4c"'LQ5,&Y'!CF!Y9m2Z8FQc*IZ(SUQA$ -l9*F3%'13!#0LHS1bU9U1#U5BhQrHK%E'p&Qd6Gc!1mLD1"j8J5XG3#kCHbaK3TV -DcBYc1XLZCSXk)*mje8dXANmDccVdaeHPM8h$e*!!PMAVBd)1ikQ*8"aJ,LK&Ca& -J(5B"dUQJkX+E20'Np'AL5#'B4d$D-X(Frdk+#c&cCr`4DP-cUXQe[,Vm4MA9C5k -[,Uhe9*I@QkSZ0I*eG4+A&P2M+C!!9FHU88TTeLH"E$Q@D%LeqNEGkS1*KP6-[1K -GMHBYe%3*cC'DpHHF&d%!RD2'5BTG48iGSq('Y%-I5m@PDTV%cEiYL3CD8"0X$UC -fk`XlArMj)X!A*VlSjiXBA`aEmJ*j6)&ZK#Qci201NH-Ij&MphM4mNqF&6)XJi%m -0EA$"NaU3!"SUQJ,9N`)eP!*P6i%kRJ,9P3*e@%GCb)![$IY',PE&8Qk1+GX-B0J -5c#k-3['KKEU8[q[1ldcYcRm+Rm"8)5@3!"*)Z`TT"p)1T&q&p!2T"c+J3JD!$!" -T8L&03*U!l&FKqi(X"c+Q3XD!M!(*A5mR5U6KQ!$#JA19EGUMJfL"!&(dYDEM(l` -Y3"5p3@iBKK2JLUi)ZD+PECmmeYB5N!$hj3dcK#GeVq66SU3FJdrDG%@LqY3N9"A -[5fYZ2,9('6TpFe1(P+&M0cI9VJbjEQlUF@ASk-e0l9+'-ZUD1[4K'Nh(0)K5p4- -KA'rlC(TU9MJK@SeFHMEK8NpHma$%E5X3akLaIaJ6EZ#613"4#-THe23RL+BrEEc -KiaA4P!40'JY9c5'[d'Fek$LPbh-@ab5rPGS"$@*k00`#d1H-AI608VUJc$U4B*A -,H`5VA2l9DPMPLRJfpiGh*eIpeHbkfCbB&-rQrV$NjE1j2mbVRmdp'-IQ(Ub8c5f -Fd0NF0I&[BSViIk+X,SGBAD[pJiY@rpMrVUcZ)Q0e1G@`ZTarYeNG'QMP8`,$!Z3 -Y6eRalA3lArUPRbm$-X#Ae-a",2YCi`jDaQ5-,iIPm2[h3bMe)ci[P&QY#FHfSN( -T`R`(#V&34TSk63K2DJBf488,lYl8HKLI%+$18&JbY8)fD*B3HhkTG5MFjAfENAL -$VILS-"T&`GLe[SqVUef(L1Z-JCV[XIpX`cqEm4LDD!X&T#PhNq6,%&T*JbeJNmP -2h[BcN!$6dci[Efk&Tlqq864CM@-2*XiH(Uk'2BbP9-GjFXRNUN&R-[G[aDGHUJh -Hd#6"'*im@eG)IrNj[T'Re4YalPRq1-XdBC[,d6apkZL2%IKErVM,*VCR5)@Jr2A -9VejprIc%j,(*i166SdY'e`DhMpT'XdEriRc(k-A4kk2AJT1M2aZGGI9IJ[mDr1U -S6I*r!!!Vkd&%3e)$!(*Q%&8,,DF!d@b6YpfPAXY+PPSlHjJ+elSXDbeY8j!!0!6 -eERRrbd,DG9Zd1KahDEZl&2Vq0Qf"kM$M3JY@3+9!##E%'*1ML-TJK&,IEcE!1-5 -3!%53!#MQ-!QT)*8!ib(%k6%-qrYrhlehllEEpa22R2-mjhN['fdh58Z3!!""%!" -"S"VrEY!#4L0q0&-G"9*-QKT584p-a4kT8%CkHBJ-cRq'CI`'8k,FLS"J21bTm)P -j6@*XEANF`F'E$-0hD1(KSXicBYlJ"%m6+U$)[m'k(Gdk$TreP6e'il"Mm#1Mm@X -'rP$TT5'ZU36+dS[rR*Flj*Sqh+&&"Mr5Y04f20VPac"rl!ID"!a8YBe&),ZBQ0` -KdD1'D,lRGUHdZ0f2Y5pSD%RTc@aXF"HFE!MZZXVFbl,K#m0&T-SjZ"FYdGQK,EL -&ZTK3mCT$$@AG)QMYcjkh&b*XZe)E-58KH'h&ScKlb&JCD09dYQNJ(K$eh#(IHb! -B4JHbbYi'N81UVB*M(He"`q92d)+2T`p6!(NdhH5Xm!iaCCICP$ehA"0G4G59`&l -HlX&'rL5q+'`DaSH1$`Fql2KS`dF%(pd*Gpa0kNl,V-f-SUiAqUV"69Ce,&!@HQ+ -ZVjFU5VcJfjFhdhr`P6eDcR!A@rJmcQ+e8K+ccU9VB5fX$#m-c@3XCLKKrXMY2YN -JlpV[$JAp@aZ[e,B%8l`YGFVl(chVGUFhTTj-$lScXdcZ(kRM&l5lmc*VIAKIh8$ -hVY$@"dSfBm[d&H5#2,0,rXdr%XJUU3fmSfQE0JDb(Qc(lAQUUNI#AR3A-ADdrKd -USq6I#1&`j0IXL%%qFKDh[iTkj0Imb-,GG'4KPhaN2Ql&D%F@lPD1I*XG5@&("[L -b&YE4NHmZchINfmU4kpL4pq8M@0E#Z9'2A-H2P$e,4mUXmK%XUqa5Y#0Pcl*ZVGR -VfN1[VQ[hQ2eDiH3GipGG!UKf'cjZKdZJJV'-@-I3UBM%h"9Q"6Z*)AA9dI(Vc#J -Qkr#a!XK%"cB6ipL"#h6JP[25!mI',h+J%CL'MbSi$MS`LpM'$ML+(l#-ArFq3+I -cF4f0j8CfS&8q%)Yk`0b6YHl5h3&Y%VpCj+!E%3q@+UdI`LVIp4UR``Ah'DH$eYC -%EACJ1J'aPIeQjIMlr2LL%)DlV$SDM!eXk`08A@aVjV$D"1HY&ih$JCdG1KV[pHb -!3*A&$KbK!rrM-qF$*9BFX)lSXhFCjl%$#DSUGL!TfS&&06MJk00R(cA1C3GdqF$ -e83q-JrSK44RFP&Jj+dUX#L['J"@M'5Y'bkaB!9D-)9D`ic9d""dhVA!h3!2aLaj -[6bBFGkRmmPI&Abi8SlbXLr*bE['ACCGX,k&1J,S*e'CaR0ZG5JjaJC0$R(3-ER+ -AkK3pQj!!1+"Tdr1!dL$JDJ*Ckmc-#CB&J!,UilVhq5-e@lLP6EGT1VE9"dZ9PfE -f-LapZFK4r1@kpk8[-@JF9FA!5V$'UMiZUZ'2LTK3mHd@M5XZZX3DC3NedTI%)0j -N0L,NS64He'##D3V$8ZTM'"T(q`F'p0lLd%4"#kQ(c6pX#,B8A2(,$[Ll1*bCk[C -RTJITr6A9%8p+hADbcYe5Gc+cT3'[hEZmep+M#qp-Ur$8U-*65AJU&dl"-EJZ#!a -XdlUG'Q!*X-%f#f4Q&9`*URY0qK(IUk'P,RJbUhP0e+EU%QpSZ&)FF$*rYq'GfY6 -N5&8CV`KkVf&Eil@XNlA[*&FD#8-+KT',Ze+E%UccTcGHHa6LKSZ'Bi415N'd$TC -HdJLmGX"&')fj3rkN5pM30CABR`!LCkp#&dPAIbbq1m(!&[2q+ipb#6D&6!8R8rI -k6fDQ*dIFYAcLhQfmQRcZA$[8L&FpPMH(H'P"Q1T&+``fT4eGkK9@(&hLf+!%U3r -qm&@MbkkL53KSJUkE,M(YL**Q4G+!*Y8,bf395jep0Q"kZaBTAB0ZK!!kZ[60)+2 -6Nik1-SjfKBq1dZcaZaSlHVCVEH)*-9BREMiG$$rHjjU+MV5LRKZljZ@CrIIh@'i -#12r`NZrK+"SNHq1Z5$H%YMfa4SZNG0&M#!2L!A[&@pV"Ze`$)#c$`f#P`X6H`G) -1c6YN-RjQpMRb)#$84'*U2a0MD!TlZG+Y$DBV,EA*dGLlPE`S9cSL9GS"TIAS5PY -*k4-BT)[KkT4qH2($)'Jq9T8@D$K8GU4-"D'K3f9#J,YFGPR4%8+@h#&#&epAr%4 -SbN!68lH#U@X3`bVCChkhYF%A6+DkUA*c"$904L6TV3)a4',4'!EhQKSENL1AIr% -G2jh2c0r%pMDDJV9CM5R"kVEH5eXhq[h*f6SphflI)@%TQAA0,L)kJS[kKR,k0kV -mY[)D-hAM4N(f(K4`"`M)0R*hTPiaGPqj99Y+#,kB%*`4(3c*Hfe)EUI(E)ENr4A -llh*e[4+@S[GqlF!3QT3M[%P*2T)h!i4X[GB-NYH[Z*88$d0YR4-P8$amAhPFHpK -`Ni,NXZ)lC84h%+*$EIe52M5r4'JZ0k'%l0P6,NQ4rG1-)(ZD3+q-)h[eFKpSC+p -qkq3Kqcf"YICq$aELkk(QaeZH@dj*UchPK!MH8lQRH*!!bc,q,r[C6`pp$8*(TaY -jq'-pjDcamY+VdPZ4*,ZIAT!!B[`,0(Y618QXM8EBCK+!J%VqiZh@Kl,+6KR[f6f -ll"5pCX6'jRJ!@BVLm!8&-ES(5`Fd"YDc)6M@HmY@VCH%!lPkN!$b`B(PE3V9i`3 -UCh,f0HIi-ZaD-XDm'KIl#GLB9a-iC-bE`jJh4fA0RTrQBaiV9-l-HcE$c'ZQ)'8 -B9I-aEapRRT4eqC!!ETE#Z$$G4'1FM@er[kM@q%#K@JX&kUb%&NMmXS`bhK-UYqU -GGRV-,NF!GJU&RX5mZ"h*APDYh4qD[8fEK"3,q[QVMlViCh'b'J4[hSKGh-@'&E% -8fAYFQ[DCZ1ZKE9Ulm4p05-rUkM2qieRcEL@`mZEL!d-B-NhFbSCX8SCXBN0LmT! -!Uf+Hk%@ST,e2ImKVr0e$YFEI'8Z3!+453UR"(Xdr)"l&&kqDFYMa9mqD%CLTX*m -@mfCl%3cc-Z'2ipMMaR8)UUc!L`A'43$fN!"m`)iX@Qj'q&i*ek"bbRLB'&dKRfS -jBMC86D"6PAlH4RVj)"Me@c"P)k8pf+S@cGFh6%CdSRi$),H(UIpE9kHB63[[d-8 -G@1),bK*I`"*h'-Zaa'bfQ)9BbN*+8N15XQdCYbR"DQb(3-Um42C$fk()DiU3!0I -1QQqaD1d)C5Im"pPAUpJAUmkD43pY#J#baAiDAbd`VQ3$hQ!UVf6$hQ!U)pN2eGa -+S+CPr-3ek#3GhB0#mH2lq5-&fA2,U@2C-RlM[)#A+Q4bH3JN"C+U+F54LdH@Z%f -hpe[j-2i#3pr+C8&12"C3#26hfbK%Md&M5448f`#NljkGKfjLUUJUTD*Hab*IVcY -L1)h8PSrp(9K%eE[EY(lMCJ6(0KHbi"JkHVV%RHKH)Z5E)L2I#68mCHleTepTf&C -G#DU(l%fEqe$FVX(Q2QS-Mp*p2+$1Y['"FVDEL&h%(#,)!p[c%H1EE-5i6Ge&(d$ -G+8cG+DSblhA(!qLQ'E%T5"eB8+b0#IUj8mI9L05Kj[+YhVF0J91eb1cBj86qTch -#&CAiaj3DP[*j0DFeKiUHVqmY63'flDRGJ9Cd[8R!ka%3aTqDd8P9q&D1jiLrX&A -cK2eG8)"e@Qf[p""aARK9mm63+8D*edJD$lHbCAp('YC+qkU[DR,hIVqD3Yb(0$b -f@,XT3S9ILicN82(h!cb-Qc[Id-*``EG+f"SKXMHh@$$PDM1U@U&U'92eDJl8+C* -&Qdaf`d@iY4i2TS(jZMfAdb-F#ABi20M%EaZkUr0PeX@YX#GVJmG-S,e%@#*I9ef -EdPdA33HM%!IiIZDS"[$G`Cf!1aqJRABZCJ$-jSN8+UZGQ4L2`X51'+Z+)L)fI(C -28kfN%R,DcMI$BL3I'EpL,$kIidRb55Y[[3QeM'N@EIiN*MM"Q,h2dj4qd)RCdN1 -VU$(3f[)31+#2`fCI`K9[e9`MV6RiBU"1Cih42KZK9JV4VUQYK5jEK44JLm+hY1' -`H!5*`U`,16`IiC2UUl#rZ5T8$kBA@)Ai&$U3!$XNZr6-I-4,fUXcHD6,1V9L@31 -EK1+T&Gi'aREkRXDV0Rqf6'bf`dRVq#KNNfU@bCA@0PL+aR8CT@)",*J!9YJ93H@ -XJHj(`p#'$cZl&I!BB4h5!VDa!-bS3iFq8S@e&b0Y)'F6"m1"bi&rB@M"1[-D2r- -!(E,)F9M&1c4VhKZD&@%JZlKA5i6Hd",fbkML)bi(ZZ*CPpHf)Zm34b)r(3T6U#Y -NpZqFM@f-mciLT'XRp#YG*ZTSrZH**kS,,f'BRBC4k)%8bLN,6B'B0Z-BL'N,DNB -['c)+#4E+)"$e$ZTq3*2q"`!GTakUeAjJA)0$#6D&DNh!($!!I,UAUDGdidX8l#9 -!""08V(QVQ*)4HS(1P`4#QBQZ6FB('@$c)%Kp(-E([DV#%,UHJ@6VQG**E1#DN!$ -j#f8a!+eS39@NKME@ZIMLF+95J0IC#R!FU4+B&,Te0ffQ0'G#*AId,!fMNc&dEXP -+QD&,'%2RLPZECHJ5QD(E3Nf-REG$5&Y`PX,-frN!J*kV180pmGepfJqNbm#50c" -e0l#P*$%3G$@8A-fD&cXrb#B,KLN43bjF2m`IMNplkFU8%b!L[-'KC#08V(L"X6b -ALScIbP#kKm+,l(8RN!#5!IHq!h,$JDpG(8UK#KI3X1kmP640#5(**2V#hU3)32) -)KDBF2%LcTeM)181VPcD@V(JAS(MVrJ0TEpCpV&"Vmk6Z6#lJBIP4PamGY)@[6aC -T9CdlGHJ`B90)B5!VTSP4X&Dmi'SP"mPF%E&Q1f1S[I--VrSIMSNMM1F+1#1`08V -cikR!P+%c#+HaJe[,iKT2$&*&GHiN8A*&F8BV)2@9j'%)"kNrMH*1Yc''ec+'E`0 -LVj9CRXM2FU$fcaPUraaXjiLp&SLpPM1rF&rDQ8q-42(5M6@fB#(F53fa'kjX,Q2 -Y355-eC!!NpLYU5bQLDYJmVCL6U*+BI1R0MBM,Dh+1-D$G,*'N5E2+k*SFSI#H", -(@"q4$&#UJ'r&e,fGXbVR2C!!VRmdrK0$(#eR4'Q8`c591kkEl*[,rIUjlFJ'lEm -D$M9*'E"d#3E0`iYKaSCDGX-B`BV8*JJPK9YFVUJ05d,5X%a9'aE'UL)qf(m!C"H -@JfNMj,6#aY&SY-)2,m%NIk4q)C8KI'iA(Np`Tq#"+&qkb9jL$Nj`TB""BaSr",2 -')#f[%bK)5B8+JlKE)"EjpV!0+T30+R%EAVUN3qrM@e4LLk0ih-&85P!M!FDY##D -aE9C5SUMXj[B8kf6,)"UcN!#UhK0!j6YQ9S'K0h,"a6S#-baBGCqmH*4ZJ4-`C`$ -F$Z2))!2k"T`!2[VL%J1126,4FCD)$PrKphk*`P)Y3#dHPaeXEfTkBd-`Z39rT8S -F@XEIepEM33*d0FPf$'fl+4$"N[`B%*!!aM5rPEDLKfeQF'+GUZT1PRbSK$ZYl-' -U#5`&JJ#Y6TS#cC-eC**dV%+5MP&*8LE)4TD1b8H@rXbf13h&a2*ST1Pbjf%63Cl -bC"U&40dDM@"23`S'rqCCpkjM*hCSb5E'hiIU6c*Lr%Q9'(rPe#%PaKp,)c'H`35 -3!',%q#4*Xph$dQ!PK@B2T8iNmBkI!iHF*+m[c53C*2PY'5,*LbRF5`U(E3Sh3jK -lTB5jCr#3!",QhJ`6jSHNqqZ3!",QmI20-2SpB[6e0NBA)mqVST!!jeiTHDk`A(T -SA6(b[0r9$[+meiNmliMHMIU!NqVH4d@U(qT14QG5ADFN)jF@)r!bj$[!L282C'" -[8JD)G9A8[LMNZPFQelhBk$'!C58+ZEkXPj(V0*AjN!!3kdPX'BApC*`"+-B4c9m -J)GX(9E*GLJ5B!T%Q)Ylj%*'BA1e#DlBc8GpK)qU,(k,%9Fh"&bFKp#HrLm*RV1+ -%2NYZVD+T(-NNmpFbmRfY61C[M%,QFhD&D5XT`j`*rTaqVQ61cM56r*T@,Qjp48, -dlqU3!$BSM1!ZN!#3!2k$+ZPIV&,5%!LSVP+d@GR5d)"QV,8&"iSI!NPeRl4LI#1 -B1Z53!+V`,J8-U&Sf506Jj09pB09p2Xl1EUNB[blLTDC4-+8r3d'%qK,kU%(R4Kl -ffi))I!NY9*MprDbSG9#kLP8,U88M&i8Qc)-*20d0`1))qqSp1Cc!KrBGTS##,GQ -&K4Ak,pYHbFU4'BFMUU'(0)3BkNPm4'",-46"R0*f4[+QC"4Bm5N159Z4`9"$Vc6 -8)'fZd1LS3UF4-bJCRj*Q+"dI,b[)eA15K!fVBa9J#cZdAfSZl("[G@'(`*K,qF) -14pqka013!*5d(0RTa96$&I@%(qVVd$0%Db)+Cl(UZ-UU`i6LmU"F)4hj+`4&TBB -9P4Uj8RK"H4!&j8'eDJSl-a5)m,*!a%DjF5S5b@`%K5(ZCkbQ--4'Tc"%1aPeL4U -'@+1`hH!8KPM$`K"VmS8KeUJ93H+LKb'1[X@hBNU29BZ(iMB2B,VK@1-'*4cK8F- -4FAh$(2ShDXi0j690Q#)b$k'**KDD1)(34+&6D!+TD`K2d%6FpAMCTi3ReN[$%c! -NXi%aSY@9mZM#%c!`dd4E5N)8KQC#&&GCm'#+UjD&+,Da%-8Se`PTL#)`4JTHXd# -&`,DUN!"XaB-9KRU#&D18B-@Ea1S-"#[U6Gh1(kb3!*Z)jf[-D3aFe,Y*P-$&a3` -6*@Vi`UZ',a5!@!eIH"q`m%9pMN-5[YMi2b9mXA&F2H%,Vabq#$Q&,cJ42eBKiXH -S42`$&,ji,1hKLhV6$56K#iC3ST+QVJ5"LaAk$K6kP8UK4c&#J&`Yp%9USBpVeKJ -&b*5'*1'K5DIGLSS*YHXK4+##Y+P48!CC$bNrbVJq"3q)#R5NKbP`-+S#FTJq6FZ -[2TC8S+ESlZZ&m4lGmfVCTrkLd+YP6pf49IC8fDIaf@@ILMZXhJ35l6HM%+6dL,( -90+&k0%r+I6-JHTFLC6FH515*45LmQVE&0S8h`DI`fLhMEiJR@#'bM&pGN5JAGm5 -pqEFD`9E@*$&T-iM+)+C-VZi@Nd*QN!#UI0V[E@bDC&MCR,Rj2lRijYC!r)3e6h4 -JUhMHDfKN4V5`2bbHF"@@EV(U[Liq@9""F%cC1M!%eSIMTe49a"h$p[c++"1HH3" -SPpYp"Fl%Ic)ef+*1bNeYHFF8*!4`ZqP&rN#9`Zpf&*&YMI"%GCJG@ic9Lb8-@!a -@,miJUaFABl8$)4Z'6)G(B0L$XpPT'l"jmIqLE2jQF6B$Ad(YTejY!DiLD64Mh-l -2lLd54Q`"ZlFF1RCRhbZcffNEX([,rilX[TBmGUmJGP-k+Far18b16mfT[&Yc"CQ -F#Ac!$)mL#40'+#IL`aj)ekc$)h,6iaJXMF#X(&aLM-bM`%hZ9m*J5IM3AEe-f*[ -RFf"'GB`&%`53!!jC$8(YFL#S`mchcY`bFL1#ZKFEACKB-#D4VL8LG`8U!SZMZQL -Va%AE94GYVk#%#B4SLMLj5B'($SdQ"M%R2$8d*p48FM(VVba`CjFC[2pDA@C,X$d -CIG2F6-XDeD6D@eSVM!NLP"M@FS#'kimapBer$*Ahk5B(1Q`jNkFRpMkDKJF33*J -kYa9aQd06a&LSLGJiX8)RJlCVKUr(cara-@VB%6$PDS'pU,ilj1V$91&Z,8+*&Q' -PqZ+SYUP+pE@j)T38S&6,U*PE1Qjd*6e%!2BIZ@S`6cH*0AGpeTLRb8HL%hN9G-$ -H(p!S6B356jfD[b*2KAmH#`hpdCEq5FhJJZ3fJfZU3H!a$)81U#MdD0MF%@DS``@ -2'kK3d'F9X9JT))c*T(V!Y%eM,jd,LVeB3BP)#NS5"ApG!QFZ@'VhpF@6X(`5NFK -ViLcYVBkP6E8fPR*%rLka0$PiA-#G3UA+e+X`)1Z)-53fB"Q9ZH8M1Md`i*R-BbG -4Ke-qCGX)($dBSb!T!Dp3YNZ#9ZQZl8J+U82&9)V(BAaTG-V69%%$IaGS#Lc*3"& -[)QDb)Kj6LcM[D'9**ed,)6Vi)TCrK#(U#6*0V"Ec+l80fc,p,FRY*LhZ-YA!c+K -L6V-V68jcM`3CLPcl&A&[RLq8h@CK"YaQ`32J0MRSl9"3rr(q$,M0kU(`c'[0ZXd -Da@f1c9EGTKV8+$a%MP1YZ*p@icV(CX"e@P&jGU85"e`(HEM6fAQq5`9mV1`mqjM -cl'I1Xk-HjmNV3)Il[-%Tp0#mmkb(!)VL2&@@9$*8q[!3ZNp9p0Zb!he4iN$(CYL -"(R3#0"a-[-"Cc&aS2h1K(I@i8*@a6E8UBp2L3T["kImRZ0$k3M@,B@cR"Ep*6@! -i8@3CAlB1,&R-Q*&9YSi(C!M8CN'0$C*8L+bb&fPkbYZp#-iXjLCjLL8qG,&M@fc -(Q0'H&fJECKiU0IeN!bhBl33NUjhr#"Z#E,"(*aZq+)%TS#*ek4m)-0*BbDIhV9j -Z-SE-RSMrIM+-6H&(HSN*0[cJ3CE%S4JEqGUUBS[ZiC2l[j9eFQr3AId+HGM#6KF -+B8Cli6ME%PY,TU4d[0+P"TL'jSUHdL8pqSERkGqSjqHAejcq@h0%bckeD0Q"SH! -0E1S0$`GG5QR%[$jhIJTj+dd%T[qm-rG(rI`ECJ8Pkf6$APY!%3[S3Y"YkX*E8j' -3!"l"XU3,'G!)b3`9(Sf#m&M!,i-EL+"4!RllXAe$kXRDk'ZSCR1qY13X`9Gm#6p -8Pe$Ef*,a04#k6&I#MQ5dcllSPbPpPlV8cT%F,4MZMlQS`a9KCX[ifq[H0HQDF6T -ef8`bXmA-Cq&2AKNp@%a,ia@6#H4CP"T4eFl)PU25XLALeXe[#@-9C,U$)4a#RQe -2,%XTXNF#jRE$%mZ#piJRV0`XaGd3Gbdc*9JE&Cp5kImeC`0X+JS2,&U@dSd%kEC -A$NT-BNb#'c3X@ZBG#QjN+-X0HCc$0V8RkqTX`ICLD*[U6C8hfNfALA$B'*3L-fG -&AAqrVP&b"L81`68QQA3!&bh0$)kTJkRE2+)e-c4*1[3J($Pef&$cda81R!lmKK+ -)X'%10JcEMp!AICVK)Pi98QUl2D`10cb$Pj4Lm[0Q0K0P&3id-m`Z8E5IdTDE'5c -)Jm-QPmYPhk1pkASkM3F%9lpNk)$c8(D*$,1k%!Jfmk3YMCZTiRl2rdk8UP94TiF -&q'q)pj6IMB*2`FQUXHc'SHPh!Ch3MISkZJJGF,k,DATejb-)eaaMU0-Z$AdVXP2 -*j%%eaEcJF,TUUN8amcL*YNZ8Sr[$iD-d*4jDFL&)8q4,iJ&6aDb8Na&'lYUG66$ -+qpZFZV43@`HkU$QANl[*K'E--[i2G8K!kdGh88kE186&H9kD(%JUP3dUJ4RCE%h -pQd9c(F8ffdHG@ffPC"6$UG-4Vd@mlZl3VE(lTTcA2UY)XCr2L4qTQB0P&,TfdQX -b`iZ"pZU0Tl$153aC5P-l)k`cTR[TBY`NHXVY58!Y$V)X`))EVmMmcamfflSVP-Q -G4iKqi8Nl%TS)Tap$NS`@fU!TBp3e6k0qS+I2+DbSkBNJrJmQ,2Qec8iVMI%l -(pI(Vr6TAU-DQd*&U&5*PPLM+K1rM#KNN#R(![jdDlYVQpD&D#$'hki9HULYRD5@ -mH6bm#JKpUkd6Ld6r59T+mJ[H*4F*U4J!1QY(T8P-UV-BeZP*jN8QETk3!*j%6B` -VV)UBQ3Ap-QhKc%cmMq)#(-`&(-$@[*!!@k8lYbp`(`h@"ZX!59@M5(&KDb[5,-a -*(8`A8)bS*MDalXB`TTb2aS@aHJ&-KTf-Sq*L4R%c%RE$Z"5%a05S2*'m5TR1lP( -0QCU[1EQZ3fpDe&[0GdS4S-jdT*3U`1[pZFUNk8aQd-Y"aZUD3@IZ-"iMcqk6-IE -ClmUcPV'ikN-ZDYckC$SYV+@a6MA%G&JaCcHG-jdP[6*dr+T@lID&!Fpp$&%C!*l -E"pDLdhDe)H"9c*!!-D1'pdH8#GQLBPa,G-,Gr#b48BI-ia#"CqAQQZd`q6Y#h3, -+9(X3$Spi02f4R9VB@K%2Jd!$mBl+ea-cFdrP0INVCE-e2j6DUPh3khCI$DD5TUE -'&2IKG(8K#f`X`&YD4fMVBG9S$BLLbB&hL*!!8%a"[Xf*%j[48K"FbiLFmLFa8QJ -CA[aDZINeERkPh2`+0cp4ERk#QpZ8QpY`Xe5j@BUEqFV0I0aFTpaFKjZjbXeFh2a -BZINaEQj3EQl!c8h+c8hb4DYDBD1"#&D3!*Kh#'Ace"I228j$,TmXD+aV88a8[PS -fchm*2qXE$qEK4jaGYRieJ)Z29SJ!Ff&D'5pVfA6#m#EFE239L9PP'`FRG1*'4C! -!jjJ$V3LfCVCSXYJ061!'#0a!!XYX!MI8hSZI+LDULSQUHRd-LEMSGNZ%U)AI&$1 -Mq--d-K8,acNN(ZL9FBphMRG1jmY%3TUUB)MF`6Z601e!0Rq"!lUTdN"T#Mr94j- -`q[T[2'4`3A8#,h8#!IE#qG5Ld&a*EC'6m"JDdL9F)1)e)'1,2TUQmb%GiqR%mDZ -9lmqdaNSZTqa,)1%&Yj2,QP)+VE&&[r36FZSB0URNFV"'M%fiA1G&)AB-(q(E(pJ -%3fT-j#1NaQL%#9JRfpqX%6hH)GA8e&0m@3eA#YL6CL03V8Sb0bh"p1qrQ5NHAlS -N%6"pl6F6cZ'##PadiX52$FqGLRIjHX@YCf$U$N$@ATB#i6J6)X2-H036Fl"e&fh -pr`F6jI,0cbMTee@8Q(-'Jr!"pF@3!'&#A0[mQUDRKKrCbSbI-ZGcLLmb2E0@A5$ --FPf`+Se2AHAb8P2Kk9*6q236!1Nj%drFC(KZcJ[AqF2aec8(([61QCd3M-X$`1R -GQFQ@LKmm1M$Fc3QJ+AbM+l@5VFK9QR+!&2DlF9(9RNh-p&8EQS$`k9)m4RaGY$N -KLqArk"TH6h$TG(Zh@4p03LIR+Db9eV`+@,'JkIP+keh,+Nb&KJU9D)KVLH-r(J@ -@6$HJ#a1A+BbTAh9S`pM%8$&-,#$AU+!K+[d)5,bN#4`j13*N-d2P9Yr!ZEfN*L9 --h3QAGSiBlX%,Z9[b+AQ4$DEd60X#p3K62f`Sp6qGH!59AQJik`Z,aeb$m@2I@fk -krMFc6CA%r[PRPjZECZ,VQIkLeXSYTI21RUN)M'B%TrHMAk!$&99LBlb9QKfidcY -2d#AZN!"1FHc%Rb0f"M,)#mN+e[Q#EPa'33DZ`a(eXRLSiTNG@Xrak`bQ`X4%`eP -r#)Xi1rmbAj!!iI4T[T6`QG14dHa4"p+q%+%8f["T2-5c&f*4eMH!'(2pKCfcSU% -%PL4'@e*YX,A&KKLH9crTaT6pV%qkHbD)Mpej6![IM4Yd'q0(I2k1BjpdZiVSTqI -jZipaNf!98L5q3#Vel0A#,rc5AcMc&`[(Ip,Y$p-"m8DIhM16Lk4NrmkCiM(Z4-V -GcZK*S6qki'a5NkECrlD`b@LmAA-dJ@l68T*`SDFFZK3MFmeY#)-9+8PH%CLeBbM -bp"lqm''k5+l+SCURI)UfJ,,Ah!A16U'I0N1Prf"qdh*c2-IN,6'R&&leLV2"L#4 -5fk@%)MmFLk5D31+iiXJ'N8#Y&pJfAJG!kS)AiC`l2$Jd!YF@AN6Uce125jEE*6f -'$[rMhR+9L2QHdUDL3lfZ-FYpp53eZShT$C)&Jm@2cH%&#CG2NKfcUC!!dX`063J -JGh((6CH2"5)erG5XQXZRS+h#S%e+3,DI(#IIr118B$hEmq+0k6L1-d6@dK6`0QU -F(ZaCDNJ%cRMaC9GZ%ejhpc#eMi34i`ACd+U*4r,S8VNAcrrRqXYdJi[PR8l0KE0 -GBTd$S#4Xp4bD4fp&fFAJ+YULc*`b)0dJ9-&I"pGBjp$#kaam#SYPr'FVPKTbb`% -FHF&51%$9L8cHPGPDRD2VlVfUlB$LVR$ZU4#TV'qHA$!'*N5Ga-B$ZHA@J'H#(j0 -MIr!QIHAq8)))ZEMFVZHjmJlG-%&eKeB03&Z4Z%2d)VP6Gl%Qf&MjQ,PZc'fRKc9 --ah-!HHiLN!#+9k"V5[`8%$f5b,B#a%6k+K+%Fm[9T["Mj`VeClB'8jbV0**I%3F -T3Q$$FkIbUf-PGI4cB*1i8cb&C",G,bDb%@DJk5T+DVCV+K84+,J#EQKRj`39T2a -kIZ3UYTKKQMLP-mCB66YKCN!2fP8!kH5-4)"5#G8Aa%CE%10L&T1Y14F5Q+rI!`B -II`j9DjL!a2b3!-c50iLP52AI@@)ZQ!U'XLDRi%1N8bTT[kkTZA+aU2$A"B-5N!! -+l'V[hj0M-%$T&3'IdUfdr5cFJ`I&rS6R$QfU6fR'8YZal)1&HkHrJJXdl08-B&d -4*SKeB!Lj`40LNAqG#Nc0!Bc2-NfKMFd9XZU4EQKA0UcNDDaAME3T"+fhQH+&+'k -l5KC&VTdDVaklQ*0hQP)UfLDL%k93ZpQIe28TdVFGl,E)(mEYcD(Rq6$rcj33%I! -I-c0DH-h"LF+C"K[U%9h%40qXL,kCL5jb&[epQqL@aRb#@GSTM$*V#Ib)5&keDK( -$+QfN&)QXH"9")"BLRR46LfTbShr((kbcXBe0Af@-5UNdjC!!19!bM)!dFSK#L#b -!JN32hF0N[RI2)%!d8f'*Q8hC)M,0kL(M'%`aN@i4A"&MVKlUX-+dQ!JZ4Kr6M[M -YUKLfdCX!66@e#TiN#ZeN5Y5&89FANYflilS[qpa@c4T9h#k3!%Rj&bV33QPTY0" -LbfY6PbFVMZ4EZIP688*GNCaSbJK9%Y1"5R,B%%e*,&PX4d"aM4l4B1`A&kb&)Bf -TTPl!E1&lG6)ejlHc#@`hN`KfB*BT9Q,1kV1(ml3rk,KQmiE#$X`)d%ph%"P#+8D -SK(j8Cq`,-`*jlIT%-FIe)4qNd5AqGAlK!+j%X*dCP`#"L14`Ucp1#r!lE&Zkl2` -SHq93&Q'R,N9TakqDf(V+lBBP9MF4mjT6P6LJ(+Pj)@ShCCfLGKJr1M0rSV1!j01 -N8,S)KDcXiM0@@3dA-ih-4,T%rK#+rH&#B8aPac-GYL(%LPXfD4IdL8K6Gl$8V`Y -UY9fm8SXPTqCE,V[BTH&pUUEMFY@&28f+SBF)SE+I'8DX[CeARcq!9)hHj94Y0mB -Tb0m,!,M*"j-!0)Q4Uba2hd6k!#Tb[Ub1D#Y+Z80F),qN0+8@j+[qFDBN3SiDCFK -KT3ZHd"h*r+*IP&6ZVF4Lhe3R%8p,+mm1YUJ#"c4CC$r5rA96%DZ)qJ3@X3FRTJ) -0B)AB#3hJC1%NA[e+p0-&[8(+il'2-a#ATL*$H`k2N!#0-)QTm!lK+p(9CIP[G&Q -Q1`*P943Fq%UmQN21PaAme'e""9jS9+HB-b+FT9"Q&RM-E"-VAIL&Zr&KkKCNcDa -Q6CL"B*098)#U3bkqe20[NeZGi'k*Z(h1iVa$A0K,EMI,M(&H*$G(rj,D"$PpUES -*0$+%q&k*Nb#`8P!ET,M'h061`3Qi&[PfD[)k*m1jK@(`F)Ke6(5V65+3!*8Z4Q@ -E(-m+k%8rfeh,jbk,r'b$e0%dREdD0e@Q1L890IdFMGq8)LaerQLaS%2UEU3$$TZ -jmmq(j%Am!!4kf8A2P+hc1&#Y02rT"C4`A`mk+Zi+6Mr#%9-Zk(lQR5ANH6Y8A*k -*MBlCFr)dL3)j"8QH4l5E-FRkEU"H!Q,lfKl"JY(FLSpS%CF)JLp4qL!!m%Hd5I2 -,@H-E#j)KS-,$jXPQ-BH(LI`Y`A3e8+F#9A[(XY#@mTfN5dDh-Gc'B+S+6&&APk( -Pp$JccQmYaSi"#6[NJpSDhN$lfcVa``rX(4[AEN*$"c2EKI5PVmkjJVm`qeam1iP -Md&P+5mbrL`'aD!K6LN!365U"S&5GXpl96ep1D!+DS[X#Nm3S@5JbJ3HlV&,%F#A -a@m@"GJ,!l39!18+0-S@G!f33S'Y`*R1DGPpE&0AXj0$CTFZ8kPB"5V#IjU6Ef'q -AGPbNRqI9`-G%'e,ES3D`,fB&Xh$T&9[`K5%2JVpd'ABBpM+*)(G!G*PL(6IZ[(` -V,Mm`lE*i,25m[5R[X[mH!!i$BL`JG!SpXCE)kYGKmMAfPh,ckB[QM[#D*dH1q#D -*ah+I&j[5rJ1abplDI@[&4MTH*,qmaa6EBQCN$Gqm`Rq2fJ8'GicdR(5%)V)80FL -j'ZI"Z@j8A"m#cCQ0EY!0YX!QN9ZrhkH!ZJh[0,J9q&m&(0rFV3LR,bAJZdcZSdR -25M)PPG!Ii3#Qa#M9h6,q+ra4,Ck$UH+%ej5cb1!Vl*c*(SV)"6(3J`Vm!0ef[Xa -$`6"0'aZF6)#@@VQAd8R3%*4FZSKG-)-9S'fbbmbQPkCqd(T(UR5@,[BH2LkjpK0 -`emMqf!@&9ZdRfK'!&U*fa$9!Ak6EREk`Df5%`H&+UX-I3D(1b![fC6pP1MJ$jY3 -4FPpjY9dKV&2TQ@ZSJ&36%TM`pd1Kmq9r+KF16rRqU5m[@m*VkDqPYUUUDJNq,1k -[I8eS%CSXHhEHE(R@mY$RA`S"I*3q-mh5mFrVa`Q,KFFY'baZi3A,+X%rIRQ*-)Y -Hri2`IcY[Y[aHq-5bQ,ffp,iS[24ABHCIGbckhHSTclcmfM1GIhkU-qQPTX[#0`A -I'jp-#EMK$65Y`r,PfVA#IkeGHh6mei@QV`[R[bk8rV2`m2F[0`P2I9diB"Qrii$ -`AjE41qke[2Mj0li5r[[Rici9rSc2(CrYFPKL@pm4(RZ$,S#VrDY!kbkiD,QHba- -1#i'U+L',r4Mah8H@2ChAK21@(`K[6aBZ@rlK2jCECN`@2[aBH%IiI),`iLIM,$% -m62LmA,JGkRj,q0fiji8T`X,268m*PKR#XLF&pm8RK*52KI2#f3R#ki*PR1A1caZ -%9crIDfRrr%r#,i3b(*JPr-[R"8m*hj`KV1F(JM0Q,C`adh+AX&$iq63KEiE`JA" -dKR"#q2BdBI)d)AZ'N!!V"'B)JhMaTI$"-pm[%AB+PUd[rFk5KfAPPVmKl(VTAkG -mH9&iiVH@LA-UK-"I9Ui@K'N93YNU)I"'qFU,(mpj9CLelZAI#`9I#UNc5S@KH8+ -SiUr2Arc@UE*Cii5KFZ(T9kF*re%U,!B!N!-B!!!Kq!!!8c!!N!-)!*!$)!!!2c` -!"kR`!*!$#PM!!&h!!!"G`!#3!aTZ!*!$!AB!6R&+JfBL3Hd!)#!m2c`!!#)mUI! -!!8T"CJ4+3'F+5%")35#!)8%!"%+R3IVrcY$m!3![##mm!!!CELm$B3!#V&52Cd" -#1!TH3UF[2%4"9%%r2!69U"p`!4(!#Pj+RfFB6R%`2+P`TdC$qJ!U)SK"qJ!J-$b -TF+C(5S0R"(!"6R91l3!L6R&+JfB#UI4`!%jeB!B!N!8"6R%I1[rf5KpQ%NMRi1" -"q[rU80"1ZJ@Z60m("bmkrpj1G@"b38a"4%4$69!!!`#30&"b3@e)jf$`G&#I`Lp -)!#!J6b*8-@N!&!!B)8!!*$&m!!%!,0+4)8%!,U!#hm*-h`m'6R9+1!THC``J+J! -)C``J3#!3C`B[1[q%6R9)jam'3IVrRR!-)LS!"-+i!aTKT'B!!6j)H[q16VS(EPK -2X(Vr@QB!!3kK'Li)##S!3!!%C`BJH!+QS"XX+J!%+LS!#"JU!!5Ae*A8)$Vr9U% -H2cJ#)'B!!1a86ba))$Vr4#)'`VJ$'PK"B3$r6#!krcc!Z!-D3IVr1##!5S9Q"+% -LB!3J4D!RCJ!!Y#T))!j3J%(kr`JJJ#!kr`T4J%(kr`!JJ%*R5(S![#m95(Vr!Lm -krZ)[1[lL,cVqbLmkrXS[1[l+B3!06M!ICb!r!%U&C`JJ6D!US#YJ"#"0S#-J6U! -I)%HJ'c(I!L"JB#"1S"mJ4k!EFJ!5"1F*iaRN%3!"!#!#!3$J)%fJD3)!!"q!!5" -0S'V9e0I83IVqGNU3!'F)F!'JQ(!$S*JJ659)!!K`!%cIB2K1G8cIB2KJ!2kq2`! -J6U!I)%HJ'c(I!L$9e0I8-$J#)$(!#Q#4b#9)!!K-hf$i6R919J!!51F!1#KZ!!a -(q[iU4IVq+L!8X**Y"#!5+)"+J'm5)&-LEJ!)SLiJ&0'6NC*`!'!%-$crf8cI(!" -1ANje6PErb%MR(MJQ,J!)+#i!$#KZ!"""q[fk,8Mre%)ZrmLK'Le)rma96kJF-"m -k!!a&!!"[A%KZrq``"90&2`#S$e92,blrl+J0-"mm!!a'!!"[h%)RUCYC6bmZrq` -`"P0'2`#S$L!I,8$rm()"(`'TQb"Zrr"+N!"R%&92,`LTTM!I5-"b"-#"Cm3[,[r -`UD0J["!Z!"4R#PP2,VJ#TL"IS"Xr2+$m6VS%KP42,8$rd%U!C`!"RLm!6VS$ePK -25J"R#R!"(8!!&Nlk!KK)E[rN5'lri%KZrpK1ZJ9U6qm!$#!Zrq#K(Le)rp`J#'F -!!@3J,[rNS4iY52rS)!KR!!&8,blrj#m)6VS&Z&"2)!0Q!!#Q@8m[2%024%9#CkJ -I)"mY32r`5S"R!!#1)%!L8()Bdm%[#8kk",4B6h)$X%&QGL!0)%"`+0(!,8Mrp#* -Zrr!N8A!BeF!Y5[ri,`T1ZJ5k@%mY32rm)'lrm+!T8%SQE[r8*dS!+&P2,blrm%k -k&F`J(h,Sd)&4J#G!!#a96dKkrM)[,[rd5'lrr#m-,`3[,[rF,blri#mZrqK1ZJV -'9%m[,[r`UD-NE[r8*@lrd!!-*@lrh!!3*@lri!!8*@lrk!!B2cbKQ%kk!eC86bC -!2cbSRdkk!dT86b)!)!Z`J@B%F!"J!R!")!!P3!!F*83!)#9-!#4)H[[-2cbJr$m -mS2a1ZJ,i9%mI!%kk&9)r2+'B6VS$$&425S"R"(!"S*JJI!!!!9S`%%M!i)"b"V# -"CJa"qJ#Z)R`!!!-m)SJGI!!"rmJJE[r-S"Y96kJF-"mk!!a&!!"[G%KZrq``"90 -&2`#S$e92,blrl+J0-"mm!!a'!!"[h%)RUCYC6bmZrq``"P0'2`#S$L!I,8$rm() -"(`'TQe92,blrm+QQ-"p)`()%`)&R##mZrr#TSQ$#*'lrm%U5Ca"96bm+UDB`(dM -!FJ6!J@HU,`UTSf#N%#lrb"e!!"C-haai6PiJAdr[!!j1d%j@rra)j`!`3Llrr$m -mS2a1ZJ)X9%mN3%U!Ce`[!%kk!B"B6dS!Ce!J#LC!)%![+!!-2cbJr$mmS2a1ZJ( -H9%mI!%kk&$JJ5b"S!"#J(b",)'J!'+!I)(`!!!&D-"")`1#!FJD`J@B+F!!JI!! -!!c`JJ"em!!(rr"!Zrra-h``!6Pj1G8j@rqK)jami@8qTG5!I+J")E[rSU(3J$5" -!)""bKY#",8$rr#"!A%K$l[rX)YJLf&P2,ca%394"2c`%eDQJ)"mS3#"!*&!b+J! -)NQS!"$`"0#S!"T4U!!)q!MBZrr*)`cJZrqj)a*D%1!&)a*D%DJ*5Jq+$282rpMB -Zrr")`cJZrqa)a*D%1!*)a*D%DJ*5Jq+$282rp$BZrrE@36e$rrSb,[rddN)p3Ir -i@8p#TdKZrr4)HJ"QFJ%I!A)"2`&brbm"3LG#TkN6)"mQ3#m!U(-'K3#3!hJ[$#" -,F"$4`#m)U2CC6kPe)"q`K@3#B2496kPd%"pQ!Q$fF2mr!%*R)"qJ-Lm,U43[$+Q -M,blrk+Kc60mFq%jH6R8!!J!!6PB!!%MR!$!NEJ!))!SQ3#"!)LJ!!Jb"38a"4'B -@)LJ!"Jb"4%008'B+-#J!#R)$X%&R"(!!B!*`!8cI$!"1ANje,`TC6cmmU'j`!4m -!6VS5H#"I*%KC6cmmUQj`!4m!6VS5CL*I)%Uab@B'-$`#!'!%-$`%!#4I6R919J! -!,`-f,J!)-!0)`!+!!!!)!%U!E`4`!@!#F!!Q(djH6R919[rm51FF!$BZ!!Jr!dk -krma86ae!rrab!E!"CK!#3`Ir6VVrJ,"$EJ4`!'!S@8mr2+LIF!%I!%kk%I!J(bS -!@8mr!amZrra1ZK(J)"mS!,#&CJ*`!%cI!$K1ANje6PB!!%MR'$!i,J!)*'i!#L" -+)"!Q3#"!-K!-38&%CLJb+!!#$%&$8QBH0J4brlC"CaSJ+!!%FKMLU!+!!*!$rc) -$5-'`J@F%F!"J!R!"(8!!$NcI$"K1AL"IA%p1d%j@!!"96dKZ!!K`rcm!6VVrNK! -ICa)JEJ!))#J!"()BiUJ#3!$rB!*`rdjH6R919J!!98p)EJ!)F2mr!%kkrf33(fF -3)'i!##!S!!3#J!$rN!0J!R$r6Pj1G8j@!!")jaJi*Qi!##KZ!!`J5c#m!`&`!#4 --*)!Q2!!!!56ANJD5!!!#5!D5!*!$)#Jm!*!$J0Q5fC)S2!!!"*!!fC,ANYQ5"T) -!N!0m"T)!!)!!F!!NEJ!3*)!'NJ#3!b3'NJ#3!b!'NJ#3!dJ'NJ#3!cj#3%cI("K -1ANje6PErj%MR(cJQEJ!)+Li!$#!,+%!Y32rSF#6C`#e-rqa`)0R!,8crm(")fF! -Y62rdF$lC`#!-N!#,X)9M"R"P6[S!XN*!2J"#3$e!rq3f"h!NYN"N5(!%YN"N"(! -!B!a`!$!$@B"U!PD!j)"i!$J$,86rq0LZrqJN4"5!)#lrq0#!d+lrm#"!-+lrj(! -"&"*b!")#if$4E[rN8NGJX%*!2J"`!6`!0JG`(lC!C%4`!EC!C!4`!'!-F!!`!e1 -!DJ*5J1+!H!!i!be%rrcBV[rX*%38J#!Zrrc3J0#Zrr3J3$#'F!%8%R)!%J,MB0a -!8NGJY%*!60mFq%jH6R919[r`51FI1#4Z!!JQEJ!-1Li!%#KZ!"*#3$`!-J9`!$! -"d)!d"R)!-J+`J@m83N!d"R)!-J,5JG+-)%%`J&*'B0T#3$`!F!)p32rb0JDf4@3 -!!,K#3$i!3N!p32r`F!!`!q@!d)SJ3#!3,8$rp$)'F!!`!G#,)%!B%(B!&J5f4f- -!!))`,[rfFJ(!3G&Zrr"`!$!$8i!d"h)!-J+`J@mq1#lrm(B!0J3Y3rrmeS2@M#" -$5P"Q%L!Zrrc3J0#-)%!`V[rb9'lrmM)Zrr"`!$!"d)$3M#"!-"!p32r`B"B`"G" -!d%Bd,[r`FJ!b!Y+"dS`J36#!8NFJ,[rdiSJY32rdB!$rE&*'B!$r4%cI(2K1ANj -e6PErr%MR($!NEJ!)0Li!$#CZ!!ib!h!!-!(QJ$J!-!0b"m""1J"`!#e!rr`d"() -!-J,5LL""%K"`!"!"0!9b!$)#iU"b!F#"dDlrr#)ZrrcMLG+,)%%b%(!!-!%Y32r -m8N8`"A))X%&Q"N*!1J"54$)Z!"*`!$!"d)#`V[rmB`*JUK!Zrrm5,J!6dJ'3!!& --h``i6Pj1G8j@rra)jamJ*'i!#$JZ!!`k,J!1-J4`!$!"jS!m!$)%G!I#3Mi"GJ! -f!0D+)%-3%(3!&!!Y3[rmF!!`!63&FJ!b!Y#"jS"b!V#"C`ab!E#"Cb"+J'FdB$) -d"R)!-J*8JG++)%%5%(!!%!&b%11SJDlrr$3'FJ!b!P+"dSSJ34)3F!!3!H')JDl -rr#!Zrr`d"h)!-J,LU#e!rra`rh)J0J9d!$3$NS,LU-"Zrrj-h`6i6Pj1G8j@rpK -)jami*Qi!##KZ!!iJ2!!!!564VJ!5)$`!!!*)dDi!%L!Z!")Y32rXFL$6VJ!5)Li -!%Le"rr!N2!#3!i$9VJ!5*#i!%Le#rr3N5aJ5GJ!@"#e$rrMQJhS(aN953ce$rp` -Q,[riiS0k!mC&9%-p3rrQGJ%k,[rQkf-p3rrSIN$)"h`!(!3p4[rLH!(VC&0%286 -ri#SZrrKq!FU(C`Kk!$S%8i9J!RVr28ArhRJ)286rj%T'CdB[,J!5,`!r!e*+,`T -1Z[mk6qm!$ZG!d@lrj#mZ!")[,[r`2`-[,[rX6VS,#%r[!!i[,[rd2`-[,[rX,bl -rm%kkr+a2l`!13N!p32rB-#lrf,"Z!!aN!!%k-#lriQFk*%!r,[rS,blrp$mZrq3 -[#dkkrBj2l`!-%J!J#R!!%!%p32rDG!!d!05Zrq`J3K!3FJ!5!00Zrq4J($mZrqB -r,[rN,`Y1Z[h`8%mp32rD-#lrjY&Zrq3`,[rDX'lrhQB@-Llrf&*ZrpK`!$!"d)` -J3%)3B!$rHM!ZrpU`E[rJCJ!!P$!Zrq*R1L4!2blrk#mZrr3r,[rN,`Y1Z[d'6qm -!$")!)!T`!"!"28$rfR3!0!$8V[rX)%)3%()!%J$6E[rNB"`r,[rQ2blrj#m,6VV -pD&"228$rfM!ZrqE4E[rN9QlrfM!ZrpT6E[rD5N"R!2m!1#lrf(B!0J3Y3rrm8i2 -@M#"$%"!L,[rmdS`J34#!8Qlrf'$1%#lrhG!ZrpXd,[rB8Qlrf()!-J,5M#""%)" -J!2kq-Llrj(!!-!&HJ1D!60mFq%jH6R919[q-51FI1#CZ!!JU,J!-+'i!%#`Z!"3 -Y5rr)F#6A`#e,rq"`)0I!,8[rc(")em!Y5rrN,8crP#Bm!!!"*0HZrj3J2!!!!NM -4V[q8F#$4V[q8+$`!N!1!fDlrP0QZrj3YE[q8rl3S2!!!"*!!fDlrP#eZrj6rZ0H -Zrj3YE[q8rlcCV[q8,@lrP2r8F(c4V[q8,@lrP2qN)$`!!)!!dDlrP#!Zrj53!)b -`K@-+F'8p3!!S6[S'HR!!,J"#3$e!ri`NE[qNeI`!!)!!,8VrU#eZrk6rN!!YI!! -!J!$rk%KZrqJ[,[qN)'i!*%k3!&"2)#lrk'B+F'Fp3!!S6[S'0#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!!3%"e!rk"b!")!dN&636e"rp!`,[r -3d%!p32r5)'i!(#!3d+i!)#e!rl!N3#m-,blrZ$mm!53[,[q3!%kkqr*2l`!1-J! -J#R!!-!(4V[q3!#m-,blrY$mm!53[,[qi6VS(ZNr[!!i[,[qm2c`"*#mZrlJ[,[q -d6VVjA%r[!!iN3#m-,blrZ$mZrp![,[q3!%kkqk"2l`!1-J!J#R!!-!(4V[q3!#m --,blrY$mZrp![,[qi6VS(D%r[!!i[,[r82blrd#mZrlJ[,[qd6VVj#Nr[!!j`!#i -!3N!p32q-,@i!)2qX)'lrV,(Zrl"N!!5S3N!p32qB$'i#52qBC!!!`M!ZriaQ!!# --*'lrN!"55VAZrkKMD#"Zrj!!8NL4l[qS,8Mrp#"Zrj!!NHlrT#e)rr!JE[qSNHl -rN!!Y52rX)!KR$L"Zrj!!)QlrT#!ZrqbL,L4Zrk69l[rX,8VrN!")E[r`,blrT#" -Z!#41N!"36b!Zrr#`V[rdC!T`Cce!!#K1qJ4#)'lrN!"5V[q3!")3F!!3!5i!F!J -p32q--!Gb!F""d@lrQ$)ZrjK`!$!"d)$3V[qm)%!`%$e!rjJJ"q+),J"6E[q-B!$ -r1!4Z!NMrQ!aZ!3$rQ'33)'lrV&+Zrk`3V[qCB!$r#!4Z!3$rQ$JZrjKf!$B%,82 -rq0D$eUlrc#"$-"!p32qD)Llrq0+ZrmJJ34)3F!!3!6e!rja+3'F!!-)-EJ!Bria -L!!#B*'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-S)'lrN!"5V[q3!")3F!!3!63 -Zriab!$)#ikL1J&"ZriaJ!2pLF2pb)$JZrjaf!$B%NS2LU-"(d@lrQL!(jUJZ!*P -Zria#3$e!rjJ`,[qBX'lrdQ3!!-)`,[q-CJ!!M#4Zrj!!8NUel[qSBfJJE[q3!&* -)NHlrU#e)rr3JE[q3!*(Zrk3Y52r`)'lrU*(Zrj!!,8Mrl#!)C`iJE[q3!#*Zrk3 -J,[rXSLiNE[qNeHlrl#e+rj!!5'lrm#mZrk3JEJ!N6T!!8%mJ,[r`X+lrp'3+F'F -p3!!S6[S#@#"Zrj!!8UlrN!!5%(!!%!%Z!(!)28$rM$!(FJ(!3G&ZrjJb,[qBF!! -`!G#!d+lre#"!-"!p32qB)!ILL#i!8flrM'!!rcB`,[r5N@lrQ$JZrjKf!$B%,82 -rr0D$eUlrj#"$-"!p32qH)Llrr0+Zrq!J34)3F!!3!6e!rja+3'F!!-)-EJ!Bria -L!!#B*'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&D)'lrN!"5V[q3!")3F!!3!63 -Zriab!$)#ikL1J&"ZriaJ!2pLF2pb)$JZrjaf!$B%NS2LU-"(d@lrRL!(jUJZ!*P -Zri`JE[qX-LlrRR!!-!'4`#e)rj5alJ!JC@!JE[q88UlrP"!3)'lrV&+Zrk`3J#" -Zrj45V[q8%"!JE[qX8UlrV"#!)'lrP&+Zrj33%#"Zrka5V[qX%)!`,[qD8flrQNT -!C`$lhL"Zrj45V[q8%"!JE[qX8UlrV"#!B0a@E[qD)'i!'0('-LlrRR!!-!%LE[q -XNqi!)*!!LC(!,8MrP$!ZrjTR*L"Z!"M4aV(Zrj4M'L"Zrj45V[q8%"!JE[qX8Ul -rV"#!8flrQQ$8,@i!)2q8-#lrQP0ZrjT+3'F!qfBJE[q88UlrP"!3)'lrV&+Zrk` -3J'$F)'lrV,(Zrl"R#("R28!!+'!8)'lrV*(Z!#!LEJ!F)SK#3$e!!#K-haci6Pi -JAdr[!#"1d!"`2!!q)!!!H#!q-#!Q*L"i)$`p-c)!!$T$Efe`FQ9cFfP[EMT%C@0 -[EA"bCA0cD@pZ-$-`-5jM!!!m!$iJ!!"i)$i`)#BQ)(JJ2$dc-J!!1N0[EA"bCA0 -cD@pZ1N4PBfpYF(*PFh0TEfi`-c!a,Q-!!%j@rqK)jami2Li!##KZ!!`f,J!+F!! -`!cJ(FJ!b"*!!JA)"X)&[!!'d286rk$e$rqT5E[rS-#lrk,"Z!!TN(()!-J$5M#" -"%"!d"h)!-J,5M#""%K#`!@3#B0C6E[rU-#lrkV"(Baab!$)!dS`J34!30!Gb!$) -#dS`J34)3X!&M!Q$B-#lrk,"ZrqTP!Q"b1#lrk(B!0J3Y3rr`eS`N3a)5F!!3!6e -!rq`k,[rUH!!i"5e%rr6BM#C%%"-8J"DZrqdJ,[r`d)$3VJ!3)%!`%$e!rq`L,[r -ddS(5VJ!3)%%b%#3Zrr$8JY5Z!"!J3M#")Llrp0+"dUi!%#""-)"J!2mb-#lrkV" -(CJC54f!!r`3i"hB!0J3Y3rrieS`N3a)5F!!3!6e!rq`m,[rUHJ!k"Le&rrcDM#C -&%"-8J"DZrqdJ,[rid)$3VJ!3)%!`%$e!rq`L,[rmdS(5VJ!3)%%b%#3ZrrM8JY5 -Z!"!J3M#")Llrr0+"dUi!%#""-)!J,[rm)Llrq*!!J63Z!!Tb!$)#*#lrr&+#NS+ -`J@`H,bi!%#m-2`Br"%kkrPa2l`!--#lrkP*!2J"J!2jF,bi!%#m-2bi!#M!ZrqT -53$m!6VVq0Nr[!!`pE[rU!!TJ!2ii60mFq%jH6R919[rN51FI1#4Z!!Jk,J!-*Qi -!$LKZ!")Y62r`)$`!!!%NfF!Y62rd3N!m!$B'YN9N,(J!1!-Y42rif)SJ4"!3)Ll -rq0+Zrr!J34#!)#lrq0#!d+lrp#"!-)054Q$1,blrp#mZrr!r"8*R6VVpXNr[!!a -#3$`!0JDf4@35F!!`!p#Zrr!J3%S3CJ454Q$SF!!Y32rN0JDf4@3!!+K+3fFb)#l -rj(J!1!-Y42rmf+lrm#"%&""b!")#*Llrr&1$eUlrm#"$&K"d!"3$NS,MU#e!rq3 -d"R)!-J,5V[r`)%%5%(!!%!%q!#eZrq6rl(!!,8$rk$!(8dG+3'FJ)#lrk11))Ll -rl(3"`S+!J5e!rqJJ,[rXiSJY32rXB0Jd"R)!-J,5JG+Zrr3J36)3F!!`!H@!d)X -J3##ZrqK54P+Zrq4J!2p860mFq%jH6R8LAb"IS#8ZJ'S#3TG1d5*I%Km`(dS"C`5 -R4Q!#SdBZL%l4)Pm5(c!I)&p+!@F%TNGJ!U*(6Y%!N!-+!$LJ!3!&!*!'!3!!!D1 -+!!'LLJ!!"8Y66e*8"Vi!J!!F"()!&N&-8P3!#J#k399c-J!!!6j#6N4-!!%"5N0 -19%`!!!&L3dp%43!(!@j%394"!!!"cN4*9%`!$`(D4%a24`!%!TT'8N9'!!3#eNC -PBA3!!!-55801)`!%!aj*3dp1!!!$@P"*3e3!"!0Q8(0PG!!!!k*659T&!!!$VP0 -88L!!!31k8e45)`!!!p*KGA0d!!%$hQ0TBfi!!!2fC'0dBJ!""!*NE'Gi!!%%'QP -ME$J!!!3bGQ9bF`!""$i!J2rr)!#3#)(rrb!!!"!!N!@#rrmJ!!!J!*!&KIrr*!! -!-!%[)M3!K[rr*!!!3!&!B)`!Krrr)!!!8!#3"BMrrb!!!'!!N!3#!2rr)!!!FJ# -3"!)"rrmJ!!##!*!%"!(rrb!!!*)!N!3%Vrrr!!!B@!#3"ai!!"KS!*!&J2rr!!! -BM!#3"!%!rrm!!"M%!*!%!3Mrrb!!'13!N!ErrbJ"Kq!!N!8"!*dF!#D[!8$8@!! -#!+FF!,"m!51ZQ!!$!,%F!-fI!8$81!!%!,XF!3Qa!8$8-!!&!-8F!6Xq!5+0"!! -'!-mF!9[a!8$85!!(rrm!!BJ+!*!'rrmS!)(X!*!&J2rr!*!$SJ#3"B,rr`!!!3# -3"SArrb3!!9i"3'6J!)Errb3!!E3"31*m!)Irr`!!!M8!N!@)rrm!!!+&!*!&YIr -r)!!$A3#3"!%&rrmJ!!22!*!%!3Irrb!!'2m!N!3"#2rr)!!CS!#3"!)!rrm!!!4 -m!*!%!J(rr`!!",S!N!3$k2rr)!!&"J#3"!3"rrmJ!!8b!*!%"%X!,33!'N-"303 -!"+rrr`!!'T-!N!3""3!!)!!&XJ#3"!%(!$NJ!"V4!*!%!3J!5L!!'Zd!N!3$k2r -r)!!&e!#3"!4,!'B%!"X*!8$8T!#!rrm!!"XL!*!&JIrr!!!E,3#3"B,rr`!!'cJ -!N!@$rrm!!"Y$!*!&K2rr!!!E6J#3"[rr!!'LI!#3"B$rr`!!'eN!N!@"rrm!!"a -G!*!&J[rr!!!GB3#3"B2rr`!!(Q8!N!@%rrm!!"pT!*!%"%[rr`3!)'d"304`!), -rr`!!"I!!N!3$k2rr!!!(%`#3"!4-rrm!!!iK!*!%"%hrr`!!$pS!N!3%6[rr!!! -4N`#3"B$rr`!!%b%!N!6rN!3!!BIm!*!%!J!!"b!!&eJ!N!3#!3!1)!!AD!#3"B$ -rr`!!&h3!N!Gb!!!Jk!#3"B6rr`!!)8-!N!3%5rrr"!!K4`&!e(3""Irr!!!AY!# -3"!%)rrm!!#*Y!*!%!38!&`!!&q8!N!3"#!#"!!!LS3#3"B6rr`!!)UX!N!8"rrm -J!"I[!*!&![rr)!!B-J#3"!C6G'&dGA-'F(*[EA"d#-3JFh9QCQPi"P0dBA4eF`j -2GfjPFL"bCA0[GA*MC3Y*ER0PFR3J4'PcDa"&H'PcG'PZCe"KFh0hEh*N'd9iDA0 -dD@jR8'&cFhG[FQ3Y3A"`C@&bB@jMC3Y*ER0PFR3J4'PcD`j2GfjPFL"bCA0[GA* -MC4Y&H'PcG'PZCe"KFh0hEh*N,8&`F'9KFQ&ZBf8*8f9RE@9ZG#!a#90PCfePER3 -J-JP6C@GYC@jd)$-*8f9RE@9ZG#!e#90PCfePER3J0JP6C@GYC@jd)$E@I3: diff --git a/mac/tclMacResource.c b/mac/tclMacResource.c deleted file mode 100644 index 671aea1..0000000 --- a/mac/tclMacResource.c +++ /dev/null @@ -1,2216 +0,0 @@ -/* - * 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.12 2002/01/27 11:10:03 das 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); - } - 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: - 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) { - 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 ) { - 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: - 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; - 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 { - errStr = errBad; - goto sourceFmtErr; - } - - if (objc == 4) { - fileName = Tcl_GetStringFromObj(objv[3], &length); - } - 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?\"", - (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; - char msg[200]; - int result, iOpenedResFile = false; - short saveRef, fileRef = -1; - char idStr[64]; - FSSpec fileSpec; - Tcl_DString buffer; - CONST char *nativeName; - - saveRef = CurResFile(); - - if (fileName != NULL) { - OSErr err; - - nativeName = Tcl_TranslateFileName(interp, fileName, &buffer); - if (nativeName == NULL) { - return TCL_ERROR; - } - err = FSpLocationFromPath(strlen(nativeName), nativeName, - &fileSpec); - 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) { - sprintf(msg, "\n (rsrc \"%.150s\" line %d)", - resourceName, - interp->errorLine); - Tcl_AddErrorInfo(interp, 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; - - size = GetResourceSizeOnDisk(resource); - - resultStr = ckalloc(size + 1); - - for (i=0; i<size; i++) { - if ((*resource)[i] == '\r') { - resultStr[i] = '\n'; - } else { - resultStr[i] = (*resource)[i]; - } - } - - resultStr[size] = '\0'; - - 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) { - *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; - long newOSType; - - /* - * Get the string representation. Make it up-to-date if necessary. - */ - - string = Tcl_GetStringFromObj(objPtr, &length); - - if (length != 4) { - if (interp != NULL) { - Tcl_ResetResult(interp); - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), - "expected Macintosh OS type but got \"", string, "\"", - (char *) NULL); - } - return TCL_ERROR; - } - newOSType = *((long *) string); - - /* - * 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. */ -{ - objPtr->bytes = ckalloc(5); - sprintf(objPtr->bytes, "%-4.4s", &(objPtr->internalRep.longValue)); - objPtr->length = 4; -} - -/* - *---------------------------------------------------------------------- - * - * 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) { - 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) { - 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) { - 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 deleted file mode 100644 index b8ccedf..0000000 --- a/mac/tclMacResource.r +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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.6 2001/12/27 22:46:28 das Exp $ - */ - -#include <Types.r> -#include <SysTypes.r> - -/* - * The folowing include and defines help construct - * the version string for Tcl. - */ - -#define RESOURCE_INCLUDED -#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". - */ - -#include "tclMacTclCode.r" - diff --git a/mac/tclMacSock.c b/mac/tclMacSock.c deleted file mode 100644 index 70380b1..0000000 --- a/mac/tclMacSock.c +++ /dev/null @@ -1,2766 +0,0 @@ -/* - * 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.12 2002/01/27 11:10:07 das 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; - /* 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) { - 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, doAll = false; - ip_addr tcpAddress; - char buffer[128]; - OSErr err; - Tcl_DString dString; - TCPiopb statusPB; - int errorCode; - - /* - * 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 { - if (!strcmp(optionName, "-peername")) { - doPeerName = true; - } else if (!strcmp(optionName, "-sockname")) { - doSockName = true; - } else { - return Tcl_BadChannelOption(interp, optionName, - "peername sockname"); - } - } - - /* - * 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; - -} diff --git a/mac/tclMacTclCode.r b/mac/tclMacTclCode.r deleted file mode 100644 index 13b23e2..0000000 --- a/mac/tclMacTclCode.r +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 deleted file mode 100644 index 9598848..0000000 --- a/mac/tclMacTest.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * 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.4 1999/05/11 07:13:36 jingham Exp $ - */ - -#define TCL_TEST - -#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, char **argv)); -static int WriteTextResource _ANSI_ARGS_((ClientData dummy, - Tcl_Interp *interp, int argc, 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. */ - 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. */ - char **argv) /* Argument strings. */ -{ - char *errNum = "wrong # args: "; - char *errBad = "bad argument: "; - char *errStr; - char *fileName = NULL, *rsrcName = NULL; - 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 deleted file mode 100644 index 3fdafe3..0000000 --- a/mac/tclMacThrd.c +++ /dev/null @@ -1,871 +0,0 @@ -/* - * 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(id, result) - Tcl_ThreadId id; /* 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 (id, 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) { - 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) { - 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 deleted file mode 100644 index 22f2c83..0000000 --- a/mac/tclMacThrd.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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 deleted file mode 100644 index fa5b215..0000000 --- a/mac/tclMacTime.c +++ /dev/null @@ -1,435 +0,0 @@ -/* - * 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.7 2002/01/04 11:21:05 das 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. - * - * 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 deleted file mode 100644 index a777254..0000000 --- a/mac/tclMacUnix.c +++ /dev/null @@ -1,425 +0,0 @@ -/* - * 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.4 2001/11/23 01:28:46 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. */ - 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 deleted file mode 100644 index c505c64..0000000 --- a/mac/tclMacUtil.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * 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.5 2001/11/23 01:28:49 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; -} - -/* - *---------------------------------------------------------------------- - * - * 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. */ -{ - Str255 fileName; - OSErr err; - short vRefNum; - long dirID; - int pos, cur; - Boolean isDirectory; - Boolean wasAlias; - - /* - * 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; - err = ResolveAliasFile(fileSpecPtr, true, &isDirectory, &wasAlias); - if (err != noErr) return err; - FSpGetDirectoryID(fileSpecPtr, &dirID, &isDirectory); - vRefNum = fileSpecPtr->vRefNum; - cur = pos; - if (path[cur] == ':') { - cur++; - } - } - - 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 deleted file mode 100644 index 0219f71..0000000 --- a/mac/tcltkMacBuildSupport.sea.hqx +++ /dev/null @@ -1,3963 +0,0 @@ -(This file must be converted with BinHex 4.0) -:'(4ME(4V6@&M3R9TE'46GA"`Eh*d,R0PB3""8&"-BA9cG#%!!!&&V!!"U0AR-&0 -dG@CQ5A3J+'-T-6Nj0bda16Ni)%&XB@4ND@iJ8hPcG'9YFb`J5@jM,L`JD(4dF$S -[,hH3!bjKE'&NC'PZFhPc,Q0[E5p6G(9QCNPd,`d+'J!&%!!"4D`!N!0b!!%!N!0 -bCHd0TD95CA0PFRCPC+@P!+@3"!%!!$d!4,5KD[qhp$6M!*!0$ECD!*!$d`!DkRX -!!86C!"48Bf`[9'XJ4QpXC'9b!!"m3!