diff options
Diffstat (limited to 'mac')
53 files changed, 0 insertions, 24987 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 84b09fc..0000000 --- a/mac/MW_TclAppleScriptHeader.pch +++ /dev/null @@ -1,47 +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.4 1999/05/11 07:11:46 jingham 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 TCL_REGISTER_LIBRARY 1 */ -#define USE_TCL_STUBS - -/* - * Place any includes below that will are needed by the majority of the - * and is OK to be in any file in the system. The pragma's are used - * to control what functions are exported in the Tcl shared library. - */ - -#pragma export on -#pragma export off - 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 5253291..0000000 --- a/mac/MW_TclHeader.pch +++ /dev/null @@ -1,49 +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.7 1999/05/11 07:11:48 jingham 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 "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. The pragma's are used - * to control what functions are exported in the Tcl shared library. - */ - -#pragma export on -#include "tcl.h" -#include "tclMac.h" -#include "tclInt.h" -#include "MoreFiles.h" -#include "MoreFilesExtras.h" - -#pragma export reset - 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 ba588bb..0000000 --- a/mac/MW_TclTestHeader.pch +++ /dev/null @@ -1,53 +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_TclTestHeader.pch,v 1.1 2000/02/10 08:39:11 jingham 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 TCL_DEBUG 1 - -/*#define TCL_THREADS 1*/ - -#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. The pragma's are used - * to control what functions are exported in the Tcl shared library. - */ - -#pragma export on -#include "tcl.h" -#include "tclMac.h" -#include "tclInt.h" -#include "MoreFiles.h" -#include "MoreFilesExtras.h" - -#pragma export reset - 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 a051cc8..0000000 --- a/mac/tclMac.h +++ /dev/null @@ -1,38 +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.4 1999/03/10 05:52:51 stanton Exp $ - */ - -#ifndef _TCLMAC -#define _TCLMAC - -#ifndef _TCL -# include "tcl.h" -#endif -#include <Types.h> -#include <Files.h> -#include <Events.h> - -/* - * "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 - -typedef int (*Tcl_MacConvertEventPtr) _ANSI_ARGS_((EventRecord *eventPtr)); - -#include "tclPlatDecls.h" - -#pragma export reset - -#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 c5daa8b..0000000 --- a/mac/tclMacAlloc.c +++ /dev/null @@ -1,348 +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.4 1999/05/11 07:11:51 jingham Exp $ - */ - -#include "tclInt.h" -#include "tclMacInt.h" -#include <Memory.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. */ - -/* - * Amount of space to leave in the application heap for the Toolbox to work. - */ - -#define TOOLBOX_SPACE (32 * 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. */ - - -/* - * 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; -} ListEl; - -ListEl * systemMemory = NULL; -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; - - hand = * (Handle *) ((Ptr) oldPtr - sizeof(Handle)); - maxsize = GetHandleSize(hand) - sizeof(Handle); - if (maxsize < size) { - newPtr = TclpSysAlloc(size, 1); - memcpy(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; - - 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) { - HPurge(toolGuardHandle); - } - } - - /* - * If we got the handle, lock it and do our allocation. - */ - - if (toolGuardHandle != NULL) { - HLock(toolGuardHandle); - hand = NewHandle(size + sizeof(Handle)); - HUnlock(toolGuardHandle); - } - } - if (hand != NULL) { - newMemoryRecord = (ListEl *) NewPtr(sizeof(ListEl)); - if (newMemoryRecord == NULL) { - DisposeHandle(hand); - return NULL; - } - newMemoryRecord->memoryHandle = hand; - newMemoryRecord->next = appMemory; - appMemory = newMemoryRecord; - } else { - /* - * Ran out of memory in application space. Lets try to get - * more memory from system. Otherwise, we return NULL to - * denote failure. - */ - isBin = 0; - hand = NewHandleSys(size + sizeof(Handle)); - if (hand == NULL) { - return NULL; - } - if (systemMemory == NULL) { - /* - * This is the first time we've attempted to allocate memory - * directly from the system heap. We need to now install the - * exit handle to ensure the memory is cleaned up. - */ - TclMacInstallExitToShellPatch(CleanUpExitProc); - } - newMemoryRecord = (ListEl *) NewPtrSys(sizeof(ListEl)); - if (newMemoryRecord == NULL) { - DisposeHandle(hand); - return NULL; - } - newMemoryRecord->memoryHandle = hand; - newMemoryRecord->next = systemMemory; - systemMemory = newMemoryRecord; - } - if (isBin) { - HLockHi(hand); - } else { - HLock(hand); - } - (** (Handle **) hand) = hand; - - return (*hand + sizeof(Handle)); -} - -/* - *---------------------------------------------------------------------- - * - * 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. */ -{ - Handle hand; - OSErr err; - - hand = * (Handle *) ((Ptr) ptr - sizeof(Handle)); - DisposeHandle(hand); - *hand = NULL; - err = MemError(); -} - -/* - *---------------------------------------------------------------------- - * - * 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; - - while (systemMemory != NULL) { - memRecord = systemMemory; - systemMemory = memRecord->next; - if (*(memRecord->memoryHandle) != NULL) { - DisposeHandle(memRecord->memoryHandle); - } - DisposePtr((void *) memRecord); - } -} - -/* - *---------------------------------------------------------------------- - * - * 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; - - while (systemMemory != NULL) { - memRecord = systemMemory; - systemMemory = memRecord->next; - if (*(memRecord->memoryHandle) != NULL) { - DisposeHandle(memRecord->memoryHandle); - } - DisposePtr((void *) memRecord); - } - while (appMemory != NULL) { - memRecord = appMemory; - appMemory = memRecord->next; - if (*(memRecord->memoryHandle) != NULL) { - DisposeHandle(memRecord->memoryHandle); - } - DisposePtr((void *) memRecord); - } -} - -/* - *---------------------------------------------------------------------- - * - * 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 678198d..0000000 --- a/mac/tclMacAppInit.c +++ /dev/null @@ -1,212 +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.8 2001/06/17 03:48:19 dgp 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> -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; - 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 f69b3b6..0000000 --- a/mac/tclMacApplication.r +++ /dev/null @@ -1,75 +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.3 1999/08/16 00:09:09 jingham 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 -#else -# define MINOR_VERSION TCL_MINOR_VERSION * 16 -#endif - -resource 'vers' (1) { - TCL_MAJOR_VERSION, MINOR_VERSION, - RELEASE_LEVEL, 0x00, verUS, - TCL_PATCH_LEVEL, - TCL_PATCH_LEVEL ", by Ray Johnson & Jim Ingham © Scriptics Inc" -}; - -resource 'vers' (2) { - TCL_MAJOR_VERSION, MINOR_VERSION, - RELEASE_LEVEL, 0x00, verUS, - TCL_PATCH_LEVEL, - "Tcl Shell " TCL_PATCH_LEVEL " © 1996-1997 Sun Microsystems, 1998-1999 Scriptics Inc" -}; - -#define TCL_APP_CREATOR 'Tcl ' - -type TCL_APP_CREATOR as 'STR '; -resource TCL_APP_CREATOR (0, purgeable) { - "Tcl Shell " TCL_PATCH_LEVEL " © 1996-1999" -}; - -/* - * 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", - } -}; 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 d863e9c..0000000 --- a/mac/tclMacBOAMain.c +++ /dev/null @@ -1,361 +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.3 1999/04/16 00:47:19 stanton 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. */ - -#ifdef TCL_MEM_DEBUG -static char dumpFile[100]; /* Records where to dump memory allocation - * information. */ -static int quitFlag = 0; /* 1 means "checkmem" command was called, - * so the application should quit and dump - * memory allocation information. */ -#endif - -/* - * Forward references for procedures defined later in this file: - */ - -#ifdef TCL_MEM_DEBUG -static int CheckmemCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int argc, char *argv[])); -#endif -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(); -#ifdef TCL_MEM_DEBUG - Tcl_InitMemory(interp); - Tcl_CreateCommand(interp, "checkmem", CheckmemCmd, (ClientData) 0, - (Tcl_CmdDeleteProc *) NULL); -#endif - - /* - * 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; - -} - - -/* - *---------------------------------------------------------------------- - * - * CheckmemCmd -- - * - * This is the command procedure for the "checkmem" command, which - * causes the application to exit after printing information about - * memory usage to the file passed to this command as its first - * argument. - * - * Results: - * Returns a standard Tcl completion code. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ -#ifdef TCL_MEM_DEBUG - - /* ARGSUSED */ -static int -CheckmemCmd(clientData, interp, argc, argv) - ClientData clientData; /* Not used. */ - Tcl_Interp *interp; /* Interpreter for evaluation. */ - int argc; /* Number of arguments. */ - char *argv[]; /* String values of arguments. */ -{ - extern char *tclMemDumpFileName; - if (argc != 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " fileName\"", (char *) NULL); - return TCL_ERROR; - } - strcpy(dumpFile, argv[1]); - tclMemDumpFileName = dumpFile; - quitFlag = 1; - return TCL_OK; -} -#endif diff --git a/mac/tclMacChan.c b/mac/tclMacChan.c deleted file mode 100644 index e728c7f..0000000 --- a/mac/tclMacChan.c +++ /dev/null @@ -1,1391 +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.7 2001/08/30 08:53:15 vincentdarley 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, - char *buf, int toWrite, int *errorCode)); -static int FileSeek _ANSI_ARGS_((ClientData instanceData, - long offset, int mode, int *errorCode)); -static void FileSetupProc _ANSI_ARGS_((ClientData clientData, - int flags)); -static 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, - char *buf, int toWrite, int *errorCode)); -static int StdIOSeek _ANSI_ARGS_((ClientData instanceData, - long offset, int mode, int *errorCode)); -static int StdReady _ANSI_ARGS_((ClientData instanceData, - int mask)); - -/* - * This structure describes the channel type structure for file based IO: - */ - -static Tcl_ChannelType consoleChannelType = { - "file", /* Type name. */ - 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. */ - 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. */ - 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, buf, (size_t) toWrite); - if (written > -1) { - return written; - } - *errorCode = errno; - return -1; -} - -/* - *---------------------------------------------------------------------- - * - * StdIOSeek -- - * - * Seeks on an IO channel. Returns the new position. - * - * Results: - * -1 if failed, the new position if successful. If failed, it - * also sets *errorCodePtr to the error code. - * - * Side effects: - * Moves the location at which the channel will be accessed in - * future operations. - * - *---------------------------------------------------------------------- - */ - -static int -StdIOSeek( - ClientData instanceData, /* Unused. */ - long offset, /* Offset to seek to. */ - int mode, /* Relative to where - * should we seek? */ - int *errorCodePtr) /* To store error code. */ -{ - int newLoc; - int fd; - - *errorCodePtr = 0; - fd = (int) ((FileState*)instanceData)->fileRef; - newLoc = lseek(fd, offset, mode); - if (newLoc > -1) { - return newLoc; - } - *errorCodePtr = errno; - return -1; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_PidObjCmd -- - * - * This procedure is invoked to process the "pid" Tcl command. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - - /* ARGSUSED */ -int -Tcl_PidObjCmd(dummy, interp, objc, objv) - ClientData dummy; /* Not used. */ - Tcl_Interp *interp; /* Current interpreter. */ - int objc; /* Number of arguments. */ - Tcl_Obj *CONST *objv; /* Argument strings. */ -{ - ProcessSerialNumber psn; - char buf[20]; - Tcl_Channel chan; - Tcl_Obj *resultPtr; - - if (objc > 2) { - Tcl_WrongNumArgs(interp, 1, objv, "?channelId?"); - return TCL_ERROR; - } - if (objc == 1) { - resultPtr = Tcl_GetObjResult(interp); - GetCurrentProcess(&psn); - sprintf(buf, "0x%08x%08x", psn.highLongOfPSN, psn.lowLongOfPSN); - Tcl_SetStringObj(resultPtr, buf, -1); - } else { - chan = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), - NULL); - if (chan == (Tcl_Channel) NULL) { - return TCL_ERROR; - } - /* - * We can't create pipelines on the Mac so - * this will always return an empty list. - */ - } - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TclpGetDefaultStdChannel -- - * - * Constructs a channel for the specified standard OS handle. - * - * Results: - * Returns the specified default standard channel, or NULL. - * - * Side effects: - * May cause the creation of a standard channel and the underlying - * file. - * - *---------------------------------------------------------------------- - */ - -Tcl_Channel -TclpGetDefaultStdChannel( - int type) /* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */ -{ - Tcl_Channel channel = NULL; - int fd = 0; /* Initializations needed to prevent */ - int mode = 0; /* compiler warning (used before set). */ - char *bufMode = NULL; - char channelName[16 + TCL_INTEGER_SPACE]; - int channelPermissions; - FileState *fileState; - - /* - * If the channels were not created yet, create them now and - * store them in the static variables. - */ - - switch (type) { - case TCL_STDIN: - fd = 0; - channelPermissions = TCL_READABLE; - bufMode = "line"; - break; - case TCL_STDOUT: - fd = 1; - channelPermissions = TCL_WRITABLE; - bufMode = "line"; - break; - case TCL_STDERR: - fd = 2; - channelPermissions = TCL_WRITABLE; - bufMode = "none"; - break; - default: - 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. */ - 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; - 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. */ - char *buffer, /* The data buffer. */ - int toWrite, /* How many bytes to write? */ - int *errorCodePtr) /* Where to store error code. */ -{ - FileState *fileState = (FileState *) instanceData; - long length = toWrite; - OSErr err; - - *errorCodePtr = 0; - errno = 0; - - if (fileState->appendMode == true) { - FileSeek(instanceData, 0, SEEK_END, errorCodePtr); - *errorCodePtr = 0; - } - - err = FSWrite(fileState->fileRef, &length, buffer); - if (err == noErr) { - err = FlushFile(fileState->fileRef); - } else { - *errorCodePtr = errno = TclMacOSErrorToPosixError(err); - return -1; - } - return length; -} - -/* - *---------------------------------------------------------------------- - * - * FileSeek -- - * - * Seeks on an IO channel. Returns the new position. - * - * Results: - * -1 if failed, the new position if successful. If failed, it - * also sets *errorCodePtr to the error code. - * - * Side effects: - * Moves the location at which the channel will be accessed in - * future operations. - * - *---------------------------------------------------------------------- - */ - -static int -FileSeek( - ClientData instanceData, /* Unused. */ - long offset, /* Offset to seek to. */ - int mode, /* Relative to where - * should we seek? */ - int *errorCodePtr) /* To store error code. */ -{ - FileState *fileState = (FileState *) instanceData; - IOParam pb; - OSErr err; - - *errorCodePtr = 0; - pb.ioCompletion = NULL; - pb.ioRefNum = fileState->fileRef; - if (mode == SEEK_SET) { - pb.ioPosMode = fsFromStart; - } else if (mode == SEEK_END) { - pb.ioPosMode = fsFromLEOF; - } else if (mode == SEEK_CUR) { - err = PBGetFPosSync((ParmBlkPtr) &pb); - if (pb.ioResult == noErr) { - if (offset == 0) { - return pb.ioPosOffset; - } - offset += pb.ioPosOffset; - } - pb.ioPosMode = fsFromStart; - } - pb.ioPosOffset = offset; - err = PBSetFPosSync((ParmBlkPtr) &pb); - if (pb.ioResult == noErr){ - return pb.ioPosOffset; - } else if (pb.ioResult == eofErr) { - long currentEOF, newEOF; - long buffer, i, length; - - err = PBGetEOFSync((ParmBlkPtr) &pb); - currentEOF = (long) pb.ioMisc; - if (mode == SEEK_SET) { - newEOF = offset; - } else if (mode == SEEK_END) { - newEOF = offset + currentEOF; - } else if (mode == SEEK_CUR) { - err = PBGetFPosSync((ParmBlkPtr) &pb); - newEOF = offset + pb.ioPosOffset; - } - - /* - * Write 0's to the new EOF. - */ - pb.ioPosOffset = 0; - pb.ioPosMode = fsFromLEOF; - err = PBGetFPosSync((ParmBlkPtr) &pb); - length = 1; - buffer = 0; - for (i = 0; i < (newEOF - currentEOF); i++) { - err = FSWrite(fileState->fileRef, &length, &buffer); - } - err = PBGetFPosSync((ParmBlkPtr) &pb); - if (pb.ioResult == noErr){ - return pb.ioPosOffset; - } - } - *errorCodePtr = errno = TclMacOSErrorToPosixError(err); - return -1; -} - -/* - *---------------------------------------------------------------------- - * - * CommonWatch -- - * - * Initialize the notifier to watch handles from this channel. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -CommonWatch( - ClientData instanceData, /* The file state. */ - int mask) /* Events of interest; an OR-ed - * combination of TCL_READABLE, - * TCL_WRITABLE and TCL_EXCEPTION. */ -{ - FileState **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; - 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 b06a494..0000000 --- a/mac/tclMacCommonPch.h +++ /dev/null @@ -1,88 +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.2 1998/11/11 07:46:04 jingham 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 - - -/* -* The following defines control the behavior of the Macintosh -* Universial Headers. -*/ - - -#define SystemSevenOrLater 1 -#define STRICT_CONTROLS 1 -#define STRICT_WINDOWS 1 - - -/* -* 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 a while, we will continue to use the old routine names, so that -* people with older versions of CodeWarrior will still be able to compile -* the source (albeit they will have to update the project files themselves). -* -* At some point, we will convert over to the new routine names. -*/ - - -#define OLDROUTINENAMES 1 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 ebc9319..0000000 --- a/mac/tclMacFCmd.c +++ /dev/null @@ -1,1704 +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.10 2001/08/30 08:53:15 vincentdarley 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, CONST char *fileName, - Tcl_Obj **attributePtrPtr)); -static int GetFileReadOnly _ANSI_ARGS_((Tcl_Interp *interp, - int objIndex, CONST char *fileName, - Tcl_Obj **readOnlyPtrPtr)); -static int SetFileFinderAttributes _ANSI_ARGS_((Tcl_Interp *interp, - int objIndex, CONST char *fileName, - Tcl_Obj *attributePtr)); -static int SetFileReadOnly _ANSI_ARGS_((Tcl_Interp *interp, - int objIndex, CONST char *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. - */ - -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, 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. */ -{ - char *dirName; - OSErr err; - int argc; - 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. */ - CONST char *fileName, /* The name of the file (UTF-8). */ - Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */ -{ - OSErr err; - FSSpec fileSpec; - FInfo finfo; - Tcl_DString pathString; - - Tcl_UtfToExternalDString(NULL, fileName, -1, &pathString); - err = FSpLocationFromPath(Tcl_DStringLength(&pathString), - Tcl_DStringValue(&pathString), &fileSpec); - Tcl_DStringFree(&pathString); - - 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 \"", 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. */ - CONST char *fileName, /* The name of the file (UTF-8). */ - Tcl_Obj **readOnlyPtrPtr) /* A pointer to return the object with. */ -{ - OSErr err; - FSSpec fileSpec; - CInfoPBRec paramBlock; - Tcl_DString pathString; - - Tcl_UtfToExternalDString(NULL, fileName, -1, &pathString); - err = FSpLocationFromPath(Tcl_DStringLength(&pathString), - Tcl_DStringValue(&pathString), &fileSpec); - Tcl_DStringFree(&pathString); - - 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 \"", 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. */ - CONST char *fileName, /* The name of the file (UTF-8). */ - Tcl_Obj *attributePtr) /* The command line object. */ -{ - OSErr err; - FSSpec fileSpec; - FInfo finfo; - Tcl_DString pathString; - - Tcl_UtfToExternalDString(NULL, fileName, -1, &pathString); - err = FSpLocationFromPath(Tcl_DStringLength(&pathString), - Tcl_DStringValue(&pathString), &fileSpec); - Tcl_DStringFree(&pathString); - - 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], ": \"", - fileName, "\" is a directory", (char *) NULL); - return TCL_ERROR; - } - } - - if (err != noErr) { - errno = TclMacOSErrorToPosixError(err); - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), - "could not read \"", 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. */ - CONST char *fileName, /* The name of the file (UTF-8). */ - Tcl_Obj *readOnlyPtr) /* The command line object. */ -{ - OSErr err; - FSSpec fileSpec; - HParamBlockRec paramBlock; - int hidden; - Tcl_DString pathString; - - Tcl_UtfToExternalDString(NULL, fileName, -1, &pathString); - err = FSpLocationFromPath(Tcl_DStringLength(&pathString), - Tcl_DStringValue(&pathString), &fileSpec); - Tcl_DStringFree(&pathString); - - 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 \"", 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, (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) - fileNameLen=MAXMACFILENAMELEN; - fileName[0]=fileNameLen; - strncpy((char *) fileName + 1, Tcl_DStringValue(&nativeds), - fileNameLen); - Tcl_DStringFree(&nativeds); - } - err=FSMakeFSSpecCompat(vRefNum, dirID, fileNamePtr, &fileSpec); - if(err != noErr) { - if(err != fnfErr) { - /* - * this can 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))!=':') { - Tcl_DStringAppend(&nativeds, ":" , 1); - } - Tcl_DStringAppend(&nativeds, &path[nextCheckpoint+1], - strlen(&path[nextCheckpoint+1])); - } - 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 cb85d59..0000000 --- a/mac/tclMacFile.c +++ /dev/null @@ -1,1094 +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.12 2001/08/30 08:53:15 vincentdarley Exp $ - */ - -/* - * Note: This code eventually needs to support async I/O. In doing this - * we will need to keep track of all current async I/O. If exit to shell - * is called - we shouldn't exit until all asyc I/O completes. - */ - -#include "tclInt.h" -#include "tclPort.h" -#include "tclMacInt.h" -#include <Aliases.h> -#include <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; -{ - 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. */ - 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, fileName2, -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_DStringSetLength(&dsOrig, baseLength); - Tcl_DStringAppend(&dsOrig, Tcl_DStringValue(&fileString), -1); - Tcl_Obj *tempName; - 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 { - struct stat 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 (types->perm == 0) { - /* We haven't yet done a stat on the file */ - 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; - } -} - -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; - char *native; - - native = Tcl_UtfToExternalDString(NULL, path, -1, &ds); - - /* - * Remove ending colons if they exist. - */ - - while ((strlen(native) != 0) && (path[strlen(native) - 1] == ':')) { - native[strlen(native) - 1] = NULL; - } - - if (strchr(native, ':') == NULL) { - strcpy(fileName + 1, native); - native = NULL; - } else { - end = strrchr(native, ':') + 1; - strcpy(fileName + 1, end); - *end = NULL; - } - fileName[0] = (char) strlen(fileName + 1); - - /* - * Create the file spec for the directory of the file - * we want to look at. - */ - - if (native != NULL) { - err = FSpLocationFromPath(strlen(native), native, &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; - struct stat *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; - struct stat *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), (char *) 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( - char *path, - int mode) -{ - HParamBlockRec hpb; - OSErr err; - - c2pstr(path); - hpb.fileParam.ioNamePtr = (unsigned char *) path; - hpb.fileParam.ioVRefNum = 0; - hpb.fileParam.ioDirID = 0; - - if (mode & 0200) { - err = PBHRstFLockSync(&hpb); - } else { - err = PBHSetFLockSync(&hpb); - } - p2cstr((unsigned char *) path); - - 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 eb6a066..0000000 --- a/mac/tclMacInit.c +++ /dev/null @@ -1,768 +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.5 2001/07/31 19:12:07 vincentdarley 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" - -/* - * 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[] = "\ -proc sourcePath {file} {\n\ - set dirs {}\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\"\n\ - append msg \"in the following directories:\n\"\n\ - append msg \" $::auto_path\n\"\n\ - append msg \" perhaps you need to install Tcl or set your \n\"\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\ -rename sourcePath {}"; - -/* - * 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; - char *str; - Tcl_DString ds; - - TclMacCreateEnv(); - - pathPtr = Tcl_NewObj(); - - str = TclGetEnv("TCL_LIBRARY", &ds); - if ((str != NULL) && (str[0] != '\0')) { - /* - * If TCL_LIBRARY is set, search there. - */ - - objPtr = Tcl_NewStringObj(str, -1); - 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')) { - objPtr = Tcl_NewStringObj(str, -1); - if (str[strlen(str) - 1] != ':') { - Tcl_AppendToObj(objPtr, ":", 1); - } - Tcl_AppendToObj(objPtr, "Tool Command Language:tcl" TCL_VERSION, -1); - Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); - Tcl_DStringFree(&ds); - } - 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; - - fontId = 0; - GetFinderFont(&fontId); - encoding = TclMacGetFontEncoding(fontId); - if (encoding == NULL) { - encoding = "macRoman"; - } - - Tcl_SetSystemEncoding(NULL, encoding); - - if (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); - } - } - 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]; - 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; - - /* - * 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; - char *fileName; - Tcl_Channel errChannel; - Handle h; - - fileName = Tcl_GetVar(interp, "tcl_rcFileName", TCL_GLOBAL_ONLY); - - if (fileName != NULL) { - Tcl_Channel c; - 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) { - c2pstr(fileName); - h = GetNamedResource('TEXT', (StringPtr) fileName); - p2cstr((StringPtr) fileName); - 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 77d274c..0000000 --- a/mac/tclMacInt.h +++ /dev/null @@ -1,74 +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.6 1999/08/16 00:09:18 jingham Exp $ - */ - -#ifndef _TCLMACINT -#define _TCLMACINT - -#ifndef _TCL -# include "tcl.h" -#endif -#ifndef _TCLMAC -# include "tclMac.h" -#endif - -#include <Events.h> -#include <Files.h> - -#pragma export on - -/* - * 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 - -/* - * 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(void); - -#include "tclPort.h" -#include "tclPlatDecls.h" -#include "tclIntPlatDecls.h" - -#pragma export reset - -#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 989329f..0000000 --- a/mac/tclMacLibrary.c +++ /dev/null @@ -1,239 +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.4 2000/02/10 09:59:10 jingham 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" - -/* - * 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 c526f17..0000000 --- a/mac/tclMacLibrary.r +++ /dev/null @@ -1,221 +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.4 1999/08/16 00:09:22 jingham 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 -#else -# define MINOR_VERSION TCL_MINOR_VERSION * 16 -#endif - -resource 'vers' (1) { - TCL_MAJOR_VERSION, MINOR_VERSION, - RELEASE_LEVEL, 0x00, verUS, - TCL_PATCH_LEVEL, - TCL_PATCH_LEVEL ", by Ray Johnson & Jim Ingham © Scriptics Inc." -}; - -resource 'vers' (2) { - TCL_MAJOR_VERSION, MINOR_VERSION, - RELEASE_LEVEL, 0x00, verUS, - TCL_PATCH_LEVEL, - "Tcl Library " TCL_PATCH_LEVEL " © 1996-1997 Sun Microsystems, 1998-1999 Scriptics Inc." -}; - -/* - * 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 " © 1996-1999" -}; - -/* - * 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 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" - -/* - * 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 f3419f2..0000000 --- a/mac/tclMacLoad.c +++ /dev/null @@ -1,289 +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.7 2001/09/28 01:21:53 dgp 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; - char packageName[255]; - Str255 errName; - char *native; - - /* - * First thing we must do is infer the package name from the sym1 - * variable. This is kind of dumb since the caller actually knows - * this value, it just doesn't give it to us. - */ - strcpy(packageName, sym1); - Tcl_UtfToLower(packageName); - *(Tcl_UtfAtIndex(packageName, Tcl_NumUtfChars(packageName, -1) - 5)) = 0; - - 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; - } - - /* - * 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(packageName, (char *) srcItem->name + 1, - srcItem->name[0])) { - offset = srcItem->codeOffset; - length = srcItem->codeLength; - } - } - } - /* - * 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); - } - - /* - * 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. - */ - - c2pstr(packageName); - err = GetDiskFragment(&fileSpec, offset, length, (StringPtr) packageName, - kLoadCFrag, &connID, &dummy, errName); - if (err != fragNoErr) { - p2cstr(errName); - Tcl_AppendResult(interp, "couldn't load file \"", - Tcl_GetString(pathPtr), - "\": ", errName, (char *) NULL); - return TCL_ERROR; - } - - c2pstr(sym1); - err = FindSymbol(connID, (StringPtr) sym1, (Ptr *) proc1Ptr, &symClass); - p2cstr((StringPtr) sym1); - if (err != fragNoErr || symClass == kDataCFragSymbol) { - Tcl_SetResult(interp, - "could not find Initialization routine in library", - TCL_STATIC); - return TCL_ERROR; - } - - c2pstr(sym2); - err = FindSymbol(connID, (StringPtr) sym2, (Ptr *) proc2Ptr, &symClass); - p2cstr((StringPtr) sym2); - if (err != fragNoErr || symClass == kDataCFragSymbol) { - *proc2Ptr = NULL; - } - - *clientDataPtr = (ClientData) connID; - *unloadProcPtr = &TclpUnloadFile; - - 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. */ -{ -} - -/* - *---------------------------------------------------------------------- - * - * 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( - 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/tclMacMSLPrefix.h b/mac/tclMacMSLPrefix.h deleted file mode 100644 index 1d11099..0000000 --- a/mac/tclMacMSLPrefix.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * tclMacMSLPrefix.h -- - * - * A wrapper for the MSL ansi_prefix.mac.h file. This just turns export on - * after including the MSL prefix file, so we can export symbols from the MSL - * and through the Tcl shared libraries - * - * - * 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: tclMacMSLPrefix.h,v 1.2 1998/09/14 18:40:05 stanton Exp $ - */ - -#include <ansi_prefix.mac.h> -/* - * "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 diff --git a/mac/tclMacMath.h b/mac/tclMacMath.h deleted file mode 100644 index 14af9a8..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.2 1998/09/14 18:40:05 stanton 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) || defined(__MWERKS__)) -#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 93820ba..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.6 1999/08/10 04:21:40 jingham 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. - */ - - GetGlobalMouse(¤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)) { - GetGlobalMouse(¤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. - */ - - TclpGetTime(¬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. - */ - - GetGlobalMouse(¤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 5036a8e..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.6 1999/12/21 23:58:13 hobbs 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; - 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; - } - - FSpCreateResFileCompat(&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 = FSpOpenResFileCompat(&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; - 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 = FSpOpenResFileCompat(&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.exp b/mac/tclMacOSA.exp deleted file mode 100644 index 4cde512..0000000 --- a/mac/tclMacOSA.exp +++ /dev/null @@ -1 +0,0 @@ -Tclapplescript_Init diff --git a/mac/tclMacOSA.r b/mac/tclMacOSA.r deleted file mode 100644 index 7343764..0000000 --- a/mac/tclMacOSA.r +++ /dev/null @@ -1,76 +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.3 1999/08/16 00:09:26 jingham 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 0 /* Minor number */ -#define SCRIPT_RELEASE_SERIAL 2 /* Really minor number! */ -#define RELEASE_LEVEL alpha /* alpha, beta, or final */ -#define SCRIPT_VERSION "1.0" -#define SCRIPT_PATCH_LEVEL "1.0a2" -#define FINAL 0 /* Change to 1 if final version. */ - -#if FINAL -# define MINOR_VERSION (SCRIPT_MINOR_VERSION * 16) + SCRIPT_RELEASE_SERIAL -#else -# define MINOR_VERSION SCRIPT_MINOR_VERSION * 16 -#endif - -#define RELEASE_CODE 0x00 - -resource 'vers' (1) { - SCRIPT_MAJOR_VERSION, MINOR_VERSION, - RELEASE_LEVEL, 0x00, verUS, - SCRIPT_PATCH_LEVEL, - SCRIPT_PATCH_LEVEL ", by Jim Ingham © Cygnus Solutions" -}; - -resource 'vers' (2) { - SCRIPT_MAJOR_VERSION, MINOR_VERSION, - RELEASE_LEVEL, 0x00, verUS, - SCRIPT_PATCH_LEVEL, - "Tclapplescript " SCRIPT_PATCH_LEVEL " © 1996-1999" -}; - -/* - * 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.0 [list tclPkgSetup $dir Tclapplescript 1.0 {{Tclapplescript" - ".shlb load AppleScript}}]\n" -}; diff --git a/mac/tclMacPanic.c b/mac/tclMacPanic.c deleted file mode 100644 index 0987fa3..0000000 --- a/mac/tclMacPanic.c +++ /dev/null @@ -1,298 +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.5 2001/06/17 03:48:19 dgp Exp $ - */ - - -#include <Events.h> -#include <Controls.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 */ -static 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 ((inButton == 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); - } - TextBox(msg, strlen(msg), &textRect, teFlushDefault); - DrawControls(macWinPtr); - EndUpdate(macWinPtr); - } - } - } - - CloseWindow(macWinPtr); - - exitNow: -#ifdef TCL_DEBUG - Debugger(); -#else - abort(); -#endif -} - -/* - * NOTE: The rest of this file is *identical* to the file - * generic/tclPanic.c. Someone with the right set of development tools on - * the Mac should be able to build the Tcl library using that file, and - * remove the rest of this one. - */ - -#include "tclInt.h" -#include "tclPort.h" - -/* - * The panicProc variable contains a pointer to an application - * specific panic procedure. - */ - -static Tcl_PanicProc *panicProc = NULL; - -/* - * The platformPanicProc variable contains a pointer to a platform - * specific panic procedure, if any. ( TclpPanic may be NULL via - * a macro. ) - */ - -static Tcl_PanicProc * CONST platformPanicProc = TclpPanic; - - -/* - *---------------------------------------------------------------------- - * - * Tcl_SetPanicProc -- - * - * Replace the default panic behavior with the specified functiion. - * - * Results: - * None. - * - * Side effects: - * Sets the panicProc variable. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_SetPanicProc(proc) - Tcl_PanicProc *proc; -{ - panicProc = proc; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_PanicVA -- - * - * Print an error message and kill the process. - * - * Results: - * None. - * - * Side effects: - * The process dies, entering the debugger if possible. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_PanicVA (format, argList) - CONST char *format; /* Format string, suitable for passing to - * fprintf. */ - va_list argList; /* Variable argument list. */ -{ - char *arg1, *arg2, *arg3, *arg4; /* Additional arguments (variable in - * number) to pass to fprintf. */ - char *arg5, *arg6, *arg7, *arg8; - - arg1 = va_arg(argList, char *); - arg2 = va_arg(argList, char *); - arg3 = va_arg(argList, char *); - arg4 = va_arg(argList, char *); - arg5 = va_arg(argList, char *); - arg6 = va_arg(argList, char *); - arg7 = va_arg(argList, char *); - arg8 = va_arg(argList, char *); - - if (panicProc != NULL) { - (void) (*panicProc)(format, arg1, arg2, arg3, arg4, - arg5, arg6, arg7, arg8); - } else if (platformPanicProc != NULL) { - (void) (*platformPanicProc)(format, arg1, arg2, arg3, arg4, - arg5, arg6, arg7, arg8); - } else { - (void) fprintf(stderr, format, arg1, arg2, arg3, arg4, arg5, arg6, - arg7, arg8); - (void) fprintf(stderr, "\n"); - (void) fflush(stderr); - abort(); - } -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_Panic -- - * - * Print an error message and kill the process. - * - * Results: - * None. - * - * Side effects: - * The process dies, entering the debugger if possible. - * - *---------------------------------------------------------------------- - */ - - /* VARARGS ARGSUSED */ -void -Tcl_Panic TCL_VARARGS_DEF(CONST char *,arg1) -{ - va_list argList; - CONST char *format; - - format = TCL_VARARGS_START(CONST char *,arg1,argList); - Tcl_PanicVA(format, argList); - va_end (argList); -} - diff --git a/mac/tclMacPort.h b/mac/tclMacPort.h deleted file mode 100644 index 142a570..0000000 --- a/mac/tclMacPort.h +++ /dev/null @@ -1,304 +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.13 2001/08/30 08:53:15 vincentdarley 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. - */ - -# 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 */ - -/* - * 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 - -# 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 /* __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) - -/* - * 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 bogus and needs to be fixed. 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 never worked (clock format 0 -format %Z returns "Z") - * so this just keeps the status quo. The real answer is to not use the - * MSL strftime, and provide the needed compat functions... - * - */ - -#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" -#include "tclMacInt.h" -/* #include "tclPlatDecls.h" - #include "tclIntPlatDecls.h" */ - -#endif /* _MACPORT */ diff --git a/mac/tclMacProjects.sea.hqx b/mac/tclMacProjects.sea.hqx deleted file mode 100644 index 5d3ec68..0000000 --- a/mac/tclMacProjects.sea.hqx +++ /dev/null @@ -1,2945 +0,0 @@ -(This file must be converted with BinHex 4.0) -:"h4ME#jcC@%!39"36'&eFh3J!*!$UFJ!!AiC1AC6G(9QCNPd)#KM+6%j16FY-6N -j1#""E'&NC'PZ)&0jFh4PEA-X)%PZBbiX)'KdG(!k,bphN!-ZB@aKC'4TER0jFbj -MEfd[8h4eCQC*G#m0#KS!"4!!!+R)!*!$FJ!"!*!$FSj4$D@P8Q9cCA*fC@5PT3# -PN!3"!!!c!%#d(A&cY-HdK!#3$3-"C3#3!mN!#PS8!!#Sr`!&G'0X!!#4V!"p!"! -"f3(!!q$rN!3$"rrirr$$3!!!J!#3"k@3"!%!!%!!!,5K[,#dal4p!*!$FJ!!(`# -3"()!%$&`!!(IL!!!(G-!N!32!%*239p8Bfa6D'9XE(-Zci!!!*Hm68e3FN0A588 -"!*!2J!#3"d,"e+(92U!T@-GR[pQ)D4N"!E`GDf!YSX,#m4G4!EiQITp3)KPT0%H -pm)+Aj!6+&jhVJA"R3l-mrA84h-+P`2rGA3*P&NEJ'N"$CKFN#JhQ2'YNhclN-hc -Rc'&RLkSTPJJj9LE05Hm!SM3R(BPj-(BUe@0PJ9eGrpqbkL`STMcK4QGqpk0,HQD --k+DFK%5Gj!aG2TfSA0YaL([!F2MV`A%B-k5mP1aP[9-#V31iE"9ebe!3E*!!K,8 -2k,YB%jrr,R99GBfm6%BD*9C#P+fFPGrf0bNqh%-!j(fTpX[@AHCR!HlaC"fJ$rY -TAcFE,a9ZCIU1V35f!RiqD*dk2N)LK#DZK(dS@-mc2b!k(YP54-)BG9NTjd3KKcD -p2FXr$r6XM"K5,P8AAXRU5T1r@cd%ieJ06bHaj4$m6RR&2K$(NpIPqqbLC$ZiYTB -82amS&&H1Y,6Z#)LLqa[`B&mML8SfKSpFVh08GI1Arp$#NpH#%I9k!ZrNS1'J,-X -RR!XkSAVmQ1G*LA9Xb"Y#YScYHfF%"8i0ji8ad"!`L["[L4cGAGIeDfbf`[q3!0K -`0j!!D3"[XcTY08L#DVG*E`NeT+-j-,`aRhqV($LiZcQNE5TK3CbYPNjJR*`PGrH -K1Ujee25i5Q1VjI+p&9Qp"lXM5Q1Y`3q#,#P@Hb*+YeYJ1l9N5c6T-)PIB+4,8`@ -DD+flMpEG&)93AS@#p[Z@8FGkpkij15JlpSS%Z0DQ@"1cUI#FeU-&b12aPm2$F6* -5pUCSGME'*Gj*,m)1b&d`"#33f5ZATdml1IBj&%'AbA+V@"`I!K+Tfm*Tc+a%!9k -Y0%e+fS))CMZNN6F!jh`'2idk+aL3!'Kj!!S)cb6qS&TpHqHc'HXcEC&#&1FPi-5 -"LekVkNF%h,,L)B(h0`Tkr9XARqjl"p58(NJ3()h`EViHGIi$e8Q'18LXclRVi*F -12,-!ITU6EiX(Mf81Z'80T)C44e-Bk#frX*GZZ,&c(je`'%D1b0+B+0cA$L%fUQm -)L'jV4ZVi,#bh4SHpq%$9#IQ3!"Iea,imB'"6`YacX',r&m"$`rHKG&'26b"6*Z* -jrfU%95I@"TD1"VHMXKrc51#8!ae(208a!E9h&D+Yhdj@YM4jUQk&kemGG-M9i5q -Yd4VApaVaM)#fMV2'lZ@bl@Kj''4j#f#XKXR56QS4Z3lk0FH@YKi$#$'q[GaiRQR -r[,mm)l+8,k5(V&q84[CCNN0Zlepc#`p)2#bkk[%8imkMICp"Aj!!Q3(RA4@Re(j -%*Q(*&'EZjM0c2"m16Hq2,8&K"2&5V&aN*#*(N!"`SrPK-IakirFQf'B-M@-aX1- -kUpXGEAi@FlE8(k5S"3IaSm1j*!IAkTi3N@M4@-`5,a8Ml0UcY`iZPbreqLY2P6H -Z)dHjSV@Y`8"DEMRYmckLi1TeIJiGlRGKSaLPcEdc*)[Sh[efC3h*)$h,k55Y8`H -3!!KP)I,eb'Qqi2Df[aFC,'SQAjPib3Ala@*hlLK35cbDD0a,6GGCk-cLDi[VG4( -(KchdSjc@1TNLGY1GD%$2K"NNpEZ1Lc46B&AJ(QQbD*f8lR-C,D03Irm%aH1eC"5 -CLM-IPN(F8SFhIKb5$Q-XjKfb3YkcLh9hEbL%m[YrYY&0BQXk$9N*GfcQbfG4'+h -Q381VK%k*$!jZ[QEHL22P-FqVe$3!iDq0d5&QebUiG@XQ-9H&4dBRZVX&Nc6%DPq -kR""%REJJ`SML`QNL!Cei9E`"*Ae8H5H!YljA(%lpF+dVReV[1TApefMDXURr06[ -PITeTB2qQZ-#-G`J3HG8b4(XQ(jBalM4K#AJTqL!,`#f5i`K!5Vef)#aqD&iZTRS -I%Lh@NrGrE@[d['!m0k80AqD*KP-kC0[jqr&I[!prJHbGX+*@G8a8%8$V'bVY@-m -eJh0)90*ak54S3E8m6(eRCU1EhSLSjSr@dF)G6XqilPrpBmZhd'BTFG3HJ0Z'+cN -+caa@MMf)IM@3!!!U!h(V`P&$qeh#P-*@(`L`Q"$UXI2cTfejh,[`qF'qlAfQR(" -T8jHqNeSR2E)CDHQ$N3ZYTa68NXYSlkD&kM$p*c`!'SFHXf[F"DpF`-G*f#S(DPB -QfL*i%,EFbh8MP0mG`pk)2)V",mSlKp2lUEQ4H*5@*Dc9XQfLqcFqSik40!)DM5` -q#Q2Z5('ZT)R-fRA-iL"N5"($Kce3E*1H"m-c`1DU%VUPi2%mj6m53DBb`08X!!+ -eE1ETDiVH,,F8XPUi,fZ+KDbV[hq4#%'JK3@"0k*''GEmT-XGX*!!(riZ9R@G864 -qH*bd64[9`"TAA4@9#X@-3rbK5Td@i)C+-arQ)hHJLe!3@r`qJG&V)XM9dP@XGhK -V@1YjiP@)Ger#4VqKlmY(CEQ6BNJ*6*`')Ebc*f[8hU8[iMQV6&TjSdBeUJSEkPe -VEPQQH[b-QH@4A)SAT(M)B`%V$1,A"UU(P!q@(iM9dD#dimpkh,DpEAG0qcbTN!" -KHD)mdD$ld$86afR[!J0e0Qm&*8b%!dd%e3"T*QQAc1m0Rr$(#%XDSU3lbl`IB'd -r1XqSUNZI9e'j3p63TXR`#N6!G4*CHA)&5'1&d4852r+p1CQD(jr3"rbU`jkp6#M -LraP$Yrk-&,36P($P@(#&LJ24TF4534lM(Jr#"ddFSY-A,J)SbmRhD0TXeeHmr)X -)Ya4GD5+Kq6$mS6`0ikqXT6I8j2I9*K6qS#b0-@R`"L$3X0I-qmb)9pQU1R))dpV -@0LMbK9IBb$`am3*IdDX`qjQ"pLA`YmH(hMXmMFP1lKGGG53h%[laIjJfA+Zd)TR -S2K'GVfYCHk`lAapUFji'T#DbLQZLh`'K"6LAT)Fl3Ph*RcUD#JT$d2@8K'$3+%& -!A"05,Z)qrrmd1QlM)h5&dhp8UhAbMkEE&lbCHLR(`kSPJUe`!#rHf"0PlS2!Tmf -hZL9+')[iQ%%"RGPPJY(rK$+MDq*@5dY#$%5Gr%kj5E*Q4)U0h-e+&!#hP,G$rf) -KNa%Y#iBMR3Am#E#H5TH%"#U0&dXh2f1#p,BYmM&lCa[)%KdaLq#1a5RGhrQPXa" -5mLbrF2mDDmVeq5RF@Ra(HS"FA!51bXYkTl9@1bXlVZZaK'VlTl5Y`ePra*J+-%H -@"QlHP3Sj5$XG0'Gb2$MAd2'25k)r1rAr)d4d9ZN(GMRVh(@9Y80cZSVLHIVIX,q -mi0eR'PC&+!QK"qSUr&ke`#Ikkc'rV!e6k#eY+dqYdYeaR(@-jXlpBhb*32dFMPX -PAMc''f#"*@IQE4B'f4Jd9i,lI*`f4M8cEN["XG#Q`)Vm#EF92*R4Lb`$6$-DSr* -[UB6T-4m`mdNRQB$pFYP`+M[#r4G6)LCHI6!MDl-YEZU*eZQ!h5XF$m6YpA-i2Re -[Q`*rT)3VlSUJRXeGPr-&9eDI-+qTm"%(9+DYG8B+U$r8`iZ%Ppidi6-TBC1pAmh -pNqD082SfKeE1[kkG4Zb6Y-dihHX6`$iUU%h1*+N0#,6%P'"1cI[M0pD'fhZ!cZ# -'A,mbVL8qbNIm2Zd)4!HS51i4P0eF2!NcV"YmS6dDFLqm(bh@fYT,@'5(!2d,"J0 -K6X&0mP1RNamU5I0Q43hKaMQq+q"SZPLdKj823&c@%-m&8Dei$J9Vq%V#"01&3%A -rkK'-AUMSrh(qbFG99Qi[J!FZ`Npi43DH[`Q@f,fQRee5l6e"IqhqV9T$CUHr1V! -$SpH!M`+#+Y2h#-qb9k6r-6fV!@ma(MV&lU3-PZf[(*H4YTf2b%lJp&p8q(b0%*- -H+K0IE$9$!`Ze9VTCVHhCc"!0ZMJq6V1`0Q,jj25bX(NUECF1%Gp'2,X%I"`JK1$ -6l1SC@N)@5K)#)6PM,M(5P0q5S$),2(hhRapTE(lX`qKBL'SIMrI#JE*QEQSUqID -KDXa02Jq!K)p8G#H&ZkqdK5aQ'hYHTqG6-q6XGRX+!5QM-I5"qrZRk%!G&qkebcf -&-rSRcMC)$UX()"NDi&SVTN5*4$R!$#c'i)J-%mN-4Td&CVUYJrhRDP5rDHamm4I -YTYiK(H`U$ceX)p8)5c&CM8-bfMVl-'j(B`8`3DpA08-S!Ck``HcVDrN"EQ&ER8B -,4JA,2I&bFqEI[fE%E%B-p&qUH)&Z"JTJ!cl[DFHL$cEUP@4[28K23N%DUa'4SJf -pcq!NkC*0lXD2VPHlb6aRKIb)@r89h2l*G+r#1MppQ,qMjaXEpM"d8F15*Iq+V0% --`6cpc%Ze[J'X&,KJZHf@N!""TAP%pq0UGKY)f&T"V%HrE,M#,kH$K,Jk5)%R,re -4KA3-a5K)V6PJak*%56#EBFNr)XDrp[#`dG3'4fImalPP,p4-XLUV%ke-iFQI@@B -+C4bG-KT$"5@6S&Gp!*Idqa2&&UB,pPX*4&[VH1pP3"@h*PJ3#AGr5Pb&Nh3!*+% -#p100)P98!B1FY,jG#ELbTba`X56'hD#!)r0q"99epkK#kV11)188HS-q[[Pf0-r -EEcP1X9Xm*A'6beXh#C,Bch(d"QK9BC'4e'D@ZECK,JVU(iDQ@@2kN99fK#Z,P(6 -c#A)k1ffp@F1RR$,(!TC"E,6`4qM$%l8m,l9&ZVMHpRie6ULhKZ504NkT)b[mXNN -%EEGVF%39#kkHKKJU0a-+&%,+jp*53q+99&pS0%JUDFV,i&6N[6)$EK'eH'Ch#`j -5R4lj3pB@b8'(UGfBr3163[)'Z#rUbK&(*9`-`UJZSU9I*Y%4$JM,elfZT%2GZ,r -cBA"pr*2(U!d#2%YB@SmLb,fG"1elYU#SHa)Q3XZMb2m['233mIhkKEp,d3mR3&@ -3!)5PNQZaqcXbQb5I8K+Ea&l+Rb[)D[h(L`hNIXl+HT5#'6+q&6jLq-D6EG"NpL[ -HFM6GL)6bR+IKA!',UCHk'SBMR!`#d1Ck3dr)l[al!Ar$lqUP`rG1X#2UYT@bK[2 -IHS,P1)k5li@J#IU$RNe`qPr0dShA2`EICXCX*LaEi-CNXqXBl(jN6S*qK`*C`lA -41M@[K)efH!mr5+HE@@BSqDVMc'IM@V-0KrNiB,35Y5G@2,EVYp!hLHlZm*l"RAI -P5iF0[I@Nfk5JGBTF,J[TSGfGZA1FD8dXLJ(9R2JUaS5pY@f29p`G%#I1Pr%GTik -j8k%a5M!6Pk&G62(9G8`&f4ND!85F11Na!A[5Y%f&afA%jNCEiIqHJZ8KCfD6B!Z --S!@+RQfC1D+THFZ6NqG@T4kLpQli#R61*VmVmR(#AY(#(QRiVabA6$Z$PrUCAq6 -Hb@1"@"CaRBqm1ZG8DHF5CqHB3Gm++3NV9&4XQ"$A2&r,1ECU,VI[P4dBB)EUh@K -A[&)06m'EI)imXYPr@5pXd%-`1((b*i3d1X6PJm!jDqPia*DQDZSHP+$0@Icf!bI -F3rSp$I6-YNHE04EVKG-m,2@EK-lrGa)X3*5P)CFl5&RjrBkVDZ4Z40l[clm"pY' -I5SPJdr$X,FK!LfLS9iGaER&$TVjFEVUS`"p0Ujp[TVL+CASq3PYLeV4Hpe[)Bkd -#DD-L[Xc+Za8@Abdd4)&S`Tbr4LYj#@KK!'$FAPfjbpLC+TG&D[[D,$e$CPV8iKh -H&1cZ3UG8C$hh`1fQZr0kD$GEQ@fV(RV8$kUNA690Z$Y8Uq6G@L'UaC!!hVJV3U@ -kp+1Y*a+jCGl2JUqrFLZY`+'V(Eq%"'A'Dh0*VcG5,Hrb'*fDrFSAZ@[5CXM1m4i -b(2IiK"4*&iMV@3p4"cNaQ#[GI@,ZPrcUi!YVm8mGVE1eXGq**fqQcq@5PEZmreE -)YpcjhiYVHpmL#EIVCcI--UVEJ(TEQDSFQARq-Ra+2*hM*VXlde[A"&Vm'ph8!6G -c&rR+C5&'F6"VbQq9iA%KS'%0I$`,%q*c*5R`kF'P1$T81GjqCbR[ZCHY&a1%pUb -rcKd+J5KqVdB28GUmLU5lQ3f)[C!!5C68k[TE9Bq!m3VpD*&6AiFq[,$f!*ZIR8D -FT@LQqi#QBl4#6@0hcG4,#UGJeM[2prG*d1$A-R'B6m&D--abPfr9,+rpbdV''Kh -R(8+R@hM4GSVV8KFXQeI,G+ReH*'d8NE"`CA$rlB,&r1AQ+CEH%+pLarE$1EH-bC -[-lN55d3NU[c#!(m%cTNiBKDJQVRCZ5XV#`#aRjFicE!HGcLc4FU`fA9C#dK0c@f -kh%flCGXcDb*p5PKBJb(IX&Z@JGa'K35ldSVr%#$r`6aDiaR+5230LiIX2-(C$Fq -j!C4kVrLLi,pHa6!5qr1&l"!%0B(@kJcf*SGRZcREc'!UB0J1Ec,Kb")89I&(ajN -55Bq'VBYK+J[94JX(HY8M%4RaEi[5354QQ$rQbQ6G"D'&p#[m-lbT9L&'N!!hT)q -l-ID0RG5K,fNGJ)$A**)PGUB`PC0XJ!U6#qb2P,%C9$UJ[6ei)cZf82Vk19G9fl# -fZH[c9SNl!l0Jc-2PCBqaMpAcPG`HBG&GGlS&fjIbpYAbR#bCkJNkIk,86pIab9L -eAmZQGU#T6-+!(S`55j3TUlb4FDSbl&*HLeL["r,,9FT"1JCSG94+Q+`8dH6JjZ& -*"@61,Q5MDl)3UUSd#Fr2cHj@`HG'[b@c95d2!#Q@Mk-ib%DLUh!r!YS"6IJL20# -r@0@U8)q"-SL1Jq1q9FL**C(mAFf1GTdj5HLhqNUVh,+kddDR%R3pANKSZ"9C+a5 -iErNp3N1QN!"XV,Va(c*)I+Qc"BdHki[de,pKmAR#hp,%&bq13(RNSLEZr%258,2 -T(4d8UU@[PVK'*"CqkGBQVlZ&Z@AHrT!!MTV8HkG+A%ZCkccaQbk)P6ZpM$EXi0I -l"5*LDi9EG(iRf(U6MSqp6U2Z%QNLD6cBK'$&$[-Z83Zk$"kl4rdqe`Q(*A1l@aa -II!G$@IiF#a+c2Z"I8DL+QJb#+IZ((iHG4VlKipm,i[b0YMj#[M6DLQT)9"aNaBj -11[,D)e,C$2h0AZHSM6MZGFXPbGhH"13Z`mE)J@k"9*UMY"p@i[1QG@0@M3aeG$h -46r#12LT`+-IMJm8Sh2,IILF`J+h)CfF,ZKR)BbmBmc-abU2bUDfER5MD9j!!&YF -jE@!VFTfrj6mChl"AfQBVR$aJE0)3#I`')!m,aLE%P&kE$GDe49mBZN3HJ`F,bK0 -dlYTUMCr@i!P9P!jlY-,qED69e3CP""V42DAL!Mb1q[@,RKN*-!XlU"3ZBV8iBb3 -Q4mq0YTUZ!ldDJB!,A"'i,$da@j)d9ha56KY+mf4H)qX2-pYK538'%Z,HL2YKl#Q -!`RAhHGk,1cGpr3YDmG)d0DAQH&+Kb6-CTM(N(IJ8q'EF!m-r1Sr`N9FXC1Ih'Ip -d+mATYZ9eZ(Q3!*p2%c6Ma&FCV+aX&F)lE*1p#FNE'qR%rTM5ZU8[fPG&I*FTa15 -UZ$I"L(N8,p,HRXRm(L9K2&S`,0&Jm)Z"+JK6ULKblaYmCcq%FrY6hAm!$Hb@4`4 -BpU05UJr`lZ-$pAh3VPjfHYq*XUB5b[%UZDR9#2%([T8JfUc,rlh`U,8Gk22IFRC -Hd8cmd%K*JA,+0`'Z-hk8)443$l`P(r,Vc0N$90mLrr3E(ShP*EqEI+mX`h&X"pE -bid1rJ3R95Td%9!U[RfS#&A6Qb8-S3G5S`qZ8&C!!)),UiXFm`apqDjN9rM`EA82 -iJdih$J33S5crQ$BNY-('3)$HGD5c8d"V*Hp@'f&0r5IHqr!49ILQ3FClrIap*Zk -3!"LYVCLa4dm`iE6N$ABmZ#`ALdHQpkkB14k$`L,[NAaK#i"IjPdFCDh'pP$rT,) -1@6PG!5TrScr#N!$'83,jEYL-kabUYIYai#bhA!F6`+5B,)P-$jr'(P8iCC[ZB(U -#VjLJc`bFSTRTH`@F2Kk1,@T*6,jBNTT28Q5C9G,J54@-E#9PIlGN$MZ+5KY200) -Ib%SZ8(RXJ38[lNBV%qCD&j1H%#f$*dc95dqJXXVISRS85pTX)k$0,P49fFqeY&S -eX&+Gf)HBYfb8@31F9H5k@KheFrEEEX+,1BFi&)PVh3rBmYV6Nb+'&0(iI%X`QHp -pGY`YVU3K##VYVkZV11ZAXiLHN!#8d"5RjX"BVPfL&N6G0%TN$rQ9#EEN%HBqGD4 -*#JGk&DJl+JHJecIYd8QdRq%#Y$hr8&l&Q*rjL1k3!26P+f``b+2a03-aFd5b,3& -aYEHXrKm4HRGhkZTSH2d)(dZBH6!HY90AQGV$bQE+'m6!T4`bS6[r0GVG*I8El3C --*2VACNPb8$UlJ(!G0"arkf94[,AX-8@&bjbrj$,,-Lp9%SikMI&bL5*RI004"4c -8AVfFmfqUDUL4m%&f3%X!3`T%f1j'")&lFrTYJK",JXHNJ@Q(Y&T`L*()#&r-Mr, -,P+,KS@(rYUB+Tr!JE@&rAGI'!$D%5HI[b20drJ*de`ZYl0XR-!)(UJqk)j&P@G, -B"([GEJqKmfF$BQ2#)E'Q"TQbM9&MH&'R[&rMC#18(&i$h)N#YQ589r(&$jMDYVa -Y@8AB4f61fk+c@2+`(dZdj-iNcc%ZH1[Z@cifGKfZLJNcC4GpUh*e[-GV3F(k&9D -$NdVcLem-R''#jFV9d#Ci4N(5#MDbeFLK%!G@C16P8i3A+JPG'Gf1Lq1plQRLaKc -f8A[fjM"KkH-H,1La[lZZFb'V5lK9#9FEX2PX-+Z5D0#[(cM08i"jXr0fF2eQ3a$ -Q#(2k8)6IAhh**[hPlC'2G0YD+P@l0&9HI,(MQd"c!#k)j4!ifdE*[(@&9h"KrZ0 -UHJ5"$)3fi@5Jfd!41`*1rRCkQ$G-6l8rPiX+cG(pDP96%Q9IT(L4+1T(%mqND#c -J%Vr+$DacXMim"UJ5,Kp$(Z*V'0@@G#S)b8fPL#,DD5XdqM1iTL40RhDIMVYGfUl -DNXSYA#"fkI1A6#BFJZb-%I)D2eA()U9DQ6YK1c"`r'Xrq3erN!#d'8XB'HCad%[ -jdBjNYR+EjG!8@[LbcV[5Y*kQd3iGcH[qR5a#N!$!X2QVY)5T'e2p,3Vkl#GcIkV -clhT)r*kZcQ"4[LkD`2qeCa8cSK%YIcL6jBE(Rm`qKIV4EC8b#Jp9H"i,RjEdZ-E -+$0+01PA2L6-Hck2cL4DCD2ehmZGDb#GI([4cQC`E"5XX8bjX`prQk)YS+ka@paT -CL!c#hrb0$af'0%DpP`'YH,qcb'p`LRd5A0i-BfKkK5p2B4[#(,DR-!f6dSeejHJ -HmS)#64ENXXQqfI4FmVNUYhU!8bL6ah&'Qhcc*DbII[+ji6ZQe,3[kd&&4$H00jA -aZJM-ff-Mr!0iAGekE#)*"epF(&Cii6TZ-kDZ*!YbApmSYV9BU)08fNDd`,%Q0Z* -D+3c%1q0ff9Y,5&PC3S$b1#@j*chXb&@*G[brB1jbpE68GEE4#Ml#*3ZCaJ)lRh" -DlD04hAqS1dfLY19e#S6pRQr0qIE,*!)#+JZ`ff4RjV)$4"TeH`j-(1%,kYdk,!@ -ILX5S#p1[`bHi8U-6E$a5i@JXV-DZMD1D[c9UI-k+"P"5FUhFQU53!)`E8L)Y!rE -Sik5T4BQf2T6l%ac8`&+YZL)XmbX1bN-+N!"e+S%km%pBM-)FQZPkbkjBVRbkLCj -Y+(idXd+BYbE5QKUm1[[M6m")XmmQX(,@22TpE%cD1Nc'+9*EjAq$&+qZPREJG$A -a4emGRqQ29VNqaX!bCT@9EUPCH!NJ!N@*3b2fCIMFZ$XFa95YjThQ"3NjRZ,!fT, -ep)%-DfSl#M6d"6LF"QQkYJaCa38NB0%ipCabYBr,-1LfrN$PT#H@+Jlih@kGXP+ -cVB0@`9e02"rq,l9"`1jRaJV6+9jpdlFFbkX!'*40Afr5TVS*!FD!LiK%Q`3&3ZJ -#`9r1dN)JhpF'F$$E$"NS#3D89@fbR5M2Ip8mVr3-SlYe*V'4PD&RAC&a$4IA)U+ -B5H"YjiGr6@4T95--CkVd'-S+HPa`P$h1fYi(f#ZL8#3QE$E[T6EUk9k6fk6K`Sr -3l`eG1"JR"IE%#EbYhr6*c8KfC492L0',)b)Z6U#rS(e9@CIf@1MVGZ3c"#,)Qrl -5&-63@ih9f"@M(U@r@)IF`BdX$iaPk&+-CeDL4H-)L62T,fIhMVC,Z4f'VakpJib -'4EqkZE#kMkaTYC)ZM)rSfdI88ZB-pkH3!#+@IeC,$*),2La-lTdVpFm`pi14%34 -iYQ+4c5idRU1VVABG6U"4Jkpbh'QY+`cl"RB)C-(a-5!qBkii$Kb&TbTM)k@C3d` -l%6RMe@[R[%RX4iID,ceFErkARL+rKT*e)N*,G`%UXFj[ErHP'$+Zi+@3"!%!!$d -!!,5KS6qdal4d!*!$b3!!0EX!N!0b!!hP13!!qB`!!"CD!*!%$`"0B@08Bf`J690 --,Xq!!!#A[%e08(*$9dP&!3#3$i!!N!G#`G85SALlVSheFKi[2H,GN!$TYB6+EZH -KB2IdYYS#)!ai'fB6hBT%(!2UY2HIX%FI&0A4p[KU9$*AL#4$i`0J12CBP*VaF"m -5,[)@LXma''!95*BV1k$iH$G!XSaN[IAq#c,V-!&61BM5CqcDp9,UKj,rhli@SB2 -F-EBJVSD+f"mi(ckFmc3%d1)YS'"'3&*03rLVFHCa"1GSM0Z--,l$)pC"Q*&Sj,R -J3H)JkS3r)YTfU-+JF8&RchX,P+'))E,c!@Zb2MMFrY#3!*[*4UVAEmN2C%QNT$" -`J`95i5J3!eprCV(je,aEj[R2ce(0"ERd2RFVI9qYJ1C**Qhi$CX8H(CLGb#Frf! -lpqm3)NPPE*dd@,B"beYhUmh+K)+`D[reEYA[U(+N-GQEcDiq[##rP&G!DmZ"c1A -C,NH'1Q$%&BFU(mr)aI"jrkAGq!5H5G6MRckP94TPA'*KLY-h)8mE1R-#`@5PN6M -hZTEj[kHcaGk&c#C#JmFi5Q!chmVqjdH6,BKd%q[eZ-+SU4+fR8mUK5Q!)`XR@!p -8DIiT9PJ*JNP5PBkV$qcbTG4A4H1jP0(6f425N4jQ8c&'brrbR10'%-2-HpC(1FD -6!UM)RdM0Y#2eRlb+d6B2ah+i%Y[JCILYfihkcVF8"8mENJ"GL-9@Z2VNeU$"R`* -Q91GjKZ55"I+l0SlPP,N,+R9*(FqZpDXVDYV4a3a+&4V$I94j"482qcZ,'B+@aB` -Ui5a5MSpS`bTIB[[L*PfL19Z3!#JV@LArZJUJEAhcBGG'CIrS)%q6S68RDP0*BJQ -[-"k0cLaMqp@*cq%D6qmk`"Za%b5PR+AKNQ4U!X9dFPNhX&2C)*DJj6de4Y"e#*S -U"4SRXc*dj,caGC@,Ylm46&`0[!lM&kG)YCQ#c4kr`jZD@#8e,*13!+'k+&FbdDa -2,SH"j$3J)aefY3de0B*'Gerk!mC@M6dF)l!M3QAepEBNk9KMeJBIZJp)GF-D0Gq -NXG22[ml2SKR2M)D-Db&mk),1&@4hS*D8"DZUZ9DCej9@V!eLCr(lLUVpHXB'kQ3 -K243--c*C%a#C!&XalC(GqAdCjG,*b8`l-(YBII*Fp-!UPP%lKeA)dAIDTGdajGc -#-F"DJ6,$8!912S*KQ9k$B58jJ[8TA-C[9R+G4+mXdTUPBN*@,SErRTId%Ekr'kq -b2`ZpeVHj3h@&lMA+mHGje-m@eCCmlFml6",6SeGrMHV!P*Q5"e#E*QU0V'iq06+ -p%)J+QJjF6C%,83NZ"![J'%F)5qE8(Rj(Ek"`j*@8$eY#86%T[LQqHj@(KVeEl55 -hDbP$KS"669Z[J9*DJ#JNHkTYlGh,62$!'qVE%PadD)[+AHrPjUDp%,5@B1G'l%K -%jKU2`fjFK+hl+0FiXPl!,A2DD('M8PJmAMi)ama9pc&NDBI69lZZT#aQ911i@YD -el1Ze!`X85lZAQk`pZARjRmjdZYCJ`PFN`F[J,kIf&fMqhQ"D6Ril`q5YlRdT(kH -lj#k+l@"dBrGQQrGjGIkI1hHD#acM%&FaJhcdZPX%K1m"FiGj5`(R)f-V+6F%Prk -L'+TN#!CFQ!Fk@"-9miaK5r03M+2dc#XP%hQ'2j[J2MINI!Y15%9kfAXajAa"!q[ -qCZ%i4ahb@FRe4X#0R@Vj&*hQ2&AJSf,A-,3VV34CR"#SACbXAcLYeLcN)3(4b$M -9eS[C5ECA'$-pc[b,aQ5J(XD2MZLiVSk4'+YpQ[@DLqTmqUmhD3VaXR3e0Yc98NT -MJb0M`51ZHE#SlQ[SA1A+KHCIX"Z!&Nr-G09IJ*3kjI`iq0A$BY'IhiNSA''J%IL -lP9@96ck*(3A$8(MQ0kr4)Dc%N!$GQZh8r@ULaMK+3CPXr[fL"(,8HQ6CAqBNmA, -2%lUm2acV5TpDSMq!b06X8%DJZed8f&MHmKNR!KCYJarfFC0Ic091KfJAb(#r6(" -+G&C+C!BlESZK[!2p)3`jpl08(H!Qie*&mDebU+TLbh1Y&QH9lG%+q#jD,[6KK#0 -*TpY@bY1Ih)hq(,e!dk1bMKTH%ecI4QmCeLSR'G`b`c3Z,EHm'P@9#XCr09Lfa3q -4D36)p$[1N!"k2'L(MVL-1*Sma-X"2'C+"K#&Y@1dPQACY'!a+6#M4T+`6pCMUcG -"qN1$&+(KVaX3[8ca8D("-0$ll!PeZRdk!EY9J(c0rklG0!D3!"8qY[3BQ"BQKk! -elcE0aAjMN3cQk!RMM[NC[!rqDi#LRkfaH%,N*a`D[bE&ERA@me0Y0+TacIp(jAK -4I8(a"%ZjD`&M3TSJ[lmJ'h"QF9a'CdqF'AmMf-e#%"@M-p!`!rE%IRI-48c!,l" -,9ZJ3XK0B3$lRhilVJ(C'9IaJ[&ae*@)9Xc%D@bhE2X+['9DM*QFZ3$mG4fFLb!C -[d%mKa[&Nf"qd8$F)MbD5V8m6'!h2&"T(Y-[HAAi$Adji6$`f[p@)HR0A2"Re[&c -EXHHG0LIS8$qGl5H%4JeQiVTH)-+-p&jjCfX5l$5mlj54AY`l5!L@Qih5$Yrl'Pk -Q9k%U-LDdK6AeklC+Af"d3'Q-&C*"r9H`khb8kq5i1G6'6a"ifQJTAd64Sh`XHIH -AVd3FX@'[dp4!VjkfXIQaX@,9M-l0U%hN5EE84Z1D!k[93*Yfq-mrTBX'PA5A-kj -I&!4`M0Zp6HC$D3K,3UELb!iSf)'&P24#`FJ%VR2qekYB(hUkD4QZ"M%hqj-l83q -S%%e`Zp94i[Ue9%269K`")j1SYEd8S([El)*'9m)JD3kY-$[Qj0*JH"0eVV+,h!Q -U@!,M$(Y&9'DG-pcYZTKZb!iT&)9Vh'!(9MK`5!hV"K%&MMPBaL9'C1"&E8hqmje -HC#P!#%Y0MBc5A"Uef%I(#c2Bhj6m$rDCl$L)L1f1QBf+0a8-YkA%GEX3l23rDV8 -MY[h60ZZ-pkYATLBREfYLImlkJ@!N9$GdI15X`#BY#dk5pU2c3ATjQRGRrH%N#-9 -8VR90$R@JbPPL`H!8-aCeEHaSNJZThIl&Y-Ec[iXNGfEbXHiN!RTBf!K-NckC8qK -UI'3+qZY4c5[4CF)hjZE@6N9[L!4(p[`$SXkb(dA)2rl[H%PVV26#(a99Eb`Mq%1 -*LcBkc2'5%'3V,(`UlYA'I[%YQmb-5SL2d)15icBp29dQT5EDJjeAB(H3!$mU9'( -,DF0a[UPCPmf[4,5#@Ma9'N1D86#d(+DLAJ!Ged"NJ9#+pXP#+rV"!VX[E[BFNF* -BpCrY6r8b4fSD4fCchZD%-C'202hPP1jpEDMNbp(-(F*SA8E9hCHlbNb'iiEMN!" -SY!rfAm1FaLhHJbPF$K)f1pV[eLC!m9apKMV)XNr"1+je(5*c@a4&5YX21ED#'U` -LX'DYkN)diqFLi%d5`@ND(KiaLPBN6qehf&+MBihDl01`AS0BK'9"B%jl33eE$hY -`LVd9Shi%bV'G%f,dF8PI)(5Y9$H!(UG(h9`T$@Ade`K#MRlf2KRCYN6`L)&MJ4E -mSI1GVHU$YT2A5'iSMVA5l9BN8RC-3UE&%RdjlmXl#IVJ36)'&14hFf*k(002X3S -FRAamS(H!aa#iaBLD!0#P0F'$1ELb*feE*@qm6(2ILeHa58I3Ia"CU'3)lhmXjEe -0Bq8kMfAQ`+Q(KZ5jA2kmAZ10i2iF%mA0Vc(8$bbSeha6&CVf,IhN[Zd@`m9Kdqd -FP)pilSqN9i"dbEG*KREZ)f["8D#mQ8#XYS$HeqBZSM,LS[GY,hqJV3(Qrh9dE@Z -)ALmd1[4[FI"()Ye2Z&hDB@XXp+SeQT3pAS33H4E"iCXlD0&T++Mf,eRhC[$0RS4 -Rp6jM*'0Th)NpYCR@hB(FNTKXHK$L&`jS-QI'*m`Ur5efp*P!Yb!Lk1k#bk(ZdjQ -)U36!DA()GRfI3h[G-p$f,,CER4Np`qiEqYBr@d6ENXQJ(*q6)f"L+aU5E#K@f(@ -kaRp0d)51PeH5DB-lAGDkGq[6MK6m-J'-I%5E@jY'6EUa&[[LSXAG'PR,#i8eYX6 -j06PRE2dTi3PQj(@GkRpTV[RVGHS`mU&+l)Z+-KKaEXH84m1K2)VI&-Zhfkh@m3E -FfLcip*i1hm9CBY6qQSfT%jiLLEdBAV5E[YXNCM+)h`K&m0jDFX1'4@J@pkZ$E)" -q@BU+Ni6)L+03P4GH"!H+!$hCjr)'X1*!a@M`5"KaHcAe+G1)(NdGB9NX[QSfi#6 -L4AmT6H'pR(RA6Vkpd9A#-P$iL@c4"[RN-(CQ&8i!c!BTdf#+)Da5k+8(@aNGm'X -IX*qrFaGpZmrm"I5pe`2JE6Sh[A4MDP+Z3k@6l,aZd)F@5e`r1lBDf&f#G3EV+Ba -XiJKI@TZCL35X$ciC)JP*VA,$I%$ckm&$Ap28HX(&`VQYFkF)T6ASL+p9fX("#5N -eVI@,VfS2q1A'XqFlAqDd8MCGCT6H0T@MMU!pcBJq+'-Q2K6&kTVcbf!DMZqfhmd -4'85i'L'TTXNdhQC(Uk[3G3Ffb(&#[XNM!'$G3SYpTf$*`"Qp(ehj'i11Sh-'C@I -Dbjr#LE,fZ$&+A5U(iV5rq$KJb`Bqr@3"r0Jk5)qUVpccDE0B+l!CVSNe'#UcI!D -S$0R*&dm"J`@!R$$ANlZBbYecPB*B$pHj3L[Y&K8-[VrSjp+B-@9)lk1mPIM@%C! -!R`&&h"MN`IZ9EDB&aVK(B6Ke#C5YXq*8,M49[DM$P([hI0-4dXqjHfdC$45Hmei -&@eMV$9&+6qY93d0+dSTY8F)%G5jk(X96X1r*Q482V`!HY&@4IS2LhM,LkKUhGT0 -6Ulf@-Yj4"k!4qcepB*!!IAdM2k8ZXq@&ef@,Vmb+AYm0PbKGBF%51Y#*PFUYP%# -[r@IR5eTbX9b83i&j$RLNE1DQ$p(5H3!Z`k*'hqbD0SAQ0@!MDkRG5b9ZM6b`HA` -ri-qDkNm&qrZEi#m41aLSlkC9f@hQUBC+%**fZIB62KbXNqK',8Xda'lAhdeA,Rq -RdYV[J2M5FJim`IVS8&a(d3U)q%[YVecd$Xc,##P0a@CjI-p`QTBIYlaT5TN[%rS -mT2Hq--FfPf&V-P[0)D4"5+U2@U9,'C!!"NZe`I'(+ri6eVjAFYih@@-S,U0[9q@ -Hr4dr3ba3h'aj`AZFCabAQdiFI[TlqAS8&QL"+(50p!$F`D2&QpCTp-XJ(D5`Naj -*#Q&bVX`r&-pfJp@Yc%[Sq-,(HYLm8*5'EjM[NJbHRBN$BAhYGk2EUQqqldBTMV) -!rI`N,M&bG@"mRRdP@bViI+KSrXBShZ$H6NEZb"[H-+bBiL@c-D"DDJ#*cSZRa,` -@Ik#83cHiqr`I-p$!"X"@YJ0+DMm*H1Fa[QVDXAZMif4,[kEc0MKKmm`CXZ%3qmp -MIX[cX+pFiB!(Zkm[E0VerEU9JEi@2DKGI*5U@*NG(jA[[4cHKpe5Gq%"*3a%YFY --jjHdeQ,!5,l'KmHR)be-Lm,@q*!!JepD$LHk,R@AciA1L)C$(h!cb43IYJ[2U+Y -fJCM"2NF4HY8hT4ZVbHF$RCq-k3KCjY3+DVp@GSqM`BQrCJ618ABfTSZCF")(q2Z -fQPfV6)3GmY@VHP0,!!2Lf88@mMH'CK''2f1bGGKNQ-"dXCdc@KN&6d8ibDMU*b' -IC(@E(EKS[Y+HXbM&2AAY&L6PEJf%F$"J-R-PI@Vc+BhL3@G1-aXSN9(6c*B$%dF -[(!69Y&2EX-Dh-+6V%X9013Re-P5dc)I#(Np,Ga,l*Ghk")Uph`(,1jd8e694I9m -1j$$"9hDerIZ41i&k0%r2UPbae2@PhIi[Th5-0ABcD21Nf'J68G5hk9(c+,h*G[c -pYF5[4cd)D[MNHk$XTq!9cLCDpi*id1Dq22Lc4Hi$h#qPP#!$Y#,&$DS4!A#h63( -*P(mPQeI&S!eBYMbN#Kc)`-8YZVq%-qR$!+`+Hf@3!"$Zb1fH%KmD(cEpFZfkHGP --`$d1[i+a9(,Y0*!!!D**lIY`QmD`Fdeh*+Pep&P+$)*b%ErH[MGGcQaCkp(!!aA -8)DQ+S!2Z$aj*c6[D%"D3!-K5&D6S$M&X5,@B0Ip(L8)@J,!$EZH-4IP`UrD5c%0 -9hA)5fVN9Yb33"f$TPV483jGM%SfLG`i"-A)Q@LmM$``,T@h!C0r2$Gba)3q[9fk -3!&kU0Br-fMSISK+T&id&J(-R)j,fECe#%iQDGhf&qQZmha2,h8Gf4qXq8X8)`p, -"0BU,04rP*$!DeMH"ZEkkK$$88YT5$&P0e%,ZlBj,ZQIR'E!&qC!!QK1TQF5K#Sp -Q(HYCLj2@NAE#(MF8'f924E6e8jE"(@QEZaUq$pIFijq[D##k'Mp"0I$mTc+m6C, -*PGB`!L@0!8q([Fhc8!-%q[RIFHeFZSf@&242@I2q)#Udh2R'IVmm8B3D&1BDLf+ -)FT5I'+Dcj(mmejQ*`QfPiNlSMLThdFJ!UjkL"@)MjI@#m12USZEFEU'HdKJXe(- -c@1G*ZBT4J-cP&,XiLLE!9*SABVeH``$PI99KU$Mc(50#@Z#(fKD`j&NAj(pFjB6 -pBj1aE!rf#mYDMAX,ha4@`3T(b9@3!183De68j9M@[`p@%UE-Bi"0D2h0j+*HbIY -'(2L%J9F%cTGcb&PkheT#NM+9Hh&6C9+Q3*jbAShH@U(kU8ic-DU9Fi4+e9"3KpZ -lf(R!PLBKHC!!5aK,FqZ(L1l,q3--ce2bCkpMSfFS3rYTQPcrc2J0I9LiHf"CHe1 --6KF"'AC#NJlpiDA+I(qHZVP!(34eR'QIKjNU&f!dRe#q%,$b4fb"haq,"1i2Ed- -Q"0NJBEMYbU@!+Ur&L0'&!"Qjac,$@I4aG(jUk3U+JCYm0Jp11Z#h#IHm$)T+0Xb --C@m5`9Z&("dQI)F,[BRPX#KJV5l`4@i-F-([jX9XR`RlcK-DhQBL,D09+c83%(Y -Bbr+9(&5e6Xh*H[KI)+Q9X6(9M@Kjc!mIPDKd*('aKm*)cq)m%3KY3mi4`1jacHc -25EA9CJfEM8FFEmIaH423T+LX)3bdPYR6Cp!9ac0S'DR0QN@VC8)qk!SS#+DpVT' -FiZkVd-pK@2NRNjaXKf63C`@c[X6Fe)H&B5b`iB+N*ph8#rSSqA5iTMM3BpcBImp -C#bDEV-Za@*XK,dlAFj!!TXe,Db*NYlQRaS544#`a8l(e6FZ!$95SbCp1kG'Ce96 -VZjSLZiHa%*S5rT'k%ULIBE6S(AHZS5+mJ(DTiGFbA%K$1q%%`ZVaFe40!SI"M5Y -"HGU(S(AY`U)&U6XfJchUb!HEJEkQ5UYK85pRRU$3`&bEP@DUD03)LNaj!Rq@f(@ -IX$c0i$he#M#Nf(+#rX[9JD@bK*I*-G#pf(&&5f'rMD@29*0L5`Sc2ELrKTpP'T! -!0FBRXl4rUY&TN`'3!*pl3HjR&@hBHB'*ZTQ8U0Ek1VJU4JS'`lKj8hYIc,*fH-Y -IIC[,2%Dd9hM(h[8AAZk(6lFa9b%kR%1CMU(kX5P3h(L@B33miTYB9a#X2'G*`hV -Z5rbb,Gh@d9@P@Y@XVL6f"6!femcT5fmYpr2qlGbH[%B$8X,mfC%"JM,*6XV4eF# -,pNSRkiH@T4(K$4STQM"6PZi0V)!D*k*@BYDaALFd1`FCP01LUkFGlDJACYVBfMC -KfdUkmbHP"68Vc(G1dqNb'U`8b')kk)UI"Rbr1lR'd2mTa*+!eB*$M,((ab*R6I, -hIENAm8i`r!#PN!3"!!""!!#dSDNkY-HdE!!!(`#3!dj(!*!$FJ!4[0d!!@3N!!! -B*`#3"!m!9'0XBA"`E'9cBh*TF(3Zci!!!*Hm68e3FN0A588"!*!2J!#3"d,"e*[ -NQ5PPB(k"b!MVQ3Um6kV5IVS@9jdaTUYQBIBJ9jD'%2H3!'1(cUbG-d3198EqHdH -"Y&"%+@Ye[BDJSH01*!'D9,5KK"dLDYe+cfkNj24GLGRILEbR9qCAa(C#"m"j4Jp -R8bA,%$8I2(CE8Idk"+3-rLX(B')(if+Dhm&VY8AQ%GK[4A[hCE`U6h--hdG(b9[ -RL(Hk%CFGY2K@dKhDDmD6V[#X#8)%%pH)&D%6"4MY@TAh2,S,9`T"Ef*8@2+`0-L -'YpTY[VVd,*D6T"I)*be"$efIb9m92Uk*E'mJ8c1PG32REY,-p2T%p,14U+UfS,H -UU'AI+F83'QqZiHN!&[icIE1Ai1ZAD)q91ce*0%!6QYHhS[hYr&Me6qA944RpXac -%P"PJ-KYD+$ESM*EMlU28H5Gf6k6rr+"9((G62AU)Z9+UrJ!RXU)$QdB$S-de6HS -(T1,*@ccJU@,ejq)Zm4(!ENa842hfHAC+2&h-DVSBT`m9U%dJmIchAH9AQSGeJ$% -1qZS,+hH3!0-$((JLDPHJNPq[ST1[iXlUBQ!eS)eXfRB@C$2H"pK&,3e9G-cjaUR -A6SbY4QcG22`e2am*9##l"4UVU5iTJ2YckHYDPc(0%TMNf5DMak1VfN0Q'N"L*UH -N(Ce0-6me95J!,&-Y+XEQCS$PH[bk&IC%3&)q@hlc8CS0H$'rM'Xqc9IHrbB`0iP -I%b5&#`5dTiJm56MXMG6'a%R+f'%$hGh0iQdfYS!cfKILrP5H'6HhmE$9NFq%aYU -bTTQfFD[2SN%4Q!U5beN,@IfGU'A+%1BaXpf)5@T408Rj`dr1kKN54CJl1bNe,DU -VC6!$*'ece*($8MC#pRcr#@@r"hJX)`NC3m!Hee(p4c"Q'Hjlhq"hY2Z"'Hl$5Md -@kG9U$K,f)*FC$Q3F#IY!)IeG,l!Q,,UqUkc*U-1,l5a@M1-p9[62Gd9I+!59Z1B -AVlp%4-)Vp'(Xb---"rkV&NX+GpYp*#d%3)RM9qa(#EZYFq-kiTTXdA[9PV*qQQ1 -Ud,1r+$2*G)QR3hfJ2c![ih'bVF2!EC!!M*l5,mR&&XAdF%G1ATeeYSjH8[S$(Q1 -pILG[,RahqL%8rdj$E%PlA1XqK1%$Nh!(h-q2r!"[4H`A0lhBL84`K0'i+U`+BEI -ThkI),TNB8I-rV!a*V#(M,h4j"-efc`3K$REe0ch8*dP3*mc@kV84pFKMr'JS+MH -2Q5-*"G#iG#1AG2,9Ib1q,J$"A%!S#NFp`1T#"Jk(*'0F%@qPFAj$iUl6&Y#K")a -Y6IY-j&)k09ChAf*crUHRQL*IqbB2UXMbfpk6IUpU!+HjlUX#,-(la'`!FEN&8Rr -UUaGfb69YRhq6%-mM#G@8#Vd+pF6,`C-LrqLbfM&@GiUeNK#**)K[qQI9Yd%bA,, -f%cX!H3[rbJL,A$JGEZ4"S!(#b*qJ+hYTTj`lVj`4JXhDdj0Zl"&3V*-4d8MaJYd -`G&6ZcelfT84Aq2@1R@$@ZBU5(1&ecQ8j+q+)),HKldD*jBGcfJS8aEH1BaE(MFB -BXHBXM)d-TFN)%UYkHDdkR[j"@PTFI1VbH5*CYVeTd9,hG`#Q`q1((1-mUEE5XJ& -f8ri$kmB,kYBLY(C[U`RbM4(#Y-[qeFh#[[8Vf"'dpX2a1PTSFDhp[IhSJdDI[bY -R0eId+$@C[-&C9#!+"dC6JbL()M`"mCairBS,Mj+Mp$SeL43#LpYqENCPT*G)bUc -iVUhS*S8e)8LAA5I&5SUf[iTV'bpdi35Hf)i0ME!j$rK8m$Jl0r9mh[4DrYb[BDF -e+fic2bVJ#*1TXBQXj(i@0G![-%[aBEZiEjMPGj@eDPCdEalb[*k2`TB$l4S`0SQ -P1S39[VQQ)Zkc-Y"H"UpDKG!TD8dhA06E1kChFV0UcV8Jq*j@45bPe$P0eB@9Hcj -81dM&$mXLjeJ,kQeP+14Ji1L`fkC5%GZ!FC%@Icf@i)AK(Rb!a9Ehp@%"XK-kc(X -L'5$9pH&SfkI#dVVZ(8Qb"5dVMbMDJG(1H(#j$V+Q(J)E3ViQ['(,c&qe'QmQpP4 -91%iH!UYAF#[&lY$U"Z%NJPrQSpLK2+&Q+L9c$QcNPmScR2h98Xk(50pHmSV4dIl -CNHPkL-FZ&BXmG@I8'4#iEkIj!qb5cZaDlLc)QcbrjLHKMedPm+hqBNf!8pf&([A -PX'YHRB%8[#`G1i83&ITF$YP3a14(GF0ZB*F%#6Ya&$pV+r`Jj`,dLU66,$*dVac -0Td%l%*q0YeJ+Kd'`Hh*jjZQQU,G2RK%DAHM[Y(h!YRaeiVb'$Kh6K"#JTl4ar2B -8aU3fe**0+Ip"2N,*da-@C+dfj@598XHf!*j9+Ld`KEEZh""b1K3L@h`bl#FKq)R -(CZfhY)AleH!Vk5Pd$h3XE3)Ca8HDiFQlmE*)UG6IlB%iK#lcrZjelh(U)LQPYAD -`,FL!rpI8%CaHj%Ec$PqEJh$cBZXPmMZ-@E8#ZE*qEJT!!pKQILQ4NlaKJGF'Gc& --#CarG52li)CIjmBSMjLq03*9C4,8[kNR6"G35UYN8hL42jadU%m3%mCm'maD[T@ -*NkfiIe4A4f#lE5afLpZCf1H8DVq0KGm"m58d`ClCV&H#3Y`B-GIB9i-(,EQ`L9m -%8[F#-4TGb#`288q1!H!8AR0J+YiTjdpL)5"+Kq6&r%[[pLq@r@2k6!apk6BQpFD -*,(a-9ed2cS1S1*rVRd[PlhG1"%SadSCGM84&kChh%3NSrP234i-RIUfS!R1CK%! -FYN`LBMUUDrYIAC65C9,q+%3PY,%-pCTP3[UND@5jl4fCJ'''A(pIJaMTaLK2VZ+ -T-+I#ld-3bk4GTQil4C(8S(BQ&J&22,VHme-Kk*e+%kAMRE!VJ@hRBP4Fd'hLr+G -q$2j`3#ZrIfhS93R+cSPbKTI-"#e*NLG0fj5lh`C!iJr!AKmAjpY`K2D+53KlI8Q -2NQC62kqCXcFG!3am0!NNUY90H&m1qfXQa+)@'b,mNBpa28edf81U[)cJU@,!Q62 -($0fm+3G8JSD9+aYj0Icf%k,e#lFiYDVM@8U%0m$&#r*JarJU0-Q(2["f$i49-5R -He@)&HfRXbqZLrYi#q6i%RhELmIpR#RpmVNLhVPA+EcPIjJ1-(p$qRJ2cl@Qe6&p -j095T5mV@ADB!'qd9Gb'If#D[9#BMll)[PD-rA324+eYNaV'GD[UIAJHRY(bk6Jm -b-Q1amcLep4XiI'D`GP26PXJZ1T9i(6f!RKN$hJ*D"1KL&2ALkXAMmaR),$k"Q2f -"E`a,8fK'b')9HAe4*-#'$#UAXSDjkNMMdqV+MM0kqf9(cQ#cZK#[[G,T"0M2IX` -P#l4XMJX'`rRdlX-2V`D-2KA-%"@"(5qG'8,k4DB[JqIQKDbU'i#4GLLZDKdIP+b -IMaMEGPPUU#4"6[GbVlIIH6%b`e16Kj,a5GP,hMp9@pdm*r!'6Xme*&XiJEAR"Bq -jc4Ui9mYUVAP3Rji#'$B52A@SEDD,jAMGrT91&C4-`Kp#IAY*(8LLbl5!3)e14cf -Y!I%DMR$)Q,H,Pi`RCr%HhC43`d19KfRhqeIh!!a"8TD0iGe2(c-b%FlDFlZUCrS -(DKXikM4Pm%SmLk58ch-$G*kU(-P-m!Iaf6GEhd5bf#3#2cj#&rI(&9,adJN+Yqf -8P)`HSh$[NlTTJ$C,r-+qY4*MC('QYeG6(6&(@,@l%-M29"P(beF0R)XjS#TYUhc -ZZp#)m-e@X)Z9k6#R")L)'lm0@c(jY)16,5'$e#3lRjI#N`%GA1AGr0DMf"-))m@ -'h,2(RJ2f"eIHV!)JCk,+VXQrak&9*H)5S98kaTcjXSRPE-4e`pR6446FJY*irIL -)YhLcGP(JGeV2i,B[YeD2,bql[U*UVELf#RIPX[X*b6I(laEQL1#cHq&f`*fhK9I -Fi-N-Lp"ZaIJTL&1)j6iKlbZJFUfb8ikA)Q-'FflQCGJT66p-2j`!N!$*RdE#K%, -4SXVVEfcUJM8fa3fBHaeCj@)#+6@Gi03*`#p6#M""26`eI-mLaN,S8lYpB$YY[*Y -YeY-Vi*Qj@4r,FL2eN`4`[VFF(d6lX4hqUmL-fN6&[!p#G)D)RUbX"f'r$pPLVLe -8i`l5SE)A'lfM,)Q[)0G+#r#8H#Y[BEJh$&!+9*U(8*R*i%9)E+N8rb5@J`66)Sr -0V,U$XJaF2Eh90aKBmPY'M-)C*(UF[[e'6LP5PJMkJhq(e"b$j0)&rlch@"rNJ(U -$q8lGU!%,aI4NMG2)'+CLlKT-VX63k6+`+I`dpUrE80@L(Z0r2C%5r!XTqmV"!eH -dd+,-!kB-Jl'HJ!'$%J,B$!j2i04RYbEa2MKP4%"TH4lR,cV5ZFb2HmGl!-IPI*c -+4d6kN!$&P+XkCeiMMD!M+mIK)@mRZC[F&`9%5RSGHLYS'b3KVjQeb(R205!)R1` -prcp)2U)Z)CHaIilL#+bX(NLDf#kX#,&6#dX&0IHTAM"X6@e@4VXTJH"TIa&@kV+ -E2@kRcH2,fN%0!3l9N!"X%RPrT*CI*fe-NLR@r4"cIk9"-,qPme,bHNC,XRVEB&5 --ehG0J+rI92X(V2Qk6ZD+NI59Eh(L*`-ETcl03[hQDiF@[AbYJ9lhm6p'mQ)m%82 -Q%RJ*[D5BUZ4Y'Dakc&HRmMb3!-,1Q,aL6rp"h00,%-r!5%BU'ET-NAIT206NR5G -fb8Y5Q5eQRaq$Rh#TH!C$GjEe!HB3jfZZee0dX%f@56aNpCi-l(P2XCp"mkQ3!*' -1%C4)%[F3Fph9@%P`Mal5lGrCU"16F$(3)LJ!Q+bH1@kC0**A[IZIp!Zb)Brj$cd -D&#bdepmjQNViC@(J9RdGb"Jd+Sb,IR&CK&V%B+ijfTfa-ZV*Uj,aaRNm3"@iU'Z -aCrQRlhFBjf-81C8R'1fJiGHN&N,EI266)UaQQ)qYZi"DQ&Mec``DjL$6m"j"Le+ -(hV&iL,$Zf!3dr4DiQ54NrG*2[%11R4X3,8+FNh4e*-cFI(RK+$#lj90B@640#Tm -J`dm+EQK%TP(ca*CD!R"[[p0I')1RA"lCMQT!C%UJRY,eSa!NZp$!S1+Ekql@c!B -!HfaQA`UM*ZjiUj96DIB&D`lm0"@M4qp4@`+'rbI2f`3Dp!EB"KmmD#&Kc9FkrP5 -Z2K&(-[V$)ll![q!rKD%Q%H*pZICBrLTe'CJQ)ZPF$0lkr%PF4Zc%NU+9ETj0*qH -4le,*HQBXPNDii'M&1)0)qh!hJJ"0GPa2rFh5CZqS(l3!j4GeJUqfG4a3@h,f9TS -C*R`F9U"&p&0*Sh68G,56pIjA[aXKPM6q1rUVpL`,S@k!$[`kD#3Im1@V+@9MF9K -+!C,@&&QEdX,mhep--PaRZA31$K[P2q`LEk*B#Kl6QdYMfYK531iiaCT!,'cIR3# -C4+'dJa[F4CSacKI5QG&8Dl8aHPr8h8Sr-4Q)E%!102R4X8f!mm8Jf#U5mY6&6") -M[%rfHiccSLk1pTG%NSl9`TL80Pbh'aUa*id"%!q8!R9-@pUj00I`CG,"Cbm5-r1 -4QJ,29pV6*hkSDU#M5UaT8Yba!G[@GBZppRQ9PePPHUK%rkZEfJUrLQGEX"B,H10 -Cc8MVpKT&l--aH#6R"Q#3!!,CZrS#@D[rQP2FrmaV8@cccAjh3jpm'c0`,meXfcM -JeRI*q,I&)km64(jYN[SBbIqcJqU9aLNF1%h2I(3L4kT,Nk8Y2X5Lh,8rk*d!PbM -*i#[MZ9!%#6VYCq*P8G[M!B"rBU!hqY[hfd)8hl9)!fAc#aYkS-Y-ZT86l-BTm%9 -hK!ld6,AB1CP[A)4*%83RL)6pF4Ch0Q)#&,LV6DIcQji-a,R,F,Hajar'fp%82eE -H51-dQCETH'(aJl8M-LHLSX-2lHHS-+J(Im+i0iX`TC[+3Rp)lZ2b[b"NNQFD9)8 -53aLiA1jGXT!!BddLX#+GR3i"T*@$!2Z9jF"6#+r5V-FD[1ii+Ic`Cb3YM8bcECC -6+bY"%[Sc`9aG&4SIBh)Kki#[jX#TI6M0q[XQdi'-&@Y0Zqi$&@1@qDbPjc#(C!E -*RmF+I""!2Qq&LA#A'0,LEQfCL-)fK+TR5K`UN5b*Vr0m8%aTXqXN(m5pTj4'fra -V)PR`epJHMaqaT!5FFUTrkEX(b`kAmDj+6P3JTH`C6p6,JqMUQR3"P&aZSC-pB)R -%L)LV$Aj,riCVJd6UdJ!$SmVH1cQGBDDLc'(ZNFpU@b2PXE-K[@9N%RVE@BDKKp8 -jA"L[,QS')eDC*@$",J3C'q)S-RI%j`@CKekRN9XCj(ZSJi5dVKM-20#D3fShS5Z -c4(rd0lZ,6aHIM%f$HX'+FeGfj6FRG6&&QBl$YeDrV4ZFrpHBANXA-ZHD1$4PdH@ -8H38*RG%i@i3Ver)Tr4XV!Q'J!,9qVqe!!h1C9-fa6'#JL!6XRJpTB@pc+Nkc!Qd -QIbrVcbqlfFjRQ`#2p`6rSf(0YRB(29@a(e3jH`pS[a"5+blaH!k3!+JrRRCamFB -BC(U1VaAa+4dP&LLl+4-!2K!1-!rmd3*qR`i%L+EYQ$bccmjEJf9*K[9MFX&E9K[ -18UicamTB,8k!F,$AG+4#GRTH&+fLTMbQ[$akjB'KQ90!4+cSDE8TCTJ,G"dQjeP -Fdh[**dre54q%fi2*@A*[k@RQCapGpMc0P+6$caTc[S)2dhMRpm)"PfLR*Xc2EF& -9m#lecBLNi'b+U#&0c"`!SV59TD*'))9dC,cP)dq`#irkN!"m9Z8eeP,PHER*Uq4 -Y-22V33Q99"dN"CpcB,0&KI'VZ&h[C05-!reF'QJ$+l[4MYaFa1[U[Ji,L)'rZBM -L(Xb`BX8`I&9YhI8hZC8Qp(@SD+MqEQUSUCpcETVP4IE[DRaE$+13!(&G#83kM0G -c"R'%R0AT!lGRADL+V-BrV*r(ipiHFJY1(KmN61aQ`Yi3bdi6FrEakmfP$8hDd4m -Y64"bZ$(R19%Tcc)YKE-V)UP)PFiC81"ZFC6TLKlp#C[MXSG+SFMAV1Z'%8630EQ -*U9Mh5GDc2!04b,NB&V1V)0LkF'0E9aEZDl0k$EUm!PJN1S#KN!$L-X`U04TVe2M -'R'020"!eq0Fe6rh6XdMB$!L#$PDE5U4(CGq[Amjm6k9JQHfV"&*1U5iR261,8PX -HLjQejH%I8j!!F[(h5(V(Aad6e4AfA#GGNr*0XDM(-XUPZlR+[,a%`@3hR4#[6,@ -"hJSRpMb$4H+Ap)&cl$$DL[UGU$p3@6@-9BEZ(A@U4Ni"(kYLH'a(V@Y$%TEjI8P -HXGfRQ)FL0T3(-12)@C,$(rbd1BF'b13F1hEV)Sk!(l)BpLGJkT[S'%iDN3CVLa0 -3jpM8SMQH$T8r+i$ec,K8d``(q"D9'YT!Le*EUJDMrf2)K8d#%raE%iL[Ra90AZa -c9Fi*YDIZ@c3XhM)VQA3[9bbaDjS9*JQLiJ2iTTrmcMDT8[TkG&!)!bHr[fTePi* -P3KdJL%b$12m(+F0h$cU@Hi&khQAi#+Q#UBd#9d5X38jPC#CL%iIT8MJc,%LihdP -B"lXC#5SM+Qc+BQa&K)jpcGBY+!66,KbhmeD1aQ[&dTbTbD4Ub3T([MD20KmL`K' --AP[bFjm6$`YIP`G-3aQRiCk8N!!ce0"D30#,aZCMcIY$IE2K$QPXXI1*r$#Dlmm -dVrK`@JpAq%0'29RKlG3D&bIfI$AVK0Rb"0G5DV[a"krQm)3Nl2V+mV()m",T"j! -!j8DY$pN4P2S8I4ZZAh6I8TU'dZ@N#*-DrFIXEI&k'2[""!%5'0qe%J6B9FV13cG -8Rdf0-ii#Um,$FU54l+mCp2$24Y&MmqhDRIXNlFUb[(I#B$Qh+*'PBfQXli,qCSm -M`!TJ99F1ck15eLf@QI(E0eN+A#ZG!BFBhBbr"AKPfY'YA"GEFkJJ[54FUB&`jP$ -hC$Pil!SArkF@-QM1P[fJ!Me)Q"DmZFNqfTFSDECk(GA)3CKD5'm0KY(AY)HJmmU -P5G$rFD`Z`S'-U1q5qZm-$F,fkNQRRZ9a$"lFSaTKikR86hQdd#N[F5B3Ba&26GG -%j6cLjGK*)a)T0$Yd130a4qXTI`BrI`5ifqk`!hLQfhZMM4Trq%$l"921q00QH9V -2&VH6L3,4Si)XZ2jlrcINL2b9d@@maDJ(1GE$lmR*)kpQf2Y'UQUpfdPa`VGZKk# -RiQF[Z$+Tf+XZ"PMKrclZQqX0c%r*#2YPcN5b+clJEi[C9MZb`#ES,0mL&*rU#*I -V#6KM-AUVHE%SLj)qJ#2CM3"9"!VCa&DCaLU*$Z9i54XT99Q5&Y3*'X@PT$@iZI) -9Qd)!TC!%!3!!2`!!Y+'MYV6(Y'%!!$@l!!##NJ#3!h)!$e(4!!0UM`!!-qJ!N!3 -2!&4ME%aTBR*KFQPPFbl2J!!!Pla069"b3eG*43%!N!q!!*!(3X(8i[Ll,+1JY&J -'afJB[4rBRPmle+j!mC!!&r@qkkE0`!2"AS94-8UC`0DdB5ZPDZ#,Zr4V%6$1%f! -RTHLph1C(aL-T3q*h8JC83H+M`C9c'q"i)Zki56+3!$S%drKB"ZDFG0NU39(fX-e -1YU1L@+U[-0C*%'8hQSNPc[85M&*cqY4'HbZiQ4P,E9mYFq1Cfre-b1QYr2SHE5P -KDQ-rM&Q-ULC"$VSYBqd),N0rQ)``+QXK'(VU"S(NRr!`!J0d-)S6bbcY1R52Nm4 -[qLN5%CL9M`P)!'KA3KU%(#lKfcQlE)`m2V8p'%k'BGVd-3r3#00IbMpUE"d"L+d -3"kJM+VK+YdY"fD5RLZpFTaZEqU%QHj8JDmAXh-8mUkrQZH$ki#'+X*83LjDQr3h -5DI6KDMhlF6d1LJm6'4dj'M`k&J'aC#rh5"kl@hdKE`3XIE)-DR`M'dfDCE-51i[ -"NmVKR8@j4PS@e6FLSChHUrKIhIqq%Vp2[(aT2m`RcTGBGfrb8&4F$c[+BeM3p$M -(!pM@apV-XR29RV*,i56!*S9RS"i4l@mj1j3qTZV#0B)[Q1E&)`,"CA"V3-I@XXb -H1LJCbIkp3Cl5PIGlArjRMRa-5h9NLeUGG@@ANBXqcNBZ3Y0VNElLa(AYLp*26(& -bMciBqFJH(&E,&FljjB3!BFqMekDIf"X9XBYE1+h56ehj&YP*25+iMpF$b!piVRc -%b[0hh8GPN6cCbCXIp61bRD4kF1LKLri-`*EfUpd6T,(%rI"(PD8,rJTS2d'3!*- -dHRpAaZIpCi3@RHP5TpbU,UCK!!+Z-($"5TK6Ur5IMJLAiRcmGJjV@(jP@mab"'d -%qLm`@B6UckMl2+mN6EZMpijUL65k#*3F6903bDUJU`YHa4PM4JX-i2h--e)q1R( -,6T-&V[fRka&B6I9AVHS-%mm(&QNCGXN6-ibIK")-8X6I1l6fK`M@Ldpldr5+'T9 -2R0a%5pCAP5-YG*KrVq5#,ZQ'YJ'ZB'"!mXCBN!!L*+aKqREM$Ik+Llj3TPG9BZE -dABqi(1k"mRp28!R64XlVT"H%0R)9KqT!5MR9b`VYfla"5pmHpQ)--VkXfMEeLKX -5*cT*DNX!&KpXek-k4"ALVK,"9eikJT2Ne!V)+Yq-eF*[SX[0BSf"+GYCDYK5H&B -cTiJp)0cpf$"jPf`!MTq@Fd`+*p&80EMX4h2JX&C#m*IkADa0(8)MX5"eqDl+J)" -Mq*(JG4kJM1r+0+l"qJHCS)-"SN31PK088Dc*!4K'kPQBJ9@%fQ-l0'l*'@jr,dC -6Ei669Lh#P`PdY'jH#qb'X%q!@dqN`)41)Mk8'Zfk-DJjhFhJUe(9!ccR(b3l!5# -[jfp#SGrU0*YF(`if9aUfTHe&LjA4)6ihU#-5CX"b[5HeUQike0&Hr56i"Hj%%&E -l!YK431Q"3ZhE,E)Rb-Up-(Nr*m&CJVZ9D9&F3"C#keR0f8IEkT5Z**fQP@F4VN* -%Ymaq*1PNElGPp#THq[f`JiD[+C3X"m11)`*XifMaQG5YplEjPUHMplY[JJ9)f9X -K4"U,Mjdp2i),heaZ(3IeDGfZhk"p)#YIX*YBf(`kRF!GVemc`DCViZ+l9EfFLZj -KNfMSZZqXRcjYDGrcDSSqM2G'YP6RXRfc'N2H#&&h,m$-!ekq9ZGVaA!"a)`@ad@ -+4N6FX4jUaIfGYRr6jB+Kr8if"N%FEZb"FmUEI(3e8C@@-&"pLYi1XX1@k6-idDm -*bYEN$J#QED6[B#VR8efZC(8T21Pk9hlY$9c+UlbfU2-Fc`d43QeD%m!CrL9QblD -F@U25%T%H!(cHhEaLa`3b!HkX$I-II2-Ze-QeXrYG[&q8jff3!%`+"p6i8j!!Y)! -ae4H,B#R"(LjiKL%6"KX-P`1Q3c0&QQ6"M4B`#02PqAZ'PR*j"KCGlDQXcX*pfm2 -5!25rKDB+d,,N"GDGRj4R`"K6EBRrRaj+aR("q$%pZRr65j6D8Hcid&l+iTNj"AR -l!DR#'V+ejc!S'J#rF!!'Ar%p2p%ljY0j%HJFR%5N53J#hF+(Smh)KKD9L6VCq&5 -[8eA%%'5k0E,9#UR3c(jMD6Bpr9m2*18jeAkclNa(d)DRF"+d)dmRS)lV,#)$8HY -%9L0[b5-"rPrrSkk+ER,LUNT91M6LP!*[35#XVKJN'Np[5l)+[!dGXK4$Z5UrL90 -'9Y$YjUP@mT%Gafjf,0hQA$8H!p5%$Q%)cbRip"JdJc1TCq"K+aGD8M5SUV**D+! -BG#-"ERZ'[,r+A%Z1RP$f$bSPRj["HE+&Fj[#r`Iq@P*90pKc+kqf$ICh2A),c6d -Za16Zl'c"Kc&ec@#LSbrh"Hb(82l+"G6(a,S[BJ0%091iYB8X8ND*Mje,@$GfC$Z -*ZA"'KAlRh@cIPd6BTPamUYFS(bE(lBU1TpATeGfp"AZla&IIF9AXVUYpKVjRdXD -+`PGdFl2@ISA8rkLReqY*E"66mY,fr6V6YR&!)cCj1baGK5Ni65dP!#N%jkbDk'X -cP8H0l05Sq-k!9KEFUB&+Ee6K3!"+#&Bc5QD0L1Q'U%r@MB8"A[GBcV029pAA09e -CPRp15Gi8q`%-,Kc%3YXT4$k5M,&PG#j0$XBSYBC#II&rHGTbRUPM54fA,4p("3i -UpiQ-[N5$pX!E@9J)8!k2LED2%Q@U2JC'E`V9"XkAdY31Y3lqeRd(5`!`#KiqAKT -iXXi+ESFrEif%BRG3J2SI4V$J3fBMH''ke5q$KDhEC+Y(9Tp$)Q(Fb1f`f)"604" -k!MDNh28k,,N`)*eEGCc-(Gl-I%RBY+T3Gc,KTJe[Iq9+YY4L$%UcFHh!`A9fPYb -[BJNA4T9hdY8$XIQY4M6"Qf9Vl"qq6P4I[kCCAb9lV6$FCZ$fN!#i$%UHK$#K&9M -F-DqbQrZ0L,,hp%HVf5B1``ffI%PG0)NPk44,G6VNe5TqA#YJHGhm9H!J-cH3!*& -I-3Qkf))Ve,YXFpDC-53Xr*0i3dL8AJHQB!mP&ASFQ9[hTc`j2)4C$m0G#bhUHTZ -*M)lMk*EEG6[UN@LCm'+A%,`3p&B8TdiJc)3l3@1@SmdEGq++1"T@SlFlN56Q*8@ -1`60,lF,BEV+BFXlM'c3Yejf4Z`p-!rG+a*68,f%`'N`q65mmR[A[j!49B+ESP") -2rGJMM*0Aa"5ehPR8m5+@)ZmBUhdRI*8&pj1hU6)+0%NVP2K#JDV'Pa!eZM))f4, -PD0"R+8hJMHM6$'$5@N16KALdIZ2"INGSpTk)ZL8ZTJ`hh50@8$2LK1$2aC@ePdp -M99Qm!*pB[ZC9pSa,Tbq90BRPd2(Zb)h!#RXKBqBcm90-kXk2Npd[4B501A%KAeV -$CT0-P)R0Yk#`$$)Q8f4rSU,l'B*,l"G(Ec'K#01#)U'!kk0k'!V-i'RZjNek&L5 -P*,K4+YYFCdjX5*mQ&,,8VR'&L,%ppe*lYRP4pkA1b,'!SZ3UQd"S+8@Jl!iUqR4 -qBX-`#EAKj9lCY6409%!3mXUM,*',4'1ad*Eb&-BEdPZReBFU4qZ'I4Baq0Y2caB -AYEGHkRQ1JV-4C$i8ZR6dp1('pXdC5M8&hCeHUhAamFKk2rSZj)IfhDV`DKGb'1j -"PF0qF[2cPJ@UE1YI@Y%hkS&&#$&#kR)@fhYDV!URT"P988"TpMr@S[3pAQ+1*$0 -kR1UCpkcR`FK5'%k@#T91"m+Dmq0("UmYhk&f$ZkV8`H,3T[YEGPGZ3JDMZ3%`#j -5pQ1-9BNS'Af*1Z83"3'l')`41TUb@-0&h#T@De!jrb52QAiMT9,!i*Q#0G@%99- -%,5'Al$AT&[a8KEH)abq[Nbk6r-M**JPjUKXTA`XYe(Z%2jTVNkG95U3Z-5ACM'E -aV"j)SZMrpZRip)H63Y-@G@89frDM3qG5B$,QEETh9T[SZmV"d+mee[BYS9KTi)J -[@`qM!2eqJZZ9)I5LN4@L3EiXrUZ)k[T'3lIJ1Nj1%@X5[@Z$diEiR)V@4QA(jMN -R+AY1h03Ca0[F`hEpFj4'r#G4M6aB3Bdp'8&I"&[RK)X&R3J90CG-4C!!2`C66pG -U'+j1+$B0(j%1jeQflN`Bp2F8GL880i'H4#jR!lSGF38miV``l)'56Mc4-k*`2%% -a3&DV$Ib0&Z$9QmN6Y)*$`qMQc8[FipGpL[ENE8Beh#NFC3(iCmEfB*iC8UP2IE! -(LYc5aP-9pd+F`QS!j3'hdJS"0"A%S33%Nfa1QS0BKk(hip(Z4rdNkUqY9ddehA& -X'q@20"lJVBK"0M`Cik1%*)MVFC0'6A6GVL6E!ZRr3c)T[pe#*-BqZi+F"F`#Q&@ -$qD&4e2)YfBH"kCBrXZ0JUef2Fi8p5P8(4E8T0-C#d[#eC(1EANVjk1cLFmU,GfY -RrY*K'"jT@1(a6L2SiUrRl8DPHJ*cJ*GdSpiAj)2N5U[-,9)X@5"IfZF)!!Xe15A -"U0j(F8SG5Z(a-I6Tf3!j4H6MIi02LALcY@G[JII1%'1Xl@#rqqK!3JFcJR[R0*D -I,EdH[F-0VY6$Ja!L)brY2`U66e-6f#RFDrlU-I8X9(#94&EeGfD#V&UpTqIM9#3 -RZQpr#3Xa,LK(L#C`9b(FFLX1P@b59'IH+FJKQY%fVZ8*95I-[ZGiir4L`4#YA'@ -0rN#%"LJ2B[T6+LT9i"!c%iqfrPh9+%M9-83)beV#CF(RN!!CrqBqTchRcHNmCTf -f"@Qi-5m+0V#Nl+C4[0ZZ9-dXCeE$"SjqZ)`Y`5AcE!Z(1ElUKKrfVbB+b`'K,3h -NUSMfT[*KYI'h[8#4Xq`1[Cc*48R"@l+jkqj2E!B4H+bIT`)9aX5eFX(kNjK4F2H -TGd5rb+ikf"SA#j66V2pa8iFP-fQ&!B[FkLHd#G)Z)GU-Jh#NNefMj1"SbFUVMe! -aCcQjL1kkKEAS,qmAc$hBr-[R#GQ&[KQ$McIG6Q8#q9h)#GV(@a2'fTN0"2UrRUK -(Ya8YhVX4",YQRqh[RX$FZY#6[4Y0`5QYMj2*T,3C9Q0E@8MPG2,EhCd5MXSe%`! -&%"D$CTqCY'hla0Z,1*!!GQS#fEiNbR)IVMjCla-GD(A)k*e-pVc6Pcr#d&9Ldc@ -E-#6m[k9UP@LB`%he'R*IGe#qc1YaBAa)R(Aeb@bbZ#lm&"FF&lC0)0-c$+fG4e[ -R2Gl**+L"q+*JmQe1G[LGkNCp9RNee2*RT8*X!b`@2%B(92!Q3)PE$)A+Lk,r9Gr -NSdBlQi8mCGVJ%S`pIP0iC,2S'4@AV6EqmNZeZe1eSiK`Br-3*+!'&-pc%fb+eQ' -(!$NP5MSb@E6i-J#K$kESC-)kdI,HFblkf$UNLrf6f3(0Z4k0cq(1r&G$c5B%iKU -Y$r&6%H%KrA#eE&Fimam%$G[KM,HAaA0a5C4i(9h0UiYii+F9iUTfCH+5aHTMT5j -*!b`fiTQJ*,jDSP+2GZE5FcfXTaK$)HfZi0Jq2!Ml1f$f*C3'F+-GQ+pS#EpbLI# -&44h"RSqD+D')@pIAf'jrbUVTbK&M#@bGb8qE5A-EU`9'"LmT-Zl4XRaF+`G"eYi -c&Vd`[k#hYGdXA[,3S"fh&J)5Jj&6$F35MpMDTX`2'Y-F6DF*cac'!b5#dhi$q+' -MC'H")GF4ARiLF2DcmmQ59D-j!hSd3T-b!,P0%ALefe,1G4em&6!GhX"lr1[-LdQ -SB2p4-fmFeY(M5c-Gq##FrVApBB2mr0L,+MY%L2KhFj9)aYLjC0jjL$d0Qll,*#C -pkQ*U&FKhp#rq&9APbI#TR+hRRN%2QBZqKrkfp,T$ddEChm-6ha(KE$hhKcMCK9d -FdDdqJCjHrfhb(6V(+[39DVR(UNKLBqh6rAVS@1B@J5&L``cYKZU+,ApikCq0('" -+X4%0@fY-fJdG[349AEh`+aqd`6D9FE8e#Ee)EVdaC@LB)mHNR[!Z#hFcUKSX(@B -b%%"p[24Y@rK1ZIkXTK)`*$NJV$,(h0,H,U'+e#ck%bfN9mrHB+)j`bQ'LKL8QP& -IBY0*NGal-J6338l)6M*#-&-8"d8X#*P,E"@5I[!(0!EarU4Q'eR'F50@I4V0AA" -IT!h2XQfH,ePZ"LE8#I2ZFFIafhUckr+JA052NGReZ(21QPLkVLN9ArM@+G-0i`& -kUfAG"'m@!XHm"5UFN!!R(3)HL*YqhMEcEh&00-G4B[rqGq6Xj`h@4mU[6(j28"k -YeBRl-@&[2"GjZ(1YG3UUm6KY'29F+(9TJ#eb4AF6l&+d5)`ES[)h62hS[!"PX-# -BHF8rZkIHe5ce@SJ%65bra3&5impQ'$DG3S(1N!$JRdBKN38iMTEcdBaV[ANG#8A -8$(&c6K"&Mbic6")3)PadNLiP*CpPC'I(6LX++%"[4")mc0B023,[&AcX2%INm'V -QfhpB%ZdI5&&"(KShjRd058$fl9Sc$#'hD",d,%%Sb*6K)ccJR1"'e$-[b`CFG$B -8CC(f*#eq6a,**BMIIE%MXDBl1P%lDAC9PGak$[0J[P'CS!ekZF*941H'RT8r'jM -peI@"a!+88XC9Kl0IRH)(MRYb!mQEH2HMB-0I+2F1f!cXDE8$%m[Nf,T6(&V)G'- -Y)5pja!$r9`-(G#E*,ja8%cYJKE$!fI3)dfX`dHJ!mXM`eh5fV1YPB)a@JFY4P@C -DU"j@Q4@[T,2EbeZXaZap"JCLKG"M4Cc%91Fd$8NiMcAQ9"14crM+%NUD(N@N+!6 -KiC!!6*9U2hGLba+,c@9r&RcP4-6p`8-HmMr!@P+preLe4J!D6Y&58CIbNXHb!$0 -iTJ10"q*HX6Bed25K'B&CN9KmV[A$,jIC9LXEE6&Y)5BqMPcpIVMC1Bp8Z#SNLi1 -$"AM[("EV(r0eKU-*L[AQ2X3bU&DD)8'f&3!0ADN),k[q'0d`1r8N+&@-[@HYS[[ -qD-5d!X'd0XC-ff(@@,0I4LZLp+rQQBG+ZNf$mRQ(rK[5)@-R0%PiPV&@JHHBL&m -0d5a,V[62J#,cfJQL&[IAV#TkTUVQFNafqCam0l@"hk+HrQE95dQ!5l50Ar4F`09 -VEV,kP$[jA"%`PP0$VXIc%CPVVQEqqa(iqU#C@Gl$kV"K@h0rPY3T8lf2SB(P'4* -&[C-''F3YRUGU-#PJQhUap3p)IYAT[Z`d,p1bc(TaMS9cZjH94YTPh+b8m&D!%1a -e4#B6fQAIrcL+Z(N9%pd!cY3AmhYY4F(qpf6Ql9mr6R4*Zlm`EE`5B#[-Mff@J[K -L3QqH!A-IYmi$8,qLE-2d4QLdM'6&c!XKKZIj!DFD*hqYhpE$9MmMffCD-QkcbZi -ZUl'[68V8a*jG9C`5mje,)X,[E&A!EMLq@cCN-)L'mIR'AJ[8"Zla+i0%Hh8I$ZQ -qJN9@3`[$@$,N-9-!kAUB*H8KNL-i"a'!Ai',LZHiCSV'hXJAR-"9k!`,P%[Eh[0 -#)k1)lhDG2hC`C@ieb)LK9Y'M2phUS1ErIbQq0e*J#I5`aD)BK8+[UEGXA2Ij(EA -SY3,QcM6JXkDl`Dk$[e0hF,)-%pXfM3TQ)&N!#Jp%%GC4(ibmE%)qXEVp1p#ASdm -H6Bj[E%i*#2-UJeN"q--)'K3UaZa-(M(SfJHd45`I+LiP3!%H40b5H'Uqa,!iN!! -Ta%-Xep250*Y2HUMmLLY8#IJHP2`*,'CYaH8YU8dP[MTcGK01MJU&FKQqLrIDh2T -'AfI19jbRJRd0H)p-K`+Fp56Mer%5`&CRfe[GA22E9GTj4U1MijYHNlU%%hIr3CT -#3BK$d$4+Y0-QI&fb#KX3Rq(YdGr@p%QI0bF2(mETr0jUi4`m-3rm*cFaG5''i1A -YG5i,VkrG4BKAK+80Ur1r4)&3LZS-6lCQC#D[D(2ih"I([Zq%h-QA(PkdVc0Liq9 -k3@Se,Jc1Pj,NEE"VU`&YY$Hj4c''I'2S`I`304ZL3Dc82P2!6EdEI@[Fe+h)4hQ -LIXM#r!PE#clf6FZqaId5N!$``TjKp+F,fZFH)&[IER2bZe*R"SG+N!$bcd)$mQ2 -rmpC@mk("PFILDGf1PQ#+KF,,MBA%#F0p*1eNip1aHeFf9%C8f0VJ0H*GI1`N)m( -R#P#Q%5aI@'d"rcGS%6F*SHl,8dl$bGl,FM4[UF,PN!$e*3%bbEbJ5j@(Z-mjqDL -TcV[lqe#54QaXfY((eDY+*F,"FM)ZN!"fIpYh+k0a[NM[l"8TbjAC6qk,)iC$hb4 -hA,6%U"dVkNlPqPaf2T'TVh#%c)c&X'm13N-h#$UEAja(Q$,ET&NmVar*lbbMA!( -[F`KC)jGZMYq"L`!r[`NZI#kMJ&`,[1f1Q!!2jcIPKNdh+l2d0&ki0l&-FGPHImH -elmSFMV39d9[#'9YlhU(HqYeeYdI*R&eR@cLQG[1l"9L'@Y%MkSU[5a-T%q`T9mM -YCZ1l'p'qT318Y`[LH5ddakK@q*lU[B34cQfG66rI"q95Xp`BmQ-Ef&8XY,1ZaF4 -Y3K[,Hc"5-[d0Zbc3bZeFllSRZLee8lC83lIlJ+hH!cdXBf6bAc4"f5FJYfeRL%1 -#r3ikdB"DfX(!UBH!Jc3H9(`B,hlaA'YQjADS[Ne$+1N6p[*babfdG(a0HqRcUH2 -4963FV!G299J(cZ*)kcUmb3fmBPGCA"*iKm3lU@b,MEj(K6lhrM3lNQ5kKZ$aIi$ -Jq4(fL&3!)NZ@A#PN%[U4A)23p1)EaKfm2#Mdqp+BD50K%X"m6NB'$9'YV&!&!@c -+TfhRkCd8C!1KHF8Y+NdP6TX4!QKBeeB0Ne$F1'TdJS68#LfRC4iK@$d1%ZGm13# -S+eEd2kQZ[`EQ`p[$3$RF@[&k,66LaIUHGBbkeir)'!LTl!CmcYY[`fmA#j[4hFj -4,AkLXam([IBpk,1[@Q5m$4Ad[V@PDm'&P*8"0%[1jJ#VMfEaPjJCFphM1S1'`!X -,[IJCV9DQiiqpa+rd0TRYAjDm!VA"mZ&9Vr4QbDGVYj4"iPA!BQGAR@A)MI')dfA -f5A3JU1025cdA-k0c8"5p!4Ycr-MSGa++Kq0RY%'NaVk'r$TlM6S!K%1@RN+RBlC -FqD@)kNTNjHfCmbG*`#D!V9$Yc%k3!"8N"4EGUj0blNUAi*Zb[D1Pb&#d!K4rRHT -`m)N+3#)Y0Nm1BBmM!39U+NlpXbCHJ6GQcca(FTImYDhIfaYPrqp,%AF#!1""Jc0 -X&+FiMNiKKC(4BG`pC+&KXT!!#m$@F$2GLh!fM*2+#-mTB''A5!PM,2E,l(BRecE -#+NaNRZ@kfT&rYAe#e$DQEFLH(I'Y6,4N%kRSM+rN[GRZP4#AfY(4$$aIY&81dPe -+ZKGh4Dp'PR"2)km4&jS*hBjm3A5a@pD`Pa&rA(Zp$hXTq%`Bk2-0eRG&i+Z6&$M -cTI,GekJC0A64%4jC0-Q6TCFmAa2V8#&@rXm(YL)Jd%85k1`15F'$LR,HhUK(lRl -)[l5i*hZPEdML(G%k,H0'!`&),F5I0[Aa3+6Uj%IT!XQ$0q)MA2pUR*33ENJVQri -Q9RI`5`d[P#hHCPPELKaFZPjr(%$L,R',pPENcTCf3P8D56LF9SYHHDMk!pRq$(T -)NhU6lLIB48Dm$I)4dP8",!#Y2kcQd2cFBkc%G2DGh6X$GmfJ!DN1*SQ0*+5e,#H -jANYC@RFZ%EqQ2!)j%Q)qJMB-!D$I)Q9,4Lp99r$T95S*r0*HI,lJTaPThB5*DjX -Q*fpAkALGC0IT5F'D('-)RMG5S5X'aPB%EVa'JV!!&DE#!3TbB0TZU,YaiJjZULL -T`fJfV(YUb+2$8hqA'pZ9cl5-ICdM&"GeGi*`C*NTUB"T3HU(j"XINdHmq3LTC&p -d"b!"2p8GJE+2Uh*V1V@F&c0RNVIb,(@XbhIX@$M",kf#,mYIRND%a@V#er0b@I2 -`$iV+QZ!8M8R$aJV5b@-QMf1qTEr02&1#rfGH-Zr+p6eJ0ScH2Y6FEGr%PHV8-cX -MaHHPIE@NjrCQKZU5$!*2bL$'02M$ieS#@-1HP%0I6RP!m09iT3+*+SpVXDr5C0d -UIK55#(p!Ti1H[Me%'-(2)P"Dl,k1`Tr28#3X$R@0Ihr5(8S3E+aAdM2)#Zl1mA! --YZ$Q8'UEaR$Vr@''Y3aT&S+CpDJ4[Y[mRFZ6bk*Qd&**f%-j0q8T6@95G(A&54e -Jl,3DY+A,eJJaRf$1kZ9H0ffNi$Q+#)1DXShfA4R$I1qZ)[r8j4BHAXdM0d$$j*b -5EMZShcfL#,'hP9TiZrTr4%R#0c#S6D+,6RM'NBpeXS"SBZ'6mE8DleSS,1m94Vi -B[+0F6dc,5F6Ammb1DJ$mVi*i(cR-Uc86ajbc40IMKp(r+r@8h(IrTTm#Y9Jme!D -mimbL$kT,Fl1j0S)rP3Gr1&mMU@1V(c+bVEr(E993*)brMd+MQ!68R!VJPlML2[h -XB)aK$N0K3hjVYq0GC)D8%K&Y1kbGZim$i28q6DkUG'kGN!!Qr%Z+`&$q%5((!Cm -2[!X9I1I2*MilY1P6GTR,Nf0rSd*Zl`SLQ&K'cDh,Ydia!EVLZ["p8KZ$FT,(RGI -A9!i2arpLe1D%NJEpVCJ2`*N!I3cd$&8"8*Cb(f+%E(GjR"#***5J[Q&U!%Z,@mR -kU&eM'8-ij8Q3!0dlV9#baDbf&bS"kSPC2LID+,$UHeV[jDU8V!!e%cI@5Erje)i -34kp4NBE5![#GZK%EqN'ARpTI2hIfQPa6NXe0V6h-CI6*Y*(1C,qi2hjG&DD+YNE -SP"P%9XJYrR%P2jR)#FjkVrq4+UH3!,d(4[[Pc$J`VN-QX+kjAm)L2rYHAq*HmfH -IL5IAl[UchSYA9X@5SrH#1B$HZA,*YTm6[4i!chP4P[FbG"dr`[ZMBl8RJa%,lXe -3jiXak64r,P#UCJZe88EMbH!K5bQ@E-MP!(3f3)M4X5e)lJdqYS)"fA#KleZ#+B" -41TZRb`"CcDjE)#PDdeLZMBqa4PrREI%S48DM1ZQ,-aM'SbMCak"MNIMAPq+ZeZ" -*L40S$,(bEQ52$#R4QSleQeJD3&G+6KIrKKLZrNci1T!!+M+YiqTHc8Bame[0(3) -'e,"cpDae-[5Pj*)*%CR!3qN&'*8,J[kTQ9kj9GGkb0a[JdFp()MZ650JSN%h3ac -YS&(K,BKM$QSH4FFJY+m$Q"D'C[k(TeLrmUUm$5*c"b)YLQ*3*2JZ3p6)X`jGelM -Z'`q8aDUbGG*QSRRhCi8p"m5IV*5rDPlK,Emc`TTJN!$69PD%cRXA%3qL@P#E4`% -@d[FPJ(LXj8Var-Cc`FahmIp"rRD,R'f#I&I+rP@PL*!!ELcEc%Sa2kIP!!!MQQm -4@HpU*V**$6h630I-ArB`m5%8fX(SlQ)KDA@bUXQ3!0&J39LDb6d*Ak(BdB"3J#h -`0f,b-%XppMJ3Mi-`bm"9B!"LEhFaHir`rTK5a0e)c9Ul93XcC`$CLElkMe"K62B -&MPGf[SSC)PI5,5LjMa58b5+C%G3##S1E+L$3&d4Qk$kJVcT![T[Gb1Pe[DSaNlK -QJh8p-I!bG0MpUb!+XBSRAVS(j#SUSqL(j4RC(E&j*B8U+i'Y*FL&pZKJHq0Zbf- -2j-h@5FJ8[E,mK0qY9S5Y&b1#-jpm`V'&V1K!@9)DUc$Z%DG5Xpre6%hKZ,9@GUr -T9@iM@Xf0V4ZThIZFRA4MVB*M5(H"S)1iXcJm%CXAE(T[hiJlLKbbCXIM!C!!&"` -&FbK8*59qNR&%V3EXEANirdBK02rcREr'(e@c+A1@AT*LU'!@@AUG3(Ji1(JH2Fp -'1CpZK"[X8CR1d@&8!m6S&jmP`AL-H!4`fdLNYcY#PM&lf9D8`,RmIrcF4T,92XH -R0B$rNBQL'NDmRY#mfPkDLc9hll8HP4M1XAZ[L1mDc$L*LbjJfDr(1k"$9PF5H4V -4*+p33pE(e3bTUK(TTc0&d$"'58K'*AD4(fU"UbI%P#IcXf6mmpplQZI1p$CAl1$ -FeEI&p,[d9r[V$&YJN!"c[BR@MSf86VjJjSL%p1B2kHk9(,jC4YE`X(H2NC5"0C( -3cJ8XDqhm4UmUjpZdJ%9@&Rff2dhT--)N6aE*p+rYhpPJ3*9P+hFB[c&NYEEhrIK -+!2R[LTmc'KphXQH#KIK[e)b'4P0G&EV6Q*lh(j86Bk#j#(aac(EA)%S*V4mm2r1 -I!0m5G#VJSa"Aq*+baC*HqT!!+3iT$Y6UAMfc&@'@D33+"X8kq(BqH+8afcrN4KE -68[#aKaG(PqMHpiddePhD1)lp[hf*[Cr#9DP!`p)`,&G#,TTbKerFFTQ))ANAY'p -pLR-H(rSKZS!1JiYF4'kG`b0CaK&i)4D6I$[34!%eZc&mF!Jj(A,*HBRRBHZS[jQ -*k"0UT"(KP+SN#9Y+r(@E"$#U2m,('Ec(9"PD9dQb,m`k4FM4+akqb*Zq3M1dP+! -!TYe+Kf9Fh-&$U[fDNb9$ii3q%pc@L4Y0kS([ZQ3dGc!Gp3'TU&#K!jP5mh%DKb4 -rFJ1Ej%!UKMNBb56RamXJjRJHSHK0LDHM"6dK$V!Q&(F'-hN8TLP-4`mfcq-[ij9 -H%L@G)39*r&qL0@Z&Y*NXN!!MUI5CE-mFFFPUFYj0qe6hPfT!Mm%4ZfD-[Pe`C"V -i#PQKX2I$FJ'H04"rSC5'@DiAG0032[r2Y2IRhdFAFMCCYkd!86cH*MMMH!'rM%M -rF(NqS0SjkHG-QX$f-a*a10X+[))aKTCSRJXBEX)%b&)Uhf5IhV#2k"EHM)URbr% -($GZM%5U,B*2UETY@%ZIEkpTf(rV3"-QA(M"0p#2(6H4M#Ke)maGajc,U,RrcbQr -`R+li[HEm5cf,*r)'Vk8BQf,3'PhfrHc3UC[UHR8H-B6miP-F-TTF1A)0rh&,GK0 -%f!3c(H(-$1i$1'ZZaP2%2CBUldr@e0-afD-[13[5Bk@3!+mQ%V)L1Xb(16r$ddJ -'UVIiPCqh*&Ak)b3l,C`r(S&lBC)QrQ!!S-`ppB-c[FiA4S0XaKGM5hqT1)V'IX1 -6d-3Fe[abXTE-Sj+m1fJk**1G9J-bZ-"M&hN)bMjF9fDqN@-5$h@e6FE3!mACXRr -ie5ZcE$l''@[Zj"LPqHd*FB8LBjbiJNNDN5Ye5T!!aQ9f9D55`TU"fRFGG!Gfj9c -I-d)A1f)qQ`jp2X$US4-UML1(BX-`8(-a)Y66m*-j#002M)UUDN&CYE(2Y8fBSbK -lMYURSR#e93#J)+P48-jj6$UTiSLYI4%[3XPjb9B#XYFSNdiZTN6!!++)GDHKM#h -0bViKlp8"H$PKf"%$U-[dMhrb4eY&l'TN,!r%QTh`qFLTCcIMZ#)Ih(8p%ASYqMQ -6`fAeF`6+EDbR-D8!qSDDUQU8[p,")MH![38q(ZTkKj-PKJ$jV)#'*)*1i!h4Fqf -#lEARaV12&PD,cS$Fq+4!!JB,'DDQ+H4FBGH'4MQ`'-NQ#)a&I"a'21&%ie9J5-S -+%[MahQ($!pZ'rek@%6IY1@dLia4DS4mII+Fmf1pGkfpDJJiGHGi3iZD5fXK@fm3 -6!paD8*mIA"TqVIJ5([-pBB+TUqhq2UhX3(qdCC&&HjfN,C6f62(fb!eJV2Ya8(@ -ADf(P"rUkH#*20M,AIb8L2r*p*afXE%Sl-DU&rP5NrGJ+cAf0`0I-R@)PVEc3cT& -h-V*c"bf[M"@ENJ`h2rXr!"M!l4JEHM)K'9[r(%XS+%li2NFdG[@V@p$bM"TS1b" -"Hq4[mbUdC*HK#!Rfc3&Z1G)*iM6q4Tfa4`kIBDe%lciQZ-V&#TbQC,M1BBC)C,- -k1KL4e5jLN!$61LA%*DqjL#1r+bAa*lN[JkeQ5V&1%c-%XiGI4'd*ILIae0#Yh8Z -phq)m%-!HEQS6eQR4`i-Y,P6dd)M4Ji$X(r-3N!$PMh#P6D3El,pFASLCT&DQ00H -YMII"T"-R1FD@Y@pT6@UYT"Bpq&GC-YH(T`Dm$UB'Cr,-ZjLXV3,R0)%EZHT+m3c -IiRK*1#&TT%VkJN$FJpVUP%BfQLEP+M(UekFEU4cTDZk-R#ChT3[4,,6"RLMe(J) -5p*bAmeVKjVZMTJ@[-f4CAcdaJmI)r54pDHZ10D0!F&d(VMPG[M0j3J$4k@))Y@` -k1K&$kN4#QAT-kVY2`-D41e6@FG-4J-hrTQR'44B'p+mhYeBrLSPDQFcYE1bf1T' -a,l,632j9&%"MY5rQkhcZ*DA6FIaA!AcerL@12bK9'EE`9PIe*Thc84!lUI$hKeJ -@b8!Fr6`(L+EpT50`kblFJP!S1HkbeIlc5)i`DjJLLGJr*CAiFmCMk9C!%PMc-Z' -,*("j&XNC4DIFrA(!!UpG,FPa''!%iM3LreS!F[fp)Ue"CMqYJYL&)2Sr(HCa+r$ -m'05QYA0EEP@Gela[jKPfAm3(QH6iqKp2Rq)@V-4mIT(fT$QRCf-ciMdE#44)!re -SD[[1IXeD,(,T)H0$(GMi#36PmG9k@5J($Gje(UrBUfD![bf6LS[I*`XYe95bFj* -bF@!d9T!!&@+G,f`RFaS#QbleLE!k(5Xe&-m9$2f)2RC@%HIGHKBQjeF%PI4V1%( -TPiHG+VX8#l'lij1h`@0`AHllQ'jE*6)P&ib"14b+YL4jP)(R@C@5Dp%MQhM1FXA -fXN1)hbF3#A4j[BZ6r,3PA,Q`(f9GRQKMG)jh*!@qSH3+0p&9S!L"&kD2'a(@&AC -8VP-X$RGjZe@8'Dp[HEb9BCU5iY8p48K&XK14r4H3!,qKjIdTYNCF6jS!h5iN2Nj -[ej!!hU"6[HGU[r`@b8ca9("Z,ikB!*Ld!GE4%U1&RP,dUB'lbPGdS1d-S)Lq9eE -@qS1LH&mpkPU&#,E2[ZSNT%@hCNUTCH42[HBGI$jFK&"2D"@X(f`183C!8kL*LX$ -,JM(#l"6dhhKVlhh3)(X"%Bc01%)#[FrSD4@-cip!r06`H%[2V5Rm1pmmhr,aF'j -)difVa8(V0%hPR*!!#,D!5i-Z86q%L1D$-3Ja1d8ZS2bj'()!q8NcmHP%[@RhaTP -Y[UQJNBDF6,QiP&`XU"$c8H23-,G#aME4BYL`,VjSQ#T)(U%*6,)XYG(SU#,$T[2 -2`bMjMPX5f,KfbD[NB3j-KLYF+"j00iYiqGGG%IdYb#9M5V358c(5XKi!T%%EG36 -Q"ANh2miSGYa)U2bJX'0D8MRP'Ej&#`hP3CSZ`j%Y2D$1dLpLA3#8NQ`p*R(fUTi -RdPD3!%#13ZNU'H5QlDA`lBqQ`#j5[DqG!G,N'MeDGI!G*2q1I,0YP*m8b)CI*!k -H-9J#kN9[rmYBKKre)JDC!E-Caelr%QP&DU2C5k,L-h+dQDJAdqjZ+Ya@Dq&9YU$ -#A[+&+15kkr-Q+6h22bSlYG@[&@1c`,`M,pX")PbVQr#@T2h$)Ld+pXUmZ8#+X&5 -%DFPqdlURHAAqqZ+iT-9d8$!JlFD"V`G1K2R1%HCYQ+,b&G6r4a3!0H3FG(MLUDF -(HiT0hN%adBAZ6b-QJk85KSQHYH2LHmrC'1iDjVkGJmhKG+f9ERQ[2`+,c51QX9- -"LK!XC"%Ra$4+RZKIN!!IA9i%m2"SNkp[Q%mQ*2BJKV(C'Tk4[f#d65fKX,CLNI8 -Sm40cFN%GM28DPG'Ydd*eGM[r6[DeTPNeF-&TB'`D%D1V[XGd`9a(TH+!S%Vj-X& -ri-lkZ%+Xcf,J[qbTKp9C'C0#%b9%DhGD)9b&DZX2Q"59I&Xa"X@VCDiXZEFU!,2 -Zl9#0PZ1b!cRRBDr@Vb`T@S*VRq*K80mYf[IEGeLHVLLD!)%b+4BRk!TeB5EZ*8# -FNC!!5DdHYQNZHa+ABP2[-q0mF44D@f9aH2Np+%Bp8!E9H'U,6r+4P#%[0Qh33+4 -'G*a``"'Y0$-X1R4LJbq2[HQTkj,f(rlcCNfY0A@m!3Y65hCkX1JK3iS-Vq@ad3Z -&AbU&pa2l-C2a8pFZk-qKF5HKN!"lpLQL&09TPT1I#GDCe&l$bG[jHa-QhPYfdRq -Tc)UX3VUYqF$cpL3DdeV@T*8EVZJB#*Y4Skjf%!DTQ1RZqi+q+VbH+9VE)`cf)@J -$a`Ca295a+$4Ve#@XQl$D"0L4bF,PQVI2(m4Y(X0l92LH@,'*i2@1Y1Z2XAH6&IU -Nki)+5K%%#`@p`'@J@pJSI[r!92@`H"iNa&T&h+ecT,dBD&dRNSHrR&&REJ1A8f# -e$S+rFGMH9+[ed@eckCaN-NC!I4lfhENA'f!Lbm"[,#h+,[cD4YVUDb'KA%T3q$" -lNlhF`'STEidFAq8f4rTBhQ2Y01HjjVV4fm`0HKfD%18qp[C'L&RcHqIF1J3H9[m -f2rXl,CBRHK8T*2k2NSB4m#$k2SCKINSq1B*`reEYYpdb$93p-$Vc$rdNB&I8VA" -%[0[T)#pYhYZRJGA*qKM&80@29YJTVeYK#L1S$@MZM&H&*5j1QF9RM!(!@d4kKi` -*#iUYNV)@9-Jj8##ULUHb[r'kG2fA)@ieKk24Ar&LF'jpfL`ZB-Brq1U5iq1bKDT -IpiJBCEc@$NaQ@f2D'"#b+-8i(FmZ[CFa!$!HVI#,mQSam,ImZZ**2S%@5cj2XXN -+9-9F`A!l3M(Bj&f53kcKIk@CMpPf#FGX`dc'1DNJDC(Re+rV@#b8UJL(3cY(Q96 -%aARcT1Q[+6`$Q%RFqD*A+i3R!DF"6JdJRHjHR&@((&hIh@UDS-dBdc3B&I&Mjj5 -A,'Vd-MZcVbJX-VUIFkBPfH#U1acKb-XlC%kC2(@4VFL%(UA6RA,N*9"L@!qSl3@ -$b`2E13RIP4Er5*,"!"A@*j3D$(G(LEJe&rjP5''H+I1rh$HD44`Bd'A9"hh"4L9 -JQ!2[NQp!Jh,NiVbGPJF[q41MbRQC2$Y9GAJ*PQ#ld1INkcR@d(6r`L8$M,4Aq4d -*C(HcB'@KlZABX'ibhl[c5#CR[A0F&B$2HlXSj(%''B&L4Yr%#pd"#l))Y)9D`Kc -1YACrC`0*KU901-9Ib#B'KhAhbXNll+#9M@K&kdS9U+B*K3)Q`+6AVX[kKV)jUd& -ffP"KQMM+-a`MjE@F,*JN`r0VZ1D5D2-%4K@TmFbVd3pTj9Nq1ZLH@8JaJ!@a4%8 -jP[q3!%j)bTMLLCeQi8UR@!HpCaiYCR5LmT3YTV[48G1j+FXZf@0X0de9&Yam!Cj -ED(ES%j6pCPc,Jr4@4('rUi3Y8lpA8R+X31'b"`'q!0liH2N6N!"Q3l"Q&ICkq"( -!fMH[B4'KZVE"U!pG2X9hiB`A6)!Nd(Z-FQa4eUZY"NGjr)hB'4b4[m&c--3jJLN -&"&(#fabR-9k8QNcTi"&GpfVY2kbU4mAm(8!FEMGdN!#0R-iE@S``NJm`c*(beKD -&CkdjGY&V(5K,MQ-$J5Y``'3+TEEaAHk6*k*FVh$kj[`D"XiNJ9,)(p)&2-emq0T -Iad8f"%MG"ZL'`GU"ahD064f,-`f9b`N6B6*bI1#"%RXKVGl'V@94GrC*M*-JKdQ -&EEY(jAFPifB8iQEZ5T`9aYHL'Y%+q$`'q2-#-Qk'DEXA4Hm[r*8H6P$VYPG3*+Z -&-fFeX-jDTpVM2jH&c0GVhS@Yi[Dlik[V3B&ep@BIU5JErTMB4`!J8J6k,I!kqcQ -FV2JlP$1iJ,6BGT+41S2"S!hLaC!!,c)GGdI*+P(H-Zr2FMQcJ"VdK-ck45"@V[l -d5Q@`"Lek6(#c6JV&KM&E9G93-cDhA[4E0APMTU$m%@NiFG("mSZq[T1F[jeUbq% -q`%Jh02Ca3QQNSiSHEMffJ"bM!89*GASkp'lPh6Ic`Um6J1cch9VlG@D&0,T+QdR -#AYc&Q+#-5+49hEB5IZAmJ9flLqlDKB`MPqVZPir4TG`P2N#eSTF)0qCUmIfeL2U -q2%dSkQ"(!dIP@IJJlidb8h!(%)edHb9N-ZjA!dqJN!",'RhN"&G"PM'8q5*Z,HN -eFiCLIQ2rR!ded#5V@eqUD96f1UGRV*RREZ`A!X#PN!3"!!!m!!#dSF5TY-Hd@!! -!6NF!!+QB!*!$FJ!-ljF!!V*0!!!QTJ#3"!m!9'0X8fKPE'ac,Xq!!!#(`de08(* -$9dP&!3$rN!3!N!U!!*!(3X(8e6'MS9UQ,qMq(Ic5F[,,iVKcE9IiKE054!XmHpr -rE-T+GQ438MaVIL$%'i9qM)JeQMh80fq54mPjdPN'Al[3X@c6ISZ8"rDEQ#aD-5p -GF"Er!GXThhkkG@`E93j41J4'aCYQ0e*j'P+a%)9*rZTIVj[rC[GKpU1R&3AB&PL -N9([LfI4M0mIYhpIc*TTJYdbcJHfkaeaD`ASBfGCEH(+0'XD*m5#+TlKU@#XJ3h, -hhCRS@FpBj,8*TG@dk3Z"hd*rNfF#dh6mDVhK@h,c%N`1KrYK3h1ELE1(c2[ICYT -XHj2AeR-*QFVI02!H(SiZ%6i`IL)c+S20#p+9f2Mq&lmSfl5q(Z@TD8qm%RNC)DY -Rc,4%&rlZ1&$1#hp8$U-f"3e9)#!1e'J"R1[P'@L!Jd(T3M`KGCC&,QCKGN&@L'` -IdHL14cHVqaE$%fed)3'KL6$I4SEST09i-%pp1G1BNB6!+,hCe8!p#r2,5V'(3FJ -BLD4dRZQh)ca'[fP-!!4Bpb8elpFME,G&Gk9G#9$NPhBUl,Ze!['(CV$URSc-f`X -UGRHc9dS5lNMXHJYfDbba+Gq3!,)5pa6(!"J4HJ#S0ZLArd0!DSXLRE!rC1B@+&J -1fD1!Z1B'-[AKNp%cRdj*KTN)6eY3SR)"5`Z'%&bfTZGIXaK,0&JRILLZ*dA%Lm- -kZJcEjEHQc!S6'PB&VZ'IRV9V8EB%ZXk6S&RMJ&DU4GB29I$N&Y`AKi0(icd"+E0 -C"SjpL*r45XYL0Q&4Re5J*$BQ&UcDD[3hGV`qLJ&qVbQfZqM-(ijD%J#AHMTDhM* -1YK9'`4ehY&r4a&+Y2FS(3bX94JKIh'hjlXZ*j*2N,l!8#!&2PMribX#E4DZTP[- -+26*(rB[-ER4`$m&LAAMD2RHF1c5bcbCZCkV#LJaC3`8rJ`'Ed8X0EC06C&Ibedk -&h$K"Fe2AA'mEa9j,rXhqkBe&Xi+F0YLC!aJGBil8d$X-fZX&9Qikek%jpK1hR9F -XSZmJNF&Pa9M0l6-,'2@*Rpl#q6SC#lG+"MEkQ#+[Sk@$i84I6FGR%5i1kl5Z,jZ -eaa91ErjSdY&CV$im%*!!hKR(me`pCUlRTdiNrda-+DfBNJKHFFBSc5[A"%Zj8VJ -8``&qfL`X[q#"d"j&26TbmB0E'*e0-rJ,,18E#a[Eple3%'3'$BV1h'pqD48aCc9 -Ka6P'X4IHdFe'lId!48LjpKN4*m#B(L4))d0p`J&K5K)IJU(T+#a#KZBm6i"q4-a -4,Q3A2B2&DE19&(P9&NKAP-5p23c+BK"`R2+[HmV",LIrK'hk,bU@qLDPXCZ(TZS -LX0`RJ*JUEC(&dX$SllY'kh-3H-JCjK#)2`Jb$$6pUNIF3AL3!*jC$S90&r5(jdH -AJMk%PF(Fid-a4eAX`ALQa-L1#Vq5@8BGM0#TGqVYQEG&K+NTEeq-!0Yi6j-m6qe -1H4K[Ja!UJ$CIrM'(EHmD%'aDqB@DGlhkEPCiJ-"-6h"eSaIJSN"!9p&Q6,McaGp -hdY[-GHG15T4L%r08Tmm#*c6!*1`!9rJeh&j`hN0MPp%2TJiG8UqCp8@NYCSSa"d -8HqGZj(H$9%deTYD51i2fVBmm+b(D`YBPRA`SicGif'JjShC@RHI60D!`eITp8@* -k'a(0rJ9J,G4bAeJSV$dUrT0EJ(ZS3@jpr9MR$qp'US42QVB1SiC"Cd'0'&aC3rB -jjX-CI9SD+GB)ij!!G6!Sd+JD+$d+5hUlZ"f`GMJ[C)&jSQhbTZDZm@$`-2lj3f4 -`8iDVmeT!pM`XdIe-`5+a26fl[ZK[`c-ljlPV`TQ69@LGB`Kila%)YCbHQCH4L,2 -SiQr')P*J%3a`bRV9+ek,Yek-8M`(cplreH#PQkVT[Fk&dkLCp"`Ek&$2AFS04[6 -B4!PMh&TQq0RBAc'a8NPI!l@pmI!eVpE'Gff"Xa&$BX#l,%hp85YIek$6j[)V+N4 -pmbK%qj-QeH!`pJ2ii6*jQqeaD"@4F#"H)@&N+-aLp5fRb)HXKKc"E,C,*54QY)6 -(5P)S[*SBX'h#mU,2e51qN!$)Fd5M-c!h*VMK(rF%Kh55S1Gr3$"Ze@Q'HGZEEL- -kKi4'%L-4LZdqQlp-bf8,L1HQIYrpA"EI0mYP20fEVmZEKP4dkr"rL39Ra([#,4` -0NE3`$##CkcHFr1Zl%3QM,2%j0Q,'XRS[lTRhIpUc638`N['`Yl@RQ&#GMF*GRl, -C4h#BXC91A5ejS(DK-bJldf$9kqj2TRjb2GG&KcA,@#&+DdDD!fKR"`BiaGCL9jk -[maHKjk*VJBdK85i3'5!0Td4kU&#J$ppETeRmN3LiiBY1m`@DpAPYZYimYbm%IU' -8@F*j1'6QTECe,-3jGH`#l-d*,9"a$GU"`4`C)af9Q!UM@1D&BNAa8#2jqJC#dd@ -h!p6p*,edVp"!*8Bmk2Y$bQRLTIdZ12jm@jT4eGM5[ML(6eUP0"YbLZcRFk`e@A0 -PFbGAb4ZM3!h&rUDZXa$[BeUAk32)TeCCSq1j$5(f6(,J'rNE!h[mTaiTcb(lfI@ -YDq(3RJi`",[+HBP10#K-80)dmIlP"jrrLX4[B!h&QA4&V`J)62[Q)*SjBerhcEf -kB'8)#*r18`fI@L&b`*d6)d'FNikqQlcR5jpb`B*l3dQZl(+,LBLVB*`[Pd`&E@% -h8*d-*k5$RalaHQfeeF'MAeQKAHA%A#q9RH`J,P0S38CQ0f`6SQ19Ef1qi!e3e5C -"1r,CTP0l%RZiZHUY-B4ZLpaFGk3f29dmb`03l$)HNFU3!*@ThZX&TbB2D'1iL&2 -,UV+LfPYD0''1CG6b#5bq3&`HIU"I5q@%53*%e@e(m09&YLlT3JDa+T6Rq%ZXIk, -5D$UDTP*2daYTMfbSBdr%f[E4i9m*[18R@0KpAcNpaDH54`EL*DNFZ4m[BBjF(i# -`3ddrETd9X&4&%q`+rirJhQ![(HH0IcT!l`$U&cFMED"4[M9Jc'-ar9l%FbYQAii -lkeNL!!1*'`kVj,`4+EfAVfkprNSXN@6#ja6R+MCF@26HU$ceRQ"C2&HFprVHI@% -EbHfE(EpcV2PL4"D&MrXi#pc'iXZ$ifr0pXRADkpZIVA'G)@HN!$K&6@2NM-@`Sd -"pNAI15*D*+kTD651iLQ6T0bj@1H`JUPU88"DTbGP*Nfp*'&&[T*RSH-kT9[D9El -'ISA@A01Ph6-c4-3!X3jDrAN69ClYrKGc6ACL1R'811@+3i5pqMHQBGa-I#ZpQZQ --6j4qDViYI#Ui#aq)-LSiEeL1L[$!,e"'S9%`6Tc3JIZ8ML3$DUkaRV'0rG5DTh3 -K@i%KKd9$RH#rh,h)cbmAI+BN1'@mbm2AACXk911m$,BlU9#U#R*F!!IEj[i3AS% -2TP3-dZ"r%[lhDGYCp52!q0'ejPkRF-N[T0-ZPPZ95--YFTQ#BNAeli2fD`Y8,H5 -GKTVJl"M5Y!pS-5U$-Nj'A*8NK3iQ46TlMb#0p,hJq!ZC`$"b%`bA9#KD"mS-ek" -GYKf[f**jb184L%!,-52j)2(EH)(m3L@3!(Hh*cb2*J$j&#Jii-IHp,MjpDX1B4$ -Km%EGe-fcb8fRdCp2hYbPM'0cIlT28MY!40jMqa!f'-ZRV9EX8(#!4T)41r5Hqk0 -XUdrkFTq8p2&J9B%P$fSV8CM$%q,MS6d*r60Y0`qLECfmkhS8AZYPP`HZ[8I!Xf0 -UBP,cJ6-C%Bkr@Y)'@(mi-QZkFV(L"%84cFPe1fkcceA%X-6a[8b$%UleZfSh0Pa -IPiS"CIm*r8)+%FmbpUTUihp"qRNQhiKQ3h,!#CkqYC&LCZ,RfKhA5&dCrr+I6!V -D&CU6`Yd4*`k1@[SiJa,dXCErfIS`h&FpT$56ad,C$-B`b53,p)[6hMkR@bA3&dB -cYh(Y)pXpp!h%`k*j"JBi%@[0`j0`d-9Tfa@N2$rD05&U9h-V,k0ZklQ"l&SiY+Q -d*miS,K(PUI*#E!M9b6c$NP@U'Bl!QYii$MK-#A%@HBdm6ekG!bB$qf&$E3,9@c8 -,"-4fMiY%@9"'pST%QT!!8jl*@dX)JEKLf&Fp+*51)&J-RXr*3)`A2a0`qHqJM!p -DJ%IeQ"03[bqj%[LD6m-G!2kq0b",5r)*Ch`Fk![iCG0j"5YLYZ,J,i9"V(G&c!I -K"KdUc%+2l+-Am0flZ59$`S+Y`[hahNfEI+JPE&2`$BER'ViBT'%,edHlehk,Be- -[9#2G1pc%RfQeNK##FHT*$56,G@`UK@ISPF`"fZ3q[JLUpTSqUIT@AD%NVJHe!9S -bS'cjaZ@5)`+ZkM5e%Q"jMIRZb0`$kX"!T34F!1EdfI$RiBlD!(4$YG%RRP!AdaG -L,T!!L$UD0RGr2h*c-C0Vb@04mIhQ![,!@)bi8EQB!&5L-Cr`2d+6*DpVb3iLZ[B -0IFfkM8P%ka6@TE6PJ88!FTGV9Ni!Q$CV(VBlCRB$1('TbEpHA)mF@8dBI3V%YYp -NURD[AH)8G'T+CJ4bF"(f,G6P*b[cbr8&+pdH`S`C#KPSaK"RhG24(DE[3c+$Gk0 -JhbjmY82QGSMU#Hlbd%r-'V9"6h214BZb-$4ffdqd(G9@e#kF@!CQQ"[0T)rE38K -`*bAD@e[B9MFkfiHY)TVj4JPrC`p`11FZFQ%U)kMP[2B8N8XjJJ,)cj95!lkAdGZ --#DplA'Y"Vajq%A)Pcp!%ZS,D!kF$A5eX%r'Q&Jaq%m4E2GG0Y@*K`dQVNI"1kX9 -EiFHR9CJd*T@0QrpJ1T(BEZ2EdGBQD+qA$b2UPQ[KaZU&Ih$VqUpUTb!qK&Iq[J' -VKQ*Tf39NM6`VpIC2@U#)`#"4UdV2Zd,0-PH-e45'"4(9(0S4@L)SY9GQ%2UrcHJ -Z%Rm&rD)@h'h+1h$'QQl1SbT1T(Z3!%bGeedr0G,ac5r9TiaFrbHXXRUV5h1XR0E -JU)iJ66#,EPM8!1bf[`3@'TY-4V[U,&SlD'1m8mlSaA5kh89kTIUcAC(#lLH[D8# -lZ!5)3'6S&,HjG3$'*(hHiK"0H)6erb["$JY1V@aI5Zl'*h0TJET1'S1'['ijL9h -FQ2eHXaLhK1GcqlcIb!#8*KijeKS1FDHHRbGc&QMNY3&ZN!$4P6IijGUaQA#$#I) -ehb*`UlX!,d@"Z(381`hKCD[Im6p@-qi)iNmZ(lmr'G`Li'%Be#l26%hQ[XY0a)S -1qccm2QSDXf`1RY*-I%@Aj(BB`"Bf+I5@I"k4"%PJa8c5&-p&),G!JHFI5k-Ce3k -Q$N4X*1Ze$l38(2kEQh')m&3HB2LmMNa`5U&cC+2brRS1kJd+`M0DFRAQi)jJ2q- -l4`dR$$J'G,3JLRk3!*,ir9-5Ym-RMcLIVeZamH2"H8)AD8IrL$3"rK@`V%9Ck1k -pbQV+hGlQ!iIj4EC@LeLMQh+6)N2jl86Ad3,&ddU%a#ejrXRhJ44-j)HEpY!YF46 -VB$ZU3fXQ5rq#[0MRT%PBA*d`FGj911G)*#KjXkc9cXP%#5RrM8B0f`NdYpU2k8F -erK[r#%KCEY(F`pS(Z2dH`iIBG*h,aU6cR5a,T3I`cKI8E)N-"D+&9N"i-MkCHP+ -aQ0"(A'5il3R"he(KLGGRB8Q(fR!PF)N9d8PRrQI)jr"`K+5HYBpNkr`NU8"NNP% -*V(NQZ'TC-&mNiC,29h*QhFD&5dLYTkHqCBmD$p"bqi$MT#3ejmiSjmlB&qJTrj3 -Pk013!"D[hrL*+,R2JI0NR4H0`fT`cJ"D-pieRq$4R1%PYcEJE8[e'I2,Ndl@$M' -i&FCC1YK&Jk3eX4+hE+Y*V&q&+jZ@NVZiKK*@QkB!64$1q1[&er6ZHI'5XY-f)dD -3!,Km*+lUAd#jMPblFZ@ebK-cV8D'!"'1dI&6M),A#2d"(5Y8'%I)S'Z'Aid0RcT -XZHYP8bchLe,lAN*MEJGeZA,+NGrakB*4b*@$bp2Q[0"re3YGIMj)(S5GK"1UAl` -BjFET,eH3!&%8CCF-jFLk9IUSP)#L$bZCFbHNk2R(Q)J8N!!K01TEDak9ZH5p"D9 -e(V+XApPYA#%IqqbS9#02KkLeirm+1`hL0AfKAlakHQ#'m8GL)NJ9"+%Yj5dMN!# -Y,B"6P[%LL#Lh%U'emr4h,!V""*Jc[9q6I$aHQI@Z#5#U#cB(ZZ"pbeUe)E$fGdi -Hq#+r#8BI"Tam9$ZbYH&09`8KUI-lCNfBpmakB,@iD23,Ul8@ER*2J#MkQM9BChK -1HBXEAdAFR,EkfdYq+[QQ[1b@pN3NecG#cE"lF-%%B-*!5-TSASqE!fmDG!3F*N` -i#C56MS$(p!4X-,-[G@2cBpqAQXdR&8iZ8)5#&LXfba"YMYM-q+bEI&1pVQQe0,H --%HTUC0V*BdbCR9848'P$6"el$+GC[I(K9!YVIm-$-$69X&@#krJPKc%EHVQI[!- -6TN$*4@QV#M'KZEmJG$pfHIidGF#d2-#NX,"2Vj!!D(Chb(B%kLL2a$T"aDejQ9p -km`Qc3birp[MUeU"ed"Vmj9jfSq&-!#,*5d`8jEb)D-,U56@R,X$#)m!B8`991GI -C-khpIhrLYSSKl3J-EHB+0YiRHR"33d)5(#!'X#+eE(,'&C99QahDL`)d%Z3iQEU -T'82[j,fa2a1'0ijQp1Er2089qc+jpl[Gkq,4jb+rK8G94Ya-iPZN"K1Z`U8H,*U -mJcDlQ3GH`dZpTIrAYK,ic`'69q"M'4m1Ff3@0l[a!r!1NF[Fl0!#QkVhd(%Xp2# -@12YkAp%5ALV*MmaJe0!ZFmFZSrII+`p#U%pRMdQ(Me5(p+E01rA'#5mU6paTAPI -#K2$R'f%kZKLa1mXA-2`CXSi'p5a@"K$Q)D-1MqBcZLCRkSdRpb4+0#jB3eB4V,k -hVP++0iB)SMBjNLaKkTb"[[(V5$`dQ353!&4@aA(*9i+YbNI`1q)a$E9TTQcpX," -BC((5+[Xp)ZNUa5,T)08!TD1rhZ,ch49+[R0)*qR%fK`mQdACh$fRRF0YcHN[&`S -i(3GPT(B@![*C9YVadD2BhM4FBR!k5j4)QTEBPi1-rR,NQS%1"bJ2kj2Ad(q3!!6 -m0T@3!'[k%-eG1dDQZ)ef8Ur[HLA*dlFkJi(4E#1SkAcTj-(m,RBJbi(bLkaS-QD -SY$a,c5M#K@DTp#SPkSB0C6SZf2Ph&[q%R%E40f0TT1QrV5)2a1l+L$$M%*QIq%c -YkERiUJq'%AL,X'(FJh%MCkm(e3$PD1FNE+fDUf$qTfZVU&Tb#)((Af#EeLIK8P$ -eX9Hem%r))%SM40r&mJ*)*UQ1@q`TkFq2HlH0l-l@R&+,!j,dP5THrqq6-m)(2a* -B2%cAiY9&R5SDZ[fhma&(A#i$'De6MH3NG1qAbjTc(ZV6%`%RQ''de1-5[d[NQDe -&1k3"V1eFH[@U8X#'BTYAY(*CbeG,5XhMjBJ1!rQ19%V*Nr0hI+$G@'j4UIbk+Q# -I!Q,h2eMFR59'L+K,#`fNfjq0+[#r!Em1r5)[B*&H`*SR3(ZD#D)IP4r@ECJaaBD -C((3IN!$BI(4TD1MMKX#q3!`Q5ZpKDH,G(,mmUXI)B-*jHPHJ9+qE[TaKKPEZT"[ -)aSi51)`F4a$C910Q8&`[#NK)T"XiNDMehG3E'hi(SM%Y(@(lVDM[ZmKM)50iUqB -Rec[UAZUUEaD9$APaY!GNf@X9iJVU&lFDNj[P[*[5)'j$drDc#&)HSRVr9T@Rb)* -D@qFrXXbP5NV3R"-jb*BTa%5GTAjh`TFFJ#kZF'!lIUN!XqHY%,0T2UZjmf&Ne') -JSKHeLBhapVXja)p6'8QakcRMA5h[BiA-pUN,66J0a-@CYc9dr1'CrZTKIDSkB`N -l1b1CRYi"5e,2(3h+8l$FaiSTcF6D$4TRCSY`rUHcY(pb'@dBAEPiR%9S`H3Y%i' -'+QlR%1d0PS![Sh,eGADD5jmr5"Gf402rVhQb4[pYDBQYkKGdf,9p$42h"ETLTFC --Q)9j6hIBZd8N0r9PFl)U(09Nj24(18-`HNR2@5!"dEUbNRZ&$h`a66Rm'dKA+iK -AMD`aQjYDa1J8!QJTrE)58RAI,+eq(kf--U2S(ZH&Rb@iif8J96(33[Ij#6CZSNh -$e'A,*@9lIFeq!rCaV)ED31Ul-J2hP+&CHjNk(IkF+)Al5ffjL+%R[[m5mC!!NCP -$#l+,LbV9Q+HfJ5T%+HN8iL&5M6i#1+9&l'#@A-6)il6!Ib+pH8q,8Sil35-+5-0 -V8$RDQa`5r!GLqU-9fDU-D"ZX)0QPqFmA4m3C"$c-hhcmqBf(TV"3EBcP#HPHdVp -6#5R+6l@hi4mcM-3mUm)RH6@I@B6J()F-ef$Hi0KEpX&-k$4*kFN&,fYc`8RiSY! -8Fd1Q5&@MMA'9Pe10UK6*4LkFV%(RJIj"d%kp+S996-ZQ!S1FmbTF'X[A"1GJ,EX -UlbV'2a`NIZ@F*G9Iq2R(SYG)R9KGdLJk(`[fmda`&,#b!26'B8I*l*`*#F%*VDL -R9%*c65"p,1$XR`hq'V4[6I*m$4%@fI#B$Ui2f1N8%HE94D!'JQ1Ma!F)``R@K`6 -N$Q0JEJKPF6ml+60r!hTF%[`!S+Ah0B[jqL4qI+",h,69B'fPiab8'ha-kBL2-Y* --6BLJ$(L!ce$IiRh)p[SVr[TrG"jVhAp*E)C`,k1JI*!!Z`LC$[p6mVj9jl9S9a` -NRLc!&%m%QbRbp$M9-CMbX"RjcGqZ$3%`-11(IfST#i)YCV!(Z@&+%A'YBT@&dR* -EMK6$@lk@aYUH-KT2Q@NTj1Y!"S+a0IDJ,c(ec2BG5XIPTf0#J5R#`*('DJGVJM% -mY*L83PG-eV%cZ!FPLjbA2SE%-[Y8%-HN3-&iHqbM(q8jGH'a+D3M02mcLCPE%qc -9MLDhmpc#a`kY9TU)&Sh$60*m-flVTT1*YVPV1ZkLQZE'Dpm4)*b!pT-EC+GM -Pb$#20IPqE1LaI),66S8Bc0)TjG"m9YAD,98ZBcMfa5RBY+X)`crZjHhYDT[+NeY -!V1bdCUF#%*L%R`mqD3b'DVbN9'aQlLf@YhiJq1HqUMCN"S*X4K4*kdjdFj!!3Rr -ARbcqG)P3TQ+EG4)95NqXAC!!"LE1!3i#3hiDfG"am@Fk,1qaV%(4%mG2dma%dNQ -eA*F9TlV-Hq[I`dELGc-(DBdYSF@HFV5k8KRq!M,4&!9Gjb`eB10F[ZipUIaK2p+ -eCCJPH[eCi-%ZKSR`Q@1XPp8,%*`*dQM8@c6-Bh3,"Dc)arN0N3PY*aFB#UK3`UV -9[$@F#N&iX`1l2NP&0B0D*0IKH)kPHq&rTH,)+Dh6UFF(-4pbjSK"N!#*XqVr5mI -@b0RlaLa%AFh0N!"FeQr+MEh!Z%b6blDMq9UrAacc1"lq(LpZIaA$bZdLhcl+qek -C1QUd'*'$PC&@e4HAST'R@X8rb$[J`!e`A@qjm5K%*('eSDB8@a**)35hH%ihJX` -Ucf)E0ATH4,&(hV%6"LB24"*XqRe$@Rj!U3h*P(Xmch%*jZZCqJ(cRXZ5VJRZc9) -E1ZI-"S&qEi2)elrVXI9*FN$K`3$lhNl!Tl'8#fYJCNpI0SMPPh6FPU2+9ZYbT"M -SVPATih0c6%,#3'f[&9a`&Vpd'83bQ*A[`Lb[Pr*hM4`JccCPcB9p#iTh`+C#kC) -ej'K8AJc9q0Ki)TmX8b#DAQYJPUcd5f)kMj!!3U%-1&4T4mhCDDrD**1A`!5(YSP -(D+F1YBAmZ%`*2Z-iIYD43iqCiY@0b[J!YDF&TCFK!LENqhQI&lJ6mIUSLH!3[%# -Sf9fS8A(ldNXT-aB`DM2V5D,1CP6BMZTrfhTqVP,k!R1Z0cMQdQ&ZCK,Bp3-CL,A -+`3J''6e"a[!qim+B0ihcQ0ID60QH,P"+33JiDGIXTih@-kppSYEpSYKB$#pYk9f -0-0CVe1IXpHei)!6H%UPkYH-2A(SrFH&UU4@1(&qZ(9[MRqBBc&e4lLGLjAQGV(p -eeIXEXr'eRj6GVb8c*p$3(9r[+Lk2P40T5VYR!Q'&(ApEc+m*GSlf1qFVK*MH02D -S+`9q,&P!HJB"e(@L+B0f[+4De1Uq4,-5`M#-0Q-HE0G&Kl5VaHE5K%&-`3D%TIZ -*G-GR5M26e(X-NE#[AiSY5b"0B0X$S+5XGC2R!*FYMT84[-Nda%5ckc1C3!YC$0e -PJDP(13k#lY&[Q1QrSA[&6)[MQ8CK&Ye0USA"FR(Xjk)6lh0,$+9p!h8dNiUAkiZ -dN!!T@D0eVQA5AY%Q@rBQ2S3,,VJLHBblYf%Y@!21KrkX'r1`pq+[)aC0j%&XkGK -DllRTf%Xh[41&4d#bX[NIpIJjKiUR*Z8'")5db,ajKC6+Q8kpB1U4C*R%rYi25kR -ilfQCY`,ecYlRU"5k41a6YRDj(MT5p9If&8NdAa!r-lKVUhd*j`Y#hf"mA51qqKF -`ir8[[-V%"KXe(mR8j2[&C'!8eU%aUVief*p+lrM4VHji$GE6L(P'F#YF3$P-adF -H-kpNHc,[(qP)[iqS@ZB!"kdVqMMVlm85fEbEmcL%VF0*Jhj(dk415IPb9ip@[2+ -pRia-ke-i3kbR6'E9QrBZbCKSq+B)iEhP3"k&*J5TT3T2`-qTKm&%+PSlCR5Q2MV -3+IPQ4P,HM!++PA+1#YBUK0!%q4Jf4rH-NZ9L'C+jhi"YKLQACk2k)"ri4lZ(adj -[)@SGM8E)kF%Pl$dX*96IN!"RU+ZS5Z62bFU@6FPr3c!$+hc[&%rBZI(NKd4clXL -0@lT9h`LJ`r)b3k8[2hQk1+%#*4d1QL@CMe0MGT!!09kjSiTPFq1rC+cI&8lGfE" -8-Y1d'4Y,00KGTF%X$UFdBlR#EJja`YZX3mUhJ9KjV5E6P!Ic9CR",j!!Z88ZkIA -63AHVEVHfU3d8`%RH1LS+1@9`h&'+dq5,R`M!qqMj8l[fSIBmXm4!3j-2S9%f*J8 -Dam0(-B@A-&VbG4)M[SUc%dMLMAG4-K(,aqrGqiHM*hbDQN)B+,DBfplPVRp*L4! -d,rkm3UQ[VdB`XDdS`pMrHN0j$"0V1N[cEhH%A[Eijdp08iiTpI3(SMIAmc!k0`p -0fkKk0bM4B4FQ2K(0Tb%*hNS,4!r4Ck%ZCX#!1INi)lE6NEfl-C!!b[NEhFYqK[9 -TV)kj1l,GQdVeM1LBapB@iNe+)FqVHJAep%pTGDJri+eVq$j3K!5Cl2C`brI,*pX -2"D4$#e1SaPfLcF*VY))(r"@Fq%Fd[M4fCk@TEbCU&RK*PAAeR6h$e+TQ'm`brFN -[LHLj)L9AGpTh)Yeq"PRP@2,C&TEYT+6k8A99,aZEN!#h'PEJ4SXlYamaB4Ui@a( -VhZ)rB%!&2q9l'-b(*BJbJ'T8N!#,r,qC"PlF@3%e$CKGCi&K2ie1ih43@3,ThXr -[!3dqr#BbPQ#9LLZr)#K,cZJ@!$YH+k3XG`P"G``r&6QQ`pKLSiE'2FQ55i-`K"A -M5fMmPC`TC15T6DI8`S(-AXQ["Pd#!D'@Z'BFS+5K5c-@"QFQeYrAT&YaFC[#2dR -Hk0iAkYNKGdYKS!AeY[SF%3q4ApFK6KMf6@bhrMA5qNaG`!J&6IKpCLU(blQ2(,a -#6EkID[iEeFqh(pB#Y1VGT!c+raUfH3f81@XEZJ**`Y0KD5,Nf@XA(e3)3(!TiPj -!A8S3ES$af,H$',`4CZqXF*-)I#iRUB+h%ha-I@HGMNcUBX#mh3D*plk@LHJP,I6 -lXD+3!*ppE!9"&djYc#&aDkdf3[E2i%bTk)A0RBH,1,@[V*Y[q@GiTl!`i'Xh+lX -U`X*%jY*L"2[[L3"18aV5rpVSSqCi9LZF1Q@aH-Mq#9A"c49+Fef29jTmidV&XUE -Q'6$9Q"D'PB4'G@,8N!"QFJKKN!!@(38(*6@R-)lGQE'ZdXrL0j,#!Z-eRcrBGHF -eZf`a``RjTYlP[J652C''R'YS&833G5'RjBUM4EQ8i6hQLQfA)jVND$j4r`c3GSh -P0kTjQY'QMD85L0e)eNP[[fPmma"GZ)f9++dReXCEl!QZ+$IlA"@4Er8eZjeKRSi -'iRecRYFp-X@Xq2EG6B-ar(%Q$Q5"8*1!8mA,fP6T&GGFJ@#3!&!M*p&`2@D-`X4 -&EDY(p4+9*9fjljQ`&#j33NkDha)210&'#ZLf&@U4B5LaBia0$'QGUjr$D1C[&9% -JaceLAI2)*E"Sr!"#$l![@QY[fhlq0YA10m0R'aZVMdBLLGLp&X"2CXe%CpBIl(S -mID$Y+a(k&2NL5-Ql0D!'A0cXC&mZXFmjkYGHD6,QmJJ61k!m%!I3UDTViTNk#Sb -U10lb,0R-D@BTXQ`fkGV--BiAMKL*A4&ME(lSNjG5L$4`r!AHY6S9+#q22B!A2MG -eN!#p`@53!(S`$Y5(cH$%0S`B$mpX9Rd)G[qmp*4+K@ZTb#%9'aICGU!I*qk0dX5 -mTqA'DXAVdF8m"p#ZFTQ*@6C+l9kS8)"AF11F[R)$&kUb45,Ge(HJ(BV14jha$DR -2lZ)0XNl1m&Q,,(e4ah8(VhZJI8YM@QE'lNTCZm-5ID%d6fZmmjpH3N3ZBC+$`0e -4reG%J`aDBre&8r2$P8FrT!9'C9+#--*iM06DYQTH1ZfkiR@2Ca!49MfjD&pMU)p ---JB#j"-SPaI80P#pT,1DNDAI$Lc$Ve4mNXk#PSE#YXPYiZ"'NFipV%2JfRM)T@2 -YGaC0X8QcD&B50%E(iRE+k1-E6aeNd#)(168#pdp(@$p@kjXm!-hY3JG(iE44%jb -TY6$i$"NaIMJ`MmPGIk,8(p&I(M,FpDR6@+lPl$H-J+e(21@e"#6q*PR+Z@q`)ZU -I*Qr[FdKTR3D-VkR,Iql8PL-'c!S[#jkD6-Ib`3Mb%8cjCQPB'5J*qDb,fHD#391 -6q1Z4D@jrkGMZX,IKLj0T14$1,ETQ9()$X@YbN!#1XC15$`Y[krI(eLXeiIp%pD& -jDG"DlHY43lQeUA&2NPb1fKmH3!D&$dVbP'd4U&JD4iKDr)kqT9"pf0N!iPXp)ph -B)rL"$j+Z1bRIqVNZe9i(iD+@TB4HX84dU[RASAL5[Aqb!@1rQp'e-mk5e`+4[pp -84TV6HSqq4DQ@4%LQZHre5m&c9DMd1*B90eIcSjT9-SUCZ(+*6&-VqLCef`eTq0S -00,9alS%&V#2HU0Zf3%VEfCd)NFf*"-hHFrIXaec&,GPN&2,"BK$(505UJ16MbPm -5h1pCK)16AeQqFTRq6TQ6bZ2B8'Pl'Sf+!mqGr1mhe45m9+LMjNF"U1c-[2j842L -r%U*21Sa,HMEihri0jR3PcS5kS'B*9!"NH8`Q$UlKa4,$)eCDF[8#I$U#+8kB1Er -44+UBpFiqV&d,FP48B4rMhJ#PN!3"!!!`!%!!N!U#NJ#3"h)!!#k8rj!%!*!+HmX -!!!%!!!&jh!!"H0`!!!3p!*$cI!!"!*!&D3"M!(d!R`3#6dX!N!Fp!'!!miKF9'K -PFQ8JDA-JEQpd)'9ZEh9RD#"bEfpY)'pZ)0*H-0-JG'mJBfpZG'PZG@8J9@j6G(9 -QCQPZCbiJ)%&Z)'&NC'PdD@pZB@`JAM%JBRPdCA-JBA*P)'jPC@4PC#i!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!*!$6!!#!*!&-3"R!%8!V33%8A9 -TG!#3"3S!8!!F!4#)'P9Z8h4eCQCTEQFJGf&c)(0eBf0PFh0QG@`K!*!&#!!1!#J -!,U!#!!%!N!0p384$8J-!!(i08`U6K!'ME3$X#h)$Y,)b+b[M@dhH@qpUpkCZ*YH -!-3"!!`#3!lUe$)!!#@NUrZ!"94)XqdV)@`lMjA1kK9'1XMr2MrqZ)$NhV"Vi%FU -'0AQ'BU0RDr#XAMm&lZ`,`,#T"L)i6&Fq[H[,VD-C!m8F@8XE1!X!N!0D!!%!N!9 -G!(!!F3#X"!*25`#3"dS!93%6L$T6Eh*bH5iJ)%PZFh4KE'aKG'P[EL"MB@iJEfj -XH5"LC5"`CA*QEh*YC@3JEfiJ5%C6)(C[E(9YCA-Z!*!$EJ!"!*!&D!"k!(`!YJ3 -#6dX!N!G)!&i"*BK18fpYC5"TG'9YFb"hCA*P)(0VDA"`C@3JBQ9MBA9cC5"dD'9 -j)'&bC5"ZEh3JFh9`F'pbG'9N)'*j)(4SDA-JFf9XCLePH(4bB@0dEh)Z!*!$@J! -"!*!&A3"`!(%!V!3#6dX!N!G+!&8"%iJk9'KP)'CTE'8JdPi`db"YBANJBQ8JC'& -YB@GPC#iJ)&"XC@&cC5"eFf8JDA3JGfPdD#"MBA9dD@pZ,J#3!bJ!!3#3"F`!MJ$ -J!0)%#%0[ER4TER9P!*!&"!!%!--"BX!#!qJ!N!28384$8J-!!4)08`UE*!!lLSL -+&Fm@d(1X4'`3p5`rIcrXejfrjql1$+GBf'%P+PL&999LjEra",'U"3ZbC6Y1)2Q -3!"m"9#5BqM@mKDIGaGRG6G,)HT+pI4mZ3pc&PmHP#aEjM6KA6jAe#b3m5Sk53El -SG,A`G'S9QL)q"HC1abaeLk9cJ@A[I"3FZ$A+c+Ce3%m()3a-9j4CR+h"Zf9c)KI -FIJai(r!m3+*2iaUXL26-$cGj+&$EM-KaUkHFa@0E8ER-cGETJDZ80pr*q`cTre6 -rb@d!N!3k!!%!N!93!&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@3JB@iJD@jMEh*bC@0d)("KFh0hEh*N,J#3"!`!+!!S!,B"(!3 -"998!N!--!#!!#!#L!4`!JP99!*!$$!"L!*)!m!'B!)9993#3!``!+!!S!(8"2!# -(998!N!--!%B!TJ#k!GB!KP99!*!$$!!J!!J!SJ%F!)"993#3!``!+!!S!+i"6J# -e998!N!-1!#J!+!$#!D3!L&99+!S!N!--!#J!+!#8!4)#!&99!*!$$!!S!#J!M3% -A!J&993#3!aS&!)!!N!-$05i`$e0dG@CQ5A3J8d9")$8Z-!#3!``,9@j6G(9QCL" -KFcS!N!-)"b"QEfaNCA)!!!3c384$8J-!"RF093e$)K)4jPjZ%'3Y'84UmN3N#a" -CUkBQ*lFpLicJGZI)5EFc8r+CIhHrlpZ+2"[Ic,He3*,9cZc*j%RB[MZ6%C,P9Z5 -*V-M[(j%rNjr*[0R@GK&*&K1b0bh*)LK!iJIr6PQ'N94%1+J,1hML*hBK,0+!l9$ -&S4Cf%PiIcijT$+G2[eNUFK-MbHfpC'm6p0EIcBDF5mJT4aqj[p)@X[AQGIR'*!P -,+@RBhU3A&C159eN[%2cJbH(#&ajm5X-QD0&L4-VGcEkQ`r)XP,P*,SMR)FNFrFA -JLaU$lM`9cA8P820dQ"q1j-RJ+KhQ[L68+ciKBT!!RHr$(BZ5%%MI@aB0YUmG+cH -9Fc#*FlDI2+6+KXfGMlqi[`EXLf[bq5DTS"GBJ&RSpE(k4UNSE)5VZ#(4a%4T(NC -4T5D'+#Hca)G5#DG%eC'a54-U)Z$aJ`C3q')!Y4*YQG#!*634DR+,6CR$@+QN(kF --V(@SLpVJf!+P0U0c9&M$',E[r55!`Li$a$PLQ,KZKIc2X5Gal+,YACH#6FZ"UHV -$eS-Ujc5-Gh6@aB"d'i-,eVDeLc'L6-mKjM,F%r*FlYZBmf)r3FhBZqB8*mKFDkB -mH&M*CEjpUU5NcqMUMHZl,G$)FrP&YX*lJ%6&V")5fb&&5#AJ#$hRCZLJ)NBKdc[ -fS@lc&8+41k84G`VH8bAIPL!j2GVYU6-RjVbF3lRZ&DPJc0[DAFTb'rRhYdi*$'i -YhrbA$q+6*eD"#2hXL3&E#6aS*Xkh8XD5XZL!8d`D3&(YeTiH)j,QXMTfCIrBQ', -QaYKL5NVMZKb[jqBq*1K-Xm!cl6p*FZL0,qj368Vlrpap[%LPH%SI@AC!''TAaj9 -1(AL#-@"3aPPimHVhYlZRfC3AeqX$cDJ8$@fJmqd&j*@%XYf`G)B2KUU3!"Si!i4 -'pV`UFE3TZ%Vi1,Y29L@qKkdk$`8SRBhC9E-k+AX1V!#*JeYF)Z3(X`,GA!A9[Q0 -'IDaq[E"flB1d$rZ$9epp#4ZUUbq"F")bcdZiN!#&AS+9c([M)*1*kmMQF"*$DeK -5eBS,0G(8$DlUGG,@)I*P,r@PJf6iV!k3!+U,`iQMEf'*D&FHY3@1%H!C2CVf%Lk -!`1`-EZQV3EfDc)k)alY-h[lIZ!qhTr,*MDZ6TKGp,[+bNp-`jPQCpEJ64GUkaD! -DXF'80&)2BbYeEc[GB!TTEhMfk&f2mYQTP@l1bb2j`E4mDbafS5aG4rV(QBS,DAF --pIPCbZIRk[pq5'N+mhpAIXl%CM(qp[IPf*a9Cbj2D@i@qUC8h'a@H[,JJMDNfrH -5e-ha@AMdST,jr-qAljL($06eY9h'+bI[Gal`F%%Abe@eJpQRlELVUi0e"4+H`Fl -,5pZHa$lSC'#l'ZAeThN#F3DQm&#m#9iTh-1AH$!(GljqYG"C`e[Aj!i!N!-B!$3 -!!!%F!@J!!3%!!3#3"32S!*!$P!#3!c`!"33JEfBJ"b"TG'9YFbi%8h4[F"Y*G'9 -YFb"bC@eKD@jTEQFJG'mJ9@j6G(9QCMS,9@j6G(9QCQPZCcS!N!-k384$8J-!!'S -08`28kJD[er@b"3!X[(9ef5d!N!2`eUkkbhrK!`15,GMbI`'+QqmlTQ0ea1KZmTL -e$!!!#-*"4%05!`!2J!jG#k`5*(CYCpqGIhLhX@ahRMGQBYMCR-G-PQM[8aXM+$T -[4l%R@JehNa3*TD-X)kfLDJZV5Tp[``K[RC!!lER"++2CdY%'ULV3kRe$V432k"M -Y!L@Y5+XZMFQ@d*6hP3B%l(eihqpZpYNLUCT@eIX$$Ij!)b0JBM-L4#&%0Hl9p+F -Ea)r9peLe3(dD1m-cUEmJTNI22emfpX%chrkrLXhTX3#1T0H(,mLU#Ub-SIi1V$r -ATi"k(6EqLD"rqSK63-,!Dd"UNF"d"JTe3&bP4!2-EdKf'3D*&BJDK+N1i45NHCU -q`IDZM0k4f4m'G[@2[Ih`h5l5j3k1$`4@V[jbZ%DN(0MYq9raa&(HBZTdm2RPHAQ -1XJD(EFLEbk*ijaf262LVa'*DY['r,[pE`&Cpr&ZfL5bUMq9Y,V[Fc$ZJP-r"FbS -AF@JTUdh0+19`pYLM1ecZECDaj5#rS#kd"'2KJ(qY9pP8)qTV%D86m-ZIf!p#2eA -c4VjbShi'lB9U!iC43VK4E[TSV`lc2YUTC$DLDXM4,#Z`pPH5fCZSRi@*$TAEHQ` -XG2r+Y6A5mMIZR6iiXM99)ZCG5j`hP6[1fbhcMEcC2K5jkeh-LIRP)pe2TA*(lhG -pG%'&2*)#lf*@G9qj!rlmR1#acl$T[2,RT66IYec1VcqH#kp[m+aSl$+c@#pX24l -46aT(r`8DYMk4l*hTrN@r8-fSE`5RVNZZAH)k)Dj6G,f2VY85kRV5K2SkH+hf-f) -RDi,B%8d51`deXC2f%l%6[LZ,(E0GTGd,Y)[URrMTd3a6%eAi4aiMp[,J1`@#f*- -kNmf8PGlcc2RfV$qfh3iTDD2bdXGYJYL'$L)MYN+&iXrd9Q0UeL&+bl11KeQ(J-0 -QZB3S"cGmpCBJ0RpQa)CAI'LiPK@ph#bZbES[3L3qfa-1qJP'0EJT[JMY%mV6I4' -[NLDLkr-bA)PXeeZViCDC4@48J[6VB(43%H*9i%3P"&XlkT*-PBI*DF"54V@#qq$ -&T'9(+*S3VPrI20+ljHUe9IhhaXF')NdVY(1V0KqEG$i!bA%,a`YY*GBdMB,9KhH -Yr)fmJ-AMcD@LRY6DSB$,[-Mm%k3R6jLC%I+XBQQIlei"kHB$*SA'ph+DC&TQ&d0 -R3))#`X!Z)5#@6PKp0fd1RSmB0*R2D8-QRhNaj!)T)N+cABL)TGh$[L*K5lHlCAl -&j%4Z1PUBUqEQ,cHNfP`J5@&fFJh63QN@p@IKd*@L*m'`6k+UJULmJH-R8+p"MEM -Xi#ZHbV)NU2$K)Pj3"!Tm*pF#Gjpb&53Q`f`lF$!'RQhJ&*e+3f#*5La9IhcpTCH -QYqhlH["9ppYRVamE12+(DhSq9Dc9Piqjj4li(B5FTULJM[KmRXA3*Ii"Ehmj044 -D$-eDQ(`UAN2JA0QRR+#UkK#`rc,B-kQ*kF93`K)k3i9XBR9q32CP9DAS$&0!d8M -+eU#JI966E1$XUUT9E2[`2AED@H!+I1SH6Vdk14ZbH8)ZUQpVZrL@Q5+*XTf84I@ -8)I)#Z*QT2@cF#H0kl@(1h8I&A&Ap6aSHV-2J'03)bG,#QV$XRQa$G3ULM"rTY&& -G'X+i&IY#T(h,*5k@+,C"`#5#+L8K)bSYPAaPrH9$'RH*N`(D,4Hjel@4DldEarB -9LU'Vh2+b0h98@pKjlY1E2eRTP8d2(%*hRXHM0eZb+Cmh4GUC%!G#DI2@radS9q! -cRX(QHC%UTT3X-H@F6+53!*I-2A$BA"'64c*+15Mei@6*mZVFNRqK+5ahl&RD5[j -EmUc3dh,"Xl,jJZ+c1`L"SN*5[+E@JT,#NdD1$TU3!+A"'#4Li08SH&-qq325'G% -drDK'rI5Vk8,3%4,&D(5U'`Bh@Be0`IZpR3l#I4!kRdTQAU$lTKR%F51M+TN2#@5 -LVGEpfVKrX2I%qZHZq%&4eC2*C+c91UjG(aalpf(KqcqE5LD$00R8HR'mIM#mZqh -K,jr60b"@+LRUSZU,VGViS2Xr2DA"KmjdUS1Q1LTlkje0Al[F-6$P6fGZd'T6[GC -qVGICfc-3r12h"b(h2@86NT,Eq0TV[FkpE6dl"`DFX)N1*5P4%i"+V%Ie`2iU)3% -,4(q(8CLd1fBep2Rh'&8[MBjDMCMb2XURErdmfFAk4RqP*l[Q@fr4cN%[90Q@Z)i -DSrSC8%JVaZC`E1R+0jeR-ACdVYT*ArX1`'D&Z%j!Jd#c%`)SLJ[MjDmI1S0((e1 -J")AX3UTMeqeGHrSXJrB[A3jqGFkj020kf3NN#Z-)!Y2eD06"rmKLlV5BqP,mJpZ -M`Y,-EmVSIiYZU[HR-AYmp%#Nf2*6epbQ[[-*aqP4rp*#XCNj$%X)A,&Pb6@RDf8 -f`2#)rdf`aa)1[YKLGZ9-fVp"G8D&BZ'@JYAlSjZ5'jY+G,5@lGV6R4[@$Jd%qER -fjqm2X,U)fC9[AkB1KBp&fj!!((2$Q!CMdSE$hf)kJpYI%6eTK'Hi3*!!IrXLe`* -pd9'S95jIkb&f-R(8B#a+B#EeT"%IV%ViC#HhDD9ZUEl4(FlN"-UpmJ6XTA-Nr-L -2m3P*68aTjJ3(i12pGeNq2hmT-VJMre&lBE6aUTl'Jl2FEJRM#8N@*%e9m1&i1mA -,1I2Xm1iK$c(E'BT6$l)*VQ`66Qk6b!&TCdc"ZALFYIBeUPXQlAcm1df%cF54&LF -*5BYRic*R"Y`KCq0"`1P@"!e`8aAHRV!f8hafZ1bq2AXVRBP`h!pE%64`4kRL$Sk -l5h&ErJFlmZ2EQKBD&Eb2IUE5dq"U##3kU*YFmfE$66@C0LP9)VGFDGa4!0E3!&& -AGDC0iM!LZa@EXd`#')4Y25DN,D*F0d`d6NXC"JRAEfj)2,j9Bc-0BY!NPbIDJj' -4)libH6KHC-Qd4a8GCN4cl*AaVeZ+bQ3ZlM0RQL1MG0)D$#d0Y#I6'P9d+Y-BR%K -R'k1+rS+8BBX`+8SPZ)0GHc*YB6Im@fGm5iSKZY*MDVfcXXS-RdIN81k9+`#3""8 -!9!"N!)X"KJ!"!3#3"`4,!*!%'!!m!%!!X!'B!!%"!*!(!3F!N!B")N&%3e)$!!1 -+$9-+Qb3!IiC&X0dj141`a3jG5dj2(GX"&32EXIVB$&EecMiSU&KpE-&ZV1V'`$p -MIe6d[rp[Mr0f9KR'kJ!,Q680A&D0p-'14[HZ8aVX",2c+"6FaH)b3VE8Z5$*F`Z -3!0p[JRD#kG&%G-mTHE-6hEc*lLZ&K$2-5eVUQP++(3Xq(j[6I`6`H[ijkXV6kQV -rRepZakZIr82rqj'@*3+i-fUMJQe@`8JQ[%@VE)a9Y9jE2Q+EYiAYB49ph"I'dPT --T*5d!R%I6(k-`pHZ'qD(TKRU8p[f6Gd2ZK"S@S!R"-J!R!"-[ISY!2lU#3-4I`$ -`SR,K!K!FJS!"JQ*J,6L,N8'-h`a#j")kiZTMNXbp+(%I60pdq8A%+fc,'!#3!hG -"4%05!`!!J!e6#eXJ!`1QB-1UDV-`X!%LBQ!h5l(E@C@J)',$(ZVC`*K9-3YM+VV -hTe1X#JZ*BmLfiRI@!&)SrH'p`)*+Z-9!Tf0)-Sk[fIFQ)JkrkFEqqpLI1PG2++D -4"4f4ZS)CZ+2&'UkSDLHN6c)+ldA1"3#3!d`!!J#3"3J!0!!D!4Z)'e"XC@&cC5" -TER0PFR3JC'PcDb"H-#"hDA4S1J#3"JX!#`!V!#ZJ!J4,!*!&(3!d!#d"')J#AM% -!N!-k!!%!N!8f!)F!5J$""!*25`#3"3)!43![!6q)'9i`)'&`F'9KFR-JG'mJBQ8 -JC'&YB@GPC#j,!*!$UN&%3e)$!!#f$9X,8c!$Gh-YCJEX'G2+9FBh011qY99@aMp -[6qr9HVIZ2IrL'aS!!2!0!!$S0Jd!!!Zb,4Z"TIJ(GQIlqH@Y,A269XhI@GL6%@d -lV3-R+QGCfFQZmRMAGd5&i&,%Ii)B&,j%$*hc3NQSKJ%P3S!ZU!lHe3A!Ni8FS"L -dp)0C(qm)NQG"[L$ILXeK[1,pDj-&TB85+iUjFYcRZF,59(MPm@%"!*!$$!!S!#J -!I`&`"+p993!!!3!!!3#3!`+!!!!%3!!!#5!!!"13!!!!*mJ!!%%%!!#"!J!"!!% -!!JI!J!32i%!)''!J%"[m%#3DP!K-'[3NRc)%-N`ek2NN05Jb%$Ii*!J`i!J%(q! -3!J$$r!%$mJ3!J!)N!%##C!!JJL3!%qBN!!R+*!!%NJ3!!L2m!!&!!*!$J!!!!3# -3!`1!!!!(`!!!$q!!!"r`!!!rq!!!Ir`!!2rq!!(rr`!$rrq!"rrr`!rrrq!Irrr -`2rrrq(rrrrcrN!2qIrq3!crrrriIrrrm$rrrq!Irrr!$rrrm!Irrr!$rrr`!Irr -m!$rrr!!Irr`!$r[m!!Icr!!$ir`!!F!!N!1!!*!$!3!Irr`!%!!'!"!!"3!3!!5 -!%!!%3"!!"#!3!!I`%!!!%"!!H"!3!rr3%"rrN!!3rrm3%2rrd"(rrj!!&2rrd"Z -lZl!4N!-3"%4%3!lZlZ!6rrr3&rrrN!!Arrr3&rrJ8"2rjP!4rqP3%rrL8"(rj&! -3rqp3%2mJ8"!!2p!3!!!3(rrrm"rrr!!Irri!(rrr!"rrri!Irrr!(rrri"rrrr! -Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr! -Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr! -Irrr`!!!"!"rrr!!3!!B!%!!&!"!!")!3!!4!%!!%)"!!"r!3!!!3%!"i%"!$rp! -3(rq3!"$rra!3rrr3%IrrN!!8rrr3'lZlX"'3!a!%4%4!$ZlZS"2rrp!Arrq3!"I -rrp!Arq"3%rrZ8"(ri9!6rqC3%IrK8"$rlP!3rb"3%!!rd"!!!"!Irrr`(rrm!"r -rrJ!Irrm!(rrrJ"rrrm!IrrrJ(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"r -rrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"r -rrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!!!!%!(rrm!"!!"J!3!!8!%!!%J"! -!"%!3!!3J%!!(m"!!!"!3!(J3%!2rd"!Irj!!%2rr%"$rrp!4rrq3!"6rrp!EZlZ -`%C!$%!4%4%!1lZlJ%rrrd"Irrj!!&rrrd"Iri&!6rq"3%IrZ8"2rk9!4rqP3%2r -T8"$r)&!3!$r3%!!!%"rrrr!Irr`!(rrq!"rrr`!Irrq!(rrr`"rrrq!Irrr`(rr -rm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rr -rm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rrrm"rrrr!Irrr`(rr -rm!!!!3!!!3#3!`+!!!!%3!!!#5!!!"13!!!!*mJ!!%%%!!#"!J!"!!%!!JI!J!3 -2i%!)''!J%"[m%#3DP!K-'[3NRc)%-N`ek2NN05Jb%$Ii*!J`i!J%(q!3!J$!)!% -$m%!!J!#!!%#"!!!JJJ!!%q3!!!R)!!!%N!!!!!)J!!!"3!#3!i!!!!%!N!-$J!! -!"m!!!!rJ!!!Im!!!2rJ!!(rm!!$rrJ!"rrm!!rrrJ!Irrm!2rrrJ(rrrm$rrrrK -rrrrmrj!$rRrrN!-rrrrq(rrrr!rrrrJ(rrr`!rrri!(rrm!!rrq!!(rr!!!rrJ! -!(r`!!!ri!!!(m!!!!q!!!!(!!*!$J!#3"!G"8&"-!*!'"e0PCc)!!3#3"!G6C@F -c!!*r!*!$"e0PCdi!!rm!N!-(39"36!#3"KaKGA0d!*!$!8P$6L-!N!@%4P*&4J# -3"B3!N!-d399c-J#3!`&*3diM!!-!N!1!!!%!J3!#!))!!`#$4P*&4J!$!*!$J!! -"!)%!!J##!!-!J`#3!b!IU5!a16N`,6Ni)%&XB@4ND@iJ8hPcG'9YFb`J5@jM,J# -3"cd&%i!!N!-&05ia,M-`05ia,M-J3fp`HA*TCfKd)+NJ-6Nj-#dj15`J3@aKC'4 -TEL"6HA0dC@ec,#"*EQ-Z!!!mp%&%3e)$!([3%&804MB5!$%clP2rGhjIKQ'-daM -6DD6N'Q-D3c)c)TZ6T4'553M$Q#EM*#,k8+k+-dK*Q)h)b@+aH3-%M)JDN!"R8fT -T("!5&*T55fNHfaHSZUM,ad0U@C5kP,,mr9%U2)S83`LC[qqlGfEZK%$4YpFkkja -pIJ-EV+FJ5T!!"%%3"%'L'P"GTCqYqq$9Q0%C"Vkr!U![a6BfGk$4@63@TX3rMrT -3#cR,I['[PIf$#d4pjhFb"AAmT,+IVl*aN!#Z[X0'EE(FmkjLXqi8B!ka`[CUClr -hf@fRZMEAr"R'cSkDbUl0U,38MF9V3Q5Skepp-&*0br+BI$$hMXhkaIhKe"d`@AE -pDe4kUX(A9l4P@YBfDpFRU(k,UQ@ScUEU+[imf"mU((HB2`rfTaZT1KY'BIHi`mA -ICa@FArD9-#$@Z)EZqRdi&!Q$&ELcl15VN@R&hiFGD5f-c#mAc4EdaaRi$dUUpiR -6Q+33peckDHXr#!Nr)IbNUrB*jAIrZId1ke9I'ZBU3lJde#RqZHQ2&CfZcVh$fN2 -824)ZTFT"aiLel(GPfPTbPA!+KeXGR4ehD2)"CaJQ1r(N0@r64cU#FEkd"893Rqe -B1q+l9IL,0m!NUBQ81#dD4H6%p+CHVjGqrYMd4mkDk9ere$Zf`Lh#cjEbkGcPQ%l -GjE&Zah6jU2kKlf#IH,,S*ijF5kj)9`T[3(Rl4!NC$Clff$mSUGNR,*Gqh[S"*[m -"*[q"50IpGEI3XP[qi*4SkTEjNP1b'UaP0aLdqNXAq#Kp'JPEI(ppc,TiK$k9aUj -ArI@akB[2+[X!AMbLkEVmHP&afA@j-&mjGD+NVTA0TP@R21pk8P`BiM9iKVSfkmj -Z913U&kK8XDP82TclDrf$Jir(h9a2+Zi-a+i)m4rpSMiCiL*"89Yh$4Q1bUj2A*K -NdSaU'3SD8pRhhbR+5rL`%#LDkeGHBDGc$QarZmTkKI1qCY1@iUFK0JQS9j5A@"q -F0HZpAiS!Q#+J$(@Y#kH8NB-`K4HhPEpU'djp%dY8h-R*+YQ1Bc04"!+a*ijU-ed -$9eD%cFT)e`lPRDj(P@1+66&e[3IM[mR(K`UmjfZXebd4Q&$1[FUaQMrrISN``rJ -FUM&TPNI1&@1"[bm5)GYV(frf,R8K3A&4b9-0f'bqHNRCpfGNZ!DNSA#Sb-X6`d3 -B,#p%N8i+8c"CYM+Uj$8,$2R#AlPRe'CpHc(C4-`RAY8F$#$L#iXLkGZk,keSLa" -[aCH'bG8"3*d+@Z)mp4+VMVPrK3J"Lk[,h'lQK)bJ@89*HJX(Pjc-1EL3!,M""&V -60NIAh3Il[&i2LL)8&%88YjdXUDVXZPY**HrKB,Fqk"1l3m8EDS5@bTB%'lSYa8p -A#@[NNih9NVAc`l)E1Uf45+4XipUcmNF'!+T,Jr&,8L4LM542(dHfccS5pKXf(J8 -DAjSV5NJqG*3q@L29dTiREcKlR5(rkUIQYUZ1d-Fr`I4$X3eFKVf@A)2V`PjRlSA -LIZpSei9+-bV6i4CiDh-0I!M"E*dr0lpKEkMiZ[b'IAMY#Z3h*-eVeaD[,EF#iHc -LkiVRH,ec0T1+e-Z&PC)2V02Rc6')`5dQd6A8pD@emURRmJVcFM`)DUqALcf+@ST -m46HMk14rj0QkMRFG9rUqM$kp'm8m[8qYVQQfPL8l10S2qbX-iC!!CQ*@,pUX@3$ -'RCTIGUQBK$GYm+5h96ieB,`CVclMfZ,9Mh-aT58b$3HE8I!ik@4*9"U%#Yr9GLX -8H100Ga4k[f2FZ&mSIFNA&5@fU@X%"ST3'Bb$iG"qkBj1BaNG+GbaCla(rSf2[,K -l4c,SL+3k-UeipI$D@mpY&mCPp-UlpCcADh`Z8QPFFHXjB6(Q&kqHX4P,cV0QKJ3 -U+h&K!!90P@0Ri'GTF8((89pVC,Aad+'9S5BZeXXeh$TLM!#"P8dXq&PVV63f&KH -FLJkG'mb&H"XLDlc2iUF,%Id5ld3FkH+IJhfqdU+r*eb6XqM[1,CXU0*idVX'RF[ -i*hj-GrQBlX,%B8UJB0G-lZIiH6pqp(hmI"JrfU#lTU+rIef@+pU&EmMSi!)DJi( -9(aE5HbA"8d0!hE$0DXb10QdE-GS`p3&A1YNbZ-$B'28C03LihEA'HhIBb8`!8S! -QDkB)hAPr'S@c9i`3i,"F1%@--F2$4903j,#-ILj'KUJf&EhLSH*1N5VkQSXP43U -"0k2VeKS$Ii$Um(8F3Ble`5F&&r-J'f,K!Xd"&2GB2fN`-'#aPU%)bQrG10S!!e+ -1#iDlF-I4leSheB@12STMQkCFcMjAMd)miErKXPE0RaTMRmlSRd+lc0D0fHF#%MY -6,Ya`a[FS)hB,U+SjeV*'NAh1a$&!k2T(XG9(%pl-2RI#cKd6$$2Ip*heQE')N!" -eihc$`i2#r2!4%I,CV@9Vcc`m)[a)iP[L%aQ@#eLK('@A()C!6!#G+!K8A!$cVUj -(Uafq@kaPefr$iMkDB2"YidAdEF1@(cjVB*4ZX@[SU3(VaS'KTrS`r3X0KZac9M- -[**UDDr$jV@93%SGak(VVaZZ(RMS%0"FQ''+,29l,#ehlTZ,!`Xaia4DkaMY-RAj -DfURbE-9aX&kdm1+3!09N-S(H,KFAZh%4BIX++*!!3mD0iETk"aH2La5-C%-rH+1 -e8D310JS8Jm08MB*B$X4PEb[(UUeDAA@,IM604j91P$'QX%A3iD,rR`p$$(A+fr' -L9bTijD*66ppJYU0mFT%am`'N$AKDS-M299aJjK5![1Ub*mhA!%DA9eQjbJXT1Z0 -V25ji-eqkZR8m&mkS,Vaj%4F1U#jFl[Q#GbNRK,`A9FPK+49N&hU(LelKPkI2fq[ -Yc5X#H%k,G0j2j8lK&-kmI&3N)HAp9-mJ,H9#@6CA)j0N34&1%l)#,GALDd2B'68 -Y0b3940@PA(!8E[rH3K&+8N)pD'BMZhHrV83l%8d[0i6p86X1Ci0)+L3AeeD,2Hq -L1-I2Rj0(29F1Q[9Pp[*5LejKGP"XPRTBiVmEKRP!1(fe-YVH3&3k@D*4dE%P%#` -N,MK&0Vh8qQ-P(EBK+NQpBk!SjC*fHT[$1'mE)QVM6#9P-bJMffc'ZlFKSf"FV&@ -hZN8(a0@15T-R"D'9+T8[e#,l9#r+NB&F24a!N!!lA8-6`mNDS!jm)+0eDU8!-AI -MCai11@dPR(N`rUjEi#%)1#Mi'"p(P1C2&"`lQA5*LM"jm5"$DRVS#Df&e-iV(J[ -3fQc6HA05dTH!C8f*bkF9,La(-8)+PdYaaBiXmHSj*ii,CY$NJ(2)k0VM40!i282 -'NjaGPTc("B4hkEd5#021a83hIZKV9ENRQ+9mD45&U3VP@kR)RcFk,f9+YqBDVGZ -1'%rHfJRJ[@$L6J$[3`5ZYa1i&U)V[[(*4QcXm41a`(+Ai@3*-QKRj3kae&SjF5F -jUqGS+)DbF`H@F*`@&1pS`J)T#2*G2#eRf1$)25mi!k)qGU2SGUf0#@bXC5M)F4c -dmrAc+,)X,m(&L#r$@JC`1D`5C(b#Q3*#j1@DD,N4f49CY&KlI,&$aMCpSfCpid4 -AZkpe3-K,jJAlc-%%$UI&p6+T@BSMH4DFX@RPDZ2*j+@#5Q0f-N$U3S3rG0fST4J -jN!!kI+dHmd%lYYr*!CKFSNEUiH!h23$f3I(h-K!fJCR%8F89IF#S"6(L&INSQ-h -*"j@hZajpS%)S!(Y)9U8cP9D3!%99hBJ&L#%Cb32RSPmm[9F-!&N0)kXq&Yp84dB -!Y`N**J"b-3DX9m,Api$m[)km82`QMT`AV+2'm6S3aBb0E4%MK$P0aFC861DQK-f -4[`4apjhU,,l2Sc1Y0mSU!AHrp1AHSr(ZVp#GeVX(iYfjk$E,h5mQ8,M4EGHl%bJ -#k2EVh3N8)34VE5+"J&3Y[IpHfBc!d4LUVdl,JR'c&pN,*L"4M0TaFE"60*'LXKX -CK32V&h)%V8kmLUYc83i+jjdY$S24I9j!8H[!M`,6BYAJS[8,JGSGE8+dZ`[U8LN -V4XHC[IfqY#C#@BTlrHd-9TdL#8)&G"dG"$TF)J3`c"f+&(VVk1VfS+X@U)aZVaR -QT&fk%QR%PA%8#D1JbP[MDleYC$e8%a#ThXY(G-4')&`'8q!R30S@rBY4`bCPk'# -`jIDQj1[VGj!!#8e-Um'9-8cQ*S-CT%`TVi04H`8l46pe&AS*C-'B'J8j@eqN1$H -E5H4`*(3E%j!!Q63Kq6l32k&)c!3L19BDQSQ-%@3mhQCNA['UYPQHCqB3TQ4leGZ -fkBLFS)`meV`R0ArkI%2pS0C8rlCYM+mahMeQ[U&Um"`E@eEb"PQ1)eQq,-Ad@22 -"SbB6-EA*G49JUd(TV,B098"KG([Rl"IA!l&@lHZX0r&Khbk62rp(`TaX)A+h1BV -jXHEEpTK-hRl0lqKFIQ6I2"HZKGfm"5m28qL2*jJ!ZkbDU%6(6&E+f5%80CM$(CE -$BQ4[Nqm`EiCTMUQahBF-KdNi$MZb9Zd9jRdJ!b%Ke!&*Fp&B'+*08#P0-"f(pSQ -FcHJHNd#rJ3[14G%%)K!&ZUllI1le1@TPb,[1Nli0E1Pp##q,Yaq'IC1h&i'pVLZ -AQ$P,CfD66#MPN4855q3[V@5J5#ebaTAbIKKB,rNLDhT"YT!!+@P4Df&[q8&chT2 -l*DfF`3IF0!GRPG@$"IDH`!m8PYkM4AQ@0Db-pCBRUe'mmfE[L8S6+NrdRYMRY"6 -DXp"4LJUZ&2U*j0%-4FMPk(b2N!!bqb`If6I*N5Z6BUiFfAFQJZJE!(9Sl!c2d0L -PeXcY6PiZ4r3`&ii8&lbV*++DmT)`*59l3f6ef&iqp$!bD#*b*l*S)KHUj0$BAXr -3#l8i,P`MP,8aAC1L1lD0M1hYkA05f'[d,K1MLp4,Ed'jH)q8)4"GKK9@82(Cja, -[)10damM%-+XE*f-,FEVXB--aljA`G5Le)pE+&983pHfqeZL18DYA9'e$apMKSC& -HFq)3Uf*!@j!!ieC2,5R-EkJ3&IDD%AA"(,2pKQl(SVIL`m3GH)@-$eNUK63a&#j -&PXZR#A0je,YY"%YB2FF`1,cGf3P&!1"VB,Z6!CLeF)1C9%X$-QQAf-A"HST%qi5 -CZNd8ADkH)r4Z1hHRPXVG`m2l4AfDPfMC#3Mb&BQ`"KqB2Ej#4H1$F$5JL&k6q!# -5m,KVK)k$PMpBKS4j)XJm[Xc#dSBQlRc(`1S+'bJk&rAqIe&cPa[*eGal&++XCjC -$`Y[P%VD5C!Zkh(UA`PeKm`G!`-QhSYbK(1`,5A,fJ!mK5i$0X)@lpqLHeY''4NR -H,[q#V@5IqBiX@ZK4I@)MYK)9'U&R-KbG#ia,C'"TG)-JRdA5JQY0-!MFMTmYZ0T -&kNplNXc6%m-!h[1hiI0B'!53!-4`Q*FaZ+Mh++YMYq*5c'63Dm+28cBCr#HrT6+ -5Dp`,9%hKGM+A31ahMFK)S4L+8'E8Q`pffT[0#cf5'DdJ3R!L)[Ad&6pGQ59h!(5 -P3"$TU(E1@p2VV,LDAHK,pcS"cP*+a8')IhK,1E&BIEdiS%8jk,56L+EbeUl*+9M -,9`cCK8,d1ZHKf'6pFqKqIbjA055)%DH`i!9cB*-Hh$Y2P""M!LP)ipcVfcMCM)K -NLXbKp#(''#iNTX)hA,@)&YBX"p$jmRSPhBC+YTZhm`KC5609a`)P-Jd'U5GB&'B -!VUA(%k+3!!TG4j)DLaE*qAD!M5fX@P0b6L9VJMi8c0l$hHV%)rN)e'cK3l'J4"* -l2cL*55N@$5Am*4iNNZ&Cf-4jC&([9bHR)qXNa)HZ)f&rC'MD0)dB!JS)JTNA1@f -DV351U3ELQ`rac6G85j-*X%1p6&e%C4beD11E@(h`a1kD%$baX%PR2j[([Akjajf -cZBFY9M+MHY)m+D"@3&$1fDD@@""9#`SNj!"TbR`SF!+6'CkE!%TSN!$3k'YPi!* -`Sa!#fEMhCR("PU8`lR(@,e0&I%Z+BP5UVT2mC9I$*NZGm+B[*ee4%eaRS#j8D6% -MHViH,h[b+$jRK2D'B9k+(kj0ASUDqA"lRI32PM31Pq*P6r,R$1QV*)T[TNh8&`& -6kCE5Nb@b+#J`*XT%dP!++6ZUY)+G3NU*4h3p3BAAPZ+eVXc3bcqUmI@*YV&C09C -8S#lqF(2BbF9Q81khGl8GK,%%PrI"L!ffVV&Ur[3Y9p"q"Ujcm8M&513%$0QpZeD -*%"S)VARNR$F(qKYRMlH()biB13U94eKe$p&@[NHiS4+F+c9EUq#%4%Jl(AQ*VS4 -`f"NfSGZ-EMmUD4(#4l0P3)3N6f(+15"j(#1hM)J-3PCU'K$Q+c9Krbf-e'6*21J -0[IbCl'jh$S3ZSEML(hB"X1FVlr`%KE5$M`b+P'XJ01T(JCB"D32Qm+3&"S9N#JZ -rpjDG)N1mqdKQb#P+ACRT'C@jf,S8erXLBCL@Hj@5Kc06*d3JDM*UbDU(Gi+1Vpf -BNHbiFkIi5[MZ2(I%FHTYF6SUiE2rNCf`,jC#`0H88c8JmMkdDQ%Y&bNb8c!iP3[ -fZ0UeQSVfS&)*#ibfE1"VeUT48(IFelI`Ba"[@PBdK2fZKR#,0U1cAbLrAi[L5Mj -Q)%)%*a-Kf&iYAS[M$Qh4rNrh[)KS@k[miXZGU1aimAqrZ"q9jZLHI5!D%+16dDG -"EL!Qr6ml&+iXqG&R1e#41VlB[IG(U%3U+rQ!Y'22&j9FDGk,'PH%rJGf1PZ$3)k -D,5q*Tp'SV-Ab8QJr9&UcBd6c1`FX2cc*aI-D$$%$dPHS(Z#SP`-0MJ["D*Bmi3% -pf)iU*8X",ZrkLqq[EUYPT$83EVH-(!b%RAJ0K%[403!L$+'9BPZBZM8BC*LCJ8V -)39ei@XlF9*%SRdp2bj+MUXqENhjF%CUI#"+jk(fGc!kL[FED%JL,R2NV4(,'U*m -S80pc9K!lqc2-GY0fC(5)3GU$'-6%$!+P+!2(Df9QV'cRU9PqBF'1B3YHk8TcaBL -m`"a0[6$1G#N$NZRcCM5HHKA*Y$h[9D89akiA)VKS@PC``@MR["Y%!!hk-N6(``K -XdGjP4Q#RLVqT1BD#Z1[iiX89BL24@P"J#6%k!pB4japF(M6M+mA,(cC2l01FAAf -D4AE(pH&+A`V6D39EaB#$[+!lSA#,PSFjFp`HU4FGq,NMNJGQlqM5,#2HGFP3Pf# -Qh*8R!PKSLdiBNiSKS%N%ZL4j%XUaFM#X%"p[e%+fMI%Y6%*jQ$2H!6C`hrQaU)V -X&)hBaZf5NZDZN!!@kNScF[jFN`IL*JL$0VN1+-S)4BS@bH+k%8G,qFM*9qP!2Ke -SS301H4*Gb)CKLp0GPQ4Tja)3pba#SPSM,&h[hXD0eQ6dTBP!8@p!#,Chfd5HU!8 -6r5jrSN3+)F@1a!0A2K43(A,hF+J8$-"('dNdlUjF1E(AF',(33E'+#ifSBKJ%3" -!#3X8c06U0U$Kb!L#fkQCR8Z%"-$F(h%5)jJ9@p'I`!cQQQB!G"-A+4)L#a#CLri -E1Th-+MA0LF!A3PF*lf15PD)Z&RlNZdTVZ)B,1Ad"N!$CQm,Y+dBq!m&)a@$Bl`a -F9kE0F$SG)ehZ''#L5GhX551Mj[6HMBcDcFDQieb3!'&"-i2&e'`&'8BI"bkC)@, -EbaH(1+Yh0fAe&XHcHMFEE`aQ-cTF5aR$GZm%('caINjAhd#@H0*[q2U[L-5N#pG -VSaeXD1#YXB4RDHY!I'XR-He&)c1QTSC+AKL8!(%E%`&1B"-U6"'INc!))5%"2%c -@%p'NM"33*KNBiUhbD0)6q4*pHKH0*4J8G-$)&Y!hDJN53"-YfNQE@,a[d)6pX3P -$e*r6-Y[Mbj3EhYAHaTFQd+A2DG2%mVEh*1bTA"KmR4FL29biq6BqY*J$1aSbDR( -!8C*J+*VXBK,E3a3Ja&c4$(fb6Kq6f(16*fjH)8pq5Bq6[jf0!$!mTQ$)+i8"Y#A -@C0!biKH9aaQ82j8P0e6,kj!!QiceRj8EUS8$8+AY-,pGDH9#$6)FL5BdAGTmcU[ -qa)dXN@(,1pkDY1!$0A2SIqKi+mLS6*C1llr$-$hp2EP"hb)QkN4"`Xdi[*X1,iS -9MmL&6pi32Rh&ahN$(*f*$La%ZG,eRJH0q(M$SNrkB2SYqZAa9XXD,[Eb$LHEk!V -3kFdT*JkdDU@a6LaRe3#@N``GK`(biIY6QXr28j&9@99NF$X6!9(6%lQjM$0)@(9 -"`VT$&YDF!lU`,,*!mZj!jU%X*Tl)Af6Kp)j4#fI169KkTrGhbCEi`@PX,1KG`8* -,AJX@eSBZA%lf*+cemr!T1b'X$@[3JF+,SPp-A6`EcJ5,CmkNB2()$BKL,!XJkH( -LVhi$#!e-XZ,2S*hC6bD*Fecir,YK0#h6@RjSSND!+Cp8-BJ#L5e4+FLSR'LS9h' -pdrU4ic)Dk8TlqFVeq`A)VYa9&ErlT(`kLK[Ch0Y!"J!UJ&+@#6mU6DLJb&qc1$U -McVQ'j8FUel(bIeTPj#q0&jKPLX!Y4mhD!FXM`Uf)C,B[a-@mA!`mfZ#id(3"*V& -Uj@f3!0rQ9Qfr-Iq%Yd&dS*6CBKGII'V"kpTRIM2D#G5Mm)+0`hba6PTKf(Fc&Q# -UL,JLKH-S-a50EIj"LEAb"4K8+Nk9IeTFF-YL4#6qb1SAGQT()F+K&hD#!!f"h(4 -@D8ffb&fbbHl'BDK,6VN,"biTVAb0M!#lb[mhNGI&MImZI%)4Q(liVa'P0HEFmT! -!dXV'3*!!ep(KIL-hM03,Z*`3500qqAUpI-9$KC2pLi'QMaZ%ZQU6TG9VqTG8VHQ -r(91%`8Za`1a9Ld0'2Ja69KF&5(D-!HN6IkM5LiFXe3"'95KUKS(4&6p@ZH)S(eZ -ISarcUBj96ACXVRiXP6MQ6-HDA-U-K1CG*Xii4)APl%(m*5f@#e6K"V1A,'I,Mj` -SjmiGqelmJMT6VV0*[qX#'Va+XB+$50M6PpbhGiHFN!$ZFVQ1[92'6IT0ELDC1E# -a6-S9D-C+"AkM6R@qCadmF#6V9(&Z9NPflK'(6(c$5,lBqp+,1K,re*!![+8M'F` -q09Majm(L`F1-4NE%#3NUPeQ[f2@+RbSljB3@&4J#)k9r+Y8r&HXG0LjHCi-bJR5 -RF)!CLSH1bBJ(PiM4b&C94qh+EcN6ka[&NBQHV8*ddhbUde&42ZJS&k)Md,RRdbp -fIkTmZDm`q9,ik6eIl!BpY[,&LpI,#mhaC'$+9"$Z2iiQZHEckl43j$!Ak3'PaBe -SKj@Z0`PPLBdZ[Fa4%dJqqQ[QlQS$#A!r)RZ)brZqV',FKQbcGaR-ES8iHS`,5!i -CQ$L&%FVSaKb!b(*c6cNUE%FkjB9-pf3!E@N3@L1KAFAER@a'iF3N8URb#2@B'1T -$VFP[G'A'b*8l!9j&#-&PpLil8&D$iS("k!S3b4rBD%!@ilbNqCKd1+FGNkf@Tmi -*&LLI`-rdU#A[[N1Y"mS-EZm6)(k8`U(cdQf(4BZESYqlHaPd[TC9mKkBjP6f%6f -`8D#I3FTKE2Nk`B[cC(2Rhi3MqU3F6,6`rTLi[4D`eRr0cA"Q*0hR*,l#l#%I1ZL -A$q8XBF(9#8G@9-Ur(*lTZXaAIR1B)cNa5em5)VRT&Cf$a6%Z&R+#)[BTjFRacd' -pb,bi`$N`G%a@AH6T)#%i1"&dPK4RR6SX6`Z63S'Da%$Ga1,UR3KaAI,dX@hGd`H -LrL3Mp9LXHd(!)PKN@Me-cL$)i3LZZ'$4$J4,Hb4mN!!,BHJB2L`X,TM4HkJ9iV4 -Nhqmdm"*JTPVl-ZpZ3bP4d!5mie#J4`[J*UlR"59#ELlH!Y1-MC-KJQDGkdhkF-Q -9qr9'C,LDA,N(0VPJ8Uqf[22M6p*R3pf2[F-Afp'JeTP#"VP-3VF*Y$QPI#b5&6Z -i-ZXE1KLCj[0[l!84cfiQV9a[FVGb)fIAQe"mhSpN4H`i@0CLPe'&I45`,BNVQ2) -iA&[Fd5Th-[&F*iL5PGrk4J(4*UHGXkhBF!",F)Ch8G#$@#fRPJ2G,C++M&)RiQ" -NEh5d%TT&)%!%'KN&6D!'#HCflcJN'$60B6(Kd(-!%f#qQVR-I0FNTchTGi1iF[d -hQ)+6f+0&4P`kbGe+SRf6#dUq#l2Cd'%HjX)jV,-*9-i'X-RK)m9(()2ChEP&$V! -CB*K!6"%i,eb0`LB,2pPh@i9haY#2@'8K"@J'9*99lPB3*fEEQQX`a%--L2f"$@$ -f5+2`bd[jJl`8CrEp!8--Y%eK3!5SF5VVJmN@)5Ll!-$SLjTl"SbMF6hh50EJHpR -PI,&im-qih0jdUR$hThX+2pfYf-$DRqljY2$,6emNK%j@J`d9)"$&6dTcFY%TQMY -BEQ-6AdSc4`S6+[iBfa((RmY,XLUiSPS3-fc5&&h(i!r')*%!Jdpd@Spd[RfUZ1* -8VTcSd+`l,8l,30m8BAB[ABAVlj6Y#DhJbXEGdZIqGcCY#K%S%eSM(k%06Z[*(35 -qlaSS1%fb%0%d5!lf6b(+&S#0XN65Ib+Va0&j*,%!HF*KQ6QJUT8@!&58kSXZM3h -lm)VM52D4`BUJLajZG'[L3$p34Y'MaE9A&)HCV+biD%)%$S,99RmX0[(X%L$)+V% -G+Bi4ech*M*2U`!*NjMP3jV+r`b"ECL+6%`A-bG$j2e,b3q4#"'XJA!0`+8Af`Bk -%Br1eXZUqp*kq9UKA[j568I4hq4$%RYqZH*23&6VYm3!eD9SN#f,m+KLGKk)-q3A -$p)b"9[9RU!6j2@frIVkqI9+p2CCVq8pCS[J24a#G0`Ul,m-miVdTl2q(%4$NbJ( -c"3)'`fSiYm3%c*&hj-MK8m9b`ZURi!$JATr2dAmXqXLCrTYMhJdF3FEBk3`Z(LR -1e40$$MHcSJ3CFHF-0pk#!8F-V(*([BSK+ZT(#'e!M[TbrJEdCpfYlj4aSc3A9"! -#P2)#N`3@eiJQ!VVF8!L&5$R$V,C(4YKSBLhc#+@96B*'0ah'KZpXG*hjHK1Z@3i -%!@)%hN5)CmS!XfJ!"42&43d*FH(c'5`-SRIBH*-mTIjBiV0L5FDAK-KP'LZ@Imq -XDifDmbr[NcrY`+G$L[d$!bCEcK&`64XYSXce&LfrCY9EHdedp$-Ye(L,dR6#i*' -*bIba+4`d&c9!46EcB$+kN!$F,+$Ha4$r-$B`Zp%S#B&f'Q!T"L#E%!86J#cRL%c -%%V-HJ5)6U,3q9H0ZV[p9*!a#A8@IEMYYd%50UhJ465LZcA5h@YlN55DE2%em%BE -@+PP99!cR"6B1a#*2E!aM69YLBqXJ5$RL!*Q9%PV!H4BGa%r+f@`+K((beVVLFaF -!FUdEE)X"Gije[A6*F,S9acU#PbF2fi-#Yd)hIlj%KqZSNI9XHCRUbH')3NFHl6j -*(8fpZp9MDI8lqHT@I6PZ@XUe1YiJj,BV(("[8X#"8$8Q$&d%Xa)LL#N`DKR)K-F -8!#bkFUHcE"@65$S-Ki5(Pf0L"6I"Z1aH0b8Q@SiUAZNXXAd!'q+TiX-Plj@VK-U -*UJP%4Xl)BH8++`c*HYGE$&b5LZ[bee`*H&Mj!T(@NTNe'2$Vk`XVk!-PJF0*4rf -4hrjH2e$3f-SLa#,pLF93F,IRla5K!icq8Sf9KqPCmI%hM*`M"FXZThAMUJZ%e(b -SchXBD$'FQ)b+6*4%@Kf-8ZjF1`C-X*48#K6e!)c-C8I1BNMFX6R4%H+1PBQ10(I -N*6V-h0'Jk'6GD2DfG25BYJYNY$,F4X%88!A6%qm9f`Blhcj5A1li)#E-*eQB6ME -+p#$-fQ"K2[Lb,XcD)'(QaS6jB''G,%a60f'DTLT-%`Zc)&LB@6)LbP4-,NUpXe( -F1mEMCc'#`E)5$*BiI"ZTkB%Y#69p60CJ46P5Ubk&1+")Xb!S#Sd`BidiEiN-YM5 -Y'#R-M$PYJhh)"*bAd0'8IlM5!D2$L2-4$854[PB8iRcaU4#PU2`20(,dJkTF1@5 -J)dHM8cRLDmdraY%3'KiHeXE*U,q@Sfp@ZFTL5H(P8aA)HKp"G&p5I'!`VU!MdNk -Ep+%f,!aN+!#VA9-S!#mK!Z"+1`8J329MkcJ!9j`jPSM8!`ab2*69BB-"J1`N'Ac -SLE`X`6i[bf$Zci-fYI"bBNa%3hiJSZ[PM%,0&3)D!Fm94#+p,-,J5%TIDSZqe"3 -LV&k9UV%hNR90d0,XHX4ElMU@2%!Uf3J+dpTAMAc0fB3"lM)KJbpZT1LbRXfB[#9 -rd*0A63XQMBqb3TGe'YIVlF4%5$)c$9U$RZ8SG@8&4lR**Ke`dT!!IA,Qh0dU#bE -18K$-2d%`ZP41(DP)k,3)S0R)f$-5*jT+PXF-M'M)FakUYb*r![!HpX3cK[DG!-V -S!TLp$eXeaE1m&MN!X&&L"e2'Rlq)4PmU$-ZEkF`!B&Y[B!2+Pp(#h6+Srp1(%"p -2Tim"Y+a@4Hr-Uk[rP@Y+%T'a34JNV4i(##`6-4-+-r2Uh"K+$+LDSUDm1QD,4X( -)jHb!XdaPk1M8$4daTT3c[S`+Q5-CPD`d*9"4"1-ISS`S+m5kJD-cEZ#)4Gi@AMM -`M%B%IQQb#0b05+RFBp)9XRiXZ63fNH+#"6NF85,UDS*!@e@,MdFaf$+fpL#&`6@ -&Qefa1Z"eZeZeP*b!&KhJ+*14$F8cd,VD*kmlPZ%Sa9#B#'#ZHTbaE$qQiDHXHKe -RrM9Cp5K0'!AqC@f`83"Ua@6C2(f$&Qa36aZdH*``fr02U@UMP,LNEp5ZAC+cQGf -23De@q%!LHrRV8jhMc9hU'eZ`m@RDf1*aaTNPV@rQe&TNFjQm`EHLh"N60Fad2H3 -CTiVibRJ32kY'$09MXYaN((%UMMK&JM+4JF5Z)bl9%DGD#I(5AZk-C3(!'RS13%F -@L!Xp3)Y-+&3bBUI`kiK2kd)2G$q'M-[YI##KXVl'3YFe9RfM*Qa844Xed8EU65b -L5YmNS(96$Z80[M1'2`DTTYheXS[EU'2U'mfH',c4Ur'**$6JH1Dl,4bJM8cBL%& -#5NGZd8TM'DZP(+Kk*ZVbU8l+3qN)R2(%j25S&`Qb!"e4NjkB9![XVq82#H$jbUR -1)0Kj88)i2A8Kc$%(#f%+E6*C2("aQc90IE2KTZ$0AL'"*q*L[8',$d0kF)1E8Xj -dFV(20D%P6ppLmBYrrXb%4ZUGMPS8f[M&fKhe)#B*XG+f[EV*i'T"i`X,0f-[Vbh -[[1E9GMQQ1fV,RbM[e2KJQJqDF[5$TA+$p`1e"rLSLBmHH1*!jr,$P@m`3&*UIAB -8h3bV#kFZqIT8#mX8qd(SBTV5J3badfiQ8Q%,[rlj-hceh4UL*[U`k*9+Tk8kD8$ -+NXUPck5SG&iD)df3!2+NjG)RdRaTPV4)kJfP3S&3GHKS+"+bKEi*l3eG#c@(hJK -0$+d)PBAQKfD&&S9kdkRdkA4GHL#GP5j2*p1ldfI68p,'G(jk8hTYHR&kYMPNGTT -Vc%I0@HCbFp+mfhc@h'DHC(l1A'$HE*jRAQ+HB6IC1qcepZ0fUrf!IBGpMpeJIpR -qV(f0[F`qhhk2IBEIj'rherZ2qh2p"r`lrGImBrb6r2Rq6IkerXAqf4RqM+D-QJa -IaU'-l)b[-RCQl-qSc4LGdC@a)U-XBeh'[4N,-fDB3UC58iHTfV6,G-MN-Kd`IGE -8+hk-RpVbUjV)51VZCA*2k1kEj,Tdpc9bqh4h&,PZhAf$A%9hRb@h4AHI)YHXZeh -XqQISVT(F*ESlNGbCZMZ@h*Yep`9bhpIGDH6Qkfi4Z8EGc50hLZiZ)rH-lMj2EUE -ZVLChUqiq4qj*h9e$EV(ZrT,F%Ghp"EQlG2H(j&ETlJTbfhAhFh*0ZVZFAAZrl[k -!h0YeYi$FZhAhqq5ZeGhr)(H6lUiLph08&q2(`%)p`&dX!$k86`HQk#k*f(j'GdQ -SpNcG*6(DYkT3'3R9#If![1!B!rb+h$lp)`R)lYCG#J+lSU1UMD-Ue3q3!#$X3RF -TL-a,pH1[aDCJRU9[GBB1c0IG"R)rdBmhifF5(9qKSk2J-%p8SCY)"dDVZPkJ,S0 -qKCM*[%Gh+5$-1e3ER+AM$PAA+1SD8A@p5PdXJ(pRi4%54AAJH6S3%`#aS6NQ!!V -X0!YJA8aikA[dkBiMGjlZVL4hXhlahmJYd&e+@1RRG*IB0ce*YB3*[)6d'&3ra-p -S1R"H*C4Q1V"AGH8-GAfPSk6%NXl@A@,#p#%9XibMiihk!8VBk8[k`NNJDDIZAL8 -hT,[ra'jS0USIa4B@HNKhhb*hVQUEYhLEd)HUVLR8T8i!ce+A8GAe-qTU8h8e80G -j9GI2U@Z[[Uc[dGEIk!GqMCrTG#"E2d$#$ah5&dS"%r,Tabm`dp0a&X#r-2[(Q$T -N8@hjIHk5qP9G"G5e4,r'JAQ"ZZDTZSJGT8p8ejkLVPJ#S+9,%e8(+1LPdDSZ5M+ -53G@96ef&q[61%K*0GkH6kp$G#q6QkZi6j"lAh@CbkhAh&A)lG2GPFLfkqbUl)NG -haj!!Zd9h+GKTDHa1)IF'A34M@ILm@"%$J-3biR2GR8$Z10hp+EN0Z[YcFM(FM[K -%"a6R82N[1SL*kJj(9cYdB6+J2k&rB-#6V6Z-DN4hH-ZMqJ9QK(Vp`mrJR0BGASK -6GcJD06Gpj,MUH-*RGZ6QCe@+aj1NbPcP"X-*JRbp)6Bhe`TadbFc0k4Z)39Q%bN -`lhiQc&YM#S`i$HU+m[6@G*GCNrqPPe2PU0Q&Lh9#SUYGG,893rc0M9pG,LB*Ul# -*G4KrG*di)(D,R@+-@#BQ`[e-E%)ML'ZSVK1&iS`i+6D,9A"'LhcUA#FDf[[%8ba -B9)bSR%9PV(B0ViRDEVc'DB9ij@Nlm5V52X2VHHdNAXpT"r$kK@E$kh20KGF2Y&b -mrN-lK0FUE3#[-QdAAKZe4V`fDG9ir9G0`@ZceS(A69S6AVeD+9l$QJQ[2fQJm(D -L5DEpT'V5XVThm$-4USqVHq1NY9$VRX18Qd%bhLEG+aUNQk4jdQaTXE4%@K5k*,T -#IUNrK)3PmN+AT$BSITC3LmJ2AB*V%'9L*83a9k`9Xk3'X83-Lbe3)8e5!1-R+9) -p$[QN%5L69ZQ%C*0@5Ph56NQ$8TP*#0l(BN&m,Ne!j3)R6P61SX*#j'6#3Ua&KF9 -i'C8pU*a"C5XUEk,#BQa'j5Y8AZ2%LFTd9&L-6k!5338$*NVASr)++Lc'Pe'T3q9 -99'T3DH2%LFSS9&T3'Be+#T@h8!QK-J@"fBr+2k'b&*8h8&Q)bUmjFD,5J-T-9$# -!U*L2bJ48EN,PTj`i8AN@P3*8ISE+#P3QSE)-P9qKBN4P'LSXJ$@SX!"qU624qcS -6r4XadAmK*VUCQ1KILBRQ%420*5CkM*MS)@+L"iQ*PK!6rBfBD#%adGq*L@iR*PT -!6,5)Q1KIL)Qq48bdP*MS,Q+Lf6%Q5JI3E18A6&,[l"2I33F6q#2L8V(@k(!T$ep -!cJ0KC2#"B"dKqhG#pYXBXY$03$CD4rB*1PC4!q2P-V,LJZrG)2B#b4Rmr!bNp&a -Ya1Y0`9DH"R*q6Um*p2STaMS8iPQ3!&lc"Cl1$*VJic6"166"ITVJ"TVJHPT8$Lh -+'er8!"C9T#rUrd*(25fU"Yd'[I[lk'LKEJZpr!"'D3C'8Rpl#jVf,%Ee$3c,M8R -mk3QD6!K0dG$8rRYQ+4-TlbdKIMdG!jqK+MAK0B9H$AKbL$$mR&i6-+kH-$`VJBc -%m$0k6C)`18-AJ)i`2#9ei'9%$NiBaSQEmFURVZq,'AJ9m1Y#VEJ(Y'e'0'`4c@F -&L$bEcd!dS[P9F4k[8@)2AK2)Q54JpQKqRNAp@M0rH+f,aIRD4)bD,Pjl33c3FYX -JT#kGH9r3QAHCcVbVGHE0ejPhKFkm2p5CGlR1[0mMjPe*c&Y!c2YMBYk2L(Nr*1E -p#6([@Q,HkiKjja2crTkBp`CLhYm4mrjR#YbC&,Mh8Z$qG`VF@45iLbP`raX&lMe -ki*j%i2a,dYBpD#aAK4MlEfJ)MBUa+acJbR-BF)3UCm00@J")YK$D2a,DZ`RYr6T -D2cd53X5'jC!!'qh63fCNi`%-"k++Klf`PP&68dYX##!d(2$ad#Ua62Vk-da!@U8 -6MR#"d0"@%+mhh,B9K1c2SP'm8A%C-f48+1Dkfl)eNSXKkIc4G3aX"ZT%,KU14p" -`TdiFUMG3a9eY3-2k"JcNrLbDhS0FHrdC%)q0id'e3m+lM*UrVf$A,)K!r8aA50r -JR+A3ZLdRP0crl4&J+hH11GYY%ZXRl(+[0eShPPrB[IfaS[N'$&SIK$CXaX!!e@K -NHFCDaY'2G9[B[(qGe[*!iISe`PHrC[hbkMAV9l"J1G+AL9i(-A6ETBIN"l[)`d+ -JF@J9GFqZDSCM)QG596-'6E,X`b!"22$Kip%6*BS,!kKJd#VUX*dSdA*8JpJNN!! -&AMm#qBVF&)-ECX3lTqJ,(ZPa`DjR[Q"jJp1p28b!N!$ra[Q235iM)d-AL&fNE`B -Ar2KQ)(6C5UU1"3m%JNdZbCp4P)$$1FYjUj-PqdcFI&6HU[XP1VJZK[5%#LN6@D1 -jeU0L@6K3mkJBTdKY4F*ihk!`+UG!XRAT2UZB00N#kS$U3&8c[h#S#JrVDU,&V1i -hM(ma)1j86h*eIqEND'M3N!!1$$"La-qi'jR!DCRLiSAJmk3(H(![Jc"DYb**Vqj -9d'`K"b,03BF4Jr40`L"p(F8B'1DJQcVj82d$q)KTmB"1cU$!A!$fSBD#$!bk"i3 -Xj%da)DrH)#j#b,'*$FYAD6+Q4"$fX%&@E)2qZDpMJlAbe@qr`FEHClS"Alf)$3b -a$AShAa36VZiYNkr4%$(Q"#Y5JPSFbeLikX#1+4IB)'Q1`+'1*J6[*-Fb-HNh0Uq -hBKQTp'8ie*'8PpemJKY8VicbSd`@UPLN9apbDL&q[$%@`5!A)!D0-3N$4K#G4p& -FiVIKV8cbLL5iPiDBUrca[83NZ(S1$j%hJ`K+9fmBd"Y1J,"Gf)iXq-4[VG```Kd -dr4-mD+4qG%4h'%@HlJ#pQ!Q'2-528p%(bfSG2c!3"`BAh03iAQ$J(Pc`8909-b0 -AA$3X,VD5382rXa`X(19G4))Xk&dSSq)NK@eC!$QHSE)CFR%8Sij[d+"2K3mk+A& -9p`MB5`N)UMEA,!3#9dm1!'2*8"k`fHQ,2IDRQSN33+EI)e2XiL(NUqZ%F6Q1l+8 -"jCP0DYlQS993Z)lAG@!CVSb5@@BGX8`,"T!!Zd*XdkB2,9'!S3f%b+HKB(MJQei -9#rA("K[dA!PLS2la-K#+YVf0e1bJmK-I&6h,$$5E'ZV)$(3l2mi2B0N*"NVU$(4 -2%!2GVQ+Jf5S'![SFEVKr5*%IZUBD--a*$90BD&8rSL"Srk#%L+-jN!$6e!!)aFG -SSSqQm"!#Ger"0Ni@3`b9APL4bH4BFV',mNk0VHBP&,H-5Ja!'%ZXmH)C&ZF54Nf -$T@4KQ"CXU,#)fN#ZI9aZ`$#R8%q1`rbS#dbpcATY6M806UHH1KrP49e5dLUP,V% -TEcDV@N5pbhPS&5Z'-mVNJ9!QfdiNYKYq&YZYX&iEAYR6GX2'i1eL"6Db3116[") -db3jGb'KS%rP,X)L9G#*JQ2K,4h3PD1&e[qRdHR8NPaJ*JbKj+M+DGJB39aP!"#( -%mVPCP9b8U(#59%ekf*+Bp10jQ230eQZ2Ip,6T"pI`j2Z2T!!(5I91*!!5B0Jd53 -r&Ld+FL*A)0PI,9Jj9&4+Fbc"-a#CXA9`!5P#!1hM5qa"&kkrL!XjFB!J"d36U8J -B*""$MS8JK[6#CSIKlme`5d&!b5"c)Y3&r`1GJJ&'LJC$#6$TCEK&ChSDHPJ88j1 -m!R%p(KhM2E`)!reb![GES`0#"QbfNZ"%`B#3!*@'PVC%Ce3NR&L$03a$i0bMj&r -ie'adDk8BZ$C9XlePES8Kf9mcU*a5*D)V2*`@#AdRKSP*R5K*kX'B-c-4M$Q6$Lr -i#!qar-l,&)aAJS2a1jR%ZLlei'd*B$TCC()'3(lC9#16[8'4#6*1FQ3bfcDeb%5 -&T)1'61D"6&CHY0*4-+03hVTE9&2!!kFP9$IeB)[B)(rbLFU+#8p4AVDhjZ)A)9V -',a`qF0I,mL+*X&'2#Y&SRKGSU3S5[Vji[lS6`fl[P,[LL3f6H0`3Hf#QkQ*lpm5 -JQMa2[)`lr,p%XkEEFD&raSF*ChK6`TPG(0qmhQa1'I$"1jQ5JBNYA5j(r('KGe# -c[Dd8eFm+$J"@'Z5)IcLE&!4j5A-aC'PF*AJmKbke*)35'f$8X`fLhSELq`*TAEe -Jd&IGJQ&`c#HQcaZp[2E,iITd`fJkP!DK'4d8eG@T0jiATRZZFT5GL)L80,B)a)B -(e3[ADC!!'$a@f96RchE$2Q@TVm1!QhA#dR#CNf3qb-ChP$)3H32!)0[[!bKlil, -5mTlKQ[5Re9V([+X!$'Cp%d[aU"Sc(SjJU*G1P#brr19LJ"-,(LJ,SLRcC)C`0)G -D*Tcl,!bmLC@UE#AlT3qA#AjNY'8aJbB,9&CRF!6$MCS#"0LBk"4+5&l`!US&e&f -6(&NNYmV#R6'2-Mb9(qiN49*@+rUTUBkX9Lb9QcCpTq$`JJr2k'V&`L#JX95P9[5 -Ve!T'RdYU49T@5JFAV0Z+KVFqM#N"3IkTk#SQC--d9Z+RN!!H$"%m1#XP3%bB"hk -#X%E)G@C[K@X#`5-Q@3'#9%5"J83#3f3!)-M-!3A-cH39)PF'KH%@([c*Np)&BLS -HGE*%9bH[k%RjlHj44R8hK9+aGHYB)cGQL@mH!aSemQEBIYF*2,BC5PhQj)"MkXV -Ve$G6-5J%F8hXKa95#m5R&bJHaB-QK826VmklkUKGHDEb(X8HBl9Z5[ANLchaIrG -L"aImT+"ljMJ1@"Ed0kZF0T9M8!'lHQk+P-KXhq5B#X)mPC1[FXT86KG&YYkHP)J -&-j!!QAGG[0+ai-0[Id%9dDJ"16SIDpE9VY"eC8'!@A@3!"5"Pi4re0m`Q*0*(r, -E(#ad9e[5j&Mpr!b&Ijc"(jh1)#9d3!rk%e"23[8fT9&FiL5UJ1bhZP%F$HrL`EJ -ff"`-++VjN!"L%cbXhQPfUQdBrVX'`iT[%kHY'cIK3GH)YPCfcjM&KKf1E4U3!"q -AcXT-Cm4jClB)9C@lYSV6b9)!93`Sa%0lEF#`EAUh#Bp1A-APXP#iMSC0!T%(L2r -mU0M&kHVbRTDJG!BhZ"jrTP%1&QD'$F2-$"[+9-jQPE05VD69Y!8EG[J4m[S@1jN -0VX`LF0f#L!l0U+jXiQK1#p4A82F9[IXj2$kF(k4TUGl+)#Sj+kiDmHH[iLl8b#Z -"RK5Nf%2SHej%UN'pL05eRKD4fM'e4D4De)[B[[EE,b)ZS)prZ*DEam80jM,K1e4 -+iG)CqT*Z3QFPqAK#j63G$f,dMb(U8pd"M+eCTIcd'##a4Jf+65CQR%aK#JE@pkS -'0lE!1'M'MmRk)ed9`r93AN`SSG'83ELpUTN&1P5#a`Mc4&JGE0C9k!*T!QHUUDU -SKlXJ`2T0200G)"8R-Ye5*#'%M&e!IVe@c4Hf[k%1aZfCR$AM)ImHaf#@hRY4d4, -UHB``h"P2B$3S1%JKY9b249IqEk*PC$*iMf8$N!$%#q`jLFAi9b3@iap(&ijL5I9 -NeN$QKBDjA+-H6,cRJ,qB3*5C3bCEeCGi8X8D6DUPR1k"dGV'Bf!G6d*AEmM-S3p -#XM#aTGHBf0+q,"("#RNJLVdBQ10YU"2q4bZ%531a2jNbU,%N(UCMjH6aJ%ZBUkB -RNNBX-aDem$#5!2aLmLcCYkb*,0Qh,)FAc0pM[ICJEdpCXJFI#Xk5G6G`6HEm)a1 -NIF,rqa1NqBe%JV4(e!R5A[8r+d'Q#a1,-EHV&T2kAb9"TJhrTa0NZ[6r9)*FX$+ -4)"HF3i+FBVefcpkH%Z3p"ej2JS`YJ*K#(Z6(@Hp3-!Lh-U@k4HQXkDcjq$jNP!8 -'9&)F*""Z,$Bc-@"5l`39NqBS$L3$5KV-&)T$3AEf,`jKURKHQ"0#l%dQ&LcGK!A -le-b5q%meL2KJ1p`-Ci1TbSVrJ%8*S@PLFc3%ba[4)a-e4Fk3!-V#$Xd+5JK,+#& -82%"6UAT,U@"$SM*GUEJ6JH&i$Y1ck-DTJZ&#f6`F$aaZ91BFXN(mQBP*X--''aY -P5KkhUKPp-L20H*NY!BKLB1Maa%0[*K2!qSD,&i"dqTN+S$rRiJAJR8`!cf65r@2 -q-B8Tck`!TV[a0jB!P)SUQeC6lkTb3*!!1L1[hdZLYF#&D,fX2$I99rcJjZ6FqM( -9YbLGGhB+Fi+"rpHF4'r6kjT%h2!PGXB0A`ALY0V`j@h[E[L5*a',(Z1'3fEVrPM -dq$JAqK3mISJcT0d,U984lN8XB2hmLer!KP4X!IfcUDL`H1S,!$+rapiS0qR'idM -VD)MBQY$mbiX[+0*McD[b6H*6Fa@'5Dk6&([E@4Ll&bZKZYE'9RA%9X8)3QX0b"a -rJiH2`V6dTpIJq%!'K(E-KJZ6(FE(lki4Yp4ceYXjUaNEAZ$,$aX#P"LCm!2%!BF -8jmH'khk*")L(eZ8-b!0laMjmN!$i0"+8)*A""E-@%XQ'(p8C24&Xp&M`$H+(@5I -TSR0``B0l,`C&G`6hha4(N!"jF3Kd3SI+*Cm6Nq2!R#j9!BRmXD#RMc,Ma$r"9*X -Sd)mf&MmGGIH`3(0mJE@[Fi&PXDfmE6dNCZIV)K#+)Efj"k62D'*hRie2E1)c#EL -l3h%%Rc`6"2rp6"c"[4H$!)aX8PE2Up8(Q@@((Z!B$5@%MZ,G)3*P-5&GC1#V%&5 -0$i&q)0h6JI%*qGlEij1Fr6SQ18BebHEZN`36c(Zpc+fk2(0mLHCe6fiN0VNP9Dp -MFP08Nf[V2VQ$h31`BA`6p$Eh0-'$h31`i4mhb6p1L8qbr(9-mPR9*"Yk#-"Chci -4pca"A(kSTm[2C()c&mFR9rZk%r!Z(&k$`bML#(-4XSQ1`qKk83$b'3*"e3,D[fe -!Q%Q*j@,'lS!ALrpE0+KJPj0$RT,Lamm`+Gc&NbX#!!!d%%&%3e)$!'EP%&8,0#F -!BQZ6lq%XZ1++Zd5d+X%"84'*d%b4c-ijZmH`d6)e06-"!B9%3+j(mASQhl1l)#) -UQTQ3!cR@1%dj6Y2A1%eI!fCP69qC@D'TSC+Tik5CB`Di21qlZlKFMih0ehIrlZ[ -phIrl[J%G9!B!!C!$!2%"%5%M)HB1R1q1L)Vkmi+(K@$c12,2*idE$&F,*m,&`#A -!jF"4Z%+i)EGf'H[6Fe-j6&i'0lC9+643$)Z502906FHhUi(b,eTGi'6kNpc)I`c -V*aR9,c9li'Mk[r)PrPRB9e+m@X5r$[ZE0%Rp@CXBD+#$j560(cL'6TI2m"r#jNJ -Me3!q-q`EU9QGUldF'%6Rb5@m9pJAdJ2UppV$JChd1lQE9K0i+reFp[&2``C*AR@ -q9KTi0SSq)6r+(`ZE)&eA6r,aBFp)9pAIDFm'RUCMjBXm-Qb8K%5J24LiPEVP1+d -Lm#%D+erM6iH0NiV9@ViNE+Pd3rfMGL+`LLk8EpEU!fqLLq6Eq6r#&NJ0DUM@(VL -4hL*IjRH',CD@U@em9YKXDB-k3fX*&'Qfh&-,$mb)SKr,QIchBEfP2HTZrN(BVkA -YkSGDAQ!@l5kRm&I#AT*fURr9%J16D9rjIHhE`"hdRh)ZrdhBF#PIcH&p`[iMl9A -rS#d2A%0IPer6AJeF6hmPrj[rApJEdNVeH5deX)$qPlb2rbAX4HQ`QXCI#2ZlP+l -q@6XBQ%!(b#YiBGL9*k6(eHHdeB&Vk3@jKhBJF$pp6hk%[aXf3PURpYH1"(j#hj& -$q%GK`k4GkMBq01`Yk6EeEHf1`%0dL"bM039ZTUIN2r&cB4(52HVpr(MB-HP*pEb -f+R!6lC)Yh"-@,!RU8HhH`#dd@RCU5U#CZN4CG8PK9"*9&pSGQ[+qaR8qQ9rLcIa -"[Tj(D9&ke15S5e(083p'FB24APe8&kp0E"bY6jTm5ABf*Nd5T%-'39,K!JeE+'c -1C%%k85G)*Bf#C)F,JMX$0`P%,`)436'3!2a`54-YcNP*GSY6Sd8@CafGC((Ua&q -L)%iQhNLKJY#Uf5K"[N6mC1)RXVP*GN%bJV0@,BM9JM4C&b6G+%L'4PAlVhITD2( -$Sf[cd[25$ZGPL4qUcY@T"H,Zk-fTBQhQME2L0HI9ff%maD+FNL&QAFK0&PI[68r -0fjRH)'j1cUa[%22&9#QK3VbTCCqV2S-JGH8QTqp0VdGpGa0M&V%jpDE4452jk(Y -6mX6ND&%Z5%r06IjrJM393ZRkpDq+'M8+9*0&665+QZSdFN3+X@E*b%@0HG%SZic -N*eq#)aNeJ4TPd4LYF8)ebT*Q"(q##6jB!K%TPKZaJ2-`,!&%r%KXT*VCS8kK4MD -$+&1SCQ'UQ!5+#p`d'9USdH`d-SD8#BM)#@j@0C4KG3a6P%Sla"+#@@5dJ1Y4)d8 -96MP9+*8pL,RAFNUNANk))TA*JK)(&#Hm6,f@S`b"HkNFl8!d8fTa-+"Ha8A)-K8 -YNTFU4ah6[@B*T"L'3QE,`8b$9hCLA(%4&*PS--F`P@![+P4N0)Z(-B&ZQ4+4H)G -i4pN#b"DR68,mX"r"T,Ia8'LeD"#V,8j$04F0+L@JKJ@b4#JbrRFDH,9-JH9#"#+ -Y0T0C!TQ)qE*BV8U'DYN$&JE1TMZV554MN!$--5J%PB)6-"6#5D8'-eR*VQSVFj@ -Sf@,9kf!$&-bM(H*Cm4NA@)RSB4iXC5+D6D0-"+69#X-5$5kEC$JUX[QL4*c5a3i -)hkFN1%*(,X*a5Za)J8!P5c3CTbb(BE0`Y16m0,E,CNb3!)0Y$-Li,5Cl+NFc[Q" -a6Z)1$R`+ebCS8%lCd0PX$aQH)TI(0TP+$Ue1)YdT8E0+5b59AD*M-ah5f2KMYcA -FRMMCUC!!4)"MeVLU5)5L'JK&2Pm0HE$J`1#+3A%C#!S1#c@G6'Ul+bSEXEPUYX" -XVPQSSRJBHi8UCXR'MZK4R)aSdp1P12Jc2BU%fG&N&QJf4%*bJVG-0#Y+-&2$kPN -CI%pCTc,a'6Q'c5F!4(DL['#'-++SNKLTKi9FPCdL['1"dcL&!-8&H#3ae@Z*YLf -41JLDkL),*3Bm1(-@8@@m&+H+P+'U9'4H)@c0`3c(5LFU))1A5!0P(TX54Q%m*)B -+#+NiQ&TFC,k#P1N#+U&6*SG9*V0$QcR'3F&&MaT&AQhNKQVK13-R!6*rY9(%3L3 -,!N(*MP8E&4G"*8N2D2)j0XbQ!V!k-89fBJU4%JXcdN)-id2iQ6(Gl#)mNC80j0# -1%8h--AcX9E#0(3(S$)9`)c`FiLK)P8CXVj'Y&I#jem0@&JmMQCe%$KGKLJ3V4i1 -CPhY9"U5-J)4'VmSJS4Ij"!F"8+pkMA)%'H"'d)d!GdBfJCbi8@CRL!(&`c$N8f` -'F9i&cB*l2@aP3d,&3E!8Qm9Q'FNHQ$eX"Q%9604cJ&a-BHaYdmd3MFPNMV%*`Ud -)4d(QE#MD)5)U++BC-0k'U4!pU&cdPRUIp!`++-m8hUVde9U%R-bmK&4m2@MK,Bq -J[@C#8$)bGfa25ba)cYU8LmCCFPkDI,3Mp%PKpHCMFQCqDN(bGLZCJeaXeX*8"#[ -)3JXlJ[9)a&P`1B,db*IblfpEBFP)cGL5Qj+DPlBj1D%JGA9U@Pl'6Qkk!2S(jLY -PN6$`!PLqMZ",XY$#NV"'q5SX'fiX0+6)p$EPk,Bq+p)5YkIPLHP6iF*Q$[6kT)& -9F&Xadbj,fjVNpqlS08@m*`Y51kE*jeSY-5[0+Q(P%3V@11+"rFP#'cJFkff)"m$ -e%k4eVmM5(Fr$jIZHLid4FP,"*Fp%2YP&+)64121a5S0-GS@@B04YeYkXmdP[GTV -3Y$HVS#`8j1Y`p`[5DT4+Bh%dX8[JjX[5S9+I&!NZN3D#8%-Ab&*)!Y`KZ#cCFk! -f269,V)M*XqB#L2(Q"I2j9MN$mprX$Hh[)qJ$KcZYET+2VNf"K&PLRTMfAQ+DL"C -pfDZ*&F%%UID'I+jPmj-G(-@@'*1&Xj)-BSXD2!fX2f+X-r-cdUSDa26F0ANKU6I -iI9*c[R8#+!p*IUU3!%j92Xjqihh5MeMmL&,9rR9bm+i&,@bDCdp'9NL'Q#)PCTB -VYBd@RC+i26Fc"%FN*C+d59MqZ!AX$X&P#G)R2@925$[$l8SX5!e*h"f5PT'm2Bp -Tehl-![T+S"k(kbe)Zl,NSb(YeJ6dR(!i,cReBN&bHZlfC"6Q8K+6Yfq&NKpIehj --dTiHj'SYU6-aXd8q,UHPjbARCPSr6iVT-BPTh1aBA%P-Bd`YZHN*'DQCq3a`r&+ -MrG)!3Gb)6m1TfY2cI9)F8ZM6ih`d6YAL$'rPNKdAGf2[aEcNV(5a)$N[*b%[-c8 -[+fA[IFa6jBNY+5KA[T@APTFeGE$dbhIPJk9ICTQeAaBLL#3,l5F$eJ0pdNqi`%r -Y@K`q$-@9qS,MLUHQpaM4HlI`jUImUF#ER`kEYCpH4A#",,5IKQ'p&[%(F+pVF8h -3MA`3&qll1'l&2rUia-S`TI90IVVCE!9!JkZeRq)BD"Q-qr`d%`(Z-aMhSDCJ"F` -,Ti#9`Hd-V'4Q``f'kq@l%KG$10lYl3D[QD+f8"XFBe2E`k`0cNF`$1i&,DjRDl@ -aq1S@&qK3q`*6Qh84VKfZ&-k2FF$FZ$kqMq+'rk[UjZF5l@I4V2eFM4LlpI0T,5i -*Nl0pcm8YQBE+i1FXlHFdc%HYpr-DZ'JY&PaM)9UXehFq0UD5YJqdRer3BN8YY[D -i5DlPCD([ch2-V@$&c`ZKC3+#5,,3[XE'r2b96rSD'r0eZaDVbZGh,DJNfpFAYDr -[d@*cY&LbE6MDQa9k3+(M&2UQ3Yp4k%F+lD[3"S@qT0$r9@JlShk!iUY#r3VpMd) -r9UK6S38+AFU`(e(SES9qUp"SK4j8k$b&HKM((Xamc0Bj#[f,3Umc2&fKXdNER[S -B8l5h,!TebD5iE'CM33UGcpJ"HiG#,l%jYc25``TGMVD43XHMI-[iVQ%kCLKdN8+ -lf-"4KIj*SEp@k#b&lP-SFQ`I9N+jQDd$fAeZ++3iHTP*A+23E+ET8i@Z9'L43Nm -Tp0q-86mQBTK#cbVdV`SYCU,N+r5-3JmVG+p#(e6S$`VpLC&1-Z'J0G1Ucmi@jjL -JQ2bH3Yp5k2F+2DE3Z3UGS0$I-jQkf0&IBc,pR3RN8fJmZkh#lSR0k+I3#`Up3k' -$Q8U95C!!TG$Rf3D-91J`KES9'U,31S9H9+M-6U5A3YpAk""fBHaP-c[hiHaZh46 -D8k(2XH&&6&DFrMrBk3a8k"rC(CBb(4[BR3-8ZP'Kqa8k8k&$&IUC3YFVp"D&[Xk -8,@6rRf5Le,+M`@9fX4ac2c[@i`Spa(B,bUi`1D$l$pBXXTQGi&jfbFFBkT-+AD[ -3rJae(c[p+RC`3"fNd,F9ZJULXqd*"bq@H`VB2Rh&N!"%aRSrfirI+A5C3NmS0%+ -K[f)A!!ZA3NmVG+`5p6#RDU$B-ccE@lKL81Q!K2Q'Q+E"YF2cPrL((%SUlT-ccZL -ap'[[RK9D-Q*GVp22TikeGfhkXZ'9P!9"rBr-ZrM'bXKUTc+`VIHH@68AeRDlrN, -DK++)HlkZH[rEK51(ETY6mIUDZ,VS,EmXqf$hiXiH"lilqH,KmI((lrqU[Qrbc3( -$GXhFqYUV8@j0NX0D2XkBiE[bq+GRrhc`LBQR0[pmicHj5mHmIFIdDrrCqh4MX2$ -MaJrcERRJh8HqH2Dr#Rihq[bUrlhpTChrH2QG6qEHpArr(U@lc'pZq(hQl&ZI@rh -jShp2Ifc5Z6rplF3rGrcac&ZhrI$3(jE(6MjkldqAIlhpcSIIfrrpeErXHqE5X5F -rZqQ[LBZD2`VjjX&IVIHH9h*66CZEjeS$Tmr@P&r$I4CYeMj$#q'cRQ5KIIB+eYm -LIKjZX"BlA*E#N`"TPjMAQKqpEJU$H#@!p0RiU94NJiaQEC!!hAGdN!$)Q%$TS02 -D)(b%-`+1$QT`""93M"EZ)!9ZPcCS&kN)C'Ph1&`6h$S#j1$3-Sd0p!A($RC8+i- -ZD)1'D,&*CHX3e&b&NBBb,CBKL@NiU9@*@ANTI&YH@Z+6D9PjD@a0f'@EblCaSK1 -R)-c(AF$mdaUbd$i0`,SIeX[J+V6)BUJPGHB3Z*ibmR4KTR(Ur-kAdIrT5Zh6,V2 -fk4l%)q"kDT&0PAN'CaV,D@b8`fb1pZP#,6+QJm&j-,!9keJV$6MGLV4ZILeb`(Z -9LhXQTF&Z&l9Z@maDY`E%pm0Ydb)(Qeh6eSLG4Mc6`QHh&l9ZJ9VNN[,DF4FFClN -P)che2V4!ZlR,f94R)KRlh'r@2XI[HTqI*J[YFa8hAB`BTrlj%5ebR+fK1JUSFA# -M$'MT'Hj'XY8TLI[ZJf5IpjfkC)-Kf5!%S@5KIBjmphN2a"#TPedEjAG)*MSNUr9 -jiJa-X"jl-Y*4BL"Yk6d&Zbq5FK1+6@6S'&Q%T+CPj+DQX`&aUfcEM5'f5HNX`8l -$0!La@qXee+ce`VRekJhA9h1M26F+%SmDlT2FN!$0$4P(!D5-3XSFKF,U+,6B4U& -40`S*f!fjh8Mc[BCUE[bB1JS*Ga35lLJNh&'iB5aDY@jFbihfQMXFMK$3!(1AqMb -a6DEAc,A*2'hAM-P06!r"4&)iqL,FE+0HF("+62rAYriLfDapF4K"Gl*!A3Xl!&E -l!PpH[X$&[[K5Fk[%eZ$R)$(9D5TViV6*DQ0YX,%fD&mXm%RI"F"Gepc&a0C3!-A -8)`4"FcFj8XP4NKNcN5V+,C*q9+fMKm$G10PPjPAmXVDKZK5r4paZf,c4)&bRlI" -UQi&UkpF(VmDRSSbpF[#U4"Dm[DiJ,ad4hjqAP@`,eq8AT+8cT#eTZ53iZMSMY5# -0K$lTHj4B[Zm,pb,FDh$)%0phJj[MZr,GarGN*"GNT1hP@r,fT*&)IQj94PTQ2TF -6dR*6q#T`[`IP3GPe6`%+Jm&b`AEm(LLr[4SAc0Zj"`RTbFc84",FRhLB8H5M5%f -fd#FP'H'`8dRiQT)8"0F'"fLG"(L@K'mT549`&VK0F!GmVZmq4T8P*C!!DLYTK1p -mdK#qQKI`C*l&-rKH*@)96qaBGDh$8"j2Gk`,pf19KH%TY12VH$k3!0)k+"&EX-U -e$Uq'6@8)M+)P)@-P[3#(G*+%Y*5%a*q%c`I6MEjMdc[j2F"+"Ri'CQ$k&QMDJpK -+L9R&SNbHVm6)H+UHD%T42+ZBXZKlf$AbE&%+N89'Y"dZRDFUKD[",3(5j2'Gi*V -(dj5Z*m%V&IHeVBrIMrL`#F*a#fcQ&!T1E$Ubk(5!cZRi*MCp0e`D(!T0dce`D'& --afHckB!$dh("kGem`EK8"YqT1"-i1HmjITpR6J$,[fr[6%c1fjY3N!#FQATaRbf -90)KRYpU+84&Xe*U5jc3j8R*`5Q*Q"ViI9(KfCf6QNGTYMM@4$`ZjPp3Z5)AP-bE -)KeLUQj0UeZEJJmQFhLBdEFk,)#2$c(R0*mi4T$8VC@P0$P`Uh$UiBMLr,1f0K%2 -bh,Y!pZc0R[T05KdhZAZj5L[*p31!c!rV61Ak)4pNY%0q!!cpS8Z3!2EfK2,qF%2 -J)1"HI2[E#q(f%Z&+i2"02LI5"[C-90SJdPNVQ1aIRPK@*0jD*R`iQ'G+dqD9J)c -fd$`NYAR&H(6K$9R+k31(Vk)j)f34BZ9!V"b8jR-J@Ni$4"+R)P,T0)K8@NQNH4& -3r%SVN3*"aJR0!mbC&bT)qr$jBYmmZ#3iL,B2Tl82FZf$A2Z`QrZDC-qqLdcaZkQ -j1r0DEBYMjiCf5&3@4EC*-KFeip`$6)5jHl$'JFa&ShVZUi*d'#9m0fT'ph#Iacf -!F6`qK4(Kde%[Pk1))A#(&M64jhDcDCQ*0EkQc%AVC@iFY,`"$@MkZ3ZKC3KM9jK -FX,15X-j+pbQ$iY!d%j!!FZCDTQRQ,UcafAmQ%[M-0G#%e(!B"hJBUH%`$["`XH` -T#'@-Vh6`XdPYU`l,DV2GfD%+9F6-AMC9f9JM)Fj%df"QT#!9G*HP!Z6a!Z6a!UJ -Y#)FULqd+Q@McCKif56kfr*'Eh((,,JH1&A"mXm8"(ETh5(3hA-L-+GRX'c4+[SN -`S@RIi02F0qdJSDElCU$J+6!bjQpCHGTBQ6"Nich,k+k-+,G@20BRC3HC+XiZ"IN -lN!!"HV2A#Cl8IMBBQCQk0b(2HYIXI-GGEI51!mr1k@#GM5p)fIM+Q2f"i&RcKLe -6fV"0XS,T"2a-Nih28pQc"#QeLa#&i18ATkferaj+Kf,LET&pTaDR$#@+QE4!6)[ -1bq)f6ZG-2fKEHEAk)&jZHkHmNS-06mT-&&0L-P,c@Z@j'DLDCL#McHLV4IP0-,X -)CU@8-!0IIQHJ46XM9)X5R4hT+Q4lAUTTbkjrENGE1L3AjH'-e-5dZfhjYA4)JrE -[,,4(CUh3SQTY'TkcDZM)Q)cq8AP+@Z0F-0AM''[CUYT8cF,[GV23D*h96iXU0EN -,#ZkYlT,ifpjP&JjU0K,&l&)YUYMN,N4$TEXNr[IZ-KXR0K[PipRGY5M(lbCA#-K -m#[E&`5q'm5-*#VF,0@UK*4eTB6B1-45T-K6hE,+KMqM3rK6Y'G%k4@8SlKXk&!i -jGSATIIrlHqFid9$Nme[Li8CU8BG-,r88ETiMQpb#GXdYD#$H8UK&K6Y0fJ*2AD+ -k"HhU@r"Tr4Dh&T9[dr(Z&"e2EE*DM!ECBK5&&kGU83QYl[18*Dc&U0FA!qJ[RU9 -&jE5kce1IY"DMq(%RLNCh(Y+L5"f"6%lU`Q'D'i"UCVEQR[mNQJ5DHmQ6D)*SlZa -ldGc4h%RhSYfPZ3H&S%'SZ3H(S+QUZ30$d*!!eYap-NrYcNK"aC5D9T!!Tm6X4K% -J"@83P%a5@@%Q6jE`+l,VNG8@2!K6bfmSdBqJ#)BABmM(YQ6NTK6J%dPDAN*L'Ri -DY),kSpD#2DU(h3kNUIqL@Jkkl#clqma5LlCdR9PELREr8K5hPqB,d[)FfE-m[mb -hK+98@hTFLaT36X8Md%NVY!&INJIrI0+!,jr8STE8d2NS`pp,EefKrG8amYG@)li -9@Pr(5&q6NIA6mSGRGqpr@RBeML$'X)QBLHZ)+HV(c&KL*[8NaYl%6$BaSiZ*m3B -b`j!!EQ8X4UV-p#)Q))ZC9'Ek-c1!'FDkfFL-KCP`CYL%jX(%L!CQ'TKC`3aM*$* -'iTI-K",6`TPjKCPaa,3aTQf-Y-(26!ic3iKC9N[-CAE9bdbJbr1)UAfH'$@"'*Q -TAlZ5Q54L9VFc`ijJ04YBc84CcF4GabDXBbVAX30ka-i-1ij(8TKKKrJ)%rd!%hT -r+62XZ2FciIE2*qB38hEEF'Ek--1B([%b`jKq`S6BaBjX&jXF`TL'P$$$KN2BPS3 -`PAZ#Q2%``bEXBFSbf@&PXXYNXZ2)A%"-&Q1Aa5kFa86-BT1cf$&P-B(bQ%"jE*2 -b,M,$@1aQ&pM0VVfE6G[1$QKl&c2GQ@&UYNF5Nmq%cQHLl'##lMM06$icl$)lf13 -GE2)1PVf5Q5J*M(8#%b+"LC[!Q"i8L8PM@5fGX8jRLe55lD688ThEm4hV&EM"eES -@9+eACm&jUR@p1pcBDYf)JFCDZ%h9qX63DRe58V8H[k4DpjkZeNHUeAS3J[CaeAV -Y)EJ"F21UpDT5Z(biPGAk#8`mF35ZUeT[D))$iiC"F0P`8(!l[U2GAJ,A$RF4,J% -#'(@p1NRAkaTdr6,9`8$A'lTdrF'HZLlAkVVLdA8K80I[23fATHY0IPhIh!HZRkl -rLF-"FC-GcJ)h50GA'H$!i-RqF*'krVJ)PkVVGhKe2E`8$Nc#RiI$B-BEZVkR80H -c9X""84B)@9rUHPk-VZm'B[j+A8r%iL!'$f,5`3@kRPDXkqN3,"f6pZA$B@$046J -XZ0fSSrHrV[FckShj4VdZbDK26S!E!8F@5ibkS46Z#"b)%h1-HP'f8Cp8E04(Bj, -h$D0HBc6U$a6#$6$U$hpTe2fTF&L-D6,UCm$dc(bM(P3#Ci($K!!-"%"*!*!!QL& -!-`DD3@L'3[%L(!JL&)SHZ2j`8#3Z-1SY)K`3@X,KBZ$!S#A8U,G"J,CDZ"9`+q% -J40YBSll"$lF*$N*[J)!E`+aGKCYRe$GLdNCFE#-8E`6#4LKIaZ%1`AA"JF&P#() -C#*GI-HUeAMJ`Z2'm86m"a3f"4[ef-+U(!$IK8MH0-qUP8&B+`8Xak5`%28X##(- -GM"m&Jj-3iL3ZFa+(HK8#AqeTe)["j"S'Vd'`DphK"K[e#J2FD6J`Um#&+U#`)Y+ -SE`@MV8$FQJ)(T9Y"9,&j-SJbQ-Z$M,U#`lB!)HL94VfdHk2q8%UMIPG@SrjJ!Pa -5SfiCdDJ,Ja[erH&`r4YelUr6HA'GAYd!&`2A"ql,1Pd[JHZ##i5,V0103$4ki(V -#$BGl!fi3A+mk[A&*R9k(`FP0GFJXF)2Vp%P$kR5l!@iPh20`B'aI!$Hr6KpYJ3Z -Ydbm"m6)QAZi1ekp1VcA#YF-"i3B8hNL"J`"9%+BU(`j+6hMKXZ$!X-&HTpHr8UF -r#i'Z3SKL%Hi3A#%FQ&rMF,MFY33i)&h,VY-V`,KL"4`Z@`(Q&H2Up)I!j#j-H"! -APa%S'$4$U4N##a")J%"EJZVdGCL`(m4$Z15Kr$Um#B(A-Ur'C!HGaNZ%q1412(( -[Uh%ZSILGC'P[KGj6dl@%Cq0YHrCD2MNH2I+SKLVIjhQk$jf-Cl[aqIVT2TB)dGq -1&c6`4QkEI+Z&@QU'B1,eNAa$!kpYi+-lqCL4r%pq[V@'Ef"-&XZHrI1j(8`QbG* -D[i8aPPh,FcLL"6lAdm-*D5'TV!KT53Gq83Gq*66SrUUFfC!!CN$CS@J-cDk[iQ+ -lH[j'!lmeL)pXi-e"[$eHGUhJ$eE*,S9Aa&ZNeK+1*A8KB6A2bUTE1IF`'B8%*%S -Lp6Z*jX[4Dj2Z6R2prkMQU(U9DDkSDUAjA"@[hm4[a22k(2iR4@Tpc1ATGZa+NZ` -"emN-Raj'GiSL)Sr2mda#TDdU+pPmq6`j#32HqVCT5Xk+,*rMHA!8r8(Fi$A0Bfd -N@lLU4j)H-f5f@jEfc`HPF`U&(XDMhY8PTK5P%SC5$SZ4riV&b(r&`N6(84a@+aC -P8-TS,81C#T14pd80VK)ae91mZd1ELX!QP(232L-)IBLAmFP&0JJ55VeEk-@DL0$ -IBS3"SrE@`'M'5J+-BTE`+$ppJEq-6*[+ICZi2CllAZ9Y,2FX--NpN!$4E-XqM6l -A-`Q1M'a,#j(b+C)@mU@a[#4HMMk0GhEbSNk&+4Y1[B*8R8!L"R9k!(84hQ*@dm6 -(a21D!$kTM@rXj$8bNID&'PFfG5KFEV4dj'"6SUmedY&``c,Z+q'0XJhJ)4'ci8N -ek*R#MM01MPQ1RPZ'GQe9["a9a!q9m1eHIUL0(kcKK`*iX*HBYjPjL4MY'PZXCZB -a4TV-c"PQEQ,'c)BrBHBBc!UqR#hq`Xc[QIQ'QEma%mE-&elq0Za5YKV&12QBf3K -6DTE)q4CCchGF$AS*r(mXLGT)dM-*k$$6`"[pLQ5Vhb8hZXcjDlLKaK4BM#50!G% -r%Zre-k@ANT45(RS`3HrNBVcUQMb5PbJ55`JeV&FI-%i66&p0a")q`d!pk#pL5d% -aDeILbmXfhYLJ@#Z!SkJ!`[&E,VUY8!0K`Kj`F$FTdAB-(#SlF-V!ehX-dQPHGj( -FL6ecp8lN!,kpIJY[kq600AbNR6pJjpi!BV"S0V$d1i'8NdR9&NGU,-kJ'kQaF+N -j"!apMXG-epA%c1'*4VSBVjHdTGR)Ti4jYek%qDNjk''%jPBGB)6N!"`(%a4A["@ -+(,bS(,8$eSrNMI'+!`"((,aBGPVDk5R6D*Ujc#bD4LS%l'DmkED*(C[mhk*M9l2 -pJ1mPI(*0"aMIJMfIkNJ`b3GSRYK9DI*Tam'58VB08!j0L16KrQAmXTdM5leXjlG -Hjr&qIQXppp[0MVBMF&M,`M%VdNTDdSTNUbTL#%2$GGiBS$Kd5@[4R$'fmdCl"bN -"i0cBCN)LdfD3!)CZPCAd)@(8AXT,krL0%Yj@a&mZiNJ+Yd*11j'ccFk[L[K8k+L -"G[ER0Q&YN8e'h(pSM@XHRmTf1qeSfNjpR0SKTEmMm8C1ipd-CHjQ+(-h`hfjflG -fapeX%EQESI,G+ZA*5PHV0&cQCZq"SbDfmBIY2-M1D`l`dDL55l#f&Ki)JN1eVIV -'Cb&#bTj#HSq3!-5!Zf%5b8fcbK,b8FR+a%(#@i8",pY04$Z+D5)Ib3#4icEE$CD -KiI@RHC[hY`F*Rq)jl)Xe)`!51U9NhSRMXR0l!$'GpR)if0,effL-KH-P2PIp[06 -2ErKjQjqImI-52arYJ-"ii,**F3hR*UXZde@#k@UGkDVBG"9%1eD@+f,RGAC&1jm -83-`$YQ3j`HH+95Y*1)*)12*)HIJh@r((@r(M'(l'b,6lK0pjC&UPHCG))pAM(A& -fIX21f`1)UEI,adlcCVCA$`5`(5-(MUSPe-B$SD-XLA#qV6L%F%,(X%1&6l5Um1m -UZi&6Qa*"f[)SQCZ!Fjbb(rf5V8Iqp(!P'Se%hXDbR+1XYE[GFQjf3"!IEH#Sc%G -lcEB6`5G6!Q(Ae4bGa6--"dcJ`RR8Y+,Ib`dPTX!lb!E6bp+M3HF"8e5L9Ne#[pB -bY$r2X*cN$6Am,MX[Y[0(!iM"SX(,0h[jM4VHEQGR'd!-&MF-[)'eKN1YZAQ"06R --Gj6VAIdFr'QX8(BRE3Q(Y+5RB*%181Lqd,I9h2p"bD5i*-Zr&SfK3ECI"V55MG& -&dDp'%kJbjFa*!iQA1i!Y#NFpD$KY5PGURP[#-cZETMA[Gm-Gl[3Ne2)Q!cIlq6X -Ph'cJ@i2iU4VbPHCD#MpYjcICH98!-9KFSm0j!Z`K[Yr1epVjUJ"LX,L'ccTfEVE -c*U)0Q@#JlF33IQdl"i4I@C0*E%rb+`%,Zj2I#&K)%PBI0RN33YZ8i4eX"R5`HIi -qXhN4N`G0da32TYMDQfJLhbG%dq&M')lb+Maq'Cp)Iq(a0NJpPSM"[R[i6U'YZ%K -D9X8IVC(lqhRlD3CiVPH#0lbGpM$EB)6e(0b16%9J"2Z+!YSFmXX+'jeT8m')RN` -,DcREI5-JBY5ZBVk+l!ih"a#c#Z#YP'cC0HaV!$&ElI+3!'+q9Z4RDhL$R65bfN4 -LX$KVUkUqXkD"QGD-2FYD9IAPCG))l8JM8kQNb&`NK"r4H8jE9c1X,`q[2m4["*9 -E96T+pe1T,%NUR'005*'fp2AM!S@QY+B(hfRBa8IAi&G&EZJ!J+5S2U@!)I*f"XP -XCD)B3QV9ASjQB&NN,93k"5i$&,Z-Y10VPh#+3%klDESXX8(1GP0BMFpLJ*`0P@M -"iD33eL(I8Aalb+JqDGUUf$qII'ZGCT!!$B#3!,'XQ*qaXmSRJ*JcGYR9cMHbSa! -$E0@Sp30IT4eLhdQYKe6%mY+LCE[,X+[k,GK0XKf`SGlN[M'VQhL,35P$DM)K[3Y -54K#G8ejMD)%9aSfeDKiRRbHE0T955h8EM`mLf@bb-TAGY0$@!*`4,l3%d0lP#9" -HDm6f9@kGD3dC4p9UkGX'pBFeAPlJ*@pT20$1ei[m3#PrUC-IL1FrH2Q"%QdL5#I -jic9mNjhIDqH+Ppp9`i[pr0%'4l@PX!%-2flR"kUdUe[jMY-%2KIBq4UE42emVVJ -QpZ'@r'4-S[G"kNQLC*mVdNqL0*!!DNN83Aj+*P%2mMXb4c)+`i@VFdJGK&8J[[T -9HpJ+hmF'NBM!QYI*$p-Xl'ePfC[mpX`!83r3mJRY@r+$pP2%d`1H8k$[8m[8rK3 -bGGappe0iGm,60ih)ji%XqNXVIH`p@5-YNF@8ihJDR6ehiRKUa5bp,!UNN!!SV8A -IkCFh`GA#RGiX[Ac4A1Ej%fIP*bQ9(M0@"2"PRAb$Pcq!BNB3phD59K@k4d,cB%I -*'p!-)U`eTC!!m3(%Ca2TUKc"L"V2J'Pl@T0UbLPrI+A8A@1$KQf9`(!l+EQ4eka -S5N4j*a1ca0T2a5`&E-0ai#RHYAKZ1#!DEJpFmQBTi2$8MZ1+G6E['&+NCMriq0( --6Z(Xpl&@+UYXFTD9j$b6a*32hQlh1*kkHEbI,$@MKhNchKM5l0mX0BY6%kHV03[ -2$03r4VNRVH'cmdIb*LmIJrr!35H[m[)J2i(N*Chm35qr&QpQ1q)Srclq*IXS6hD -Y4eNbfeNV3R,(#Rj)"hf1G8A+(`%eRY#@FX5lZkjjP9&PVqS8fDm10AMLD4"Hqp5 -E9-5#G"-HR+pY3f-#4liQCj9N'5&,0bTNUE%*lbZNUk3l6XY5[91@kVahX,--q"U -lfmQf4`VSLm8"fii(S"2rfPpXD5%)6&Hh#AJJ"bmL3LTQCL@-Y,Srb)0*Z!k[KaT -C,d[V,JJ!X34PA6BCH+4)!$JPK%G84[J@K"4'k-N)A`XNVB*`J,`'66U`6*!!$L$ -0M8%2MIhe!KlB)B2lej("rHJ%-1C&$0`XN!$IAD3a3r%qP6CF$(PK$*icZb1ICTL -P1ei3R(Fm6bh5(Gd%kBjH'&["hLXMM8&hKQd[#UjYIB$RZBh6$,`Pk6D-MS(#fci -3R,F0TaBmrB1qcG*Y-`AT0YcERb9,4q)&k3MHh1-(Nb0i6md4&B[V@2`L1)mXJDC -2F)#Ii!$p!E,d5B+!"i@)d*rdC#D8L,i,r6VmH,29VNe3X5Z,M1`D`NE3mq,K#4K -CJ2HrK@aaKT5!B3J1rq([C'G)%eNG%U33l1,$!r#''1cB`reP9cLRQ@CAH"Dp#5D -*YTLP$-L3!!%C5M!hBjEJbQ"kp`5"K*hCNbC)Hh"kYk+9Z@HQi-SdBUU8U3K5TJ9 -Nj*r-#%(+3Vq!'[6bcA*LiF%#Pml#D@D4dm`DM#LE42-&8SkHBCEbqL)F3'HETGh -)(EY*lN!AB)3HQQf@YYF*q&l%3M$IMPi"m@[a,5K*F1D65qDA#P)qY)mH+%Zj11& -FD"Z0$*MV`5)3#faZlJ3"Rp!)hfqaaD1Mm8%YLh$m&Ya'TmR5$VcdFJFbp1KG@13 -,cKhG`AP()+MBG[YAXT3b6*!!8Y!A`Ikk,1dX%D5Gf'hl"eJi"Aaf**ah3TIp!Mj -#ML@FNm(0rUSX*9m3T'6dKE%MK5@UJT5)VCmd5rBN$U*iDj58'#Q3!+pSJ$S*$9# -CX%@3!"))5U$X5@!Sj2XBKJq+'$jB)H$E*)BKpF&N,2#fRdNa@23@R!FKXH[JmcK -0QUC)Ne,`iHqkJ)pr3)'SDEX&CeSq80*bb(QR!HT0!UFd*)e*RE+8IP+3!0*aK*2 -`8VadG1dS3RHCG16[e#jbXp5"#2Z4R&CJ*)3#S"Ta,J@l"0)P3c,Li![3-B4dd6! -LEa8-&9`&h4PU+%M$3(),q%&A-J*D()BZp"L4M"$qm&U"p5!aiY32T`QZ`bbh(hk -$'A*[DGp&JIA6-D,kh(GBB2efM)""qhS)V"q2%HPYhiX#kpGMa%hfI5HipM&SNB2 -+&jf1m%T)+3H!L24"dLGJF9JJAC*d*-JFE!ek+%NkYMIR"F'9m`DEL(iRT2Z8MZ5 -d&m+5lP6kqeL!#qPHTC1Z9K#&G,I58BhYl5'ipM,iXcGEB"h#G0**$)Q)G"$68FQ -Y!4[5B8c(4Uc"P8N(-RdV&VMb'REP08ceFXLU!piZVa"Fbbmb%RX%9D%iUq@$9RQ -#KY-Sj*QA&`ZZ!#1"6mhY!TkkT(ILa@S!*L+"h6L3!2DqJUGp!'d"EMXfZ2Pq@GS -i6T!!PL&C0'2VPL8,RQ8*G%DY)Y8H%&beK849,4*Jl6c#UUT8a[XLR&A),9)9GV8 -+ZrSbpV%+QIrP)l*diKl"H3+`4cUa$G%4%Rf,+)9%Da#Y*&'%i'TSSY[08N2hqbN -JadJSeJILPE,)H(jNRFEGJY5BM`9&pB%pUd[#I9b6ffQi@CS-X$Gj"!Z6"*H"!'h -*J,D$!GSIMT!!*31"B,YPD5*H3$B48RALNN@!4%9XhbIKT$Zh%'!J5+1KlS([m,B -ml18$b*Je513e1185l1-$KB,d!#UN@pYNem1NdT!!r+KHr(Dk!5&faTp+GXBrJ&i -f5f13!#V(B"0U8QAAQAb#I1B$`A9Q1*!!R@IQim*"0B)VU)5-"#N),B4,d"Z#*bL -8AXDV)ep'C4T!'1`LMp!#cp0XTaTUM'C&F$EMS4kT18'3!*U4XfUDm!"Y%Z%N9JK -1%@01m3Ma(Q#*U#(&IQad)F)&"#kd%,M3!Z5@Lb6D*EKDBJK+#cDdC3"$#F9)@lA -JE$15D*RJDPY"80V@)&a*0UN0p@EE@(,I$AibC32ChJf("1H'(")G&k30k(rP3pC -Z4hAP`rkeca&F'aNXf)KkG@-TUK"T)rCY@5eKXq`3'9U'lSR,!2KmVq'CAF*HZSc -VALEA[C`XZ#iRN!#kmI)VJR3C((fiI'dmmU#AjFCY#)q`N!"S4KUk!8jH5(!#fqK -&DlS"X0D,M(!l!*8A)+JHRC,UN8ZpU(0ZHN0`h6516#m0%X45[!a9+YdNZ-i5+#Z -G4H)kba,A@3KmPP5FVV0NrqRe,G*eT*j,!f6ASdb-4cm3T%Ia*Sa,Df6AXi'NCR` -@pG9*)pRGNlM#5EBA*jF)VU[XhPFhND'VJ%aA)H)P-#['14A2)fMA[)+VJNP3F4d -KZCbVJM9l+JB)8J8biL@8pLXBc(X)J$RH,6XI)NRTS8+XAT!!TBX!'[()pAFK0GQ -AbA6V&YG@eJMDLNE3eK%XI"dKJb4EF94&5#SUX)X!M@49F-NXimV(%E)8,`0D&!( -D+'Mm&+(YDdQjheP-8PeePH#UEL!ieG%)BmM0Ue%A9(q*qlRd%Y*Fd,X)@Ap0F1R -NC*ak*'3eGJSZSjmN#L2*VXCKJXIBLfE@++l'*B!XRMS2MF,[BT1h#*l*6A3fIVF -fe,-%(S8%rJ[#`55F#$Jl%3Pd)S$e4#6FL6LFSLT"+X,@6N5#,KSS1)[k38%4@Qj -&Bd(&m8`#%*id"1+ll!CQf0RDRaGFpMiXA)"`2JP()i'1YV!3&IGS$`'MSj&l,Z' -!*k+KFJNjEL)JdbAXi8481[L[rNN6d@,`!Uj-a(PkM`Y1Eb(dHpr(LlMalVmke!- -2I!9JJJ1Yfb5l1[d%LRELa$Vl)(3p[))CFJ68,e+b'Z0RCJ!a)jZBb5EQ6!ia39j -QKK2cXXT-%M%"#F3d'jMT5BaBc-`JBPVbL@RMc!`KCN-T-i1*D3pRCK`a'`Z*K-Y -UN9c$@8,&0Lq,)8Pi'4TlbeKMlc*Ji@A@@VU-r(Vj0!Z4+Lqc9(NC4hHCjH[DkSk -8#Q+YKiA[)hb&KGd3pQ*KR1#k3B#,G10qK#NXl)d`N!#&i`9A&31I9IFJC$QeDKK -#PTZVd()l`9,NL5d)XeL)&XB*YV8RENC9`d4Y3"2dGM4U'fm'2)!3pDqJTH1T(dG -Rip@C0k'LD84fZJi)H6fFC,6Vq-'a-9Q@RN@KjeNdU4Zafmpf#DjRKj08m#`NIMD -5Y101)N1H"0KTV*+PUkM9Vk*@Ed3lq#Ukp9i&@q0LfA9e#C'J1!$*A@3KkY9L"J@ -,NH#+@B)V4KB[CX@EBVIJZXB++0G1)LaQ)3$+Y33@SQUj0Tb&U05ZX8UY!NQVJTe -I"Fk[JX([#ZaE"B2e&8L(&H`N+mB$Q+!kV%ELH3LCXaUYj,Y3m,S,Z9P$iHc"V`A -T3G,44!&3'#biP"L5rmdi!M1kQRA*NRNKBRcQ[3F!!9@Zj3KH##@l,)2)53MYCMc -5UQp0r@2NEr#[m)FIe%dfebXbmJQh1bjbIIr)"HcI12`ELhpZfcphh1I%Iep1Q!3 -rh[-C-q-'%9)[+pdNI)cipHr(%E3&a#qDi(C2m(M')rkm)jcp(4Q,!hp(-![6((( -SP2K[(60q+5GmXb1mCF*LjdbRbGrkMZKjChDVNIHYdHf4ija-d3p1UljECVT0rL) -MalR(&ik,mlJM2*iPj&k4B4j2R-Fc`B%rS9[VpEc)b#mBhK-iCHJB(cQE'%,kaKB -aa%AcE#,-Mhc'iiiF(mQZ-6B@("CkaMQ3!"llplFH-2KGT)2`c!,2Z-J*(VH(X9[ -U)8F8&rPTa!@h*a5m2-kEfEBmr9e-i8+bYK+@f1EB"2c'dh'bMkhr#jNhJE#C'4Q -jP0$rL09-XRZliAqAEHAM112j6h3`QNfL@kbXlR4%BqHkekal9E!H(c*JmlZakSl -jMbe8Gbj5(eQNEZZDU9VNYSr9$(RGq+RmUEqEfY"ifIMLX(2Rc`mpGfcS1F9bEUJ -U2mhqhJKqPrhVqm5)*ci-2RC8AA(ZpH!lKjqDX&$Gj3M#Jp8MFeAjT39[2l(JcVP -U&M-lJcmk&U'ZHZ,Qh`blF'T#le-Me,h(hMVfeq#22JJqrRT%K$ULQaV5$ArUVjJ -*A8TX0hNb#p5P%@j2Y(U1Q#(r*!ErjCIAPZmCpIrRhjT2RF[$iQCp[ri[khr00Z& -RCJ)(rYL4UGHr8@lmRilihbrmllp[GRrQARrFielrjhrAVpq2,,6qlalhUrpdcR$ -hFUlIj[aEiC),'2fRfahQGRrMG[I$CR[(*'`HFBYUQIrBSYL&D[kaKEdA[4AEh@& -(G%hrqmaIcq`E21a8jErhi04Y9f)ArAABXI&MHhI*(kL@L2FM4KcYLMMDTHk)rA- -XqIYp4%6%1l%4lb`DXZLG#*2&aq0M4icr*r%M6VdAm9D%HQMSd+&rIq,prXHZU)r -rrNje&9bDZREZ5pKpE2NMC0pl4"`EVqjriZCr2R(crd9m116+fqHk6MdI%Ia@42# -aL)LhKJH2rBhD0#*BlE2qX2S(fej2YpN*cYGqTqBlKcYrie3h6H#f2iY+CCqm#Gd -(CTq,MSNTM)Nj&H%KiERcm#YH1YrMijk&r@(JPjXVj$h[fl(RqZF,H`mjI+H` -p*Ac[r(-alhed2SD!E$AC&8%B!`!!(,Y"4%05!`!`G3p9$@Be%4!KiZj#[lbmTSr -`90k&UP2MdMj&)AT+[lp%L''CdS'3!!Ci[(EE+N95THRShU+5b+L&$+IVpPM'T,5 -&#VUlU,Dac1KdT9*&N9@jaKJ$afLLlfG@BVb!*Bbe$)Hj!f'-C+r-iPVA)hrr[jF -dDB8dRTRGfHm!&@C1-b-2)5)KN!33)H8Ejr2P,KFH2(1!39$K6*3C[Z2$i8QPS5P -3`dX#9Z6E0-NISXNP#bH[lDpql9G,PS)P9Kdj-cTh1+P-bJdeTVbV$%%(MS0cGM% -Q&Cp,$kl*dFI#f%FGUHV6jT,k$r#LARL1[GJ2VVP3LSpVXBr#f-FplLV!B`62-A" -1JS!L3B+Fl!$)AV9jH"`%bZc,p)9LE$d%5GL`@N`VljSUNZF2)IkA4V@4B+TYM3G -IQT@r+G[+PAH5r-"9p5T0rqPUGl2FA,jcrG9dPIXZ,XaaIj(b,!m'PY$rH8F#5ij -9mUX$eApFiBL-MK"-PcLB#G*4&#a3D*D2qjih"Gfqr)hqEMm+rZ+3!'l(p`albD' -Mhh1@[@bJiU[!pH2d+&'63D&9aaj++[!ilH[%`cJ6a124Tp9,[2ZU6j-MrKe#C,T -Ur)B$3Q+#+PG[,pY+"BV-HXF$J'p436XH51E-B-F$dpb8hpcL0Y+'HDj95*je$mN -Y2U[i'hU8KreKAH12qVA@U1KN%dC&'Am8VeV&fkh4lQErG[1Fd'5'6a`IJe#PaH0 -#&(m[d@E'%LIXd$m-*48cM##@ea&"--m`C5PTBa!&fbJP(MB,N!!(!E5JilXLjkA -bBE!B+mac9VqTih1[HbKj(HKp*00("FR)HBXlA![YU0aKX&m,,5H!3ZfjpQ@c$+0 -%8V(!!P#pX-er6q(Ll@h2Y9fUf0i)k&cV5$i`FQ1KDQDVeR2&jP2L34pNZfAQi&` -h-XJbN!!!V5&N+DP$rF2Bb'R!i[X'UPGCCK8#A0F4hKVXZ0mpC*icf`M!p4[*ENG -iebGFBkpC#Njk2q&'b2RFkm[YVETj&Q&!TlIfZIEPcBBJXLeMFTDK)lKheQc14XF -E&F!5Jh$)3(NSZ2JeGjmiMC!!S"8c"3!(lNLB`LHiYHH1Q&jhGVDZYP3",M@K8NX -"HPHL-!Q&CZ#*Q,T3LVS`fb$8'F*8499CGdc8cAfqSmPZbhNH)"I#D)*[8lIGeb- -qlqlEfY6GX[H)'B@56BDZfQP$[Ab1hDqC8E&bcZ%5cB*BTD2HjQ90ChD+9ZU4hNf -'-1F`'qUF-R5l``@BUh4P)$!@YFqA3b,TmaS)kNjfZjd`b'$(j`YE%-,4-e&(Y#D -8d4&J1-AT9Dd*)96`64$0h,dJ+X8FJp0#0!(dFNl%j4jZ,SD![4`5C)5#c-KclFQ -XBCKULN&BCQE+(ErrkGIB3&J5%MFrVe[4h@fQ0N3KE!j'*RbLFCSl`Q5'A`!bl`e -1DcX1!h52lQa1L#D%Tp2bQN-6UhUi'Dh[GFYB@&'b1pQdr#a(L*@C9*0-kV8[TfS -eQ-KF@8*cC+b'&))JBF''0TMrl$DN-%9LbM)@02N0JMN3PJM5KmDcIBP!4#%#%B9 -Fph!+09cTFQAl&&YG5i'@Mb!$P299DH08rp9ie85S%i%'K"H4dC!!SI*iS"D"[QS -3$+r-Viri@Xh+lU(I1a"m+TYE(@U(!B**J)GjNDS*hKV,$1lKfRJPmPX)r4G6f&) -TM2jQS&E'N9GC-[D2#0&i&K)6%K,m-)k%IDdb6126mV#d2'j&-aU1VafSl4q"L,I -'+jqVl)%4-$-)qr%`IMTTB@C"3a1bJK`@q!-%j`&1Jm`XSqNAX#%HH!0AF)qMK'" -1(,Fi3U%m%PL#!m8X8BXH'+(Ke-@fAI!T4kHA1Rd9L8j-$Q@VS(id1r1T@PG3[aZ -"TjP2H9h"Tb8V(EJK4A("V#3k6U'Mj-hU@8RU1&(pBHN*C1Q6Z3r,c*PCb9fBF%3 -5aKR1VQI#dMX(`8-$LDNNAq'UH'2"+4ldVhI,paiTM*b2A)X8VdD'B2J-2#)qp4U -AMr[T4I@TjiP`di[LJlJ)QQJN[5![Ve'B55p-*@K#kQ@[MPh@LFX8"-I5I#"fq#P -ff"K,N!"5+AL*S163b$P+'J3P%@4$P5["cqGZEhDeBXZIj*Vbj5elGK*BRDebNJH -9,ckbNp$fmNdcFfFVlmbHQ9ZT[2Gqir[fS@Z+KLSCG)5hfl0"aBCN+m@JI1@Gr*Q -j0k#Qm4B'pI4KN!#k[LQV+EDGKdh[#h!@`H-+9dNY'-P50KPN@lYmIFMd)KQFY$Q -@S5#C1f3+D5(m9VhU+JM062dl[V6PTG!c4%[2c2cPCY8d$aqECX,@58&1-+pPR`b -5FF5dfaNE'U@KjJ5S@KKAM"Xmlcr6B*JKR5!$NX(PJSCfRjQGD@L[+rK`Skmi8&e -rib3Qk`-(AkUIl[K[l0%jCZ3$FF*KaF3qSahV'kMq6SqFBaPYdGMNXV,p-QHCK)% -"K3KAANHeF[U'mL)R*qU958rpk-NVZ1BTei&*TIi'AH4BA#r+1ApDQ+QA,`Qf4V" -9!*KMkNj-84Id6SJ,TJBTK@`H&iAXK'RXY"pmUH&3`'&`li3q`F-&DqmQ[[NNZ$' -4G6+4eCQ`"NP-rDIA)ha04mY6&,i`KdF-cX6[h96KN`+NGlYLk"'[Q"kl)T5GX)c -i*6)fl8I'[p-ZA3H4$iShf+9e@0lde-'q9JVjP[83QI6VG($+dVr,+NU#F'e$K6D -Cb'dE@2CBQe"eQU1Up[N)kU5TeiTic`M-E*p+51Je!2)QchcUmh09pB,`--H@`X8 -#$MMd!KkThpdrF[&X&PdC!jeEFI3DCIZZVAR$0qh%p+#B"0H4@FJkENrJF-(5I&) -b8&e+*'pVr!@*,35HS&Hk&Ji2(Q`NJ-,D05B)ZL3))SpFNiB4`bIcd4%iECh#BJ3 -j+#dSm!5@C)k1N!"JNkU6cr*!I5"38+q3!-M9Gd(JTYI2e"q&U5)q5Jl9Ac4qF'T -&%)HTNiJf`',[bGcilZXMm59)"3'Pd1@L`S!fL1&L8XQ%Dri"6L#0@)DAK"N,VB& -64bFQ@lk"l2p6(l+,QaPNX@$,i)j!Pf&`29fdR[Yf)Y%+kUG4R&Yh`jkYQXePMdp -(0K+&NAZc9@)G#F*MFfCcbSUNK1%U&FA,&'Dd6ZNU-Ya*6d1lQ'D9h40E4#G-dCQ -L$Z#BY$KmpX#N6TL8J1pY,!0I9VTPP,,$`PM'[4'%J6&CV@$i%X6EJSH'@HQr@&k -#M(XMCGbi"Uj4YVGF'j%T4)VlNZ@S++GN%(IIR5SYXipY'N3H*UY06@T8H9Q1qQj -JLqM19*DFqBGA@0*[aXpM$PjcIlE+Ej)+E2)aJ21ESD*rLJSTikLP#P%d1kAb3S" -6#frD0e&ifje5H-+LpV46X89"YC++-Aamj@I-(EQT)3PR@E,E)aB*cXZfiSV,Epq -dba0(mq8*C0(6A+f$3dc*G%rES[I1l"H6E0"UD9""%3Bj+@1L3GeJ8blEC2[4i)Y -(r[c9RDf,[Liah"A@YpdYiVYrrXU[p4`5&EFcL3PcX+Fpj2RfI(2ad$8$H4'bRm% -h[`SC3pGDLD(8CYR,"CL&!SrANi-pKrT(4*!!D189-%[,A!&V(k"6cjYI1E6[fqj -`epP8aMC,c$X@*QU"p`2[GqINA2R'H1Ha5TKLTJ'K$e6bCB[c8TJ&FX[BM`VNq2j -,$H9qL2PhXSV0iU,KV@j`&2*@BEdQN4#q-6qUI$RGYkCC[Z)2&KVcMa-VU8l`VL! -)&pc82Me@+G!eFk$5%EYb)6Pp"!SD2JY80h`XAf%*21"`[[1Pa8(i$Q5b"MBA15J -G@qb@*K@0*V'T1FUc1@a`F5GeV-mU1MVK-L-T0NUKEKJCPFHA6#J*%J-h*i5ILGr -N1-%819lILi+pQ6,Sj[J,JXGTBh(&`F,4N8NBXU%HJU-MbbT--*(%Y0""JN'))A$ -M"@4qdb-C%0ReCiSYT2emhP8BBI*J`mIp-!M)Ef[$C`9IT'FD2PEKqV61"@LScq* -lfK'bIY*3iG5Q(bdbY6hYq8mL@cPVBQ$)f0XaQ@[iq+qK!+kLQ,UN5e0D!GFE2SX -2hh$&$+0)8p"3pk"0l%8&aX@qi'bi`)SD(QUqPMU%&1feNjTZ+*lYe$dZPqqVI%f -r%Z%PQmbSY`A,UrQACS2V,86X#SSc)$ZPbNqV'qTPr25-&($eJca1aJ$jX@)C6K[ -F&-ZJj%C*MN$9B"2+0P&8Z#rqpie&k[c$&TQX#56,a8`3(M0"''ETaD#FAjHff$- -LFP@,(lJJ(9JhGQ"G`fG"$cpipq4,alCdRTq1EkR[YdQqAL3IP#e%%QE(NV!,LC* -GD4)q[T)NM!dIPi66m56-CdQ)KhVA#9MTe-mL!EIN"m%QA2%jIX&[p(8IcRBTYQZ -4Rlre2l,Bl,PdM*9CHL1,65SffPCEMMD`PLhLVc$FHjDBlejHeh,41Ghe83ZpTPN -QHFY14IjEKiRe$V'T@[YdC&PMZEEJH%(!l2-fNk#&)(!KCA@G`9[M!PGa0i(VcH0 -k-qY%8DAEihpAj'9e-%I0JfpEH2c`bkaRDh[&$R3pKUkEijRSNmLmPeEH%a'6f8# -)&IjaF4eB-)eHm+(5a`YcA#i`C3%pd+89E)ePR*Z*!!#B)-FkK)q*j'Bi%H[[S0U -HjhQmN!",dqiF#2IM1jUcRPiBE8rll8X'YLYX-T!!6C!!JpdXZkqS''iq5SXqiA, -jYI0Fl#AbHXQXE6iIqDGUHH,L-!R$X8f'#X)8*##RC`5AkILd%ERbHXL3!(9(#Qk -P!J8C$3ic4Z'kq9H46+1Y@B9IIQr0)FFkfe8K5jH(Y0qm[XeZ4Ilp6!V`VNa-Q*U -9i[kiMJ%a[C)VN`!(AreSPSTJ*+EhF2&d9U8#'K(%*q%'C(!LEUZE$I@KXhT!i!8 -(3%VQ*lX)pPhRXVT3M6kqdDGmkp+UrBe)!M@0JrS,[-T3I89Q(il1SCF0-dXV[39 -,+fRUbDX'&m[TFm-,q,b$5YENkmd'TT&JNNMm1iL%Dc1U(GJ68FL2(3i&Rh[pKHC -@E31!ZbR$93#00,cXEX29$Aelfk53!)(rCMB32r3#@aUbQ&qR!Nq&(+)-JNU#"2+ -BFqI!1,IrGK@hTAUXdJUSY&p4j56`CjeV@L*1U,X`CR"21`k#5'@[T*+Pri#Mq9h -+PfDI4UkJ96SpqK!1ILTl8Jd1r#X`T@QZmb*%!Srb'Uq(ZIHehpGN%(#b[A[ma2c -B+kY)Q&JB)f1GfDKhJS*eHekrVkQ9*`k0*f3iF[ameeFiFVfCZRDcVRZTDiS+FJQ -(BGHQA#qI2dC(,i8IEU6$+pMKrrrE(Hi%+E*M5"4$l+fF`NClfPSh+9aTmNl33&3 -k[VNM,qD!ZDIprlBBDUbVV@"&*Rb-b!*M1rreZe4`'&p"-e%U&T,DBe'#Be'3!fB -e0-@1KKUB)*C)BYA+YRXRU+UMQ,2mc(IG99E91##C!0Y159618b&I&eZP`UDd*DS -`prd*l6Y3X+5#A&ec`B&aQpXNE@l-[I#C1('cT[P(TXIX[b%ShlTq1!k%d&'#3Gb -+",!#rY,-IB"iZL#HE`%'@HBV"[ba$m8Y&B@5%*bc2f5GY62PA(#9iP(K+N-SX8b -a2@p('(09!'kEr`p-!Rif%k6VAQe19!V+&plMbBRVK`$Rm8J&B&d0aB0Rm,1UTSC -H8B!STCqDRd("aYZRq+1ZhcNZ100F[ra11[+Zh34FqFH(q'YFqJFSPAeXiJ`**B( -QDB+*H"+2,ZlKK)`qcLP@dd-1`U$LG1a1S&Bm6m!cZa6A9$(SM`U6MULY'5lS5qC -G"f$9,PjrN3SjRB#SAk-*df[f[i&$h-!$2"1"H9#!`P`@'dBMNHT9l5L`$8[(jXe -K5S6Bkpqb9c935bkaLXeVTmU,E-Hfmp#PcTf0bCahBX(CLhccfY5`aF%eA!ejj[f -+%Zfrp"2J6FCr(UE&cfB+iESfikH-PM$[GVBV,T!!'GfkL&"'"U&L(@$i4Dk(KN6 -0ZEfl8@ldPjT$&YcC3aHj4S%h8fA1iA!CGH4X9hh$MQ2[f3%8r#'Nr[ceUrCN*29 -&e+Cf3lPKAM8[*i*%9XcG12$Y`-p3E'%"V5[IJIdh)GR$D)i"G(h4YM1F2fCkGkh -PfU,j4)EN6lKqNI0Rc+%hYeQ''iQqqiMjk%i%C+aF'V")Er5"`qNZ-HX1EQf@`Ji -,PaVm6&(XdbM4@I"LD*FYEBM#G04lR&L5lZBjc8p[1FqY+c"%82kBDhi0j+F09cr -d"'V3qcm`TmPCR5b!B-&36lZlA64`-BDklFRZkiHSH!BfB"(R46eS"`-CkQF3B@+ -5S1cq%9ra`rKBeR5R%kkXThpq"%BkI6`R2S33G5F,Bp[0lPdfA+U$Z!J2fV"JcFm -h2j0JB#K"j(PFTbBi!hpRrKiKHd&bfdq!DP5i*9-K84%8@5pNSe+BeCI&K1"qPMB -,mD'YeFL!bIe"HTNXTqlPr9bJ`bMZ[5BZSdfa6'!ec&qc-jFpbD9Xi#0ZS6*pa'H -MULLm(e9(j-q#P[GMN[iAiVk2q(%@1Y2&5ij1pR%U0R((i@3IcmFq[,%"FQ`Li#K -Q(rQa!jYL!p+aMp!S2BTSHGJLQM2XDEqNlfaNRBR&M*NQ$[e"$,9XKKZf-QNCc`J -+M)L(R4kAfFYPpL+c&jQp$,+A3IYB)%B5AQ,bb[PXFm,XcaF3c[c-R%J1rQJ0VQ$ -"PZJ"AhSf'SEN"F8LE*,Fa2[HYI[d&`m42,QRrI0D`qbHf$Y%%&EjIML%9k(*N98 -Sj(AGj3%H1a#P!h4**IIecUi%aHS5cC4$`XZ(AM`%TT%*Ae9bG#4f8#Yrq20Z2V[ -R#%%3RbZmdZa1!#XN11k,%)m-!X`3'"6@Z-j%hUqS,@4'4pF#qp'`L3`[1BK#5DF -CIGNZ[9aCbddBYP@a2@$hGH,(+D4j9,%V0M'E"6KL'U*P1X8N30EC$lip0P5RiB+ -6$65bAJa665G,V*5JYeYLYR8QP1kii&D9@)$R`!c(K*MJ4rm1+HR&KbMam`A*50` -9&q$SUB3!4aq(!!rJdFER406)dXJ+09qY99q,r#,k12[2SdimEL$JM)CEJ2H`G4! -"P3!PXaa+6NLL#9L"4eZPB3MI6[1JY%'iSNJ"epD9(!m2R"JGLBNb9aq1A`)9'P5 -SF4@N)(1hkp42k!#Th,@#UfkM&jFL``j26m1p2KM5k,#fBkYG&'iH*l9`!cNhF++ -lDA4%EMUk)PE"J'R&0MhZ5MH26BdY`iT2KH06[I'Tc[J8A!p5,XDfV8Hq2,+',Jr -iTPk2rlL)PTeLjXli`L1clXT3riZ$jf0,99H520CGE+-c4Cf8A2(06kr-F'B1L4% -H5ia1*)CcLP(#Gf%8LG$"*@GPLZmZ!J4Sm*S8J3Y2@G,`)bRTLBYG#@"#iIYVN88 -FM8ejUG*B%+XIJTPBp%[HlkY!4JL(6VET#LJ`b"#-m,V(MQFIL34,&4$C$Lrc"0J -bbbT6#q*MJ9m%qB'f)lXNiT+"B`&M8%R*ac&!Q"V2GATE("4F84IB#lC43lSaTj2 -h#G!Pi00k&Zlr)kj5G[JD6,@9ZB1[SBPNR@a("K`$MQR+kL(PB2$q(SCbTJa#!iP -c#&Y,*[6f(!4E-Vc+h3lMGf+EmpR38VaZ[S*JQ%4Qim15l9Bi0V!Z-C!!1UY@Z!f -kkZ8Y,%J@PEBJ(5-J%Fh(+D4)bPUa-5G6mRj##69+CSIU*22'J9r+e-!8'%0VH#R -!bM9S3f!0l"S,cM)#kSieMb"hLCKJl'6%H!@)kmqiX[`9X-%D(N2F3%2H#R-Lp#` -B0M!pb[p"BB3G@8jJD`@Z634`Yp-&a'aJFcXbD(3I)mG[ZABNQ!S3EJqBLAB%$RI -%'k,5rjP6I$CB366STB'heka(%#Z&h5Lk0eGJqSUe(!*LVAM4IFlZR'mB2kTSa!L -p%$mqV0&aN4STP",Sq"-)-CDMFFrbEVBmP,'A$r*q!11Im2lrbDhiFIdTRmLfFJF -[VrV#f%B2ISC%NjU)dl8)H+N`J@HFf'i324#rdRL(*&lqBCTN*Q1LiaCSm0LLR&- -@a9ej&PfJ*ikB1phBmNq)j(c#P5G18H,KJF4$GI6S!Nq65[pTFl#r[EqGQ%Pd+03 -``l8GcF-&N8hXHJU[e!R"3P)(@DJN,#8e18l%%rU$-RjGq49DmA$P9bjU2[P0Q+@ -%9fBZmZXmKdF2pq!abK8m4$k8@FH@jC!!R-9)2"J*FH*54N,L6S$S[-MB9!j5m`Q -4'ZPk#f3+bF6KD&@4r'IchYkFe158-9iJ$(V6"CIVedm([lF&j&K`P)@d9a[IYIF -d@T'&C,DL-kG0M4`C6F22"[%9J9T,lS(c10qE4!AFF!ZZDjeZji+Q!X1LLC[LX*X -q2K!,Ni2pKmc"AErNQU@i$I'1fbQhA(`eX)L1LGV@jQ3,A#2Ir[k@%L1p#H'mjU- -V&M5GJ@0C[hf"rFc`r9r4`2ZhN!$5Qdh*PJII0M@22@PRejHBdE'ARJII&S0`c`[ -qk1frE$Pcbpf0BR56qCq`IA2Z--,qKLrNTNXrZ2pVHMcapp5&-"&F)9J$I`0Lm@T -mQ6iMYN$eHeZ53kEZ,j,TF+fIL95k!mP0bkXG1!&hACXTaeNqFXR1K#@('kQ4Y+r -ca81QNlD*JVhF8F9)d*S%#8Sihm3*Y,9MM"LXL8qQXc%#Q()dGQ%G%3`C#lfp&d5 -fGLU4[5f-%GN$iiKXD5U4[5dNfphKZa2Mbp4T)a,VhDk`+T-JXEH&Zb5a+@3kPEM -KCa&Bi2QT%e4"8i+-"EDR"Nk-QhJQ2N&&DE1kBrmE%('Zi3%`B&,Tf%r%1XCXcdE -4ZbM`!l$FV35L))0$ASNU85%aa!aqHm0R['b(kjdUM[jPRrpa`9Rh$Aq[ITUri9q -&,,29M&i+5bb'ml65U,bccHlBZFhZMU$phK[q[9B,P%kciBp*$pRT1ddAHSq)5f@ -RRc*9hA[)H`5+9rZBF`i-m(FTi*)"&c824%6hE8T2ZNUY5@64IA'f"KA&PP5`%HH -2[Q492)`X@"mii@dC(8'e@+Zm)QA%k@Xp)`Q3!)NjN!#q'KGG!Xl9ArH-`1RB&RH -85h85"JaQ!pbp)&A`BT2,aLDPL5qQ6$`mC@*rI)+bra4&@q-G##cBr"9`QKcVM14 -,M"Ycc%a-*e1FFHJ3DiLG-Q"d["-[QNe'EBfA&[p66D,$%88c9rfHaAmc$h!9$@T --@63MQJ3k$5clFHPpj'5S"P#FkKP*9%!kp#r8&CRL-'ca5#U3!0`Vr3%!P[Q$H&E -J6q%Nh8(m-4c6$DM$VePAV1$#PUG9FTN$Fa$1G-%N$jf'F`N9U(`DQ!%6T#"D5Hi -Q6JVNq2@E66pjErN%6b*$06%GCY1Dh(*d36BihQ'4*d!H-[Sq&VV)Je14`05lNd- -S1"E,hU0P@5IFjE5X8b`fKdEE*hlX@'hqm1Aj#+i1MD+`qQNdm5GQaLY1U)#SGXB -2KlE6iD`cIQ`--"eViJjR@D'3!"Flj65F51i`4jp4[+Lqdh,8A`acUjP*RX521E" -X9pPp14lY(m'!U*mFJ94r&Ujai65kCei"L&J"YYR-p-(TS%+j"jQS,LAHYL'3!1T -NBB3@+fMM(4LN4$CPZ"l5d*X`$kV#[qd1R1,&l*2pd4Imq4fCQ+jiPH"r'(MDFr+ -e25r02ILRA'l&RPPEFrhrGZ(2ZC%rN[r0`Yd[cDh"U%GIr[T#hRX(&le8mfDJlD8 -PEqCmbc"pE1!rEXcGQbZrF#[hbp`Va`pqrB[+JiGAVAeSpaphrmf1hrhZGprkai- -IIR$VUCamiErRVZpIm9pE1VlhJp`(&flq12ILKEr0[AlKCZjFfj([eGArG@l*Kff -($ZHkrh&&rC,F,3!!4)K"4%05!`"kK""9$@C&!4!a41j%[frl(-YBC-KL&l(kC5c -,-R8ZP&J,"Q5+M1&4MaTUL#GC1E"CSV*M10iH(QkkJ4#5F&*#1*4bZ-m0"[$pDq! -!6DQePQ-)T9b8`fd)*BE5e()&5LQKA*35,b,ZlrrhIGmfK35HqhPrer-#'kdR+4H -5)!J#)!J0,qlPhh3im1#(Nf3!%)T@RPa,N!"2Mm@YQIaR2a5p%BmS6D&A4I5D!"K -DH($K'k'Qd-IL(3(%Si+[[1lj)-%%#8`cGBdMIhS`ERfbCf*&3#6JD#3X0K&TTXe -L#S#!i9ji('![!VY4-&p,*)!Z$@2*[96N#f92UFdX6UahEc6TkRUj%SN65&ij)EB -$9"d!+F3PcK4ra9eLe#3&I`@aS#5iSR'@2&`[qYY1Z5f4,A%F%A*RmN6)Yc%LaHm -NiVrFB,+l*92BA3!b85m2c+RNJB1"q"dDeR6+@6c,NVd$RFhZ5Zib4CrUXClJVSj -jfh2&GKZQ-1e9TlfB6V"TVdh(&A`%E!AS5P)8!#b6H!!0NKJ3HHe62@(AkAU!GZG -YY`"J#4"F[pq@DNXe0#Pd1UJ`M1%%k"5ZY)VY*JpG#Q"0VU',VZe'9qHd%54d#1c -hd4"Al(9FN4IXEH1#9DS,4Nd9!6!Y4!#,H$'6DdHR6'V+RM,*23C'jMd#[q+#0%) -F%pI2!C3mjA[Bi"!#dijHkj4DdC2E%bN`4R+)fqC0U8diNiVMeN5$VF#`2$+#*Aq -U&k@f&%63BM6GDNeb36KX2i2$YV,$5[32%d#B[+&r-#A!2H8r&G[2M8hj%jXX+$@ -j`hh+"&%%m*XI)!3pKqchYp&fm*2$q32k5*GX0$8kjAYJ@baZ)'(bpSp1f3Sd*ZE -f%&+BV$9Pa!8(R2Mrhb(BCJ9RV-)9Y5MH,k2PbHe"FkF0+""BeaJ)!'0Ni%h&"I$ -Q'!I`pfjp(pII6,--Q2@D(L-JFC6!V[F10'Ph"e`Gc`*mlFEr-"rKFC42KVR0VA[ -9(GQ%)+$&jjf)MJ)$2PXLL1T%&clr,Y+!c`*mGN5Lq26JXbF5J#2iCG6SFL13!$@ -XrGN2!GKBK8ADE!TPfK&-0b0S4F@#1HmI$)6F-pIjC`%-0`!(@L8!i8-@*L3maN1 -kL&6)K$h)I5AX`1[X`1C-1jCpFf,N&qZi&!PARH!P%@p&*IG%T*!!1a(91r`jmDM -*Shp"9bN!0Q8Q3RIFmMEB"LlK8F!pRk+S$f#5ZrY-paQ`13hD3@@2pTRrhNV!VV# -10`3j&I+jilj&P*SX)II$p4GqcaX5!GXjpH*&XVJ6)XbjUP3!dK*)!CG(hC@+ep6 -3Ve1mrEh+pBjjL`T$[,[(*,dpS(M4@F)k5aES,%&R!HXX@+#c303*MK(Q8HBHNC' -J6VPVXS0)9lEaAD03GZ5KJ9m!2R%["%NH2NU3!$@$j,MaSSpR+Qi*Q@*"a10'*d8 -pJK+!PiimkmF*9fM3iDKpNC`Kf'j`4-VF#G#0c9V6H#YpM!rb-3,S'aT*0!d!A$3 -KfAaY*pdR`@EkBjjaPXMHB1$j&#cT998-,(,k*eN`i4-$D)J*i5U@+H6T,bUF*@a -0mNpQJ,AVd9lHcJ2G23#LrbR"r5%5H"6d2Md'L(FR26J)'f%)q8p"dTrkHaiB@%I -LP+DD,-ND6bqraq-Q$km%j)3VVSD086mA639iD%e42$idZI$i)Y+**Q1'*[)d$B3 -[+5iR-3-E3`Uf0Z,amhX41jY#KX8QA66*VK(T%"X@Q5)")P5d2S*XSXTh(ba5hTa -(H)aB%q&J5qQQ133Xmq@S$A1-$FI380[,id4mZHdJBI$*@D&,4&GiBpBBL*%00-% -YE#+"#CGcc&bTZ$`EJCM,kD%A,)SL0(D+KJQKFCJeTX95m#V4kpZ2m2@+&ipQT35 -2E8S"(Le+!alGbJK-+&c+2BM@C%a-91lLNDYdi*&3QMjp""c-46ckP%%m)XT%2!i -UBhLiP@Bd'P+'m3JT'MadbRSF9U`3NEbC4Gb*,"r!bj@+MEdqBKfcM4PHd`&JPPq -b$CmDBZarqpQT%iU96I66",dQ1&r-%+3,EHc#)@@pJ)KkE6-BK&"@H2(#6mFBSN& -P$&-k0Q($4+25pa&YD!K4S"A)Aaq0+4G`9'XJiDi-*%bdTBc!3GTN))dGLbA(S,6 -!)d"RBm!##YEYMmB#kCM-$Q3lRE8TEim&FS3PJbMS-!dD&LkLh08liNI+8fa$LRb -)FK(6MbL2db'ePB'$EimT'@rhqE-`0-HIL8I-Rd4N2U2`FXa9QHk#r4bNk1rDjMX -fM'C2fHVB)JHbr'%%iK&Eq(-%3-I5U5XGZaEkQVQe(N,'TI8Rq,e&l[Q1,C%4)3[ -raKB89EI3&$*aPr-@'Z`%djX23#J%6memAJ)'ZSiGFi@1LI"la`"1A`G(Ieki!Xf -h1&B5+02&(DXr*k,eFQ+k3j*)62VU1HH2H-ALQkI!,+hHVp"4-`,"(-I+aQKS#') -k&Makp@a)`PAX1KbqqY)TDNE#[Y%M$M@(h3-jKC4YiR,H')hHQS*r*PFQ")KVVlZ -4&d2`$GE#m-@e'-[Eb#8`UREmK2%6a3pe[iMZ5@"b'dap%))0#*lDIKF)mVAd+K) -a5R[6h-r&)BK',4KfN!#,DF+T45(-Ljm5%!HBm,8[3N#1ICk1i[Si'ajXL'Jid#* --')qmiB'6YBeF4%&e("h-N!$p"T!!p@&3)hF"A,)Sam8-!EjVIip,(kAcBJM,G1j -4A(Li)$,ai)'hdlNA36QGPbJMH"3JS+Ic"J6dG$k#J*lMU)06TI01,XRCNFbQ!,M -lPDQjXC((R)ik5m3V#mK%`pY$%!2T#0BGH1MJcZPFSecXIMhMG@G*MH@5*C'"MKM -V$V&ZC'Y!X&(*a@08HHSM0J#2IZAaVjp3FKdr-IR%SDPVF&9*l4PaE'#GNN#%D4` -r5GC30UlNCTA8QK[j`r8eCbqGGF1j)d(h[8KF#c-ZDrfFmpNMj&E-&31#+dUVB4D -c%Lkc5!Yc"M,'@9d)Gpi!Gpk3!0YM+U&Td52H!@"Q3l+'AKXp$fme("r(mD*6UV) -F@2$SUr,4#,jq"0q)8iNG(@FaGAldZ#+biUhidGpl&,c'f'Z-AK1H6p'0ReKZbP2 -R4HNQ)KT"1ZiqSF4-!$eVGBTB@kR%-4PNVc%)0NcZX63U0HD(Ye`kbkBl%93UBY) -$!(D$8qGDMT!!8ba+F%Rka8T(4IT`)d$DerI40KlHmVF65LIE6!bEkA5IcePJ+rj -GmPBSDZX4YG3%BQ0eZ1"d2B*(3aXC4L@cab*k"#"Q!eG,XbeK([&J%0!)l*Fc+SU -F+!`iP28(ZKDi0PHq0K%@MpkFleMj,SC$9#abV&DA%X6qJGml('*aXUEYpH!G&"I -9B1c[`TDqLSb`l!a%990Bc46@-`1Ae3QA-diI3BL+#KC!F2fLK#[c'D"Ap$QbC`4 -02+cT2!!3`U,qD%G9H)f@LSe#-)[+`5``0dPajJRC2M%#kUBY&$K-dQ'BEab'k9i -NN!$%2qT6'X8lZ@GLlS%r+"SbVD(riKfiXje06T3R'I*Fb6@Jcj8@C!Ia3!+2)-Y -@'J0T%2ZD`!NmqJ128(E%-T-[!YNqAH!%KSa-AFAA$k`,C'(V8V)'"@621d8)AdN -4`GbiNk,"+G(Lk%H'XTNL)q&PABZS'dZrcRr@bBlQmprak&[XD0&`Y,M!d9RUd@+ -CSd8FhEV!`5jfm#!lYX4`E-N#ahDTajBXH#`6i6i%m%8QBS`E@!5$cEVY88&CK4r -!R)P&3M2,c'-3(`&VI@fP2iXbDCBpGiQk3)kFh5C+p*XS'53QG'43#KH2C#84E43 -'1K"23iaCJ&QN+C!!T,K66$![9BC16dV!2ElHjkM[NS$f"XU1V5F8&eM!$H-KZ2U -2iV-H,([8@UrMK1V+"h3Nd'f)f1XdMRT6b8GSSJa4TKd'-da"LMZ1Z(5X3!23lJB -``2FSQ(`d%d9AA)"LVmDa!8GCBA#'BQq%*VCJBMLh4mL5e8`iar'+'LclY(k$U43 -a%EX)D%!&dV*-!S!&1a#`mV&i1DCFbZ4&pp3eJ5b)eC8NT!2C*Lq%4-&h,+B5J!N -J4T`FV0!*4"FCHkbQ&q&kHC%4q&F6Q%3[LLmL'M*-VI,a5N)qARPm@XFVZFEMP9c -jH#8$SV5Tl2'P&U"2IrXbF-&K)`B+C'0Q8N('3J"Ff68DlXYdZ-qDJ[h&ibA+b[p -(5FJU(N9%H8efm3ia)`0lU0Lj[SD+R963YYDEZ$m1Sp15dr@K-5"HJKr[GdL3!*C -!Z$`2dF'BP-!+!,QcTJSNNm01*a$Hce!m+aEAISRA-qLm51J,6%kJdURmNU,L2VN -6IXCP+[Z9U!BXadf6&apDI%!1Zlq-M,#1$p@1,``G3R(3PHRF#91(6!l!mbk`Q1F -*C)UI9EKdLcJdTjcI256KJLf)LVP@qU(L63k+Je9(+r3,-[J!kIAS$#b(VlqihbY --V'BZ`iSeb$T80TFVUrUp"&cHIUQCCr4!G#hlf3pr[4P$RN+!M3-BFSq@')aRFc0 -(3(f+"382!RBA#KrjDRE,q@TNQL)qeMhC-el#m0D1H@ZGfRBK%m8'pS(&fMFp&M+ -!+CPV$5'!l$Xb4S-!DP,J*[(D,`Q%YlC"E4*A$pcA[a(6663Y0dF`DK@DXSM)q4c -CYX1'V*p$X0L-P`C[G'R`(5qe[r1PY"MBF!SLT"Xr,ILaiUF2!*00iKd#fikf1ES -"K$b+!8%'J,3#*1J6@eKRUk-&R9&$CapEEJep1&V`Bm920beq[lHG!!R-b9FZBLi -HT-aiSBi!M$K1ab,$cNMlVq0&a#8J6SRl+#YR6BqV6BqcK4)4E,SkUTkq4!%'BYN -V"#%Ql(3%SLJYI!5!'!&kJ++G!+Vp1Rj3"Nl!dV%9JR1-&@4DK5""*+a)P,TTHQ9 -(GimqN!#,!4Y)Q!%-4X!,#")$iir!#*+&%XadiK(,e0)"UjVFR-#9,#[`#)cR6JY -!-Lj4dXqZ6&DD8'$+'@PQQ8"TJHmJe"R`b6@H!j!!H!m4$"21Sa$d1bfdlB4(k0B -lh-1jU8#ImFXell(X0+Z-')Q2LIMT`%mLN98'R321q%i,EH$h$pJ'QPMfeX+%mJP -LR(GD%K2,$0,NRNVSbNb11%8dYCHCPT`P1be'%+`D84)Crf04!3aUqUcTM2d+-Vf -`5AT&-Zd0KdrA&`41IrA!SP@-J"m-+MB1Jf!0#d2EcTZL2JbhBhK&`,5+$EmL$pF -C!8I*C#+EkALbTl2#qeLihFGKk3e$EJM)C*DS!'C#6-5[`1GcQ"lRp#3RYL'3!*N -miiZrq+XhN@JF6b`"XM"%5(,jZAETbPqpMb'ik8dM!(M,4bJB#YhNS))C,81L5Lj -J-r'VFAb-M`Pd"-"Q1Bi*JL!5,U@Z"#pHDZLZ3[F*S6[#LhITCdFJcAKV+cPPC2P -8@*C3@#C5P&T)RZqS3M&CikJ5#XViA-d5'f`)@5R60i,AYi&39hb0XN`Kde-[1a" -p[qedkiI)2LU#GiiTd9pPYIcP(lJAA9D!2kJJ@B@A39D8r0Mq+jLU!HJ'PK5&4l# -N%J(j&4eq02KC$lFUJ"X5`5HF'(%fJ"$KBBpS)ST"BIQ9X@-&DS&D)NDlQ*`r5J3 --ElIi")RRkP[DGTL'`P#I)P-Sp1Be0+Y4'ae`1&"8imTbHG$X(dB#af#)9hf9M0I -E$PdcXH38`Q(raFK4R&G#e(!q`bJ1JpbGFZ5Df2CT'S*CPpMfGMF50D4KBckRY`* -&+%bPF5r[G)BV,1RE`2*eU8"iei&'!a!qM[mPq0q!JR)*3*%"hT@JMf*mZ)3*@bV -%%m6GQL$!Neh)i(bf%`#fR1$ddB!I1hkk3%ESK+(k@qrFMBmBL%iN1Z)G9H[1pJr -qhCe$rba[9GKSDdp%Kif'M0[%T6'a$3aKR-3)Mb9Vk"UZ)mLMlB4#L8-'E9RrchF -@@,)i$K)j*C*5M-He`!hac`l!@*!!$X)4)Ic%fF,rk0V!!XHdi"JVMK(eMm(`1!f -RBBpHqqId"BBe8,C3DN#)"VKG*JR4I'Rm[HUVB*+5BDbh*AMRp#Tq%-i8YQErY&a -JDjqYG)pp"i!+J,c$#%U5Ba+j@'*%kfmDk2SQjrYje-@ef4imITF6f+pX[3G#)48 -&*X&3J-KK1c%"UJk1V!-l[38!'6Z1&GeMh6d),VVQARi!aF8$`9lqQ0VJ!&!i+&` -IQ#02-T!!cN%'*%,a"&-(8F!RN!$133E53G#@36U"(GX%aLJ'aQM$,"aZmQaM"8k -PcK!!Qe$JDf0"X*8&`3a1!0TF"+f$&,3Zch(@G-L44Y'["Z(e&)a4r'c,#YHE!I5 -lL%3Z8@ar138jqN&%M#&CK8rYZ&5k`e35d2%rFJ9!QRh"X85$f0+pcaLF2Xe!iTm --"+55$bTjP&dMST!!ZqR6$#@1Ra!5mN9c,5K)D9K'&`H6VX(VH[BDBYPHR,+pKq6 -K",l@B@J3"K*JR9S'YF`T@dmpV(q"jf%FK*re$+6GCL)`F4F&"j!![P`IAGI'Q`D -%)0()+5R$A%[fZT!!UqQ8GJ!!4%mT9$er`e(i@3rb925JDaZ"9Z*)cL3)Xa%5CS` -TNBMX)N5S3S5@"PEdFP'"E''l)2"9"Qk#bX!"f%-0H)Rf2)"D(qXc2IPhCDBRFaP -M#eSK@Yhi'IS1NG5*H86JY1ENha@b&mBfkS!'@#6''JNX8K40,ZUc50pDhmb*25T -0p,2q*NSQ0bc*aF$6XjLTl,!pSF-55A(39m+q@'#f1@#Q!ZBHmrS[I0ckP4JSXJM -!m*r!i&dXEMX2NXkZiC5@[iDe+U-e!B4qlD#3!05["-5GNArF!2")5S4)h8KGJNe -3XAH5X!@BV'a'&ZPP*2**F2eAX%!&*Nm&P[PIZA)rK-3cjIpIkK!bXJRD`HRchKU -#5G-%)Mq)JdFH&88NB0SkI9lX$"2hVcR$p6"%*2CB(-c-,Y8pdDQ`cQCa-1X[fIT -GF6NK)),ZeTXhA3#jFdJ[&,!9*"ec9Ce+$i5+LDJ2Y*')MAqpr2Z8i!FN@Jr%"k% -I@(`+"K3Z*,k`T1pd[dRJdK%BRNCD#,40*KCS($@5[8X0H!kIF@T)aKGkMF,b#bd -4J#cAhF@Q%PDN'JFN1XZrc``XhQ$Jp5&M8Cjl`6Bd!5bb#B@je4@R$NSShUTJ%f' -a)b2p4rX&0QFPLPq&9`%N`6(,9F!)0C%3AI@P,K69#irriiC%'!H3!0XAB(J95`! -*8ZLdQcXGB#JQQ3SSdY9J-%NY1Z%UN!!VNP5R@5BE#)%!6UED"ErHr,-I6[4E[aH -mTj'Hqr+jP-0+4p9I"`QS!QFDb2'Ki(S@l-!XQ#p8rDda0K3lNdZ&b-R%*-19LJ3 -JM-Q6p11Y-'C-G*Be+I!"B(DkRV0QGS[fRT@',DZeN!""K`C*)TGmAcY!4ScB@!& -,S*EIMX,ShlD08%$bZSXM(MS!6TF[(U9#Kf0Y4p@b'5'!@QK#MMbJC"HM!,cF3rI -C)(9(pE[j)Kc9J1-,qip5)J&1"E2&C(kFX,(NL[PNfN3G*'`B)Xr$M*N+%@Z%B6! -d''-&Z9@Q-%2T4"*-3aaQQ!d0*I(i(4"kPbFDh38!M`-i6N,[J898TUlM#YL$3,, -'RXrVm@0T'QMY!a2qCP0Ia8"f,4EhSRBJk#&3qCphdI++3h%N@!3,CJ1Bh#d55(# -BL8*Li4Y!'+3)#4N'A5SeL%M*8A8B`!`S&RU)#Icc(&SZ[+!)q1FC-*USHNj6"J# -eQ"`$!*J`@1MmAfpZPRlf3jBe,Yr2+H)*r!V@HlQl,kFVL624`3-Ab5Rql%2aSN" -`Li#94"`9*J$"%ac$kraarAQ3!$5H6F6+ZJC0bkl""PUf5GE[YTfR)QBMQAHY%ee -,b)"V0BVLbdd8I5YYU8KbpbbZ(F&`#NTHFJ0Y(bh'LYHQi4DcY(dL+rc%lL4V-K& -4L@(KJMRRdh8S4N)X44Ql&ZP#C"&T@k%)[(Qf$D4YfdKEAaZ5Z,!)'jM9Pcf*h!U -ZXJlAL3ZkQ8*&Jr`)QEU[lUKk*Jq1R3q3!#"0kMH,0@!6TcmfEBTHZ$IIT-('!") -I,kPZZ@`LGemJeicBXH62XU@TFeJQ$YkE$f1r4E3B+1+ILR59(HJHSf'QZh$hNfc -*@TKVVk6Pk6pUF1c&UVZ[aXY5i4!ipl$BhSM#+!lZBa%[Afa@,pi2Jme#&[%(5+K -KHk)3mH*TeIRFBJYF$je`[SR-CEh-C@qba*Fd0+MY#c'hVAQqc'$CFIhNZ14JMR` -'9%ALbTUeY-b#)pHX-6Tbc6*bj$p(Y&,TM*db44*`KrNa$T!!`R8K1e4LM)P!&[h -FQ@%95!ELUd5!r0!*j6VFTJ518-aE$l*T[KT6'KV!pp)a+1"h`M"NcGY@jESFPA5 -3!(!)Rh4B1DE!f!6')bq'3`$eB8"k5-F6LBL`m)aKm*GP&hi[UFL)%6Fa'fKbJKQ -Jl*@4M+bR3@!Z@`&SQ3b3!)"QHd)J&S*C4[%dEd,Yr1h[lE53!00'A,-U!8"mMEf -)Z$*$3'P4)4MB$(Fa@%mIfp*+"0B5X2YH%GFY2!lfp$SYSja*%-25bC,db%A!Z&T -X(#3`@5qhpIIb[[kMa+)+aABU0))Cf'FS-Qi3XQDjd(LkCfSD!Vq&#L*aY5!b6"R -hqQLIBmc81(dND$8U#AL*)5d,cl(YfC%9KT%dr!%f01p&hmY@LL*N)8)"aP9pYDa -"AUGf@K[D9RC$IVd0*CAHMSpY4dhHAJC"E!ANB@*!`&BD1[Y(IhUrqPH8DIHVaNX -[HVUifi@SNi$m2+(!MF+3!)[36K$b[ajI6-K(baJ6-Z!F4Gd1paL##b9M(JU09RL -#SaA4hUB+6bp)*"94)H1(-+MLQpaM'BMZhJ&dpP9%S4BMZ`)"lhDq-i!LXKFG2R4 -dN5'$%F#%$0"2KkL0DiA%!X4`AkN$k@)[c#Z*B*9[1'iqCBhdJbDA!$TC1`X"&fl -Ea9$XG#03QaTkXb[#&5)HpSTi,ikT#10kZj`)@`958F)a$`4)5rGRBA[#-mI(%Mk -lC[q[3fZG5[!*Sq%H,B8HNSeB@Lc-P5jaY#)mq`%HpYQ9A!$NSZ1f!+4NLa)Z*03 --3-Tel$"LT%JC3!d"@"MB8"'Q!LleBbFqeJN[NKIXh6V+)Q!LK85j6T!!J-E$V%X -pT*`#X[%#1*d)"LZ-DqaUNb`biaD+$@`L@EdNbhL*Ir*K*BPBRa%8U#%ZkFU`GTM -2@6r-UG"pZRi$%U[#e6d8%1DF2E4#$i93Z$LM"e'DT'r!jd-"#LjaNJMlR!bUT$f -@N!!L+Y-l'EY-C+k#Q&XJDp*MB$8cRS`+!j)eeL5*!PNDJ-NH)Z($"-j,![MF,4* -3[AHQl!3$fPlDQ)m-ikLi"P20R4e9AFdb3L#1l659X1KKAHI5-mK-G'IT#%CK2if -ZM*qK6`M2JSjj5#E6p1%admcMJ2r5jarrj9HIJ5('jp@UCANS@Z%c[,ieNpZ"9PM -I%&4`B8FbC@LP,f*"%iHrk#4AcHdjiQ(La)P-aQf)b!UpT,04&,E#c['DMH)&A6K -B[(6I9JZ+F#ib$[J0-5TeYHHK*N&U+SH43aZb`VS2EZ*4NIAeaH9Lf`HB6Pc65Ne -pBYZ9kp`AlH0MNB0*r$"2$-AEF&"aL)U#kiG(b"`,%E9qq0`ehj,UNaBfrF*[ceM --++iMLDpp[FqA3PG,5iK39IrK53qF)RFQMJ`IHSA)Qf)E`#&88$k6K)b#&(%!l** -5LZ'VN!!,!Q,6D$I-kjY'!8j!N[VaBP-S[26e,CES!"p1pa+cP$4meC*JLK55NUj -DQL'S%2b#&-$bLM)jFeF["&)6SD5M6A`c9pl%0h10QrKQVV`*#C[iTVS*2pY%"G[ -%3'iIVLeKQkJ3Qi40m%Pd5AG2iR#3!+l`krL5-q)QMdFS(00a,eKmZBd&BM%kKN5 -Yae0daYLT8DjBI%qKS*E2'L#J8"-BSkPU&UjBNLkLZe$Y,Q6G2VhZae@dT%1@-N5 -6Sq3@-4C83,)HL`'NZA'1,pI(QmDLBcbF[FVf"HFKfC(UXH!H'4!IZK*m!d6Y0lL -Rm3fiX64NU6mENmDG2fP"C"6ZZHNb2haL4Y*1XqM2HQ&aHFcramp1)Y$Z6"(pD(S -qjKqAFY+LJHU'29qkc'ZqpmZlbmbL+mZ1TUjV89VZ4QAC+G'&aLP3UA3+af)T(E9 -lbVR(CBk,cMq[-)[&@EFaS2MD&4UJ8eD!p)N"Tf,&imkb!9((-Jb)ZXaIr@$AbKU -c+'9j-8#keN!$JNV0q9*S3i'+B`d'K&hQEablr9m[M6UDfj%iTjcEAHB,Afl4h3M -p)05bl0RR-TGVKcCH"ZTGMXdi[-YPhMldMmTPS#ikDM"!G*PrC,PDFd28iilRd6c -Z-VrHpq*rAFE#"ael-5$S-MXFMmqq$23ENA#SR$Hkc*pP2$cK-Y$A1VCLJ0CPIZ6 -QPGJ0dGrNf)(QQl!i9rrMrAG#R`"%HPXBGK4Kd,$,22QI"ejlTbeJ8,hH0JBGUc" -Sd'8qrBVR`fPZSaK!SNRB"JD3!"X[kRcl!%2r(+(rHaPp#FhUJ6if5bj32rD6-BE -fYaRDRaM3PYJLZQLE51+6lc+((V[ih`cC!SCXL3&C2eZqBYSFQKDkc(qBpEe+KQ+ -8S@JhS1KL5bHJL'4$,[21r[#r6`2*BKEK!T)Jjl[-J6jlff@JZFTPVTQqe(`CD+j -aQArcd,0E,`20jehQ$hrl,dY[L'D4brcaeqlY[!`dPlR-DrrdkTHAJ@D0bcccS[h -Tbd"cKmYFrErr8(a$0'YGj[`r[P9i'@KZGTP04`,2A!DD@ehQIp+e[$P00+@I@f+ -Zf@BKZKh,IfGM+(B4LRm`"+KI@',&V"%fr19r,$)cp$jLk"de"U0I@Q)5D`CRc2j -rra*MU)8*0HY8fe3ji2c!%[1cCSL3!1e,KU--V8mB@YpH!#d%NaN6e[@p*&*`P6[ -2rGr90d!+blASjhF50d!+VMcKhqUF,iN8LmcJhqrImT*S)CLYQrlbmKZJ"9IEm8I -YqCG%#d*!1[2eiKXJK@$`c)lDhldN8R#%TArqpC)E))9!fTjmV2!'5`9(RI6Hh82 -64!ZZEdNa,X6D0f*#&)i3BNrV1ElPP$&k"R51Rc(8'KKUARfhYj`e1Xf[EKe2CFK -GB8jr@prT,HH0cTcrrX,I-I51-[3qQLCk@**$Mcrem3h33c4p2lVj`3h4JrXirVM -frlS"HR$UmbRrrX%0N80J1e+q[qF'b#'kmKUA&Yd!16M4@mU!rBB,"pIZm&bCIN2 -N%1KHE0YrmJE)34$mB0[U6fqiF(!QhF0lIRj$p1$N[crld,[63ZrKGjqTjY+IUlR -REp8m#S+4R$Mi+TK3!YGk+"QEmcBBp#YVc1-X4,LeeUZ&#E1(Ker)ZPe[eJl%2%X -qBj-@-,8$B),$f4Z)'GG*+miIHh9Cb[kMcb',cV"!VCPdea)FFhTV8kJB*%VGa"" -88-)[I,cLr)4ec"'P9TTi$i4-QLJATBXd-30!Z"DS2&!!lV*6-52VpJ2,([15c`D -HVNKlk+Z%PjKcpP+[(4!p!U*"VBH,d[0RXQk21l[NXjM@ajGJf@0Qjqhk,`%dGRU -iBb'BH8j0iNFRQCHm'BI&rj)h8bbrII2mZmlEXHJibj,24TdqlVK1`jrr$+a'(3S -"',3%a45@*!B0-9fK(RK92R$FI-FVaNZG[Yp@RrUeFccVQ,2NXlMdKcG6j[Mi*%[ -X**Ym$j-Dad*jQK"J(H@XilVFBEACE'VA$0Ce9Hl#&CARhfdD3),m'IJTEb,9!cQ -11IKj"6m9q+PVDQQkdh5KDDMe2)XSRMHRjDmq1H)CN!"'+!Mc%3&JSmL!#,c`0q@ -#X9a!3A(Y"E83KB4#SX8i`4EQTR%#LBAdAXeAM5qA0I#+1[#QX@!P)b&H-4E%`[9 -i$HZrbS8m[,bJeqMbKUMAKLe'3%Pl1-5)Xa9TSBh(P*Mr@[[ceH210[UARGeRKL% -#6-pM%UE1Nr1rDGi2N!!b,aH,ej`*&PrV@[,H'B[i`Z`8jrMk&,MRda2@K1!Uc[% -aUHJcFV1T6pHY1BZS4#!0ia!f9592qH5T#MB9,)kpm*-8iD"r`e6TJhk``%%rAq# -JA`J(Z4U,GG)[ccGGL&iJKh#dLX@,cd#FY*1B#(dPZ[$UBLrQPVpk#XX#ii"3@X` -km!H1")AL-J$LPJHIH+P'`CV5M4a*T%3`VJ*1i'K*!-*X'6fQ(*pTFK51([[X9rr -b4`C+C#lil-&-!B`3*X)@!RMK#h1Xh#U)(8rfZN`P%3be3'a&`e,@Mq[0XmrC4S6 -1G-PA%&N(8Ke!I0Z4!,Hl"b5i(Hk"5+ekU5Dh4eB[b""E4)J&"F!Ff`B$4m'3!,& -IkTMhVG9ZcSJShRC5ME`HSJQJ-@e"L--X`%1*fQ&!XJNQ&3("K8$Sc80KA`-5P)k -Ad+6#S4C2EH!JBclq+C+A$YIa!#i+X%Y@X-1(b45AViU539TH*1`HRC%'%2VF0Rb -JSa)Gjp$KX3N6Pc#4kFJcHI!"!mY)K[cH"RN0NQVUFM(Vk"eYRjVCLqmZVYiX -`JJ!K+'JdpJRak#R"R&e)RJ[MTDGRr)J),qF'CU54+@QL%CHd1r+1a+1Mh$%Ml@" -$%j!!3'$&BqV6-p+Zc#HbIB+4QDZhpK1`9E)+TXQ,V0R*ikVrL6f#YLCEUlU-NUf -IVeHMi4U5%#-LmKCCFr,bbkm4Q,$m84#kH-,HK!G,IX6K![a+(Cr#fHXFA(eSX@c -qJB(,mD0h@IPdH[3$)4!NUV@MbC0JUQ8CM`6ib9ZXpGr"CrRl3)qATj!!%Naml'2 -'A*B2XY%d#56q!qbBC,am@!lb&K"lP+(UJX1X`T)5Q(K[q68NJik6)C@46&cp1N@ -3!$@*M%qK,1XHSVH)L!$PMm,N@PJB-R"F48S(U[p*Q"a2j,I4Z4+E**9c!*21*92 -&[1Th+4Y8ScQ!D&j+#mi%)L9SiM!ZmeDIJUP@1a'Vbam9QYePB1(i%b&$i-YE+a- -0'NC6P`J,$6[bl#NT@0iJ-h8a'XDI!GRf1R@kJmVl*KXD2+Q5ETZ&)FJh-qN6#@Z -5"PEQV39)1#G[,8eCdj4E(9@rb4#@c+Pd%`NiPlU-ad5k3"b*d[)%B)$pVD8C2@T -c-P&TC!B0@%kSXh$$8)6,'de!+F,AZUa*Ri3T`J"S6(*E3$DaZrfNQU"jTr%3CBd -k1Bj)3Z3i$*J0Yk'Nb@ci[,86C(5&ijip`!c@3X+fP&Yd0Fa@0A"$6jQQ`e#4C0c -UA5+r4,CHhX)Xl@-'E@'DZS+!S,bI4'SeY&J3$V-`@K*&@"*-MaLL`+FA"9&jD41 -NIIbb&jE[H+Q&rA55F@'hLrS,qqPq[80ZUT-RhQPKM3j&+QQ@cKHfcT1%THNR4FL -+-)48-5pGb84VJkQ6(BE'5+*ebqQ#)R2p"3SEYUASEbXXP6D%eP2Z)*C9lJ#e'bY -!Q08m*CM,&L6#+K()Jb2ci+4fH@)mQL*DZbN3kK2FS#*T-,T#Hd(d61q%-SePT(+ -iIl$ld82AL+`(TFe2K$a"0i,83+JE@G-e,*@RDq2T,@[1*U5ZFkHh(,kpi@cB6q5 -D"JkcNaJe'0PiqVYVcLHNNA1R[`Zfm[a9lTXN0dUXMaEcfp0Z@+2Id"XZ2PhrK)8 -QSIEQ3[VCA[H8e62A+92aX8Mp@0lpC[HEZiraSe2bHNPTY@-blh92PS6Zb4le)kS -fHh9bQ*SGG8`Z`(5$fMfLIR5Uc8SQakMC4XIN1+D$DRHMqU'9Vjbm5Efb'G2Ee1k -*kSH004P5QeK,!p0&&C4q68Q80&(L`[#9fBKChN4QK9I@"mL!m-M5dN64)'0S28X -K['I"6'Td5MP)h6AZdHQc"H+q,AYb65)G5M$+%`G#%Q9l$MAE)h%03Jq-#FKe2dP -hFaMffN3hh2)DCB9rq[MUU9km6&l61c"j&4!A*krGR6fjCA+4EGlN(GEXb9Xa[%J -GVQ($BFL9FfRmk'5SU[qNLkCJ,S-KT45S42Z2aP49$Q3-#)E6,YT%Hbcm%d[XbQa -cb#`LS658BNZB!(PJY[RPU5!NABP[r+NP$KCdpXNBLR8`VMYTmLjqNjmN1C!!##a -qmlL05k%Rp)LNDX)0PH(A6*2`98)NVfN4['KaEc0#"6&Z5)392S`LRhLkpBbY@R, -K*h!0MLJ'PTaK**Z6dC-N@V*ABRUBTKZ*pHAK6EQmpQb0*C!!`TJ-%+TLJ5@II3K -feXITpF1c'(bq#XQL$KX2U5p!BMX89rIU4h3*BmcM[9)Jf#ZjBRGD2dXd0jd-R+5 -$G9mdmTVc`L@0Al6`iqIaFaCTYiYVcj*bc0JAABb8f65I4hm5KVPrZ!d+Z@"'1H& -PQa4iZ8pbJI9ebKZhc8Ze'4E+c`4b'Vr)P1a$iGdFG,1AZflk,)!bqBcq)#2Umpk -a9&Yh$beirbJ1UH,E525$K1d!fiSTLJ)d,U&$5`q#FBU$2N@r858j'DD'"18dd83 -BMB0J$Ne3'H'!@,j2U-b0QebcjVe9Q,li5CBpNFS34J*QKTiljlf9VcEcLRiNamY -r&bmJSa,KGR4+5NI9jK*Q+K4Q+0U-K`KNFe*%JNEEDNpK8j4pCL+4Ph#J[GqVLRP -UiU1$Zh[++Yk4QBp-$[16ZrUE$S)pCiafPF-R,"'8(a`d*NS0bZTB4&,T8RSS8e@ -5[(1-CGe9d45@I*813'*dTCNba6%H#630,$J8)[r0XSU-QS@%KKibp)MSh0QTqdc -KmD1TqeL!'0XpP[TD4JqQEb+JM#DR4Mb-GEYArM)Lrli*CYS`)I4L`'YLGZVpMT[ -Dp['SQJ!'(!1m39d-aMab8P#&UkUr,EC(,BpH1aL*0$"$jE"JNZ$)BN-,`%b6-Td -#0Y!V+`F+j3L&&)E#%%0RM!SMrff*$"2lcj)bDkME*'9kBHjhMd`Ebi0PTf`QS(U -cHVm04f!$$daG6e)a`5YNJ@`6$fJ6l@0FC+bkU+SB!U[1L2C!eK3#XqQ&59SR3i3 -5Q%#"$2FDMbCe9UPhM!bqBl9UB'erLLTd-#j"VRXdpBjT@hJdYB@bY@CZ``4EB$+ -p@+kbc+[",P2LS1c8PZV(S$V1DhKpJLU)k$FXBYkH-+'ZBDKV$-XI&Tca54BXDD$ -YC6f$qJBJN@jL4k!c(8X`e(%c85+,6@'#(H4KQfNL48XkY8S9YX!H8ZHcjT!!S0C -RlepBT3iY24GJ`V13!!b#D"[9i9!6*A'(-5L5qc"c8%b$15U`eQm+)S(1Z&Z@@qD -@Bd&8P-!$RpXFb@4BGV55#LF!Lc8CAfNJUJX)@lr#3$X'QQpCJNeD1ij'PN&('`q -#QZJQ(,C`0a))TYl%)jDkVaI+2P2[ia&-IF#5%SCTfpJUNXfm!F8r@$`X#%8%IPS -kUR5Af#CK4NJQQp92U%Zh5AbLejSkK1++U$Hp66@*T`TECS`IA(-)8E83MHci!3Z -2!$FkPl&dr&le1JM))Ih"iN`SMUm8qk#%lchQ9!"VG93&Fm!fcJ"L0RDBHJ%1SJC -ha`rZr3YH8$8+pq0)#BNE0Bk-MUUAbp8M%MLL%8IFT84rXMSV`5&BXFf%)0M&62P -p"R0q3iDC9f!`9Q&L&m9H%fS$UJ,rbdefE-K$99i`GrplHX``840pi4*28PS5Bbc -aJiX"$P`-F"$#K&dYXSp3j8SUJ%e$&B`)K@N`qL8r,95k6Dji%aMK1U0S&B5*S)) -1@G(e3cUJe!JhISJ5mJJG@D1eCQ3Qea-PmP5'K5EN5NVkrAT(,$b8$P%dq1brNB% -c,8Yj)Y`1GY8I'BElek%LP-0L0`Lj!3"VdVJ,MJZ$8LKVb%[h8C*qI1DRPm!8hZ9 -B-iS"$S"S`,j534P9flaDNYY6#SQ&TBbpQ1SeGAN(88R&--!eP,9UiBj"l8!r!Z` --'!#Y28BIKS)fZG"j+K5Sbql2k*%ccE`L#U#b5[k3!*!!'++!*FFF+C1pN6%8-iZ -(H4SP0r8Yd'"%D!!RFM)&6-f#ZHN9+10"m#"e2[2@GP'#6b6)K3S@5P"2"Ca`*4P -!5hYB)T!!aeL$LD4m6$mcSX+@V-6Lh-c8bA+K,e,kU!3lkJ`TYS'DJQCLD52E+(N -bXR#!GbK4)BSMImQk"P3@)JZK!R)jBcT,(q4M"ifaKH!m$bM-3I8d594JI,'#ML@ -M9[PJ"-N!SLq%3bqTKlDfpV$%V1Qlaj*Ik6d41*KDK%FLG9QrefCLABq-ji)+!Z( -$IdVp1+pfT12MKr93G082FaNB&b,VpeFjafJ+JE26j1SpiGqIZSbF!@E94a'3!%- -G9GqZ3qC,Qikb4++%8JZ5-B`Q9m`j%8Jc0E,Q)GQJ@A@0Nh!09!4`TB@'`[64*EK -*Ic&YPJb&#cD`#1G+Q"d!XepfbE3@i*D`!0Za!'AF!bS19)D)%LPI&"C'DD+&86T -SBDJCkha+@!,PFA9*6USI+@V(493(aKJI+*hkQR&j!YH4X%CrH3kR,J2b*D@AU1( -51bm4e0Lpj"+&GD@A#)XfKah'!`8X8)kSb-aE5iQX[,38qDKb#L#)RH6mLfVGA$$ -Z4I,!b9#M8)RN,j13!+aP$JVfYjbI*#HB!JN0`!kh!"S@C58X!3J24ae%eK5ih5C -mT)*j+6ET@-+9#DBBXTar-m8m'XM%1Y0))#I2iDKcjF`ZFY5cai5%5jK%*+c(M`B -)lR56NMi4Rj1#P19@i1F9S%r'm,AXX3&EX11D6P84@30$EU++A+Z-h1J*TF'a$)m -44a&YKfh&QjaJ`jT0%i(F"*11N!#2a$r[bd1M[-8!pL`P`I$K1'4UPAJY`JZTeJq -$NC!!Pc!X*'%a0H#SHe#L8#+l'cVIdlDVUK@1!A3EC+Ej3A)h8HI2ZPN1Fh%ZX1[ -rUj@CJSFMV3$Q"NdGD$i4#fpM`-a'(19PL6UeB"1#62(!(FG%HS%TQC!!!#"S8%( -3MHePB(Z0cQ"bJJdi,JJjJ)"'krmJQ'BLbI`XZ)@Z&F&QCd[T$"6!%5d%E!&85(G -"k@3R"#iaqc(4cl+c[5B2@!jImRb`&0R*mm%BPYY'NrrNM0DILN4C)j6U%3JEGPq -BXN+HL,MF&c$T%J"Fb[[%&Jjb5LK%5J-)m%j*me$ifHIZ-lNDS"`J)68JL6eH25( -hKGmV#E"Kq!KN)4!E!(MY@'B#m#"kLTK+aARI)J0JHk,[4XI3%He"J!$6P(pmTf0 -B%21JNK)%fQL0#R+bU8"9!M[&%l(G-e2,%5KISHUR5,8F#R[KGqHP&QPRLKlk5"5 -`*[)VU9*G!GCE*YUYS-T[YJP-*aAE5c)9*>reF*aXIY9$%HC6AYI4G@1PBd[3j -QkB4K8J[&)qFF4D63%8Njm-R!F%@)q#)!e69F!D#p5#$k-M$G#XTXK8C0&QSfX"I -%e6YXDN@b*MVJr`fV1%Y(%apS@*9m43$m&hG8M3bcSU6AG*)"b4%)1ZFk%5b0eH9 -X6j-065PceT&KF*PXFA4Xq`Qe%#JD9D"Yrp%a+KT-*[0NJ&G[bL"-E+iplkDk1A` -+iP`#`$B2#P#mB09HV9Fc0kimKk3G$8%%E&NSjBAe"9)H%VI*3JdCYTH%8Gk)+C! -!UAap)1mS#DN)%MhP(5h9,+`L#f`TN4aVl(9VmVbSINX9,pYINDmKY!6P+RND"J# -&`QG"m%+T9K%6"mA8L+P[QEGf-L8qQ)VY)Z'3!#"FCjB@VL51&p8aN!!6pbp%dh" -C33Y8MTTF$(NA5qSjJ5&RR`Ud&K"m-ih#MKep3$ekb+$djD4YIPkFK&0HI&V#D9+ -&+Tabh@KSDN,cE4#4%dNij380`QQ6L!0)1!QEbpY'%k2GH34BeH6&C3'9ec)k-bm -AMB+#J-+Jie3afcFf#)J&jX1B2!Z&N!"+Z-C2YL%E,3YL#(('QUFb8N55$$c"d'Z -P!#G,p3%RHG&T!dlbSJ,J41-hJNkUGY"fDE'qdD`L06)Yi%K9[J!F+3Z1#!QZ9&5 -UF5d$Y&5jdY`cf@+5fY%a8[KR")eSC0")V'dQ+8kQLPIJ2+55j6rh)CK38''*'EP -b-[SP!ij!bBTlr[B68$R%'eb8'2$F31TNYiY)5JEhJYXj*Req$1+TP)ZY[5KX6TP -)cNF90C'V)'0C"ZAa4G0d1d5)bF9cS%+MlTdGEN(Re(HrEcd[A-ZhIYkhIG,Sc1e -Eb&d3R$BiabJC!J%)YNm#JrJm`"L9b2U$P29##+dCj*N)QJQ!IfB0C5pATqm#S-F -FK94bTFih0H$B("cV4!-NA0QHJdB!`59bffD@FJG4F!Gap+hmGqIRLFEPlUKDIS* -B`(kSd5SG#GrDVaF*)Q1Mq2DEHNVj8He#P`S8)a!1XT%GbR*1%ShcEd2K"hhZa-- -2h3NFLG#55!d'4iB,!!6"`@mVVl'Q!3*qS+,$Fq8SSQ35@HJ9%FV9CMqG@SIS+XI -@kXSIPB&$JLJpA8m9&NDeQ3TMiP,d"L3*!q"k$pKKD8%LA$0`+LPESm6c8BPV3)k -8q$N-X+SNhp(8FHcchkP56"K0V(5XAEJlCU%1QkRkh`8"aii%Z![*d&JLQqT'5Qk -P,EE@"hNE&2XpaEUU2aF8ZlXY+SN$bQ3*h#'Jb(F5f!F%+DR#%PQ2j#,HdHcT`e6 -NR$l)+[R+9ipI8rff,A[f+[bXY1+Mh)R)RCYSGISaX!-[HdDK9P``JbRr$eB&DD' -UHQC[GEUf(54mEb3Q9%e+R@#Ddp6TU,"TQ9NHbF$'*Y*#LDb5a6BHd3)NRf,5#F4 -KKRLRX,$SJ1Tbr@M`9P)dK%QTMaj6T4Bm25S3)UaRKZ"K"(3l!flCpB"VH3b)1HK -IN`LTa'Hr(ZPjG#iAb-P%,QiDS'c(#+#L"'ZL*l+e00!@4EV4e+m381V!PXp,(BF -URa'Ge8mL%"'$@eGYafHGX%NN'r+J81aPbGF!3RVKQK&)d9m-m%(&Kh"eIJZNM&[ -a),rqLMP5%V1+Er#&8'pf&CR+JeHJp)%DfXVj$2U)@BqRm9[m1KjAqF,i'rcU+qM -+6R1AmeY(0ZP`N!"B$#B+e5UB'Q+")R2,S)p88RaA,#kbY)cjP%4",#"2YXc%4## -,4dQC`RH2Z'+$V#QZq@)Uhb!U6CD@)+"kYeU1HGJ!9)-p3pFqM3eFr6pa!p43#fI -k))hIR-EN!lf0dY5me#f)lLe(10p&cF64e#e)TX5f2KFIk4)U"Vr+Y[Krc',!8EI -Sp"@X8q+[%K5Y0aJ9UL0$Cd'8,8f3!,q'kK')[@brEd'@R#i-fVJ1aEiI)*X*%EL -IQP+RcG3rH0,M+#Vr+59(TD)%%PdTU!kh!ba2G[dk-LdCjT5K#!0SBXl!%Hhp[J4 -ETVBJ6brERE18KXU6(9@,8D9J+5Aa"Q64S%9&Mhd)KLaChPSc@j3arPUC384@44G -Pe@#T0!)iI)&KEMe#,,P"N!"I04#M5"8(c%F)+1J1mK`NL5Cam"(FCTH*b&flN!! -JYSY0YS2YRJ2#!iL5Q3T0YI[P,MQM#5$*A`"9a5Z,mE%0)-b,HX)Q@a$f"N*B(K0 -()P1cM`1`k5k)C#Q$L9-9pFeJRHL+'#+jLAdHea0UKS8$)@qck4S)Z9p,(SH(0hN -5(VEN,AKmN!#m&9R'fNUlB%LN,[-ZB8)f+9)GC3-!lQ4Fp08H#aa`kqkTH"%-Kl* -R,kqdliBj8I*@)R2,(BRZGlkdV0N5QhVV(Dm5KL3EL,43b)3&G+Q,Y3J%bp(8$9" -lj#%&V3C!,a51(%UAA`')h5!X#T!!''CS68hH3PIZ6Z0ENbF*&fFGV68$X,@eQFr -#Y%Rca3$I+PVC%T)Chr,+&i6Y#JJCPYI&1ZhkJ&jFm(@pcBmD,RY0hFjEf2`E-2p -kAhEZmT65$S`Jq"@1CK'%lAV+(Qii8,eJpc(P$IP`Bq!Q9ap2fH`EKU[5KD[d(39 -(I++(VXq!VPX2AEXHZU,a%%5!3DMS)bdFDMK)24KSq[64(!kL-T@ql''JHp0Dhba -C2lj[F3pN#k"`'094m9cGMPY[1hCQe,DS2-8S,!6'J"K09JckLJRQX#h)@r#6MKr -a#c$lh-SH$b#bBDk,B)4V)6T[XHN0*-MaXa!relmJ4@YZpRJ0Mk-F&EYFZ4M0GMK -QViUi!GcBa4ae$j'J+)&EhX-Yahc%e!Cf6jfpdNM!3U20)&k0*YF5m5UVHSG-VR, -YX1bfc9l&MP`0J#HBYpPlGq1"U!!c"kFF64k(6Aq(1H8@`E6248580mK*585!6Ia -2J6&"`A!A@rj0dHal2(P$YS3UCjM"KhFQUrSF5mj)#LmM!5Za6DMf[()Q'eJ(%jc -,(S5UdYNJ3I3)BSFYGC!!Phpal([$I"Gle,)&h@-8B#8C#`S`98KjNG%maJ)6$SP -XJk0mNcRM"5B`PT(V+&p2h[S8%hG-E$$fLe@2K%Ge+d0TA)*%-MUVRe#GY*b+*kq -++1CdbFI,V*f--V&i8"$h*9`U@[kQRK,2I%(dUfk0M--NZ09$M&ci%'8*Z#*F(43 -%Yhj&)d)9Fe5S'Q4!XaI*B+BH)-&C-*Fd`E6'-XA*(ZQl,daZJD(-Bf5XBmZH2Jk -0"QhcTUq`c8YZe3HHQ8$fIT`8S@pkNKlE8,cIT`03,TV0T5NV`)M8-+8PMQ#a+%h -[T+6U%GrL&*J*m"mATUp#a6V(U!VC(aI#a-mamqRN4M*C5K`154ARMd$P&*Dd%5" -ETL!9KLCZpXF&9$frcpf88cJHSQH*Qa90$e`kK8U29TMLF,-rQ6UGpqT23DhGD'S -j9&@IJQ+f3(#!M(bJ'Z9`G`qC#Bfrai#p9F@SR16jLFa`U%VD4@4*phQK@&#!"IR -19hh+kDqJl*`lR&$E!N8DbLiBiT+LQ#dbXKHHRMkhqrAZedR0%DQMrR&KYLI%YT4 -J'f"(Ac0XC(6+-C!!@SB[R4)DdjACRU!k)%J$8#b5qUcCdqF#N!"(!f!UlIGF!SM -MIpphRk)"B!VRBJ(baimQ$`*pUeSirdqf"#'f"1)l,!'l[LC6Ea%%K2,G+E5d4h, -GEA6`p('iELmlH+M-`UDB[-edl-Fl8Ee0L!PA3V%QaJlY`+'5LM3TA5J4LYajDi5 -&m+F,'r3I*$!32`NAAJB(K#VZa$@iH`e6NAA2Q[drZr%cM*mar&Jlj[h2Q`4q3h- -BFAeM%M@Pa#K%b(15+I'X)3Z%cL`BR9XLMIS%i!49i1FY4@`jDb48SV,qH5r@JMQ -BP9a4+J&qS9bj19Ah$P&@P-0-I*5*`S)'H5dQbB!F,Zb"'9%4&X-P4$T9@KKrR43 -eUF#RG(&dEKcCI@(kJG(XZA&(IQR$)%C`B%U1QBTX1maHRJ'`(k#ea8kRJ`!$I'X -C3k-+UV)3&338I[#!+J+NDikif1'&T3i[*!8+G2J`9j(ad!!#Im9ITdqUIPhBNUl -dPR$"I4JkdXI2d#(HqH"MQ*f&Bb"m&TdN"8!j"9!1m`c8b!,dmYZY)%Bk3&XL4iQ -bSMq8SZdX!!1)EAa,!q$P1LI2e3-m%c-la6Rlk5RT8*58258G$Q2""d!$H5N-D"e -PjNp4DYBdEiU6M!i0NC-[9jC%a'452$Z,44!KQKLbd@2XT4BDeG16NTTMJJ+Me6I -Pa3931ZdqY[E`5N28!5!j0jicPlPq!`8SQ+G*3Ar#-db,0URQ9%L#NXRSTe6a&UQ -HE(cl$[l-L`%HKp+0J(U)p$-mS,5YK4CM0CMKEcc(PN*I)3HCP-&FjUm9c&c5,jM -$kTP,%Z-Hkk8r,+5PGb#C'&Fa14I%R("b(iN9E+'Q'3Y-6P-df0T6LU$2M!T*6*( -!8+Z`!RYDC-HIBP(+-#a-$Pr!8$#Bj*C"BRh)6B+14%5c$XV)+ZQ2iL!`'+Yk,!k -9Vb*[C&@2qCLa9Sf!e&r,@h[d+dC$KZ@,M$"hXE2&,9(02#$1(eS'Yk%M4KK)TF# -`3'%3&a3D#%21&Z1!2*Ce#3P8qJGi*pXm'dL9m2-SLY%ecM#FHiG3pD#"qFir0#+ -)Nrq45H,%`)E[J")UEA[f$*-+e2()!S(pd3hdCap%+A!2Ei3+m8*DA0XY)4#Q&Ke -*`0bLb&'Bb*8GF2a'jRTH1BJcaFX$A)Y!r%"``,eKS`1LmjMM'A4I)mGY,ZGMFN! -R)Y5IkMqiC3#"Ub)PqlkU+Vh3H%RCS-i%#NZk*iL9jdD!`RS)PK+K5@V4"lF)+@- -5%&TdZ&Y*mX6Gj(3f[(L6-l$3eUR)mJJ3EA5F"4[Z"QY9ZUN3LCQF9CN*Sirq`Ca -r5%pRLVIS6m!Bp,aGhL!)`&"l+@-G"T5&3@bR#PU9j)B)`%be%+bCiIK'GCj'Jq8 -XlVk*#Z%$!)9)N8#@%PD-&8)*J3,4@)HIHZFJU96!jeD+f-4K4VUY)p@Fb#bfPAq -I%8N14ZF2GI3e1AC%,NERrph8J6C(6D5E'Gm0XJ&cdIKVDQ1G-+8Hmh0dIDjfKF& -#r0cNY6e`"U$d5dTiid!#P3h9Fc+am3PABm#`-!"r'-!elH$fmV)"PB3I,D-cl5r -r#N1#Pl@$aD0k5p-9Ek-N"SBQAYC%NC[)39%@2J4qBQVTSCCAL"ifM,*0'XL&J3Q -eUN59!DePLXFj,4NPS8&!*)9hcq1$e#P"#@3H&8KK(T%RY3['JcY)Z$1#9!2!eBq -T8ddqlTEJqJALUlUN6b6f"jUJqNK(3fi23qA4(!)bl#$6,[D(V4LF"5Kh8*0)cX% -X22l"HC!!'T!!ZLAKcbM4$Kke'jV'"55hPp-V",hpb4l"q5Ki1J2Pa`f,arNFTYk -1%K#LFq%EG-PIdRrd+,hfKpRNfi``qh`TC,*Bj+hY(ac&2k(E&6CdY`U,XcfS)Y! -R0+FP)Q',+!m,S'*EURE`e@mE"RB*LjLr9adB&4Bh[iMFRL'MSdTH)8TU+@MRDFA -LVriTJkNdC+ThmaFH9iqBV`kG,+#5rjr#NZ6IerU*V+@[d0fS)%T3jmX,f-HmYA1 -e4XAcqB*+hhj"C9D*DZ"FSC8GC$-8E2&"YC,E*%j*"1N2Mk!r-J*1X`BrT)jqXr0 -HFJ,+Mm*9T)44JK,$a8d$lVl)$P*ia`f+XZ3%#$+T5[e[!+*5%M[paJZ2k`FB4Y` -KjD`Z%N!`CRXY3D40VjcN6ZG[1GCGM!,[80*3c5Rm)5M5`VLa`JUBYj)KFi0cU+8 -B19h6"r8$YDcDK+&NTU46ReM!$)SpTC5&$aQ*6$i$3jNNfYUS-#`S2q6ecA8XL1! -2Nb%5!FKkDff8A!mIj8lKchC"CG*V(BAdCm23(`e$aSSSZ0-IV`-J&2l!K(a-03K -U6GP%hP-pP@m3-5#4`9bYN!#TDiT4T*GA`X4fN!!%+YcZeFT'['V8ep[X9869a@Q -SiUfl'5!*kV+CU#-5X,A0kNX2$2YTm5Tl9F9k#jPU3J-cXahQBXPec$$ljbCbRMG -KQ"P)),MR,D1%6H5N)1mY)m#DdSZPHSeHUEZMkPrZ`f34i&ZQ`RFGA'39I[D#c,L --+Y6(5b'*'lM0XS@2iHL`$5"0pLSAL[FQb)4(-"AE@rdIBCJ*`X#(QpDT$9Dba9M -TG236L1Ch*'6T@'H!@!0KSDJ"IPk8K6D-+Pl8Mf"+)PMp#eDJAiT#pY+&Ep#M2ec -qhkc3XF6BZ,`E"A&e3[mI!!!FPN&%3e)$!%6B$e80Gc3"%#(q8!CIS@,&aZXB-m` -3I6,X1S+8Q-8MaLJJFl8c,DPNi6a2+p!L6U#Tb)MC*A8`jicCiEBMhV,EHGkLk+E -(R%HmaYXjBjcc&X2-cMQc'1)a3p`dhSB-!GYrrlrh[GIAdJ,ZlRIhq`XEY%AP8)) -JH!)J-e01LQ5R%rr%i-H85"Qh#!H15d(f#H"RUjF+4jpMUlIDGej-&NN)Qr,$LF! -VekHFY&3#28qdEVi`hMdQVZLA@T!!6,40Y0SY6d-)KQL"Kad6fM[hfqbGE3LcpED -0Q$bUAlTL`,DQFlpc$4YHLm,T#BUba)S`USU9Q6j+rr#AUr4,"j%@YBMaG9C+'[A -KdJ2SS-6P!8bUX@k3!qiX,D[[FZ[cQNYTb(,-Z[R1r&ZVR8jPFR-TMTqYVPKDHY5 -6@B@()@JdEPlA#(+GTNm5@CKq`UaAhIPKT(G41IRD6r,$RheeA@-`R8ql)8db5*1 -m9[[!'#BG`U3"A,jDhrm'ACCJM#A!aRV'f,34LE(ePLS0B`QCXEaeMH-05)4$QCB -9kaUYpQqYj8!dCYZ)`ASFZT1VZKk2LeKf@9E$Z8-AAF4$Kj3`+THf09MN@1eMlI5 -"aaUVr3Yf()63eVB@!hIJeGPiYBbrHJFH#khfclMSJikKUp@[p*i!#FJ9AZY8CF) -6G63C(IdB(Z,$1(Kf9C+IEB-Q$E-&A6(+&R6pNf`"YPC8X`ABI8&5!@e'HTQff3e -ee!Hc!#l0YNpfVKDHS*8[2U*Lb1`f+DK[b4JqD,JrR$Pd#qU`E*1CGeZRRJQ2Sp1 -hH@QTUl`@ra*9b4m(bj*TdfdSJL#P@"1,M@QS(LN6a,+,r*,&QNZbqX-+Fe`-[@` -"m4jCb*JQd9r01J!HRdZkYGIr)6BabS!5H'(QMlE(G+mNCF4F+5"X-fGZ6dPIX#" -Q'K#LjdK1mUAMZHPUZTB%UYY6,UA%CSUL$q"NmMbjd)CC!K4Z0&kPa3Clc"h,ha# -9X5'AXrB08CET(IkQk[-eL,+J%'eU4aH5f1CMp@NeCc2+c&Ac(mdiMQhCX+dJIF# -j-PRIMmp51"m'k!12rHLQS'`r(PHa5(ZY9'c3jedJ8E`+i$%*1%fpb"BiSLb(,HL -#8e$60)"9Z`EdVN"B4bhPDJF+XNVr3lfJiblm"&-GB2YDBLGH2SfK*2V!ic`@1Pc -r'-#,f$NIFMfQ0ZrRi'98A$$@2H%p+@Tf3Y9GbXQ-UE)5eHb-M$dkA5aG+0V0hT0 -b-cYaNdpM#MqHRCQEF61QdfAV)K@"-TCe+IhQTH2(Xc-LPT*55)jZ5MX38),jifE -KFYB!YF@LeEj"8VYc8cbe[e)UYXKUVib[GY%B6qh$LYU(1+STjiLL8P+iqD*D'9R -KVfJ9AKP4iDmLpHMqXeFi138Fc*'615&CQ(d-#+U1iPqL,0P[,-rdFZ64$NAeR!N -E!6cCEViY9hkB"%IC#(I0A,085SHC$iJUp9UQ`p+&&-%eVVB%K4DN#Vim48HG#@X -2'ljT[LNG4Qk-AR*86*fC+`)L!)%2U2Xbbha6Z4Y+4&hBK3X$Z($Sk(-*"jMGI1& -6A"fJSrX,-4epNGT[1P5IYqifIGkbZIKia,Tj@6@)UKX[cLAQ-@d+!S%fQNMZqXl -VIfcT2INfMKF"r(2JU#1b-L6@KQMDm-R#6'Jf8KNPF1dNDZ2VaYHCa)dcHT(q$62 -QRBe)T#X)$G1Tm,UZUB2IVN09mead-DU$jRjP-*')3LQMkU#Khp*Z'4'9H&4&)44 -#D59-`%[`D'3)CC!!#AKM#%)TN33mk*D3!+JX3-F3A0jaKSY-$dqk&bfLV%"XV%# -@45k3!&)9bTJM#3-PPEpNk,bq4!rc#h8PdRi1)BcX`dSI!d,iaYF)!al$H$b2abN -m4[$SKLP!'!JN+5"`54+1Z%Zck1X2"ee4D1LiK)D+"aNDHJMG$I5"aa`X1U!Z$p# -3!*8'3Y4&8kdQ0&5Ldk)K"CRF'65*DlD#+[*LHGQkRkUj1@URERXX*cI$9#[-eLe -B%'&8c#b51'S%GPa5(J"S"#aim0(02ZjL(hhd-Cj*bVDdN!"SScJ1&aC[&-a%fId -&)8d5VRdeRV`UefL0*cX+SI[INP3jT65#+LFVU[6A-e91,NL9aBCSK!j$*80QNQ[ -IFRlpFZAkhHckhEMq$,mH6SFT6p)(QDQ`kmPFC3PGIk68lf2A,d&`DlUq9A-pMLK -G`aDlTHYV)'lCF0e&Up5BfKp'ak4GrPp[KZ"Y8BqK@M24)JRF#+TP%pQLfh"XAKS -%8)H$Yc,'Yd)!Vh,'VeVYM45JAX9M1Q0m1KjVLA&-Daec-pEA@VCT@*qZB4f(60R -0&PZC#'lN)KL3!+T2Z5`+biQpV'B"CPp8YqIZLSNL"%ak,CD8ZcdP0bG6qfl"VeC --j(0cFP0%"B6F*JH!j)S&'MbYUDji85M6U-Sb[,Sr$)1E(4MBJC!!P3Mk($2%K`S -*)8#A''H"ISpekSL!k0b!#BK`hHUGpi-0cK)M%!SKci4"Rq4dNQ''M44E4am%,Q1 -9,"5QiI1BHQAm1EV+DPmjQ"qQJ02qA"D%dmC!`dDJ88+&E)0J0lA3"ai-0'`!$GY -T*TbP5K(E6QZ&dkB"$6ULF6&Eb+#KA2rZBU1!'Xc+dPaR&U0M6J`&&kX[qCj6$iM -Z$p,FiQLU-6@a2cM1TUda#e41"B`KK(BD[8BG[IUAD[ZFIHbe,``kKI,Lm#NJFHA -D8AkYF%S9"e,h`fV9QE!8MJTr@ARJ@08fpll+Dpi[,riha`IY,`fpF2JcSdpFqAc -2&fE28QIf[Mfmd[bZiCfZcikX',0dIfR#jqlkdmkrlI[@JZqZrYUd@`1GihX(ApR -aQ[k)mG9$hlH'qhrJ1pVaSqHrN[rATrlbc&rGZ"QmP*@4(NYNRXJpm1,a[*aXe`p -efe2f*,qFp00G2h[bEhlbBmrPae,6(Mhlq-PR,Rlch$HHrXrUU8mppr&reApel[p -pp292rrq6rjhd2a2rjDh[V&hAX'V0'fpZh[L2YHq[Ifr42p9mHrkrflqhr"mqr0H -PVfrj`m)r,VP[`rfEr[RKhdhqEGhGFhjjlhp2[fIHlHGrImH[V[kQj4GErkleJB1 -rE[[jk8GZZllrLl[rrU%(QbmdhGNiTE5iC*R0UF"+GM,L[$djD[SH(3&35#@S+0( -AQL#3!"[2f#9@CblQS5bK)r[3`[j`NZ#11m'4P[fG-NPiRFe@qje$#+e'8&8L*!p -RThMi5MPFaCmrHRC@1Fb*&'"!9GJ(-JVMdP1($Z!NUr(bQA$#bp25%2ZZr[l`'$V -9EEcEClbFF+ai$3%-VZ!6Q[[$5!)GUi%*@j)rH-+AjJV-pq3&Nm3S,JTD+hl91`I -l`eede6(09DpSVVU)j(MJD*V4NeL6*)aR%dJJ-U5(c6ETCG4Y0`a4L#'E28'4aG9 -5`%AUdqF8ed&pLbdVlMY2e3--Y',J)K$,N!!8AP%e0l-G3eGS1L90KTI3X5YIjB! -h$F0[3H5Ad!+G"c'e4r1bJk%P[$Ml,0$5Ui*!Eab[6F*VGNahKb+N89&im!S0"N) -(GI[U,U0L*4`"A@IYC8TF*`j6!HLfNlPJ+*%ZRUbJSZ,*%LSUhQ5e2r3mIH#a48& -&a9[`Q-Z)G+1#LSVRDSNdRmT3%4haB"TE6*C48EQP8Nj31+a6ApYIh2VD)`'hi98 -3[Rc0&NDY8ipk[V*d8,``)&Cc-dc6LdLrQ!99e8+'mBU"UJX"c5!8J@Z(3`mfSUU -Cq6%"!$T!!SYVV2EQG[SJm6%FBNc6F)mXP,L84%#6!%VLiC0'j@E""@6cKBNe(P` -lPNQUAF48Z`JNHLYAEDh9[VZ%2["SB+UP4c8,*%mce9D(U,C"SeSFm9!A@bc5)(N -)@1mFeN(LXiJY5!#AXJ8%Z*d4+",Z$l)Sh5L&kcRC+HSPQ35V%JU+T5-,SiYGbLX -+%Hhel98c6X3bAYbq*dr0bpfHGbNPim4h9G"i&mKmqU@85fVZGT8&#d8L096Fi1k -Sh3M6MbUBYEL$J9ib,20V+h)0AUALd(!Y6X9K!-Ka15V!8S$UB"9mHq@pRGI['aN -qZA+[F+"Di+C!,4'GJ'L5!YB['Z@!eHlGa!*@5[2T!3`1I9ia9D,ZL!TBlGk&TS" -eGe*d`)T`F*jD,SH##&&ie8-6XSS@+@6G[bP#b,TF#3Y%-`[mPKF8XRka84ZbmS3 -P!MpXI@MP!55j[Ec5aU[jZf+kE$9EKa!`me*+ER*-cGU65-4d2*UM#'fFVf2T4h* -3V%HjC%"@FL!MHc*5U#Tb*+`TfS*+Z9$`&q(X"3XLM&C!H16+MN%TD!!)#BG,UG+ -iEDa+8aQ[`Jj$5QiU"M,Nf(S5iH&3M5HV[4I+3K$N9FXRMLQ+-k#,*P@R@35kh(U -ARS+J!%--$N)-P0iLSF`-h!1&`lKV9*XBS'X39!iPfVQa9"SYb,(JFJD(MQ*"&i) -JHKd1aEadq+E*f,0(P33ET-jdb)$QN!"d%-XKHfUk@5f[IY4#b4#[hT8IaD4"e1- -9BT)RC2J@G@VYj9KJiPK`-3cG+R[hYFmlkNQ8pRCL%pk[B[Um9,V-GUmDb%F`&qJ -,!F`V$$#IL!1B*q)"TPZJ`,C8&$!I@@m#c(d6SJ#c24jJlKXa!HCY,Fm#-,G+J2R -)K!)!Xl%LJ(PE-"*J+X)&*3c01'#'1Ek0!*Pr%D#T2Gd%QpVK'3A1,G(!@@@Z+(! -#q"`F00-b$@UJ1Y9#BZd1&@fSdL%K15AF#ic+#6b3!"@!bdC+ZD'*3F"%hL-#+%m -m14%qb#!*iN3J'SNj%QS$Cbj$j5rU@A)jK$dHF2H4!iC2'SD`GI85q198"!5eQ`' -`'4M3[4X(k&`XSFJC**1ri8H642$%1%a5M@QC(@S!eR1)U*'JD!a1ikNqZrm+Vlj -9NTYhkcHrPaUX8Ml**)DR#ZfLK8m*I%maE'hFkU%$A(kBTM3Ql'VJJC-VdH81q0+ -mDA4mAM82[E"GQ,-DqfA8)59UCf,VJB#Q!-TTf'`)"06bPT-`k[8HHAfir,h(bKi -MC2M!aH&Z3q$pamaP-rF'!NVM!2BLQZdB@)+C(%($)i%!YMQX(XSrkAMLb0,HX[F -[PehQKcbMPV@Fl1dH&HpjKXA4Y%6,1q1"J''@38DdD+L$SjC@'ch2)b3eA4+[!i@ -`NaA'Rq)8aPb6F%QSEjp20HT280AL`Vc1kaY!Y1JIh-,$3%0$ieeL9$A5%5B#)!2 -5MX)[S")iQXP&eSX'@QMZS4aZ,cqKJ0NqPB'C0f*5cfBT4iMV4b%l&6$jmL33-Vp -%b%"B+XR)@L&*@X8E!45C2IMRb$aXN4#lFX30HTNDF@L%GT!!+@T[(%9Y++`SGjH -XU&CXfFihEUq3!+)1&Ak"+fSaVc3`i0HU+l"I8GHfKq+V5pQi[#QZ0RR6CcA)KTa -G9mQ"caEeY'&*1CU*@UAYd#M,aj6eJcM+fUe49U8L4[H["LRPcJ[9Q"m1G8J`TFa -@TLNEp4XMZ@bd!+T"P0i34-NBMjVNd%i#md'fLCZ40e%m'V8*&2(p6eGS%dp,QbK -I80!QCK9QmYPX*)GY*#r14VUM(86hf`Yf%&'$#A++iK9[&`rSb1@&TUlQC"(XX9` -c-@Y!3$QI+V'9,k6e#9pUcD1a&N-jTA#pS8(BNic*Rm9KdP8)Z"$%G&lI"&4#U$N -#!-e@ZVQL%FB8T'K-1"h2!4Fp3-*ZUNKV%+b-9)P`1EVeH@mDV*ZEh'D*G#p5YY9 -89Z2T$kGIi55@1XiT(4G+KY'!%!(N6ZELDY+iZ(DMXYd&&eGE4"GAQq3b9ebI*NG -@aUAY+A'5F&ZTm4@T+PNJL'cLTLUPB1m+qd!#PU228G9R-)Lli$L&fCK6q$`8USZ -p`Lq(TCZEKXk%JeiD9&,eG`E02Z-EH+RUm4GK(Z4eqDQ4f@1H9#`0[Zi4C'+A6KJ -42IVAYb$"CYhXR-m$ap%3JEM)"1+C1!*4(5fdQha&#HfS,,4%C2'D#L,E!j%GQM@ -K6fM&eTGk*Pb6&QY6QX)a)6%KYlQ-ZDr'B8iKQ-Gk@HL5)R3LH%8YH`$)I01"1E9 -Zi@-K3H@AK(p8V(mdYV9VPZD#YHb#lm5jB"+EZ)K0I#r1a0V#"+RdBZIehpB","# -@iF'V,I%"L%rPL+Td9d%!"#Df-'CHMm0-A3Jc$MUdD6C(AL"I!3"#kD,1kh@*PIU -!Jclk6q,6cBQM)`*cIB8R+i53!"reP!,d6@T4K0#%B!1DK1iXQD3eM@L$1l0XG%% -[XFYf'9-jS,5cN!#C[8L$CQfKeM%&r6DbJNSFTJeL8j-)VB'X!c`ZE*684"@2*M- -24mpS940&B1j5$L!!CDrCYff3!*F!ikXI&D8Bj6!BmahJVb-3Z#@`3#$3I+"lPYb -aK(8id1(URL89P+e0FRkMNlC`&Fe)"&XJN!#!J`S024'5LBPM3"PShJYA#kU8c6Z -S1AC(1$2+i55HP"a1GlKNKa1FJmcKe+C8S8@b8S@Qkd-F6[BTTdd1Tepp%Ze`ZM9 -Qfmdf9-8V0S6i+L8RGmDP(-SdCVYL1@SLpcL[[1l!"daJ-$BMe93SCXk-+JC+5BG -5q-+bqKEqP(rSZ%(++U3UQk5Uhqm`UDTa#929HDDU%UDUmp'UDPaU8Y8G+G'U)Z0 -19PaETH,L,,"dJih5$CXi#dJ@R&p)(hJJMGXi5"pic'%X,'%XK"JJm+R6f!*(r2i -KYYLY+DbY5Q%G1d@&YD`M3Q&PS'DI%SXU,Q9d4JSXIY(2q'%JZ+FP`bCP!i&6LUY -4I#U"8b#*`!Q+2G3pDkGJJhSbHXcR)"'59-U4NNUhhc!PPCUZXU65DDCQ&dXURBj -1+MA0-b@9cTq,6LSa`Z#9!JT*XFHcYj-D+$mHT4(UQN'&(*38JZB2$P6(Zi5h'KH -E"6@,2FkEX4Ma5HB)NSV+RqF)Ka`X[&,5l#09NBSbGGkpcYZjQNUCQNUK*KeA8j2 -92Sr-MjZiSChp`RaQNRH3!+NT`G4d--S3dRjK29[JL0X6TS"(84-Cfpm0PPAP4aU -iUL!CX#XJ%cL6GQK`4T8M)3TH349L$DqL#M&48CDNN!#b(9%+bCG!-N30+C)DlTP -J8N2cqSUUSIP0NaVQ"H1TJDHZ[")S[Uc,"3JUQP$8`)GQ3!dm5$f0ULiRYE4G[i& -!TP"k96CiQYjK!S8(lp@#!X`IXf43U!`&K3FRQd$KRXHL3B(pG!'VRNZ')k(5cda -1CU#!H8"`P38%[iS6%(6,PBq05X"4+!KD($RFP9k%H9feP1T4,Pd&iLrD5@L8-!8 -rJ+0j!6q085B0G*0$H5QrhU-*BTJKBN1))5)'N!!m,KQP9*PbLA0([pbjbNfGF0l -RV8++`MQLk4T9AN1e)@r9-$SGQNi$kbc$iLiNlT[l65TDc93dS!e@q%&*INTTP%R -"VY"eAVplR%)T[$B8Vc*18j3J9b3A(15Z@U!SB0@hiK4DIdL3!$Y+c5QNB,IU-+j -UB-Q"dEL"l@aP'NXZ0aA"N!#H-I4D()D#@U08CQ6N*J0#I&cM4V"fTe8c@)C+%!@ -*2HMB5@jkeK&J(AhSQ+hTF,11$R48D6SFV-1&SY[2Le(T8&R(1A4-eh3-X)i'G(b -S&#A[m,!10&H`VAAjmI0$,5"-V8LEYA%96Y)DcXT+4,YU1GbP9bI*5lVJ+AP*E+6 -*5f)f@9jL5lB6mK)EYjf5Pe#2l4!c'lEEaPN`h4djQ#D8`e%jQ%i%L(djI6G+k6X -[*58VXi5rUrZlC9A@BM6d80(b,PpNL5G&[DJ9$iXfId!FGMPTqd(Kcb'686pq))` -I+I`hH#UXQBber$lH@5ChM[21HEacTk*!I)k!I25BQ1M`8!HIe)kZ2JelFKIF3`G -%KkQVhp4e&9dZ8jI18AGClYb#cR1D6PA6Z4DG$CV1!8hR4A3Z0(9@NC+N+k-*3,T -%!1Sk)TKTFQ1d9bJ880aEd33Ja%cclN)%)"6aErpTAPEfm6KfIpr[f2(pl26Bm38 -,-Q-TSN+1*8ZjC#!X9"i1HZ%JDL8K8F[aBh&GSX8m+a5T'aY%k`dY8QF1(#iHVFR -q&qL(pYVJbQRK$JarSJVZPpDJJbr,%Qke[-i$FYdkREY$Pf@CTZ,k$FUdc+8%B(! -CYBBkIiN"R5!@d!$(@GXJ@K*P1Vr$Vd&)cc1%p+-i#-NP(63Ma!`(TV1$-q)Fl0% -35mG-RRk0J1`,ZN4bS,FIpHMm[eLeXP0*Mb3,3hY`51-'3hUJ,R8kZG88Ske@F[f -'+NV$Z)iarX-iM$GS$F@"qKq5NXIi0d3rd%EZ3$)!Kh'*pi'6KGbm@N$B*3(#l`i -9B2LG9K($lmQl)KPqbiJ,5P#5fh(-`%r"pa[@TFGd$#"#"fE-q(ZfSKEQG293%HB -AN!$`TjqC1Q6!+3lml+3AKP9Zr2KA!-BiE3M8r8F[SmLD6Be$+%'R[L1mGDZ%iqd -"qYNr8V1+aQLGZpd#ABklUfP#l5SaP'%BAi@8$MTlhm'4l6!`pF$8`X-2q$TrAER -JS&N6D1LiLbP2D5b"i`%fJH-bf%M*cP8H*LJrML-SmfPLjr8je-cEhAY5!U%SC3h -4P#+5S(QVRQDAI521CA8K6JelqBFi0SZ#U2`i58,UCXk-088%,*qbblmHjr+@8)G -+8bdRZ%J[0Df*Nk6XNXNb64Z4'[-d65M3BGM)+Nf88(Z,('"5UTd0cQ8!J04ldbH -Q4([6*r*QC+HCrbPfD)Z5d&FD+cCjp-T25Y*L&e[3%5bTiQbKihM$P$l&H*0hikG -0,3i6Q('6eeE@Q@8bbH#[8U+qN9ha&P[3a$1(KCCpBcNeK8KmT0d'@p#V%l5*5YS -%Uh!jf)6R04[Tefc%U0R)Z8)E'5aJ)p-d'cNAYC'R0"[T#pR)Z3JE1DIC5%M#eFN -6N!"5XTp-9`MGmB+i,DSJEL1&d#&m#LQb66&[NDHd-B@2"$ZNBP,lhjq$UZJ#[M' -*i5bfD1C(RC@0H%d+Ef4($3FVf8XRmLQPYPXU1U1!qqFMNiP0U2!TEQ+c&U$@-)" -D&3HJGM2%XD&)a,'K5-3aRehflFLA,A1%)Sj0YXlV[dbRCMXJT$IL1N1lT'P!m6G --MAJH&[(0DSKS5MrB4Jh0b)J@VjM0BMkDYI!','ZPiiaTq643[m[rmmfFN!!Hdj! -!d4Zd*'*HL*Lk*'+k4"4!6(G9K*MH0aD*Q1*(9!eUZH3%MGHXC!IFGc2HY%6jkEM -CA%%M[#%H'Nf8Jl!G%(H0Nr-TeC[+M9Y1SqX`0C*!dKP0*T3T2MkPjQcX)*CpipA -*rQ#[QDS&l)MHmJHHkIhFD!RF@#8dq1jPcC(6F@3h(AN&"j)"Yd%jYNrYGLZI0fD -QJV3'P'(jXSG"("h+"!1QlK)ib!S&NFQm%5Ec[BU"6f1TBP`0YdZe$"VfaK))5MY -GUalc23U$T*'ADK%M5GI`)rNe'f'%raY[NJD!PM#KrQ-FSHi1&HS0%0GlKbSLe-U -d8+'qIf4'KITqAm@%ZXkM&HSk6m&#rBH4rkK3,ccel)Akk2(XPjq08"I$U6j,&ZU -a-3V1re`&Hj40lD1THrFAPlb0)dG0NeS`D8+dm(GLSJ8#5%d*J-5hN!"3dU$#$SN -D@0TNhXBQ,$H!"2$#ak+,AP-@@m`"`l'DabQ0P@JaE0Y&a[X`ClZ!VD+Sac@J3Xe -!q)p)hjR66ifDqYJ40@0#1YJJ#&$!kXJ(Mc-fKX#'R4RDdm&Ve'28j-REU!'@HaQ -`r$)bX0L5%(E2'U`Df,#MTr2K6[[!NS'2"qS(XJE5"hbGlJ&VlFF$1`DU"pd$8`H -1$1M(p@m1R1NFU[Q`Xk'Qmd"R[@"r!!!aY%&%3e)$!&L-$e8,ECFJN@bVrb3[)3V -[kRGTTSkVZMc(F44A84YhUlTQHe)S"I9#&h*TcGEHV[aFfS4"1Lj6Fef@lA*"rAc -T#8jE)eDRBE9H$V0@CFYeVC-CVY[9j#bXB9P18f'%X&cl-%*3T-TAfceI$jIQqr[ -phdY6`*klhChCRId!&AGH*$-M2a%5%3)4)JEh+Q8UNF#2R(F))-AN"Q`+M+Ja@p& -`NJ98[SRE)*DLMMl3[EP!cVGLKAlIRjI*9XlH"NH,)5S0'@SjT1AR`4kjFLb5VdS -NI[4,&MaSc*9VXCSRVG"-HF$Kqd5MY%*S[NB8!aR4$D45')JI"T)rJBCdRSpHB4A -R+fT$D"#@c26)%Pb4QK1AbqMEpLGGEmdX""B!YVm351+R90Y3Ni5`k)Z&T--h"a2 -YUrX(`'F4[K"6aN%+RS3*PdbQB-)Q62GCQ!eDeALB-e[VrX%Cj@4TQ59M3BB@9dj -lU@CH*X9,C#2ja)0Q%NLM`cGdfP%1r5Lj!3$aL$J1$9&j4'UQ&IjpIe'j[Y[KkM8 -BpJ`Y(G(@(aF$e0rhCj8"rIS!GE(YY'0Da6%q$NB-H)fmHRq2E$eBlD[49Lc9f50 -Vd*LZ!BJF*ZKi"%fX%9r@+R[#k3TBU6TekT5-"9l`eQM$P2`ajkP,cJ@jkPKe`R! -(V2$-)!###%p$)mj(dm2%N!!(V*XCU&AUB'0@J)h-@'4KTKU6ii9@KL2Uhf56Imr -KEE0#'X'8KMepFNPP9P%,2"P0Z6LDFAEhl[c*$Ef6)3jIS!QqQDYm`2'+fcS*36M -NcQQY9UUV(-$a5@A)F@9)$&1$1qiXKfB'VE$,!@MhpV'`GZ1*"c8eVcjeCc+P6&J -9%`k[Ye)#fLFMl@3MjDCN[LK9Q',F@6j@lM[1CSXJSYSBAIp6@l6$-HfcLY,XZNT -*9C6aVU[jA(f4'a5&k+6%dXJX8f)jHG)$-'%bL+1jk@&Ri'314[[E1b6ZEPQj+S* -&+l-bXRIEBYMBPNMi8KBP11$&U`KRYB)SIF'kZCE&8kHr+1dhVZC2q8rHF&LR#&a -ML%Zpi3"m-R*%PUU!PHamq,X1c6MeKF4)S1#48%'pcEh6`cCeY*ICKI#0kNmLL5+ -@U'TqE-*`RjF4'&(3eFX6cB*%1LKQq#`cX*Ej$"f@R*jJL&LQ*jP))YiLPRCDMM5 -K$V"JR)aLD@D@+f)j+IANZYHY*0G!%3Re,JY49XD$a(Saj)6#HLPITQ6b-BYmmHA -`fTm@NK$kXVk-%q)0KpC%fBMjY18`El#!d!F0H&--X*Qrhij`#,'XUBbh-RVlN!! -$QajL"X2dHUeFdI6kq4L#ammd&'9%3)06UT4G9hPMJ6+I5-i(Y%#f+#e[bM+kUTR -K@PL!KTcdNcKm(TRN"*md8E&CJ%CiLB!5@2Fq6!H3!")!PL[h)i2q0#-G!$KjHU* -IiLaPNH3lVQB5I1![PFbS$Rf0R-a+S[+,CC'SAMdV4c+CYLfIh0`$XmGa8qFp3DR -@*S)r1"9&-VbS-,N2f4r#&FKq2UGKFMlh4E0q-LhM&0ciQje+eL[6$5i$*aS-plc -+`J+*!@Bb"$fFT3e2E*`2F2!8)[K'3h$e`EAPe!KLSZKZ&S%(T3%dB*e#+%MP+K1 -SpUS""0c%"CMiKPpP)XTpUL(C&1)%#pcfaXp&Ahr"QcdA`dr9Z4"q20VjSdLDpfp -1KNQdJ''*Vf2EmDc8CXpq9,'J2&ThpU1qJmSMkqa(hhK0H45QV6hKfQK8maCpN3i -dU2j9*[b@@NZ%X8!P!FD3!&LFNeZB4+%S5eDGBp@,*APel4eV#S#AFd0rrQlaXF6 -!h'1*[X!JXRmV6H$m!'b$-EpD9JNQeYpNpV*)*q#i5#$b!SY@llM@H*6CTNi'56d -a3`eNp4*[1bqe$brdq&k9mMKhSFIIq)(bf(r@Bd#a9cj8(SD*l(L##Bcdc*XLi1I -+Hr,,dKcXNI'*Kk"%P-Z*#5a3NMTC)T63C)K8S!8#"14-#$+#$`KM8@#LfA#HBVM -H'j(PN!"XH)J&0,m9%X'm6,#4A#FSY1A*Hkc(8!hZ!,*#pE#QjPFR)j0aU1l(j0# -DMNpSBK2#FB)-Hbq8U!R$MJX$a(5e-BCUAB6K0PYPU%jl#ip*"J1Fb%U%Xi3'0F! -XDBI*UEM3c-T!0@$#'&FXbk%K[%,,F[bBhlS,8D%qMQ$pe0p&l%T6-)kQS"4+cdk -%QDk%6ef*lHH'rUNVdIH`'2MH6J5jB"E4%prEkB[6aADkH-JUYdNmm+'bG3*J(EC -fckkL`4fIPY'#%(BLl#3UQpeFV4BK#`i)Z9CrX[1B-,RrL8[miP&G%'C98UH5SE' -*V50c@bA6Z`3Mp'Q("A&dRa++H*3*lElrFbr&aKTMDrH,*SPPIJk[M4l*XFZqkA$ -$&a)9fLTHQ2cL@,LK,h&2Up56BLQ[pV$CL-[V8M[D`lP$XX%*JV8LPJXP`VPZI'U -k!JCC-mT`1bHa`cSjbXd26QJ(+9iLR+*$m[rcrk,rMrpLCrdA8[j6m9m3rqNA&4` -)+6P#ebc(&6KM[B!rZN%68C)K5'(3+K[bRfj9$,Rc6lGHd*!!ph'SP`hjIc2VC(4 -crC!!%V3E-A$j)EPBaB[[*kDErR3V"KbTac808D0FbQkjD2(Lla,6pV!MNFM+ZY4 -6l9hPB8a`Fe8BQCeLSj%13&lUNDMQiFq)T-qB0Q%)-q(2%!J9J1M+TkVPM4j9+Tp -"c@ldr!-X,6%bV4i*DkNM-3iE*1iP4UU#)'E#e-#pBbf)DLJ2XGNpl@4R%UqE+YF -kUP`HUP`qUPbP9,QN[!ke0`C#rjpjQj!!F2pYCVHeQjVM)jd8+[eIr9!*2l2`b*Q -Q!d2&N!"-GI',)8pc+2kV9aXLR*!!eY+jChJ!-4FKp%r#0&+aYe"R1G3DiHT1+Si -6CS@5a+6N5@SemLfdd+5f`SXS+`!XBM,rR65R"3l,Q[%Hq6#lG-6ZKL@$%RDS$`j -CmNFp2cJ9PEL@,dr4j6%YjNU+4c3P@[I`M[fq9*bJQL3HqdQ)QlF48-ddQMJ-6-S -LJJDHFFlilJX(r[j6TcM35eNiDr2I,NdNC%a$-2,E15c#YLJ['Kk6X8SNiX%&Vem -*d313!2JbQVS)m1-K%cc2hHD`pCGc-JcLcr4a8l$[2Lcj8kJ4C8-I-G&a3U+C'8T -ma!U``%'Llch182*H*%cF5K)BdJc(6LLKK$0rKKdX[!D(kYMC%bphi[V[q@5X!Qi -Yhi0DXeM03E8PSDK5I*dQBcZJm[C0KTkk!lM'DGepAb%BrQd(Kh,Q*"`qEb)Nm%) -59h"L!!MGdd4%le3d)Z0cLDFj8EYZ0dC*P"rJ*KHZr"lqI&5)'cNdZ*M!*9F@GT& -T#RehJTRLFKb9liG"1Y3`89`IMTfU&-`kZ@-rZ4(ZTb4ITL3r6`B%pcqUCP,ZS%S -RSd08"3&,!(k`&H*eIcjf#NV59iM2jZSUR+HJf,XQF$%$JdGLcrbDb08leYd[Sj& -H(fI)$["Ha*V!#l@5iBdL,PQK5rb&Z#YA&h9Fk*+"&TF-Y,a%YZNEN6p-hdKGY-8 -P)bdZ'6RVNZhk4Z6Qp)h8a9TF-YcLNZ%@PfMem9S&L`Fj1'5TI!Qca$Y4kH!3p0T -Gqqi!h-b5DF)CjR8d6@`ar-3d#iDR`N$X,8fRlj!!EMV--UGJfFU1r9lla+QmI+j -m`ahhh8G1*5VUirMTQmP91S`j0Q!dXPq(kE6"YI3-6+1ER8$ajaVqA!CBH)f$BNa -5*Uk"N!#lc-dQ3$!0%&VAB&5(B-VAm((SFa`kJp-PQVrY)#+DdC!![QbK`LEfVRe -Tp[BSJi41,@AFBM(Qbjf3!!!"pfT&&L+ch($C`d6Er#U8eJ&@C,06A0hRGq0eh'D -3!*0S'cDcpb#ZAT4pcbTE2ir'S&@AFplfIBM$pilaieQp1[$PF2#,k4@#UJ()X(9 -)EVdD+!"%c&K3+N1U2R6Y&**1T8U!a[BhZ%)La#U(MP)BpFV"m8fe&3j9hp%5(") -KHXi%J,#,T6)r0ErE2H8*D,-im)h*F$lme"dbpTGV+r3+(l+5PB!4cN!Xr!q#k9! -&N!#)lhiC+KC`EK`2,[T5"'aGI(`E`VIE%$JDY-V'"UGr``p4eHB`k5S5B43IIL6 -A99Gj&N&M!'40r(NNqXc20q,+3Re"2[0LIAe1MTe#T))JH8pJAC,KImrZ3PQ6Sk% -AKVi(m-29r*4R0cjf9PE*a$+J&+dQ(hcU$QqXS9#3!!FAPY6+d"aJN`iF1lfL2`c -B#Y+h`3SMbG[&NG#c#qcfP,fjpN8Sl$C@f!6XGc1Bc!2`mF2PQeT92RJmZZAR)P# -"i"hF&[0"HM(#,b#F)`b(i*M0f)(N`!-PNm18-ldGJp01*B%lZ3,#8BS2k+3K2BN -I5ZNDE-C@&f@LN!$1Y)T$1P$,![Y6ZBS$MI,aZa9Ybk'j8+QFQ+XB)%9VeS@F-15 -+BIcTj#DAYI[T0XP#IF'rHYm@DF*-2F3L-"a'hFfUB&ihEpf3!!r`KiG0[3dLIJ( --Qr)Z3F9BAKKpS[[8&bVkE+EerEqi"NGQQ"dhH0!J6+%#HN5c,Y%0S+!8*M08P0i -m6f!RGFqIf%cr)CjQKD%8H,*G1&!1U11EB)a6c"j@%4Y'49!8f6jFX@Fbq,kF*(M -ej&8f3q!RFa8lf,b4c@l4Z,3mJ"$XmEQ+!ka3TU)j&5#4qP`r"-##iZDfqUR$LGf -*()Mm96KA`UbpFB+HSMjZ)"UfT28NE`kK`P@PD5dD1#j5)Z1N2(bN5QbN3)k3!2S -iARH6P-TQ0%G[Hq[U(XC2Bef+AJl@RH5AQSf6[')!41(AT+`Bd9l,[)M4Lr(-#j9 -H6'9H41K&9HC&P&i8ji*D&NEG8p'Q@A0"@iaCVY9J'D@P8@45l%GL'V)GU$MJkM9 -K*,j'"(m2j&e3p+pC`HIkBADHEpf48K'SqcMamkBY4mEXS+C[fA[9Nb%QrlUU*b8 -+(8!-Ged%G*TFdr&a"PAX4HQVXC)Fq(BcQEM[FqaNFqLqYb"+"dQ8eT4+RH#!idf -%0q+9pekN$8Nj$&B-XB$dTQMEIiE+h#dDl)+TB2B"C[D8c+NfqeGMDaVE&SKYUm5 -fU66#HTEB0NpXZd4XUb1QZBKTPiKT'V&X9R0PQ,8Q`kD&$)2@C9K6b$!P$kEi&DD -dCTKLCTJ5&Naa8c9l`JRApQ`q1&0qm"CFrRUp3aBPNIrQFhrrr"F5XmprdT5MEph -AMQ3SFcX#Jli9iaDlb5k+Dri-Vk6FCGed1EMDSqL1HPb+UUb9-+"1i[Xk9b)"UN% -d-0%BF9A[[AAXKp6NL9Dd(9Y43"M!&ArcV'F6VV!$#&4Cd3PRElMUI!a1!AMj9$r -$dYMLA%ARYY[1fikHLQ'h)qC)$#F5q"Ka1k"bFVV+i5eTGK)Cb3Y9rjCZVZ4F6+j -L,05SQ4#(Hr`)ZmIl$c(*T!Lq#+SE-hH1Q"XKYNjSTA#K4m#"A0R*RB%cp)@*l&% -&P"ZhGM28NaPJ#'*%pLXJAY9T!`"Ub62LXA+*r8+(22T$r4"[mM0i68NArpEKa!# -b$h8)S*@61-i3ek0eRNd%"JR)m#F%%0V63$*5b&cP!JK8H1XrcH``2$SN#i+!Q!@ -iDE*-E"JJ&Vqd@l0V4[0(Y9MM!`5m4I4,U6'&3NJSI&*#8*VTC,MXjj*EZ#A8p$K -#Ma[e4P0LA!&b,3KM,4fU`XqFc0Bj3-Bd6L*`I(-AMQjDdr&0QfF6")"8ed1NA1+ -U6$pfVfFZT$ANEcjh4bHDmbB#Ni8PK*8ie!YiH-&GIL4kIbmlTmJQba2)4VIlBM2 -AAEG39-Rp3IRLG`8%J0!EAU!Jd!-!bLVKG[A#a$[Lm"qr#p2Nb5`'aP&SiVcm`%T -j9c!!$2ca#3mlldp2[!140`kcVX2,-r6b')BX4h[`iZ[dBJR*XmbK0KqE4TDR9cL -j1L6'0ciV(k#L2PhcQrLKaCGPCFQDMQFqj1-6ifcU[(R[(+l0bPCFUiT(r[1beIS -h$%!!#MqTEaf@49Q$Ri*%%j!!VrmXIk3qb`m`#"9-IafA2[a%j1%!M0khNYPJa[N -rmD@0cdDh3ffc#q#i,89Uqc*pV0$(Y5are2a-$%M5bjejrLKjQPkHDT-Ii'8A$DL -M!5cqadRY(q)PNEVG0-"(!rD)LG%H35,JJ9q3!,hdNDH26QA3HiSEdVMYM#Jq44q -(k3-"J&L%f&SLL*DamZNi'CXT`)*j'!L#c@j-FJC-l`))LXY-#L0jVPR*ZPcAE9C -!&U$da-kZkrL)VqPipJ&&'FRS05[1d+`9KjVi+-Y+kD22A3GTr#9LldQq$RqkF19 -jGN&%Nf%A*VI5C"Y-[aN((m,"lRaCV*a""SD3!!!5a(N4Nej$!"3#F-$JEJS3lD' -V$kcTf')`m)YD2%LLSikcMQ)9IKCDajBB#ND5X8[60FY6B,HKcS)$L[JmA*2ffC+ -+L"4C(q,L9PBFP@B[h#-q'UfqEj3E%8V'6MZklAU,SaI)F"$!pkil(MfUmJ6,P!j -S,SP%bd`8cY&A10K88j5I@NJdd`8rmDRid"#%!053!'MfcLUE@L'"%!HFXrHq83j -0*Lkl18[*cie5TT,(SfhY@pUa94kBj%9L$iD-+%-'a%Z`@ba-465B1%VHHeBFML9 -2'JmXSfSC#"FXFp9kC2di95fPUKYJkM4AcdFH'0q%Mf1e9If4CRUe*#Vk)cdJ,am -5BZ14AH1E@+%L8jSh3ZVd*eU03UT3jJ+M2U&QEj!!3%Z4))+jB[YK&N*TEPX&!GD -c!+qK)J!)IUdd@XhP5r@X0-F'IF[,b5F(1mSABj[,mm(RlR#6#L)J#A8@I+UIQhT -I4P,)IYF2*"5#HMkYS)1TZ&#[F'%f$Mf!H+Ub@4f1TBCXfD(H4QX[VRfMR08p055 -bXTmGfRef8550b#4fCd(SQTa!(++3!&SNV6#5D69550KGrYQlY)&)fN2D!)5amGF -rPqV6EePPMGBBM[cVYh"*T$ESDEGRDje(NK38@RPI46",)5!5p8bbSp!G#kqP`%9 -I25VH!!9JAS-#-pR*k@X[m+#mp18Rb[k!JJSbLKm!C2Lj*d-D"b&9VZ4bMZ'$[!b -8qqb6C@FI9F(1"LZX"1hfXa`()P9c(2cRi+Yl&N'SH$jJ'hVDH3,KSKN("qkA3c[ -qPK,ZidMZBC!!S2hji0Sl$%F8NQ2ETZ-Fb"cEYQM3S'%-qVLfK'CJD-[2+I(0X@h -(5UbE@pSjbIPcfV5#bYAbb9XlrKE+X(CiPLpEBKHP6Q8+[9TF!IPi#m8J1QQ+bXH -!D4rhbF3j,)Dp5eC`VFj8KZa'BJiZ'HC0a46`@EY8#(2Sh"pFQeDij3f(HaEZRL0 -N%M#j[-P+19C1NdeZa-FFI!%9ZiNr$QMb4pf*!8UZ%@6B5(c#iN)L)XJrd!*))&# -rb'lq)29J!'iNGVB4X%i@jLB,U$acXNKKpNjf!',5N!$C"5A3"hHd'PYdDql5VaD -#UlfV[d+LXmShA3MC#-FZFMEVd`X0%43i"&*jjGp,!D`2jdA96HAed2"91[,VE&j --TSPL(l+SNfaV1YD@8MKGqM3QG%'!YeTPA,RpjYKYZ"+a#KU#kJ&!2A1GXhVI4GS -qJ'j8qk*Q@I&CaeMe0#ZTiQb2,+,T2Mal8G0GV9+ZYaMU3-0p(@r&PpI-c*AQ8re -mVA+`8A[`8MF4EES6`4iff$NN*K+b@)U%a-#X*4+63rDhN!#8HqLeff*h*b3R&8G -QNMPbUNf0XkU&f+pKXCrZ1!4`dUmR,a8@1'#A$))rTi6J8E6R,MZ'E,j14EJ)mS1 -CBH-FAX[R#Q8#LS8V9*K&ec++br[Fj1)8*iDX4l0PrC'B)P$c4CdY(8NU*'+bFpe -Teb),fAb5XYI%KBL9)KCl80L8aH-GGY"Cdr(FC8@e[mC9jVlV5!L%&E)jc8h*BhE -eMYdk*N6j,l99I[Rp88fYr2lRHl(*!5A4KbM4c!c$M3acbX&Z2(50LL&M2G*BP"A -l@M454K4"NTqi@mN%mA+KI#+%aCaCrLNdPB%f4[53!!+lGhPGb'`0KdFB*UXAEVA -4VR*ZZ-V@I-jN-$m'YcJ4D2d43[X$!EcdLKG2i%8E"SA!U*&#'4hSd--Kj(*D3N, -$C%HZ3$N9AiF,'MYH9EhTUkP%)AcTYqi%CVhR&-DpTVRB9H`fULU5fcJK5k6QFHq -HhEhZ661*Brj&Q!-E`rfhf!311RcjbPlPSShHSVM)DjM,-NSCGfMf#F#c@P)*"pf -"ND"i0j`6f`1c[Mb-d#65)fk,96VS)LTH*LUYiVi5Uh9E3L+h+mE2a4bc%#D&8NQ -QYCF-[QL4q)$U(i,U(l+iF"SFlH[-qriB4YpZj8"d-VMeSTDL4Q3lrVbSZ"2C)8$ -'X29@C29eE+f9R!T8@`&Ed2$bMj!!+%e)I(CLFq2LMeL!8I95#[Z6i'S9JJ[%U`m -+D%)h@+9EJQjbCCK,[)JrlES6!%L3!$p#!CFaEKDLkX@2QSUEl()4MK3!,MS6V`2 -#2!3(eMf*EVM[VNmFB#IH4"XH2TVS"%Q88SJa'4f`iLl(f+fP"9cr+2imLcrVZ81 -%,h*d@iZM+rPSC2!3+CG(De#Gl(1*e`qU[T9!#'Ddmb"HBh&jBQ0!pGS2UYjiIG# -e844X!)RDr19Q1$&*Q&+RYjjraM$GQ`A3(8edXRX9%)V()5"i-GH%UF,&PUB#r!6 -`GQ$(+KI&eCL`lCi&p&N`,c`3$Z3(B%b(k$#rFYLMA[Z&0M3Ki00QEUj``9)q!Z` -VjT0k!E8N-lLbY['Hq'Mb*!QKEL+%!9EqAY1E$j**l"')QC0#5'N,C(iQLMdF%-8 -e)5,F'B'Mm@2p)"$%CQh@'TbI&`8!$rLHaBD'))EXT'DXM!Lb)))X)B)5!e!Sh*6 -U3q'I6YI&I2cJV89jlld@JQLrlQKP[5+(XZc1`NfGrD5XYe0eHE&49*Gb%SlPpBm -*Gd--D"HN%T,T)fY+U5jl,e!GQUNkb0"[)&3+5T8Bdf6S25U5de-UL3Lkc2!lQjG -T(TGfU6L3!+"KSSXp*'1l%(Q*[IPF%Z*0#B@fLQ+Z"1(N#CjE*Q$Z9@fHVViI$,f -XACS)3E6HMcqAYB!Z*N0V&*%rL+S!9ECBSMZUK*V1HX3QIPPFU'A%DSM*r[Zp9#9 -FJf"0cqrC)([qrR#L4lJMFN)TS[GA'(`Ca0I3a203BMfk%N-c'#38`KF[@h"["pQ -E`q0I+S8&VX'KcRcDL8#ZLZ)-e`iZ6!r"35JmYV!BA`CdJb)%`eYl%[Xj20$KU#h -+RpJDN!!q06$Mqbi)C6MTV12NLREN['&EV#2Rqj!!Jcd`[K#&U(E55j!!9SQG6h% -!GbI-`1#YF2K+[,k[Ki!"Cm%NXBe3iSPB35LG8c$aVX"j+"XTVje3QHcLX22a%), -1%5iDc`94p5[G$+YH)mG,C%QiAMlRH-,*F#q)[K`QKIpp20(PLl`k"#F0TmD%DM0 -F!Rk&60hJiSK`iZ[@QYa6Xe2VKNM9r#*0eBM3"bZEb+Y"ZU"*85GAX`c6Gd%-G-' -C[d6lJ,BIa2D6[$N8,ZSj%81PCbM#'AMHPqH#"0iiAVh)Vdl%L)cp5@+lCY$b!5a -Pe&$%`Xf-8*M3J@q)J6%)cJ+*"5H*"HHDMKm&&$IAlA"lKi!NB2ZkU"JF9T3&ECX -L(QkQ#3Gak#rj82N'#BLE3M``8b!FR0cXP`83NB@#ir22)`2V&3&Kk@BmirKUJN* -QIm3AY8&Fr%"ETX#&U0ClU$+h*2`1S0-1Z`l5m0981@3IKdDhYbaBElH6k$"*G"J -+i2FZ!$mI!Akr&XhRVcNBaS3kkZ#`TRH"QXJ,"2QpQJeTlVbU3(kmB4hdFbY%T4h -NAlQVQJ%q0&lhA4MJLrVBHEBakLch4P)%9-Yi,8$((FR`4KlH-drJ(`*FVi"FpPM -##G*1BL9!%2m4%H5A,l+S1[UBI&0ad6-8d$[1LK*GB,J*&J+Tc`B`L9$R*l1X+,0 -F8+$RVc*a*+G-E2c,6f-#pjrC8A!1%erpUdhmQf&PSZ+%5P"d'SL4[6#)S3S3`fj -[#@)!%&1+JP(R*-XN8,Si%F(Z1$YZVRj"4K*lS"T+X`(ZH+08FV-j'jUTeZE3k(h -qf%Sf1&1pV$ijk1T&!lB93G%l5S!d0[Em8Ndak"VNac[q9Rr8A,ei[aAFdXq1h)@ -bXHHRCHKPVZTMcbr+N!!Mcb)6i3!8S&KKN3P")80R@+"5jdaV)1+l&9'&VQ5d*)R -lEQdZm!Uk'FZb)+C,Kj8Vfj3,4j3,4h$K2QdV4&Bh-TA8Vf)#L3iKB4Pl3e4HhI& -mV32#p4#)3!F&893)2j!!$!dm+,6(X8l'0U*-EbLfJ0*P3D9)%5i9c4jPSkR!M&I -'G[%'X58UF+CXD3"EfX%1T@-,ddpLNB,LZ((@aK3K(P08,J4cT1A@SZYTDb(DQT- -+'i%%*ZEe3ENi`9Uckq9mlSJXKRDmhB*piCRUSYVGkaVFm6EB&pjb*`0AJ(dF@ZI -(1pl@(h@!IIR`FC9K$3*+`-$S9S*+`-#SFcjJ*Fp%3%$[`lBmY8-C'P1bY%p*hU6 -)a&39H4!Db!T2'U+Xa#JVPeXQFP8SYNdQ!KYpE0STe)+i0XHCE8$f$Ql%4LD`NH6 -B4QbN8V"#+&$4k3NQf!1hf!')*chaAil)E'"q5V1R'H1fk3JCcVDPL+[A5Sle6Zr -J(cJ)Y$%BGbE&34J'cE9cr#+6SA#kZE6)N!"`0)`L1qXb@hfHLr659T&NmQf4('+ -VqQ6HX#dZ!(V&aHi*l68i5h6CJJFG)"&8Q!dAm$f%)&Z5!fCD&AFJ9NJb)0IJ3-- -RpJFiPf%4`L+%44!,&BX)&N%X([i$Zj1KL!8@0aNX4&FZiUMZPSddFQ5h+i%U!`8 -*9*!!0@Sa2PI@I-Zl!Z%-Kka[KG%ee#fIHfm[[3+mCie`Ce'qC*j"2aJXYTfb*3i -kDVYfXJr8!RBS9Y#aFS-K)bZApGM-RcQ2`d(!E')B!q4MhXVYr`b6bfi2`Y5"4*m -1J-$9VP5%'[)"VC)G4q8qJL-CK0cQi@krKT63-EN,2p22RA$BpYcRY#)Bh'icRRC -#18'"EH!KGlN$2k-D,!JZlS9MD)dH0Ubi`TIjiL`#B4TSa#&3$C!!&GeKGDGr,Uk -#$30jer22b1XJl9ke44XBXKrfVcBD[hM39N#(I@L3!2KAja%@j3mi$Z+a&4)2V0k -*R19#b2Bk&p&!Pf#iE2qbCHM&,J3S-95j6K65@MNZ,B-6&&d#EN54Qee)a$!$H!e -"lMCUbfeNfF1%`Shqr#N3q#RIDa#6+GrA5@J1Z&q"bJHJEL8A(*pcZ"`Je!C-"RF -BPZPlRi11B24N'6UTZbcFJ!V"9HF@"fh9`ih`V[jmlL%-PJBDJ,KZIi#""Uriq!c -#RLXZ('Ma+`Jd"#r8p!)NST!!!$YT[V*Z6FHI6lPch%NA$R$TPr0f[HS-IQMMFFV -%#XJE3i#r*ihj6@Q&'[Yd!"Z91!QLL)PXGMG"b!#0BBNX!8kZD"C`XUq9P5dpQU2 -XeZ$KI['3!1'j5+C3!LGkE8GB$#fP(i!2qjNN-TPGdf'BR15@QA9SVC0ml*!!FVP -G+A$#"ap4$YBI)X44N98HIMK*'mSm4!'&#N0j1)'+"@CmkYhXd3cF@AA19QIMkRE -6cd%J$"ZL!(5BQB3U!rDL!m%4UAk@`p-4JKh6R&G&X$Jp1jPNQTlIP*B`Xr1E4,K -BGhSp2D&T+QFdQjR+@@[0I&*Q1!Y$6qD2+PY(GfXhphNfe3BA%+4Lq$L#SU0-'KT -D$3&!RSRF)cPTR`#F`meHX1%l6-M-8aGS,%$-5NZB(Nm@C+8*XR)@aP[+BLA!iT+ -&f`I+Sh8fpcrjmk[@5Craq8f[lSeC$8GA(d3iRF--8Rl-QV'DQ3"'H"G%ejYC#MT -(V$[C'3j%FfG$EmBTM0`R3[EX'22Q$R6m#&,80i%QbE$e*2rr1hB8HI-[P+iKhkb -fMNj+[D2)0krcjm3l@"C%jiJmmI&9C&ZG+"*4#!,c#SKHGmj+q36Nr%0YeNS*NF2 -9C,4rUT4$Hp,k$$YU"2a6F,J`)%j!bZ%9LYb)!ND6+2KL'q)&KmlkpSR3#lXhJ#d -[ch1J$-[@8S6*3))MV+pDZrGrNeNRXYXkM5"FL"021"YBhr%ShFrTaY!S(lSEI3p -r0Y[N3lRSEbFHLqlk)SaY%SbP!(J*X4GZ#IKST%kHfN(S"a#XIS#VqA1"q8eRXjd --m3!cRT850R`fkrHXkBLm`-@r6f2pr93%r[jrmQGA,H0#l)p@@l2%rPh%p+[%FR6 -9q6XrXAa!9-6IM5MXAV*fkjdkqJpCXrm'PNHh%mZ4F,qlRQ%jIqlA@Ikl9iRPR3$ -31ffjIr,lClqj#XH"b1NEJZ-i'q6X"0`0!)V1`UQJPCNeF)fk)6h!4E-9dj!!FLX -hLGdj9+Y"AILM%%['5(Kkp$I)%!c,2NX1#`ImXhHh4&mRSm%Re*L"cH5L(eJQ,q4 -@Z&p63)PHrf$L)IFX+f#i5(``QB,bkX2dRXQ(aBHYlKG1I)"T9lCbB$N[B9KmQ*X -0blH--0bCD!mU&dLhp%EVri@6dUFhLD+(J#a[c!XcK(+cTXJ-"`3,rY"p)62-##8 -"NThd*YdcT0KFPXP&4'lqfUXf2U!9eR5%E9#U"NJ#&`I6RZQhCS@Ui8*'h&(SP8i -BhXcqEh,BLJ[-Xp(T4bR#TNphfX&&bI`XZmiM3q+JAA63UcJS`P8@"b'VdGrJ)0G -C"c@M8Xp3Q$YXRC'Yk(CiPSr0A["BS5cC`#N-cbjb&,#!kRp!Jq!*ESB4#0,Y!bE -G-S+kMBN&[8XZ*UM#"d6AYli`N8VV44Hfr)1UD!GM4iL`BN"ba&B8VKhC'G[jRcQ -eqYT'2JEFa4Ckd5%"0I'CD,2-,B+d'PC)UjFcC&9R5l,UH&3cd*9aVpGN-Xp96HD -JM98[2DX[&h2F#5`48D-JSKS8)UUYPQa#GD[pD,-%39DY%%qM'H*Tq%,%%bG')a* -$,6#TK-V!hH+Z#Q'1erFcbDQmVUIApd6M2$%#8INLJ"#B8&U9Zf(dRM[mTAm&C0r -,+XdEd3`8dc6SCd8,0h)iV!IG&XJcGV$3"0`Q!"F(AI%d(Sm@9)@X'UJPUe")0%@ -G-%`4kE105,D+#j!!E"AZhHaB#-+Y`PY$K4SMF-U&J)UD3XMVT"NUS*[)-Gj'LJN -bX4',ZQDfLX+0$9eXPh[Y4MNL``mJ6'ai$9`R(1H+RNf+3N"5a&hNDS(%53cJFi% -VCS[#`3`ZJDL2E@9a&,*4plFTEadP*N6m[@Q4P&k0&EIK8",4S54LJ"*4j83-,,a -5eD!UT#'%60GS2XI0k,1)3hXQbG))40R*"'+k`ed*9iJN9h"dBAZakLLfq!BU+lD -P0,ffG9h2jMa6k(lBB#GPfjrr`,AZU#d"m"@LqD9I9KjGC4#mrrhJ5frS,hcM"&" -ajb`QGbqGGh#&c!S'jc,$'L"D!T0P,ehR9qKm22C5!UmqQjG#j01J*)ScJ(QQaB! -Ea"m,Sd4ccUZq(hlTMBjY@!4IfTafJCST8P9EN!!U%RJ,(I0'-(NCIriNMA!cZA- -)([*TG!+EZ)H$e2a4+$afpEN(XUILmqMFeL%RUaD2RcXmm4!'(F'I8TYXrbDka#8 -(%`SkA%@ikNML28!aQbHiQmGhi8Ur$S,M1N*DT3KmRI3ff-[3cFYZI`!313SXl*r -MB5"[(,X-"(K3E1iVjeqE6Zb(Jf[2iZ&MMBRY2SEZU80P,bSmGi'PZ62$c-b`-!q -$Z`)GK)k*-TGkEp"N+"YcVqd*3@,30TYSF!1libD'-,`*3Xe#YU"SBZ(j63ebp8% -[#'Mc"9h`LXjeD`8[([T%&m5S90Y*X)GCYE#ScA3ac!rl-`m4mRCr*c2*4JmL3ZR -Sda5'm3#22Z"El2bRZK@'dF1QY-Q4#db1YjJF5CmX"p)Q'kG2PSGD6$EF'804"Za -Y-F"XFIQlDCI(,h"jDB[*mI6,Z42iNrZYlr#MQ0)Bd9pD@Ea+kmL%e9dH)@[iLCB -eSS[G3Y,)4H%8i3QibJp@,`iIV&j5V96,MNbiSfQ3!*!!283d-pK33b4P$jS`15) -8(a0XS+kP-`iYNFVM#D8MC0%K+m(jL4pcPl64$CmAa!P))9-4#T9(heH!ZbPQ -9!+B)(dpJH$XAE+I150#jI(ecY#$8bFS"S@5SDpmcdKa(m8N3632q[jMr%q(k`K9 -&%E%3UL[$%+S35U(cll3J9IP!cS!i&0@hNNQXHdIJUQT`GqC%&ST(0EB#%Ba,I&( -+I-F[1SElDPI*pB*-[HHE9`M@d'ZeemN2E"j5[4k3!)8'%G(@1bfD8+GGH*@k*%A -M%851kCp"df6EVMPd9$q$`U!3EZa%baHTBQ[$Ah9V$D,"G'mE0`3)6[(i(EBFE89 -&NqBNZIdJqc%'aq&FpY,QLCa@j#B-%pYp0r3-bBXLQD5'Ua*l@E"L-(Gi$%&UYQc -J#Z1cQ5K%ddI1Xhej8fXPYC1QBUkJm6466JUTh,FM[F($KNJ%kB`E(Fp$Q!HiDhQ -aT@rX*1"#IT("hm`-2T3qQ)QBNNTbKXEaaUKSQ1Bph*hmIbaqCHRp+ZP3rSN$!'G -#DDdlbSj@dF1#a+#1`6N!QeS@X#,q`34US!bXqHP)YRM8#Vp6NPd9M1#TAVd6TcP -U#-%dM9CKbRbKhq311p"eaj396MGIShjm8rjUSrYR$eV'*FIa2QGe0JHRFp8fcee -eAh)iUpfj,+$LVUX2j86K*PV52cG#5j1EX,5-%hM05cZ@F9S1B@QRTBAP%#hG@&U -dc',TTQ84bb`Y#eJ@DGQ%CB'@P9JfdE)+bdTDjV#XSZ8#PMPDVQ+j3-XT,>kF& -bLTDc@(TS1BrP,#h(iE,Qc`DTS*(m6c8EA+KqD%'Dq"2((c[q$1'2C3A28Z!TBU5 -[lLZ#NHl[+!6rbf`@q#F3VZXLakdileHFbh55a%9-Z-VXR$bT'dL)35FM$e)#T,[ -q!"9!(8PrS+[pbqF@Mj2Dhi8rfeRYFc28@iI2,Yk3!#f+6ZGq1[)fEi)ISBS2kT2 -rp8[([R,kC0m5EkQ#L`YfSBV(S**h*F,N8Q"30lX@LSN-falHTE%LpMAJTB8!DY1 -&TYN5&ji'N4j#XliDS6'I1bH+!6amR%b8!C8Z[k[1rBXr6M*dALYNKfRBfq-%,&3 -iq)L+Pe'FlQdQ2LT'6e(RQK@$I&`&"j&Vr[e`aFZ*F6Vq3hk-*[md,QdAPqkD%q3 -NGki2KrH-NL!KJf#lVLb8C0Ym3VTRP3,B)mY*G*!!9$R2EU0p1K(UFC!!!TRDlkk -&!k#5`#`@@#"!Vd1`-r#UBM2MqH"89B&l5YQfiD,rVK#c%)S+i4l0LHk$I$(A,H8 -eLmU2eEj'8#4PcEV3F1)MDJR1[GZm56V35&0d1d@LZ!jc-P@F)q*,9ZaJ&i3@6U, -F2ETp6R3&R46GMb!%A,2P6MDqS6TrPd@QY9$N,XCU%)*K4fGdH80KX-2F3((emT! -!MX(&!af$5qc+h'VeDMjVPMX-DUlf95kV0ZY*"iF8E5Dk`TZb3RTL+4[YBm@"C0S -S93TGA45(jN'F2I5m9,q0Be!3PS[$T"L`SZC3UcA)#@'4bl5pKF2V8A*ijHTjl[a -5ACUBC@J4lVF`N[GB2Hi2#(!Z$d)#lKA9LqV"kQ0LJ)d'Y#6im3q-6#UGPkY&*FL -qQVR#*',"YH(Rk)[S-ENd9JlhiB!9fY*IGllVYTjKjD)NL+flFNQ(*m109!9'G&% -3pY',Iq(,SGELZPTM%!kQU+(jrR)fadepDKCkPYQPU3mK-j1EU&BC`(X`L8('LEX -r[LXMq)0`cSq4F(!NLALcj',&aQ@L`kJUEXja@1MH!-0!@IPMr*-!-,GUhaUDY)* -*UG-Q-5$-NbkR69V"T0C'mqN(S8K)&,VDN4JhCfiaJC%iFe4d4BN-"lp,$G*r%GN -0IM41+[qPAkGhb#5k2G8Cq4mY'GQQ-c+fQ8%&BQ5E`XK`1L0MjfM!@Bb-I8L-"%J -9@a+-M%ePVSKR'-QK-%0Rj$2pGHECM)c9%#-0(A48HeSb8[eYKT&Y#QJMJQ'G'@C -'RK(-0%pMCKaQ11TQ%jM+2mRrNkPP#5Sf%2*Y"A2-L4aqNX5SH!--`,[FNP(rFHi -r[m+-kKY+Be3FM-)r!8E6D[KD6%eHB#UCa6GfT%fYSDNU6E8V8q1R6B9+T+RYD92 -Y2&9ZTDQYbY5D#d`p4P-2TdeYTDQM0(9)Q@Srfb!a9@bh+@hU%+CHSSNPAhhLIk8 -MVr5P65c"a")!m$hL(br*'(0%0qB+hCMCK$k4EXba0M,QYTE',$Skb41`Ci8b(8J -+'(#$CJPc!2M6HXMakA)3Tjr!&VJj&"C$cZl%j'JP!i3I1dkJc$)6b4mV9CT-3b" -kBpiDJ%IFR9A%E)BX)cJHDMI(VbE3Q2lBU`5-$GNXd9ca-QY#e2a3k6SdYTRBPaH -*f1rMIkK,YJ-3$RKfcb9,ZA&ATM6ZGU-Sr+h&iHCE[JrKa+!H[1Ac,)GQHb(NJif -KYHdH4iXUdqLHr5b%2(I&b!i1RYh&QeTbiQj$qEI[X[-K%jedCHrLXaM8,`BeS&R -QZNkK5e9d`N+Efii'6F4VFPKUq!UD#![m3Qq8%236iBFI4e!,AG49XD,`,R2PXMa -`8BjR5(IpPCRq#Mp6JU6RbmNKap!,&6(F`*f@iH%RU1N-d*!!5C6K!B8*8[k@f#$ -PHi#mb+d2*[ab&Ni[P0J1$$CSDT`RIV++!bM+F5DZlrM(eqQaSErqa`rSY5BDkM6 -T1,eU6AZe$YI-YXMDE)YX66&Sc8P-hDIT3F@8q'HH!1P)11X(p[phELa3jk`ml6- -8U)YB5G%e'X-flNcR29cN(1V%AS0"h*8XB1-jr*X9(0M$TIZAdcYjik&eAh2HVQY -pUTdlhiRGC[qAFqCc,cR3lE)dq38++F0j%J&0iI4NT)2Tr-mVFI%A[$i0D)mj3JN -Tkdcq*e8Z2)$YTDle3J03-5ArXhYFL$#4B)0jp(i'!#3TH$%GaCbNAdhE)Na"fNq -lL$YM0849"Q5!%"XjV*JSF))#a34NV-#iba'ZiX+8EE@&Lp-lq!)!!#'"384$8J- -!@r8293YXU3$CE)[rlLlVZUc0RYV8(P,VjlTm,U9d'BENGK`QpfYYBGhfYXeZP8h -5BhBLlPC$CBmA1Bf(ZDbh,@a+JbfY8*8B!NcNH3X@SiK1NY0FL+GA1`iDK'SDJlN -SjAR,-!k$[D6DprIrIprZYp[ZSMecjR5Hpmcc"aTX*5e#!#4"%#4")-pDaHc3%'l -LMcHS)XA-+V&i4CK@ZD+H92m)V`qRh"HArXRc6%IHdL,&hCDhjlRVVU9&qV5V@J5 -RAK2L"b-YLjDHaU8-Ph1iQ(%jL8XeK,FEV@ejDep(8B*4FEYUPNkjrMBdp')e1JH -[$3dphIXY9&`Zr41b,!%LKCkrJdL@NdL@"C(AF@R'T4kAqEM-`f@1MdKERA!l#4h -VJe#K61Jc4UM%5DM%JY!+A1T`fBA,EP`DF@Rb)j6P*25l2JKpaJJY@V!mN!$5DaB -XYq@RK9MQ+L-5%+UqlPU`[#0[`BYBA[5[4m8iZT%JrIKI1r+@4$#CTCU-`0%J*N[ -m*jI-YCaX`f*[cB)A(h@*E[jMDC!!IZMi%204Xb9%$hqaC#jrX@!jUZLMF,@,+Yb --Ie(qSXVd&+mD$E55S$hIda@qZ'!jFprXUPN5SFrI9-1*S2DjC#lrC%F(%cq4)YG -S3@4@Ga[pN!#(3iaNY6##a#JrJLfTL-KX1RC+k#(PGQf"IN)%849Sp!3,rb%GmlV -d4j`9J6T%I@Kk`LQ1k*'bb#bUf1Qc1#jXdCRC31c8Z$X8##T"S"r53kKqb&&AK&) -A%F95$[23pQKJSN`BIme3&T!!Sa`44e-flJi'J[&31PBfT!I6ej!!SH1ZXU'Km(@ -!,"!FUAA6GMS#`90$k34$4q+i(+a5JN6Bi54XX3RCQ[-+A)l-"L"1eCkqMHKM86m -Q`),*$A`i#-(N@893"[K[)eY-PCCBV)9j`Z&$6*Y*f4fHi!Ha5iSJpb1c+-JC5NX -J%@[j@(Xp8ZX6M%0`"adk`86,)4Eb#HV"r!VD%2@''h+%-PVq3&8`LN[RLb!Z581 -6B&$8U#bR$$6+'HLkL500V9*FB-JKIS3FbM$a31[3N!"l#3)T!dH&q))1k-Rfcb4 -N+LSR+5%$b8Sh`M'Jd('SZXd9G9AbX*TH4Z(J#CDKBMSHBSZU!,aZ`19CA$ELXYc -e%Qj$Z$`RSpZ5)`j6eZJHij0!HF%4&11"$'iaYV&H!'dE@K+dP%L`4D[m&kQ$#j@ -69%a,PIX19(dNP*-)Q2@"I[-iQM48JF6(r`R(GTI@T-c"bUT!JE[da+Kjb"KY@B) -0AL+5kDP6ihV3(JeN$Z15cTa#4IqT',*f(6q1-p$pPq@%Zh`"C+c3AN4QdA4T9C5 -V#!MSj!82"!3Np!0G50k"8qBKUQaY@ckd+Q+0ZeVbkA2'1T&Xb6F204F#I"fLcS$ -(S6be(4q(YlD'd[%bJ6"rLVe)kGG&X$R,`j1k3qr!4,)jhi0%@ajdKc`)6IfTX!K -R6"cJM(i!"A''MM#Q*4J8Dk%33UX1Me-5G!CHh%9"4JRBAB93!jJNjSBGUS!k3jN -B$V*%bcCcDTJP@#'1X3)`(MCM9*!!kITh&jTHkKEj#)#e*AP!P@X"P@-!j3e(L!9 -4L!@45"X44+ZF366'JiJc5%q3!,+BXbKHh+%a"Pqe2a*BiKf40RG1)00Z%YQjrkd -VZGek)KM28!"f"HqSZP)92q#GeLIec0ekmiHh"4GhTNG4KCcb2Pl3C)pk0RVEpQf -jF`NDKiS6%q'8IYJlile9G%hPFLD#cFP"SJhZL(U#r@$8TdAjQlC5Hi@liYjDICd -k!lKMLKcJFHjBGHGe9#lp@ZMNf!iiTQ6S5&fK1bTk+q$B*!Uj$$VfkGCp5d@rZqU -%&bkJBMHmARD[HbUAXd+`rj5Y!3j9ZD[ZcE*dL!!NfLKUpP"BjTka'Uf+HqBicj! -!PV+f[,dfa4UCaFF6!"Z#p$&MM9Lp0Up9XG'#h-rZFiP[J$Q1KJYB"RGKHPCVNYX -4kD&&%CP-T!p#RqlKK$lGidmS)T1LX$C%6Y[N"'1Xqd&3h-##E[GFeV34-aJRp[S -V&1fhh#5mqe%YQBL*(JMPQ$-Sm-p'-#BjS+1iG#5I3)Ulq)14b1cqDCkSF((JNX$ -&L%XFPbjFVL&!18L4r[jT`#a(+I%jNUV0lN5iG`SGPhjFFR$*CKf46X'5KQ,P`ZC -aaR$'F*!!E[HLqLj2bVCSkBEV08Xhe(FT&qXCb"1I-8iLQ$1jUd9-6pl0%YNkmrB -SUVp#peMeNb+QQ*03D2"-G5`I'Ql,khN2(AAkF"ZYQ"U6TmENUEbpclMq"N$Q0#8 -`'IL*d%Yj'9[1P%@Q%8$*pJ'%4[fP638*#`#G*P#GNN0C6LSk+1jfSdPP@p"L,CV -Y#`"V(d`Jq)G0"`XMkH96+U)1QDMM54,95(S*JG(D%Z!J6iZ9&KE0pJ8ZSYKA!jD -3!,ebSSa2jGSdd#3KJd-*fha"AE!#bi8bdD-FG1FNRkr58m4Z#23h@[rek0!31`J -(rS[l2NJIJ('mE`5'Mq0,@-5mU"Y"J1DVaB&XkVEJ`k&e,9iYpJ6ekE5#jLd95(# -h[j2PTQ2c"LlCXP3BMG2Tf2YIkflr"%)U@UkD"EZT8r*X,clcD,RSjNd(G9#Sif' -+J@`k*+MEXq!jeZf4Y'i2G9d-X6l,S)kl,-1D8#kCC#Ll95MREJUPEY0Vfb&DE)P -SDA"!L-Em%5(T6XV+E2m*VB6j[0U+"i5VTMl$-qTAY8#@4+2+@'ZL1jb8A`bM5Y1 -G(UA#'iC`"TfG&c8!R3TdK%0MBN!#T$1cPZ*1B5d)HbMmC!,cq`Up*dP`f#6"-II -&qQpj@M@`)9'2iikbcBNbB+@Q[Tm&rl)CCj!!N@2DJKm88jHirP[B`2+f2!LVQER -&SCe!&KJSQT%#hS`BH6-bLUNcr,MIh`CL+Bh%Ve40$JNci-k"cJJ6[YK-`MUj1N- -6j6XJ2QSKAY$b-5NEm59+R"8+U4Dp2@1+K*,f*r&fR5RaqacqiMP4NqkAqB[rhab -6iT+&H,0*9iVmaFqi6#*2@SM[0LAHYFeIr&YPTX6M&Uld*db+9eQ)ccIT5Uqrq!1 -55A',c(bJbH5QC2Q,pjMl%%qdjHhHJ#C[#E(!hDZT)I)YZ6eT-V4fq41iIBl*$,h -K,kjhQh6HBY2eE5E&MIlL$eDEG+A4Ap`V6'lk#J[aAT2LVrZ,2hV0C,$8@iJAQa6 -IibpZ6*YdjE5&q*K*m9CrmIhj+2iDQfNSDR$9l&h-K5l8-H"4CSU*I$8MrG9m)1c -a!4-3"#"(`%3,P'i)4+A+!3BX1AJcGl'%-qLpmeMe*Q0krcP(R`DLIM9`4K8'K!L -9"+M-3$FUNlY'$4*2#1TUTfrJ9FaSlLD`a'K(1(Z#FAFkpQi*`'L`8&iC+B0TbDR -FSPPE9D4L4qPYa3a)mVN`Rc9Ec-A1HQUfD+01T15'PKUZDDh+3!0UqTeU(!$QV5T -JhJTJhSS+N!"f6Qq2hPD1l""kd"DP,KdM0mE!E`$h!,eLReDLb9mI81,6pRSkM$+ -CMThr,$k05AiBKrS`HJH!c+#ae&HCdFkaZ-Ua1"b,$a,(fR9q"SPM0e51hB"M0`D -*Be'9Be%i&KdNMT@T(#Z$Bf@$a,'M+XH1`V'MJm3aXmSa-a`c$a,(UP@19F1akN( -L@+[+X9BieMT)((1T((2"-GFJF5bYFL`0ap+$a,')bV%)()X-%XHU9)j9`E'U3H+ -B8H@B%BiC"iPMee51AB0Me`D*BpdUalVK@2FJFHbdbV(6F1cd)((XR-UaFh$Xh#" -a6&)j*X%aDC!!1(C5jGK*1(CbN!!iGPEPf&NiGRD3!$JfUA*X%Sj0$K,(CP51cF# -aQ8(L@*(+X5)i9M4)("Y416B#adEqIcMQ2F'UU6CiVBqH%+2Xaecf)bQ56je!BD$ -$[8!N-5!hEqq2(k@LTdXJrBLk`)993,$UM1XVXEc)D1A&Lhi+*e3)iS"i$UTp%lQ -I+8ND(*!!qh8mZEhU&LU+[PGNkmGadr8'Va[$Ad1'#Qr06V8DG3'0bSPPEARIr,U -p%qd%A4!-EPT`BP9EhPhrm53%SCCf9maId2a3mdFLH8Y#$i[N25Kmf,G,4`(Me1G -k6C0J!JjrJDDd8b#I+F,JaGd1(JK-B"NAk01"bEDmEamclF#G14U"1frdjF#G6JI -[b1l,J6Z-KKfiK',4aK@EhUK,mb!S23R"QEDmAfCY@M#1SYBl[ZX[k"I85IT49q@ -e8YKD&1VTp!U,8i%-Vl3eA"MB"p)4JdK("Sc8D"#TFD")GkibK(6RUJ%ME65)Y(( -!5,FB4,TP`%MR'83kEm")$3E6cJ%(dmibJdM,"ScdT%'N*`H-0+dKEIrbjY8QATi -fm6*Mq18p[5CHHJfrh,AGa-YZ`brrVGl%5a-,[eYLiQA%m-[l9jKiZGfAJ6!q!P- -UP)8S9SVKNX%PKD'bMRZXAB,8#QAeQr93'V!piUHqmN!LES9khCL5p#Q`2*!!m$l -X"8Zr2cD4C%SX6D`JBKeABT',)BDCQQi6J)d#U2(%,Xk5dMe6[A&!E5G'Vrma"`S -eXDrH4+&kCMp8D`30Sh1N[A%)K,RbXaP&VIM(8C-C&IDC*N8'-U#K8T63#L8Za+R -JB9+j,U$8&@PiGDYR)`SF(-C*Aj!!bN(VAi53!230AqF+Hf4f4S&EqV5rbSmLGP6 -FiX8!d1%$V"J&+Qj3A39ip44[9-*4VP+hSq,X0BLYJYLU1!kU"k%Q0-Q-XSaKNmH -`)*X0Bq+&1@PDTM)Jd+XTe%'9+K%3X5dAJ35$V1#m[d1N#JQ64"PXCLVhYliAc9K -iQa!d`(S9C63+NhBcmRZm(BA&qZ0U`9[13Pec(8)L!5FlFLYjSG-r4N%d`ibp0-S -[BGL&AP2'ZFc96#(e&qGi0J*e%bPBF9%A'RXXE')L%4c1Q2klkY8k'N6*L6#P,(i -!(p)))lh0Kj!!%rQU%X2$Y[N1'5BLfpL5CL,#KEp#L+I&q'8FC6Qf6,e9+qLiCe0 -Ybd@#!MbGE+-"C5jQ$'IB#k+&Y,R1cGQ@Md@9pp$JLeiYSF56lLSNP,pMD4f@&XX -*SiiPM(Z(LVf8B(CKDS[mDTImDJY20*LDid`f'!)q0-F[iG6j%Jk'Pka8@T&drXS -b[i3'VI$XK%2,b+50[-dPI#X9Pe2"EEfF`2L@rc[%j#d'JQ@d6&[#XQBLhSV%8[[ -DCjk0E-KjAdP[2Npk81Q-+3qal"R$SJSSf)jjaYa(!SQ,"iEQdC!!2#eC`C!!6`a -*2k1hIV9mU"H*20@hBQBR$EG'SQA!IBNkS4&JVjk+#qUfG!RA14`)#Cb5&2eJ!C! -!Eh40B$,H`CJ)*Id5*(dN64l5806*8*(N9fpk$hLYUS&'G5U6!Jk`LP&pdMaNLlT -c2"X98Pm8k&MC4ka'&j5+m`-Cqf8-j[cb(D(EcH-`24E63lDSdGi-KRV,D8U'AD( -99fh(ePcGIa"+)4PRm5k8b$`[NCTbPmC)9l'`1-M#CD9cHU9c'U(5j@1[+f9N@TL -XmS@*ERr3MF2C(h`B60d1"EF-1N'6e18ce!f5@68b#FQNakFk-j&NUM03DcGfQ-H -KR"RV$+hqa(CNc5Il$q!i$h'aVU6lQ(bF&CfDibZBi`IBFHUFdhA1D4bRdhHF1KQ -CGT`9UXEL)"S$(!@Ud5N-F)3b)8bZCE`(k8L'$N4UQ5hAZS95DUPmq8$#8[Q56F% -G9F2P9,jm)0'RmU92QAXA+F`48cE1C3UT3561B4KlXTR*&-FZ'V,$c(djKqii&HP -FF4H-@J9CF"S9'qYDXd4DRQ14d1T864`E9N@$(G$!*rAF"fm93Ib!qU$qH#"Qbff -RS0Q0"LZ)4P#h&hVkrFPSUV*2Qq&%bV$kT8ma8&2QeQfEIa4i)NkSS8aUcr,dacP -U4eqSMBAlIdeZbUl%E)@qSm"C"`h2L+0U!%G+`'"GEX5kZF3c&SHTSl!M6XI8AXB -He9mV4K*qK,rd@jMajNGqaTCZi!)mFa*N,SkCEL$RN6PMkIk,)fLNHFB-Zf`m-q` -9N3E+#UL,ldjl+I'$B4arj@[24S[-f-8c3kf!1c"#RS%5NJHVN!$K)CQ3!,dpSFK -a6ZL9V85)('2Xh#!KPLA*GXUf1S'06`kiElG`aF!@IMFb`)8P!e[iEpd$A&JrX)@ -l"NK`e`!ciKl[!"If$QcKcCN",M`p`)@V"lC`CrV*,U4"!$RG!2k6[SC4(TJJK08 -ic4['8cSDU9%pY#hU"!YGZN0Z&SHGRD9KCfI*B"G+8AHK3JDl8*0bTifDZKQp&G@ -GVDV1`KID3#P@19b+3C,VD2%IG@f3!'4AL!DQS$[`04"riDUjRiEe0()9,qUJ'+G -pB-P[dF'Recj&pBI4[2pfL@+&k#kRk#iZ'RG(DTRc$SDZQBZLL@fPJcecPJ'jcLE -fYdXd)Zb$$H#5PGrLJ9&034Q)GK60`J5U"ZMNb&[#A5E90NFIfI1'PMhad1TD@p@ -D@S#JShU`cdaULQ[CdF5bSj9PdKlRp"lR0$)TlXZN2A,(9-ZN*[p-FS)Z1FL'E$5 -DQA!'R4h@9%CfmiVhE9'@M64Bj!!bNJmB@DN'!"R3XPZHfYd(d,,E!QKa,QFN$[J -",9mi"k$*JeB4"LAY``"GdPA+T$S-&"i'drjK%,G#G*G6G"FAeDHKU*pNJ4$d"8, -FHX!r%0DE#J6&2a$@$c!3NR'%`5@%JC&YlJ',c@9Kl,Hj#VQThYceKMGA#bhGpU" -&F-R9*j2BRLCeD,%0fk-1+dbT#HlK5DH[N!!#'A5Jh"@"IYfQ!,!2NpNikYl*46P -rT%&p$X9f(i(q##c&TU!)D&pPLjdem6Rr03`#Q5(mV`f!(Ld!%M5!P!d&PJIA9[T -#3-lqV5e2qE+I!I-e5cI5!)bK"-bQBZJ*(`6K'hk"!4IApZjPYhhXeX4ZGl,E(Hc -f5hCVC,G[XpYGl2C0h1EXhFPZGHbfPYe@XpXDGPZ"@hVI3qb@C,I(f5h&EZ[CM5R -eNX-Be(5&+M04HFQ'H+X(&k)"0j-!KZC-S"[9Sm1`idiV1KV*IC@S$JL'8bhhkID -TI(X&kq*8H1jLhC3*EE!9'j61$cf($c[(Ca5IAIa69LiZp`F0e!1QKVjN!kCJVX4 -98lH5Ge`TiIKh-GHD@30D&ljBZB%CUPfK0D83l[82aV9QPX4ZGJS2DiQ0K"r*@mX -#jEq8X5S!KaD8Dme%LJ+'!![RJ[QD%cM'36Bmjd[Im"aI9jY%LfCpR6)1p$"6hDc -$KieL$9CVN@k(-B@86@0bC@LUh9il#S-cHM*aTfIB0kLQY8J$!["MQdm4RC+[2JQ -([(i%$A@NTaj64eTAE(*#M@kU%peRTrD'h+NpJdjYHG`QEh$8ek&&SD#*lL`0SUB -$(iBahZY5IDdfd3(9I6SS#ZPV23I*,66q90Q5E9p8RkpIV-qRiY"&FeKaD$l%mZq -p@4Bl4lIJ$NcfdN"B[DDqGbUr"6r$B4l'(A-L$,N&fLbJc5+dp6kd@IjS)bFaZ8a -'ZibKAECJ&AGdlTb!SVNI-B-BKUM0R8FrAqKe[MK(&G5X%`r$%Q6NJBZI%KdBL!K -(M-``6l35@lAFj4Z)',[Ta8-L'*Qe9CMGReDD(pdHVGRVA(iZ-X[-6Ra14L9Sf!! -KkaZ9,8P$'Q&@BdL0LN`C`&b%2i+MIJMLjN`PX[5l56+L'ML6!"0BRE3,MbR%[p- -3%c1LUJG[)ThMq*rLH8qQi+m`9C6#Mj3RL"r2fhkQMpXrG%FpZl@#'0@#&&[`2&[ -`2&Z3!2*I3'cZ`@Ta4RKaka%+%PajjA`aN6YI+*JU&aISF'#!U2C36JMCm-H"D[- -i#YrldH"3`3N@)QJ2BZ!rIC`*&`$!I')U(i24BpYPFaY)C!S#1+MJ!`d+'3caiX% -)#UV+br'!Jk"BjdPS#"L*lTPC-J%0jZIR!&"l8Ia`4NN#c46!ADA2j66ibp+PEj! -!5rTkFXM2N@c0%HIKK$b-@`if%#FQSEJRX)QMkXb9cA0XJ5&AbYEe-'8FKCQ'EXV -`QeQ'Ha,ITdG$2%m)Q$!HE)!-[U#&`CSNV([[MNf)fdAb3dc5DlDTRGL`d1%S6'" -F5#EdmI3cA%M3`b#5a'aNGfX9i@CQ5c`C!2k+4b%R2!iIfA5#,f96$YQ4K*db"*Y -T@b,)M%##*`2CZ-S*-Y1L$G@-P,PK8+#'M-6%DDYS+DSr4lAPC5)RNCE9'9c@1$D -2QfDJm18)if&89#(cY'eUMa`ZR@5Eji#4D4Ma)"-,E-Md5l3K*h9XL#)kbARR0U4 -&8N1Be[Q(,E4QI5bNEHH4#Cm)EHAhUj+*&M6FC,E"PfJejjJCeHLEP+h6cX`1SK& -R@6bHS9$f-0$PK9UHHCiTCdE(N!#`*HG2-VEI,aZK5INCm1!Q0Yjb(N)A55hS)V0 -D5!3X3kC"Bb![#,lYP!!fVaBpRKk0K-Y"'aNBp9XkSmlN4*8+c3AY"ea+BDY0)dU -b$qHf1B-NZmmJZD!+NQ`RqBr%8`L8X(JU$EB("Tp0bpaRif*'&5iDi[4NRkLl9+J -66Y393"a+MfV'Mc5Nc'!1K9!"@&c#pT&)P#GF&DkYRRR%9V5$p1"K!b"j6GX!6Xi -cURB!!k($)Zi0%jL'aV'4%P`JZdpQJ1b0(5dEIfIFR-!'VkY,"JV8)M"2%hX(Md[ -aM+Sb!mCqZS*b52@S@8FJiCINFA!ZjS#9hl2U)!(Cm6Ip'aPbp@!cEC5&i(YJSXB -b1J*XmcS4KQklflF&GYS#-Ql#AKq1ES[qiSeN`FMaNDSA+Y)&[KIPcb86YLTlK5& -@"L)1(iQclr%I,`L0[6%RVM#QPA%I`im'pZ1SQVP0B,YBdJ&EHfX6E!e$rJjfiQ2 -lqE1acJUBGN')k'mE01kbVqRmPI2kff$m%-[Pc3%FmF#d0$kVmAN@i0NC&2ldS"$ -a$*UD(QC!k`3"qKEZH6IYAY0jJ)eR8,M8Sb9jQJD!(d4Sa9RaBS)ClLPMM`G#B(B -Lj"#F0cB4R!m"`E8R&CVGkXNAR1b-![DdLC!!25f`'AiKkar%GKE%%m(r-EBirX& -MB)Zdi#D%FP`1jH@8f@#*Ca"+TCLi5f16B"Npq9C8b5R[P[L#`qHkaqJq(p$$Em- -afHM,5'0F'`UEe#GY-,$3DBA3"5q&dr4M#LJ+jfcrlI3%QbV5hk"AB181'-'@AI( -S2KEFK3hhCm))l43,ce+%CcF"2[Kd8hK1U-*6RrjU+`Uj[Dl$IX`mj8-N"f'(C4# -U-TF$DX&Y4qa4ld1UX"cM$,1I-@Jpa9KVN9q3!*(4*VF'dXB&!lPDT[*4@Xm!m*E -,$&!$B"C`D'"DaiV),!b%9&'f`93)C5BaHQB-$Nbk@`f3!)!S3hl36%E2$)*LlfN -"KmcPc@fYLXdje#c9bC!!JMlQLN",F5%XRP%63$E,!$XCfbU6Ul900T`b%d$QP21 -`e4SH!Y,2L3Y(ak2rK!,9jBmiaTRTUh'B[XUi,iRRmI#Q4kp,Qd[)-%cL%NY@'Id -5(ZEdZAiV!RZY111p*#jmBH8[qG&JkT0qTPk!+93GaS5d$TZYNAIBf!-J6SJF!$c -k,ijUS!iCh3*4E#G!,jNS%PI+f8P4,)jBVMULFi'i`c`1-#+l6-J"!&EdMYMhNG! -4A,%Gd8#ePLf(4D")frL!61D`m,M3a2C$KD(mE%Vq[(!fbEF2!!@QmM'&J$Vc95@ -&1**eH6kk(j5`e9QDc[#I-LZ5d'Rq"6SG%p39J-Na0(d`)&A)f%iLN!$Gae%BJ,M -rK1MhC4NH9[&j1+5%S63'8"&'jA"MB6$$+VjZe`cqXBiAa2!i-9Ca&1C,f)8a@ZU -@*9JedqFN#,DGM(e)MkHK"9p9fU,Tc"Zk*cEe18*Y3fkaR'Q%2$%4&MN!CF2LEE2 -q9[5fCmbKH,+eUMMUVJSN2kK+E,9AH6BLmC6V)CI8)RP$jh,Z@I!I86ed[cAkiE& -SI0hU@SKQke[prf(CLV,ELdYhdHX-QpKS$Rf0"m3&-N"DkYR)(X!$4pV)J%c6G4F -U!kJcpJ5+`A1k*Yh)!PBNK3hlBi2ja6pI2MAmjQA&[@qVqGNr&pi()pd!bNETm#r -9'PhD5hHp309IS08FUlcX!5XF'MlCl5imH80aIqIi(iql#e%pB(q3!&9jT$1Ak%0 -h,f82[m-2[4$Qm0I$d&8f'GbQ6SG-!*h&b@m@m3lEHP*931-!0Iq)&8Sh`IYZa6# -!**+1!j@C`8HRN@e8S,pHiGRQq0k2N!#ml-Tm*T6N+Jli$1)6J`J89MR3I`hLr@A -$aBA'k8qh6"6J1+8`50KM(UmXK8Nl!QQC8CQAdNd9jP"PBE4+3A*4VZ0K)V(+3ZT -)R-cF9q8D6RZ0dqp[95rB@i8&Pk-9aZMqLZjKQ2aKbS#1EUhc5D&(AD1DM$QcR4k -l0*3qbkZPU2+$UL#TfQAc0L1UAFcMVeDb#KBfhG+F&%l4Fr*,aqYi5!-DRR%'(SY -d$TrJ&68GVDMQ#NeGTJk`eL%-Kdi"FI1LcA9JU1-8m%!DiZ6GQ%B93#F(*'$+'"m -SrT0'8!&ZML&4eD8,+(LHY5*iPP%PeHDk8q01"1Id%"'L4e-4LfG9@9C86)!3Uj+ -T@IXLEdl#"9UA!5"4&'T3PhQ(P`ZDf@1UqNE#PV*TSI1P!+(m&M,$R&3T+&qd4Si -5AEX'VV8XA3``DE9$$`C5-$Kj$CGiZSX-8S,er&5XBiaSA6VK,MhTF%lTBTfb$QB -TajhQA,Xj%k$#'c@6'+RhCa,Y"#Tp!U3L4UaMj#-4a!1%RL2RmEGGqULN4$U*bc[ -5Ikrlj$HrD8fm*pdLYEce%qR!(#R[N!"0qR&Milj22jEq6f1MG1lmZpEcKE8Y(kj -erZeFUrUlHHhUPSqPYNmHqHFPfTpdPr5G(hemr-GMEEVdcU%hT-$pap['m`l95cm -kp0DKGhmXE5iY,0hqp#*TT,"d'I[rmM,ehm,P1elj@(VPd1m2IA$PkV)edX,jdV[ -&KaCGZ5SGr,2d`rR5qDrCVpDYdLI(TAFDIR-eUhle$aH[UChhmZ,5imG+Abje(@c -VSHGGG46qX+0DqS-dq9MrY38PU@APck9ET3dleajD['+9p1fV8X26E4IS!$qA!Jr -rbmqP[bb8MKhkrFqPh)95GE(8)Gfd82*m,6hFpT!!p26$9pXZcQQlMX")5PNPAdS -,hpZ`3ITmAZQmV"r1HAraLS8V2PkbH2Zq$aEm,PqDbC@QYeepGGr,#kA[II$"6ej -r3rV`VCqmGRA1STp+eXCpqk5&4dU[I2$HqGVD`[0(2V(QrZ`6DprrhZel[Z()NAH -Pllcbf,F!reUbN!-Nr1(HmVqPAlrFpX613hrkXR$*cMHN"ZP8@p(h&V9m18pD++@ -PIhK0+PiQr8hkD28bUFcD8*KlT,!LkdMTmIa2VY4,IpMmdrHN`jZ[p%TrH$GADQf -8T*F[pdTc$PQIPMa5mk(0dVf,RelkHqR2KfEHNQllTI6hV!qNYJETRqGGNHlZPIk -P@ITrGDqmMp0A[Gr3F1cbFFQ@$`#3!aJ!!$5S!!"I5!#3!`J!N!-J!!!r2!!(UI! -!N!-+@-!!5S!!!%U!!*!$'Qi!N!-"GJ"1F8U$CL*"l3!J)$`r2!!!)MbTm!!"5N& -Q"%T!C`T)3%K"))!K33!%3UG"q[r1d2`"!#m),c`!!"PZ,`0K!!+X9)pR3%)i#Pj -#Tbmm4%&836mm"0@S(h!"%F!+ANUICaK1F6!mUA#R4N2k!#SLL%(k!#!`2+P`TNG -+JfF%F!&1G8lY!#*1F8U$CJ+Tp(!!6R9J"J#3"3&1F4mkrrC+(fB551IJi%(krqT -3d%kk"Dj-h`F(,cVrhNjeB(*"6%&%4%008!!$!*!d8(*"E8MRB2"d8*r#,dJ!)#" -2)P3aD3!8!"JK3!!N-A`!!3!XdT%K33!ZS!,I`NcI$`C1G8Si#PjR$#!U!!KR$#" -!)""R"Lmkri41G8MR(`C"q[qHF!`L+J!%`VJ$'Q'NCJ!"2NKkrij1ZJGZ@%q`H[p -DCJ!"$U%D,JJ)+J"!!!4R"L"i!UDJ'b`U!!3U+J!)'#S!"*I8PG3J1[p@S4ir1!) -JCJ!!l&42,%JJ1[p%)JE#Z!-D@%&K!2p-)$Vr2-#i!aT"q[mi))"+K@B%S5*J"#" -&S#GQ!!#d+NJJ$P#!3IVr###!)$Vr#P'!3IVr!##!3QG)HJ#m,a9)H[m#,cVqiLm -krZ)[1[l+,cVqbLmkrXTK!!e1-"pR)$m!5S9R##"0S#UJ+f!%)%fJ)b"1S"mJ4k! -E-Gm#)'"J)%kJ(b"(S"Yb!")%j`RM'H34!!%!)!)"!1!J6D"T!J!!(i!")%fJDYA -8ep4"q[jf5T!!C`K`!D#BF!1JQ#"0*8J!#(!!60pJq%je60pJq'!!rVir!#"1S"m -J4k!E-Gm#)0A8ep3`1!)J-F!+B*()*8J!#%cIB2K1G8j@!!")j`!i+'i!$%IkrLT -&q[iU)"5`NQd%)")SJ%U!Ea)J8b*Z!!LL,L!8dC14NR!!B!3`22rC60mF!%jH6R9 -19[r)51FH1#BZ!!JS,J!-+'i!%%(krESY52r83Llrb+%D,8Mrc&92U"``(cS!$%8 -!!'pF5'lrl$!&8d8r!+J298m[,[rXU!d`(c`!$%B!!'rF3LHTQeP2,blrl$!'8dB -r!+J1)"mY32r`FJ%I!DQE)'lrm%U3!'F398m[#+QQ-"p)`()%`)&Ra#mZrr#TSf# -m%#i!&'F+@8mZZ!+Q)&qJ'cmmS2a1ZJ5'9%mY32r35S"R!!'H,`"1ZJ2@@%p+!'F -+F!%G3!!@6[S#'%KZrq4)E[rJ5'lrf%kk"@T2l`!-)#lri+%H,8Mrh#!)C`!"C#! -Zrq5K(Le)rqJJ#'F!!93[,[rN,`K1ZJ@i8%mJ!fB!!+CC6bmm3dp%48*RU"mJ(be -!rr"+J'F!!)iJ3#*3FKM6`5m*6VS%Y&K2FJ1`3@Cf)!dJ3(!SdF!Y52rd)Qlrm#4 -4F"M9`#e+rrJ[#Nkk",TB6be!rr`JE[r`S#P35LCZrp3R5J!S@8m[,[r`6VS9c#! -IFZM3J9'!*d!!,&925(Vq-LmZrr4)E[rm,``["#mZrp`[,[rJ,blrk%kk#XC86bm -Zrr#TSb4Zrp3PE[r3!!`PE[rF!"!PE[rJ!"3PE[rS!"Jr2+'B6VS$9P42*N!r2+L -I6VS$5P42)J!J#l#"CJ4`!'!#F!%J!#9!!"`P4!!J*8`!*%Kkqm`r2+$m2cbJr%k -k![K86am!6VS98MmmSCK1ZJ--9%p+J'F%F!'JQ#"m!!!"@M!35-$JJ()'X)&Q$%( -k!+iLI!!!!c`LL"em!!(rb#"ZrmbJ'e92U"``(cS!$%8!!'pd5'lrl$!&8d8r!+J -298m[,[rXU!d`(c`!$%B!!'rF3LHTQeP2,blrl$!'8dBr!+J1)"mY32r`FJ%I!DQ -E98m[,[r`UDB`(dM!FJ6!J@F),blrm+QLB-)NE[r`5T*R%&92,`UTTM!I5-"b"-# -"CkS[#UQMB+33,[r)(8!!&NcI((K1AL"I6qm!$Nl36PErr%MR!$"#,[rm2cbJr%k -k!La86b4!5S"RA#m!6VS"J&K25J"R8#!+*N!J3#mS!!`r2+$m2cbJr%kk!Gj86am -!6VS81#",)'J!%+!I)%XJD!!BS"mJI!!!!9S`%%M!i)"b"V#"CJT`!#"m!!!$2## -!(A`!!Irm%#lrr%cI$!"1ANje6PErk%MR(cKC6kPe)"mU!%KZrqLSG#!0)%!J%(+ -'d)%Y32rm)%"F5%2Zrq`Lf#,B@8m[2%4"9%%r2!69UD!J(bK!)%!N8$)U!!L5DJ! -%2!%d+J!'P'S!!Mi#0LlrmNM$1#lrlNM%PS3i!8M%PS4U!P+$iS-p3rrf0Llrm%M -$1#lrl%M%PS3i!NM%PS4U!P+$iS-p3rrd0LlrpYC"282rqM)Zrr653Me"rrKC6d+ -R5'lrp%Kk!'Cb!4m"FJ%r!A,r,`&#*d+RU4-J(bC!,`#SF`D&!*!$H#m-)%Y`%0( -!,`LSpPP2UA8J(l#&C!*Jp&92UA33(fB#B2C`rcm!3QFJ(k!b,`ZT&#m-UD-[,[r -SU(0-haci6Pj1G3!#!!"19J!!51F!-#4Z!!JJ#LC!)%!L+!!#$)&"6%&%CKBL+!! -'$)&%3de3CJS`+!!+FJ1`3@F%F!"J!R!"60m-!%jH6R8[#PP22cbSER!"(`"1ZK* -i)&mN5&P22cbUER!"(`"1ZK*Q)PmJ5V(*CJB`2!)!B!3`2!3!*&p1G8j@!!![!cB -Z!!J`!dM!!S!!!!J!5S"["(!"B!*`!#BI6Pj1G8j@rra)ja`!0Li!#$m$6VVrc&4 -2(8$rr()"X!&Q%!*$"rp1Z[q!X%0Z"(!!B#KC6cmmU*p`!4m!6VS4m#!I+J"C6cm -$(blrr%kk%H!J(bJ!X)9Q!R!!60m!1%jH6R919J!!51FB-$JZ!!JNEJ!+)%SJ%#C -!)%!b%!a"384Q+$)S!!)-3805CKif"(,rYN&R'L!S!!4b'1+S!S!!N!2r-J0)`E# -"C`4`!'!#F!%G3!!160m-'%jH)&pF6dl36PB!!&925'i!#($r2`"1Z[q5%"pR%L" -Z!!JJ+!!%FKMLU!*!!2pJ!R$r6Pj1G8j@!!"96dKZ!!K`rcm!6VVrC"!ICa!JEJ! -))#J!"!+!!2q3!f!#F2p1ANje6PB!!%MR'$JQEJ!)+'i!$#",-,`$!A!!*%`NJ#B -m!!!"*0H5"T)!!!*)"T)!N!-J+$`!N!1!fC,CNLJm!!!%N!$CNYH5fC)'NJ#3!h` -'NJ!!J!"`!#4Z!"!NJ!D5!*!$*!D5!*!$)!D5!*!$5!D5!*!$2N*!60mF'%jH6R9 -19[rN51FI1#CZ!!JU,J!-)!XS3#e!rqK`*0R!,8crl(!JfF!Y62r`F%MC`#e-rr4 -`2YR!)!b3!)Z`K@-'F'91qJ#b3N!q!%*!28$rj$B(F#5f3'4)F!5f3'3%F!"J$(! -!-!0CJ'S#9S$NJ(J!1!-Y42rif+lrk#4%&)!J,[rid)$3V[r`)%!`V[rNF!%8%R) -!%J,MB0&Zrq454f#`3N!q!(!"2!!f"h!IYN"N4(!"YN"N"(!!B!a`!$!$8i"U!P+ -!iS"i!$J$,86rr0LZrq`N4"5!)#lrr0#!d+lrp#"!-)C`!435FJ!5!Z0Jh%"54f# -d3N"-haci6Pj1G8j@rr")jami*'i!##CZ!!`k,J!3+'i!%N*!2!!b"A!!-!(3J$3 -'FJ!b!V#"Ea4#3$3'FJ!b!Y+"dS`J36#!8NCJfN*!2!"`!Me!rr)f"VC&C!!!Z%* -!2J"#3$e!rr"`!$!$jB$3LL"!)"!Y32rd-JC`!$!"d)XJ3"J3GJ!@",C(B`!!JM! -ZrrCb!F""d@lrm(!!-!06J$3(FJ!b!V#"Ecii,[r`GJ!f"#e$rrc@JpD-)%0+8'B -5)#lrr0#!d)`J3$#Zrr*8E[rb-Llrm(!!-!(3J0#-)%!`%$e!rr"J&M!&d%$34M3 -Zrr"b!$)#dS(5M#""-)"54b!Zrr6LL#e!rr4J!2pX8NCJ!2p%60mFq%jH6R919[r -m51FF-#4Z!!Jf,J!-*Qi!$M)$F!!`!HD!1!!`!h)(`%%k!(!!,8$rr$3%FJ!b!Y+ -+)%%5%(!!%!%d"A)!-J,LS()"`)(4V[rm)Llrr11*dSXJ36)3F!!`!5e!rra546! -&FJL`3@B'3N!k!&*%-Li!%R!!-!(3J,#ZrraM!Q#U%#lrra)Z!"25!C!!!8cI$$K -1ANje6PErr%MR(b!NEJ!)1#i!$$SZ!!ib"(!!-!(QJ$`!-J4d"m*#2J&f!$B!eSS -J3a!3G!!8!#e#rra`!$!"0!9b!$)#d)(QJ()#X)&R$()"X)&R)%U!Cc4J-M3'FJ! -b!P5"dSSJ34)3F!!3!A)3ikL"V[rm0!Cb!$)#8S(5LL""%K"`!"!"iBL"V[rm)#l -rr$3(FJ!b!Z+S,8$rr($rFL!f"A3!0!15JZ+S`'lrrNcI"2K1ANje6PErf%MR(cJ -QEJ!)+'i!$L!m!!!"*0'Z!")J2!!!!NM4VJ!5)#i!%Le!rqab)01Z!")L,J!5,8( -rm#3m!*!$J0@Z!")N,J!5,8,rp#4,'"*f!"B%,82rq1D$HJI'49*$282rh#BZrrM -LJhS$aN983ce$rqCf!6SZrqEVBce$rqKq3-J(I!!F"$e'rq*i!HYN8d3p42rJ+Ll -rq(i"bSGR#(S!1J46K@!#H[mp4IrHH!Jp42rN5NCR4LmZ!")[!$m$8NS[#NkkrcT -2l`!1jd$4E[rN,bi!%LmZrr!r!bmZrqa1ZJX)6qm!$LmZrr3r!bmZrq`[,[r`6VV -mV%r[!!j#3$e!rpJ`,[rBX'i!$'3!!6S`,[rLCcSN3$mZrqJ[,[rd2blrj#m,6VV -pMNr[!!`5!#!+F!!3!6e!rpTd!$3!e+lrl#"#%""b!")!dflrj'!F2blrjMmZrq3 -[#dkkrI"36ce!rpS`,[rQd@lrj$!ZrpU`E[rHCKBb,[rB8Qlrf(!!-!(3M#"!3K" -J!2pk-#lrfV"Zrq"Q!!#8-#lriQFk*%!r,[rS,blrp$mZrq3[#dkkr3C2l`!-%J! -J#R!!%!%p32rDG!!d!05Zrq`J3K!3FJ!5!00Zrq4J($mZrqBr,[rN,`Y1Z[eS8%m -p32rD-#lrjY&Zrq4@E[rD-#lrfP0ZrpT+3'F!r`!i,[rBGJ!f"#e$rra6JpD-)%- -3%#)Zrrc5M#""%)"5E[rBB-i3,[rGd#lrfc3ZrpK5E[rBFJ!b!Y+-)%%3J'!!rVi -b,[rNF!!`!9k!jS"-haci6Pj1G8j@ria)jami*Qi!##SZ!!`SEJ!3,#i!&#e,rmK -`*0I!,8[ri(!Jem!Y5rr-F%MA`#e,rq3Y62q8*M`!!!%NeklrP#!m!!!#50'Zrj4 -`)0'Zrj3S2!#3!i$CV[q8fDlrP#eZrj6rY#Jm!!!%N!$CV[q8,@lrP2qieklrP#e -Zrj6r[0QZrj3YE[q8rp4`I0'Zrj3YE[q8rk3J2!!!J!$4V[q8)#lrP*!!M,#&B`T -`C6e!!#K1qJCkF!!Z!%*!28$rM#4Zrk69r!!!J!!Y5[qS,@lrT2q3!#em!!#!!2r -S5'lrk#mZrk3JEJ!N6T!!8%mJ,[rSCJT`Cce!!#K1qJBd*'lrN!"55VAZrkKMD#" -Zrj!!8NL4l[qS,8Mrp#"Zrj!!NHlrT#e)rr!JE[qSNHlrN!!Y52rX)!KR$L"Zrj! -!)QlrT#!ZrqbL,L4Zrk69l[rX,8VrN!")E[r`,blrT#"Z!#41N!"36b!Zrr#`V[r -dC!T`Cce!!#K1qJA!)'lrN!"5V[q3!"!3(8$rS()!%J$5390"28(rd$!Zrp$33$e -!rp)JEJ!F)"$3VJ!J,8$rX#4!,``[,[qi2c`"*#mZrj!!6VVlmNr[!!ib!#!+F!! -`!G'Zrj!!,``[,[qd2c`"*#mZrlK1ZJHk6qm!$LmZrl`r2!%N,blrZ#mZrl41Z[P -F6qm!$L4!,``[,[qi2blrd#mZrj!!6VVlS%r[!!ib!#!+F!!`!G'Zrj!!,``[,[q -d2blrd#mZrlK1ZJGS6qm!$LmZrp3r,[r3,blrZ#mZrl41Z[N+6qm!$R!!,J"#3$e -!ri`YEJ!Jrk`JE[qXXHlrX'3!"+K#3$e!rjJ-EJ*)rjKN!!$#-#lrM'B!!)`NE[q -3!&*+YHlrU'0S)'lrN!"55*(ZrkJY52rd)'lrN!#4l[qN,8Mrm#"ZrkL4l[q3!#e -)rq`J#'F1)'lrN!!LE[qN)#lrl+)Z*'lrT0AZrq`Y5[q3!%KZrr![,[qN)'i!*%k -3!&"2)#lrm,#Zrr4N#R"R28!!+%lk"%)JE[q3!&+Zrj!!%K"`!"!",J"`#$e!ri` -`"h)"`%(4E[qB-LlrQ(!!-!(3J0#Zrl`J3$!328$rQ#!(iSJZ!&0ZriaJ!2mi"'i -#52qB$'i"!2qBC"!JE[qX8UlrV"#ZrjPJ!2m)"'i"!2qB1#lrQ(B!0J3Y3rrieS2 -@V[r-)%-`%$e!rjSL,[ridUlrb#""%K"`!"!"28$rR%T!C`!!`JaZ!"MrM')!!*J -NE[q3!&*+YHlrU'0S)'lrN!"55*(ZrkJY52rd)'lrN!#4l[qN,8Mrm#"ZrkL4l[q -3!#e)rq`J#'F1)'lrN!!LE[qN)#lrl+)Z*'lrT0AZrq`Y5[q3!%KZrr![,[qN)'i -!*%k3!&"2)#lrm,#Zrr4N#R"R28!!+%lk!bJJE[q3!&+Zrj!!%K"`!"!"0#lrM() -!-J,MU)k!8'lrM'!!rf*`rh)J1#lrR(B!0J55Jq+S`%I4E[qD)!IQU#i!Q@lrM%* -!28$rQ$!ZrjL`E[r5C!!!`M!ZriaQ!!#-*'lrN!"55VAZrkKMD#"Zrj!!8NL4l[q -S,8Mrp#"Zrj!!NHlrT#e)rr!JE[qSNHlrN!!Y52rX)!KR$L"Zrj!!)QlrT#!Zrqb -L,L4Zrk69l[rX,8VrN!")E[r`,blrT#"Z!#41N!"36b!Zrr#`V[rdC!T`Cce!!#K -1qJ*B)'lrN!"5V[q3!")3F!!3!5i!F!Jp32q--!Gb!F""d@lrQ$)ZrjK`!$!"d)$ -3V[r8)%!`%$e!rjJJ"q+),J"6E[q-B!$r0M!Zrp+4E[qB1#lrQ(B!0J3Y3rrmeS2 -@V[rN)%-`%$e!rjiL,[rmdUlri#""%K"`!"!"28$rR%T!C`!!`JaZ!"MrM')!!*J -NE[q3!&*+YHlrU'0S)'lrN!"55*(ZrkJY52rd)'lrN!#4l[qN,8Mrm#"ZrkL4l[q -3!#e)rq`J#'F1)'lrN!!LE[qN)#lrl+)Z*'lrT0AZrq`Y5[q3!%KZrr![,[qN)'i -!*%k3!&"2)#lrm,#Zrr4N#R"R28!!+%lk!9SJE[q3!&+Zrj!!%K"`!"!"0#lrM() -!-J,MU)k!8'lrM'!!rf*`rh)J1#lrR(B!0J55Jq+S`%I4E[qH)!IQU#i!Q@lrM#" -Zrk`b,[qHF!!`!C(!,8MrP,(Z!#"PB#"Zrj45V[q8%"!JE[qX8UlrV"#!)'lrP&+ -Zrj33%#"Zrka5V[qX%)!JE[q88UlrP"!3)'lrV&+Zrk`3J$!ZrjT6E[qD5N"R!2[ -H)'lrP&+Zrj33%#"Zrka5V[qX%)"Jh&CZrjSJEJ!BdFBb,[qHF!!`!5*Zrkb6lJ! -JN!#*NF!Y52q8-#lrQQFQ)'i!'0('XHlrP'-D)'lrP&+Zrj33%#"Zrka5V[qX%)" -6E[qDB03YEJ!Jrj3`,[qD8flrQNT!C`$lCL"Zrj45V[q8%"!JE[qX8UlrV"#!B0` -JE[qXXHlrX'F)F'Fp3!!SB"3JE[qXNHi!)#*Z!"`LL%*!28!!+%cI(2K1AL"I6qm -!)%l3!(!m!$iJ!!"i)$i`)#BQ)(JJ2$dc-J!!1N0[EA"bCA0cD@pZ1N4PBfpYF(* -PFh0TEfi`-c!a,Q-!!$`!2L!!!(JJ2M!J*LBJH#!m26-b!!!k3fpYF(*PFh0TEfi -k4'9MEfe`FQ9cFfP[EM!c-$%ZB`!!6PErk%MR(cJq,J!)+'i!$$BZ!!T`!$!$1!G -b!$)%N!#"FJ'`J@m!!E3p42rS282rkP*ZrqJ`,[rSX'i!#Q3FFJ!b!0+-)%%3%$3 -(FJ!b!Y+-)%%5%,!"C!*JeP0ZrqS`,[rUX%GM(()!-J$5M#""%"!d"h)!-J,5M#" -"%K#`!@-#B0J`,[rSX'lrkQ8#B()i,[rSGJ!f"#e$rr$@M#4$%K*`!"!"28$rl$S -ZrqTi!$J&,86rp0L-*N33%a5!&Ulrl5!Zrr$3J0#Z!"!J3$!328$rl#)Zrr65JG+ -Z!"!J36)3*#lrm05#e+i!%#"#-)%L,[rddS(5VJ!3)%%`J'!!rc)`,[rUX%GQ"P* -(B!$r"$J(GJ!f"#e$rrM@M#4$%K*`!"!"28$rl$`ZrqTk!$S',8Arr0U-*N83%a5 -!&Ulrl5!ZrrM3J0#Z!"!J3$!328$rl#)Zrrc5JG+Z!"!J36)3*#lrq05#e+i!%#" -#-)%L,[rmdS(5VJ!3)%%`J#!Zrr`L,[riN!#"0#i!#R)!-J)N,[rm8S+5JV#"E"i -[,J!3,``r"Mm%6VVqA%r[!!``,[rU8N!q!'!!rP`[,J!3,``r,J!+-#lrkP*!2`" -1Z[if6qm!$$eZrqS!#Q!!rMK-haci6Pj1G8j@rq4)jami*'i!#$SZ!!`QEJ!1+'i -!%Le-rr!J2!!!!56C`#e-rr4#3$`!0JDf4@3XH!!i!be%rrMBLL"%%"!L,[ridUl -rm#""%)!J,[rid)$3V[rd)%!`Je*'B-i[,[rd,blrm$m&3QG1Z[fb6qm!$%*!2!! -f"VC&C"*`!$!$d+lrm#"!5K"Q"&*'B1K`!#e!rq3f"VC&C!!!U%T$Cc)J,[rNH!! -i!be%rrcBV[r`)%38%()!%J)Q,[rm8i2@V[r`)%-@%(3!&!15JZ1S,8$rj$3'FJ! -b!Y+Zrr!J34)3F!!3!6i!,@lrj2rXF!!Y32rS-!G64dT!Cb!J,[rSiiJL,[rXG!( -#JS#",8$rk#!ZrqcLL#e!rqaJf$3'FJ!b!Y+"dUlrp#""-K"`!$!"jB$3Lb"!)+l -rk&*'8Ulrj'!!re4-haci6Pj1G5*I)&qJ*5k!DJ*#Pdl4)Pm5(c!I5J&R"+G'B!+ -M4Lk)6Y%LAa)I-"mJAdS"C`5Q4f!#SNG1d3#3!`S!1+!"!!8!N!B"!!!"HG`!!AM -F!!!%23Dfe$3%LJ#3!a`$XJ!64%P86!!0!+*"6&*8!!S"5RCPFR-!!3(18e45)!! -"!HC3Ff9d!!!"rN4-6dF!!J)+8e45)`!!!Lj%6%GB!!!#1P"*3e3!!!*'BfPMEJ! -!!P**3dp1!!!#ANP$6L-!"!*U4P*&4J!%!UC#6N4-!!%#iN&9Fc)!!!,kBA9cG!! -!!`C$6d4&!!F$%N4"9%%!!!0b8dPD43!!!hj'C@&d!!!$LJ3"rrmJ!*!)KIrr*!! -!J!Dfdj`!Krrr!*!$eJ#3"BErrb3!!5B'YY1N!)$rr`!!!DF!N!@errmJ!!)&!*! -&J[rr!!!#G`#3"!2SrrmJ!!,9!*!&L2rr!!!$!3#3"!)!rrm!!!2C!*!%!J(rr`! -!""F!N!3%5`!S"!!8V!Dfdl`%Vrrr!!!8r!#3"!%(!$3J!"8k!*!%"!(rrb!!"'- -!N!@#rrmJ!!4c!*!&KIrr*!!%J`Dfdk!!Krrr)!!%N`#3"BErrb3!"+-'YY2!!)$ -rrb!!",-!N!@"rrmJ!!6$!*!&L2rr)!!%d`#3"!)!rrmJ!!6P!*!%!J(rrb!!"28 -!N!3%Vrrr!!!9k!#3"3,rrb!!"38!N!8"rrm!!"[$!*!%!J#3!b!!"5-!N!3#!3! -()!!&-`#3"B$rr`!!"6m!N!3$k2rr)!!*GJ#3"!4,!"!%!",@"VE6V!%(!"`J!", -[!*!&J2rr!!!*NJ#3"BMrr`!!#G)!N!3$k2rr!!!+%!#3"!4,rrm%!"-,"VE6X!4 -,rrm%!"3a"VE6Y!#!rrmJ!"Ai!*!&JIrr!!!@r!#3"B,rr`!!'!#3"S2rr`!!'33 -!N!@%rrm!!"S)!*!&J2rr!!!E$!#3"B(rr`!!'aF!N!@#rrm!!"XL!*!&Jrrr!!! -E,3#3"B6rr`!!'cJ!N!3"!2rr!!!E3`#3"B$rr`!!'f-!N!G!!!!EQ`#3"B6rr`! -!'lm!N!8"!%mF!"`%"VE6Z!!#!&NF!)d3"VE6b!!$!'-F!+R2"VE6c!!%!'dF!1j -E"VE6D!!&!(FF!3Ve"VE6E!!'!)%F!6bY"VE6F!!!rrmS!9ib!*!&"rrr!!&HA!# -3"[rr+!"Br!#3"2q3"!!"ANi!N!Err`!"H-i!N!3'F(*[EA"d#-3JFh9QCQPi#dP -ZFf9bG#"%DA0V#d9iDA0dD@jR)&"A#dPZFf9bG#"%DA0V#d9iDA0dD@jR)&"A$Np -hEQ9b)(*PFfpeFQ0P#90PCfePER3J-3P6C@GYC@jd)$)*8f9RE@9ZG#!c#90PCfe -PER3J0!P6C@GYC@jd)$8*8f9RE@9ZG#!f*A8: diff --git a/mac/tclMacResource.c b/mac/tclMacResource.c deleted file mode 100644 index 4c06237..0000000 --- a/mac/tclMacResource.c +++ /dev/null @@ -1,2209 +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.8 2001/07/31 19:12:07 vincentdarley 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 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 char *writeSwitches[] = { - "-id", "-name", "-file", "-force", (char *) NULL - }; - - enum { - RESOURCE_WRITE_ID, RESOURCE_WRITE_NAME, - RESOURCE_WRITE_FILE, RESOURCE_FORCE - }; - - static 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; - 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. */ - char *resourceName, /* Name of TEXT resource to source, - NULL if number should be used. */ - int resourceNumber, /* Resource id of source. */ - 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; - 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) { - strcpy((char *) rezName + 1, resourceName); - rezName[0] = strlen(resourceName); - sourceText = GetNamedResource('TEXT', rezName); - } 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. */ - char *resourceName, /* Name of resource to find, - * NULL if number should be used. */ - int resourceNumber, /* Resource id of source. */ - 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 { - c2pstr(resourceName); - if (limitSearch) { - resource = Get1NamedResource(resourceType, - (StringPtr) resourceName); - } else { - resource = GetNamedResource(resourceType, - (StringPtr) resourceName); - } - p2cstr((StringPtr) resourceName); - } - - 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 = (char *) 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,(char *) 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 acfae99..0000000 --- a/mac/tclMacResource.r +++ /dev/null @@ -1,90 +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.4 1999/08/16 00:09:30 jingham 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 -#else -# define MINOR_VERSION TCL_MINOR_VERSION * 16 -#endif - -resource 'vers' (1) { - TCL_MAJOR_VERSION, MINOR_VERSION, - RELEASE_LEVEL, 0x00, verUS, - TCL_PATCH_LEVEL, - TCL_PATCH_LEVEL ", by Ray Johnson & Jim Ingham © Scriptics Inc." -}; - -resource 'vers' (2) { - TCL_MAJOR_VERSION, MINOR_VERSION, - RELEASE_LEVEL, 0x00, verUS, - TCL_PATCH_LEVEL, - "Simple Tcl Shell " TCL_PATCH_LEVEL " © 1996 - 1999" -}; - - -/* - * 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" - -/* - * 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" - }; -}; - diff --git a/mac/tclMacShLib.exp b/mac/tclMacShLib.exp deleted file mode 100644 index 8ada490..0000000 --- a/mac/tclMacShLib.exp +++ /dev/null @@ -1,1062 +0,0 @@ -AddrToName -AddrToStr -BuildAFPVolMountInfo -BumpDate -ChangeCreatorType -ChangeFDFlags -CheckObjectLock -CheckVolLock -ClearHasBeenInited -ClearHasCustomIcon -ClearIsInvisible -ClearIsStationery -ClearNameLocked -CloseResolver -ConfigureMemory -CopyDirectoryAccess -CopyFileMgrAttributes -CopyFork -CreateFileIDRef -DTCopyComment -DTGetIcon -DTOpen -DTSetComment -DeleteDirectory -DeleteDirectoryContents -DeleteFileIDRef -DetermineVRefNum -DirectoryCopy -EnumCache -##EnvStr -ExchangeFiles -FSMakeFSSpecCompat -FSReadNoCache -FSWriteNoCache -FSWriteVerify -FSpBumpDate -FSpCatMoveCompat -FSpChangeCreatorType -FSpChangeFDFlags -FSpCheckObjectLock -FSpClearHasBeenInited -FSpClearHasCustomIcon -FSpClearIsInvisible -FSpClearIsStationery -FSpClearNameLocked -FSpCopyDirectoryAccess -FSpCopyFile -FSpCopyFileMgrAttributes -FSpCreateCompat -FSpCreateFileIDRef -FSpCreateMinimum -FSpCreateResFileCompat -FSpDTCopyComment -FSpDTSetComment -FSpDeleteCompat -FSpDirCreateCompat -FSpDirectoryCopy -FSpExchangeFilesCompat -FSpFileCopy -FSpFilteredDirectoryCopy -FSpFindFolder -FSpGetDInfo -FSpGetDefaultDir -FSpGetDirAccess -FSpGetDirectoryID -FSpGetFInfoCompat -FSpGetFLockCompat -FSpGetFileLocation -FSpGetFileSize -FSpGetForeignPrivs -FSpGetFullPath -FSpGetIOACUser -FSpLocationFromFullPath -FSpLocationFromPath -FSpMoveRename -FSpMoveRenameCompat -FSpOpenAware -FSpOpenDFCompat -FSpOpenRFAware -FSpOpenRFCompat -FSpOpenResFileCompat -FSpPathFromLocation -FSpRenameCompat -FSpResolveFileIDRef -FSpRstFLockCompat -FSpSetDInfo -FSpSetDefaultDir -FSpSetDirAccess -FSpSetFInfoCompat -FSpSetFLockCompat -FSpSetForeignPrivs -FSpSetHasCustomIcon -FSpSetIsInvisible -FSpSetIsStationery -FSpSetNameLocked -FSpShare -FSpUnshare -FileCopy -FilteredDirectoryCopy -FindDrive -FlushFile -FreeAllMemory -GetCPanelFolder -GetCatInfoNoName -GetDInfo -GetDirItems -GetDirName -GetDirectoryID -GetDiskBlocks -GetDriverName -GetFileLocation -GetFileSize -GetFilenameFromPathname -GetForeignPrivs -GetFullPath -GetGlobalMouse -GetIOACUser -GetObjectLocation -GetParentID -GetSystemFolder -GetTempBuffer -GetTrapType -GetUGEntries -GetUGEntry -GetVolMountInfo -GetVolMountInfoSize -GetVolumeInfoNoName -HCopyFile -HCreateMinimum -HGetDirAccess -HGetLogInInfo -HGetVInfo -HGetVolParms -HInfo -HMapID -HMapName -HMoveRename -HMoveRenameCompat -HOpenAware -HOpenRFAware -hypotd -HSetDirAccess -InstallConsole -LocationFromFullPath -LockRange -MXInfo -NumToolboxTraps -OnLine -OpenOurRF -OpenResolver -PBXGetVolInfoSync -ReadCharsFromConsole -RemoveConsole -ResolveFileIDRef -RestoreDefault -RetrieveAFPVolMountInfo -SIOUXBigRect -SIOUXCantSaveAlert -SIOUXDoAboutBox -SIOUXDoContentClick -SIOUXDoEditClear -SIOUXDoEditCopy -SIOUXDoEditCut -SIOUXDoEditPaste -SIOUXDoEditSelectAll -SIOUXDoMenuChoice -SIOUXDoPageSetup -SIOUXDoPrintText -SIOUXDoSaveText -SIOUXDragRect -SIOUXDrawGrowBox -SIOUXHandleOneEvent -SIOUXIsAppWindow -SIOUXMyGrowWindow -SIOUXQuitting -SIOUXSetTitle -SIOUXSettings -SIOUXSetupMenus -SIOUXSetupTextWindow -SIOUXState -SIOUXTextWindow -SIOUXUpdateMenuItems -SIOUXUpdateScrollbar -SIOUXUpdateStatusLine -SIOUXUpdateWindow -SIOUXUseWaitNextEvent -SIOUXYesNoCancelAlert -SIOUXisinrange -SIOUXselstart -SearchFolderForDNRP -SetDInfo -SetDefault -SetForeignPrivs -SetHasCustomIcon -SetIsInvisible -SetIsStationery -SetNameLocked -Share -StrToAddr -TclAllocateFreeObjects -TclChdir -TclCleanupByteCode -TclCleanupCommand -TclCompileBreakCmd -TclCompileCatchCmd -TclCompileContinueCmd -TclCompileDollarVar -TclCompileExpr -TclCompileExprCmd -TclCompileForCmd -TclCompileForeachCmd -TclCompileIfCmd -TclCompileIncrCmd -TclCompileQuotes -TclCompileSetCmd -TclCompileString -TclCompileWhileCmd -TclCopyAndCollapse -TclCopyChannel -TclCreateAuxData -TclCreateExecEnv -TclDate_TclDates -TclDate_TclDatev -TclDateact -TclDatechar -TclDatechk -TclDatedebug -TclDatedef -TclDateerrflag -TclDateexca -TclDatelval -TclDatenerrs -TclDatepact -TclDateparse -TclDatepgo -TclDateps -TclDatepv -TclDater1 -TclDater2 -TclDates -TclDatestate -TclDatetmp -TclDatev -TclDateval -TclDeleteCompiledLocalVars -TclDeleteExecEnv -TclDeleteVars -TclDoGlob -TclEmitForwardJump -TclExecuteByteCode -TclExpandCodeArray -TclExpandJumpFixupArray -TclExprFloatError -TclFileAttrsCmd -TclFileCopyCmd -TclFileDeleteCmd -TclFileMakeDirsCmd -TclFileRenameCmd -TclFindElement -TclFindProc -TclFixupForwardJump -TclFormatInt -TclFreeCompileEnv -TclFreeJumpFixupArray -TclFreeObj -TclFreePackageInfo -TclGetCwd -TclGetDate -TclGetDefaultStdChannel -TclGetElementOfIndexedArray -TclGetEnv -TclGetExceptionRangeForPc -TclGetExtension -TclGetFrame -TclGetIndexedScalar -TclGetIntForIndex -TclGetLoadedPackages -TclGetLong -TclGetNamespaceForQualName -TclGetOpenMode -TclGetOriginalCommand -TclGetRegError -TclGetSrcInfoForPc -TclGetUserHome -TclGlobalInvoke -TclGuessPackageName -TclHasSockets -TclHideUnsafeCommands -TclInExit -TclIncrElementOfIndexedArray -TclIncrIndexedScalar -TclIncrVar2 -TclInitByteCodeObj -TclInitCompileEnv -TclInitJumpFixupArray -TclInitNamespaces -TclInterpInit -TclInvoke -TclInvokeObjectCommand -TclInvokeStringCommand -TclIsProc -TclLoadFile -TclLooksLikeInt -TclLookupVar -TclMacCreateEnv -TclMacExitHandler -TclMacFOpenHack -TclMacInitExitToShell -TclMacInstallExitToShellPatch -TclMacOSErrorToPosixError -TclMacReadlink -TclMacRemoveTimer -TclMacStartTimer -TclMacTimerExpired -TclMatchFiles -TclNeedSpace -TclObjIndexForString -TclObjInterpProc -TclObjInvoke -TclObjInvokeGlobal -TclPlatformExit -TclPlatformInit -TclPreventAliasLoop -TclPrintByteCodeObj -TclPrintInstruction -TclPrintSource -TclRegComp -TclRegError -TclRegExec -TclRenameCommand -TclResetShadowedCmdRefs -TclServiceIdle -TclSetElementOfIndexedArray -TclSetEnv -TclSetIndexedScalar -TclSetupEnv -TclSockGetPort -TclTeardownNamespace -TclTestChannelCmd -TclTestChannelEventCmd -TclUnsetEnv -TclUpdateReturnInfo -TclWordEnd -Tcl_AddErrorInfo -Tcl_AddObjErrorInfo -Tcl_AfterCmd -Tcl_Alloc -Tcl_AllowExceptions -Tcl_AppendAllObjTypes -Tcl_AppendElement -Tcl_AppendObjCmd -Tcl_AppendResult -Tcl_AppendStringsToObj -Tcl_AppendToObj -Tcl_ArrayObjCmd -Tcl_AsyncCreate -Tcl_AsyncDelete -Tcl_AsyncInvoke -Tcl_AsyncMark -Tcl_AsyncReady -Tcl_BackgroundError -Tcl_Backslash -Tcl_BeepObjCmd -Tcl_BinaryObjCmd -Tcl_BreakCmd -Tcl_CallWhenDeleted -Tcl_CancelIdleCall -Tcl_CaseObjCmd -Tcl_CatchObjCmd -Tcl_ClockObjCmd -Tcl_Close -Tcl_CommandComplete -Tcl_Concat -Tcl_ConcatObj -Tcl_ConcatObjCmd -Tcl_ContinueCmd -Tcl_ConvertCountedElement -Tcl_ConvertElement -Tcl_ConvertToType -Tcl_CreateAlias -Tcl_CreateAliasObj -Tcl_CreateChannel -Tcl_CreateChannelHandler -Tcl_CreateCloseHandler -Tcl_CreateCommand -Tcl_CreateEventSource -Tcl_CreateExitHandler -Tcl_CreateInterp -Tcl_CreateMathFunc -Tcl_CreateNamespace -Tcl_CreateObjCommand -Tcl_CreateSlave -Tcl_CreateTimerHandler -Tcl_CreateTrace -Tcl_DStringAppend -Tcl_DStringAppendElement -Tcl_DStringEndSublist -Tcl_DStringFree -Tcl_DStringGetResult -Tcl_DStringInit -Tcl_DStringResult -Tcl_DStringSetLength -Tcl_DStringStartSublist -Tcl_DbCkalloc -Tcl_DbCkfree -Tcl_DbCkrealloc -Tcl_DbDecrRefCount -Tcl_DbIsShared -Tcl_DbIncrRefCount -Tcl_DbNewBooleanObj -Tcl_DbNewDoubleObj -Tcl_DbNewListObj -Tcl_DbNewLongObj -Tcl_DbNewObj -Tcl_DbNewStringObj -Tcl_DeleteAssocData -Tcl_DeleteChannelHandler -Tcl_DeleteCloseHandler -Tcl_DeleteCommand -Tcl_DeleteCommandFromToken -Tcl_DeleteEventSource -Tcl_DeleteEvents -Tcl_DeleteExitHandler -Tcl_DeleteHashEntry -Tcl_DeleteHashTable -Tcl_DeleteInterp -Tcl_DeleteNamespace -Tcl_DeleteTimerHandler -Tcl_DeleteTrace -Tcl_DoOneEvent -Tcl_DoWhenIdle -Tcl_DontCallWhenDeleted -Tcl_DumpActiveMemory -Tcl_DuplicateObj -Tcl_EchoCmd -Tcl_Eof -Tcl_ErrnoId -Tcl_ErrnoMsg -Tcl_ErrorObjCmd -Tcl_Eval -Tcl_EvalFile -Tcl_EvalObj -Tcl_EvalObjCmd -Tcl_EventuallyFree -Tcl_ExecCmd -Tcl_Exit -Tcl_ExitObjCmd -Tcl_ExposeCommand -Tcl_ExprBoolean -Tcl_ExprBooleanObj -Tcl_ExprDouble -Tcl_ExprDoubleObj -Tcl_ExprLong -Tcl_ExprLongObj -Tcl_ExprObjCmd -Tcl_ExprString -Tcl_FconfigureCmd -Tcl_FcopyObjCmd -Tcl_FileEventCmd -Tcl_FileObjCmd -Tcl_Finalize -Tcl_FindCommand -Tcl_FindExecutable -Tcl_FindNamespace -Tcl_FindNamespaceVar -Tcl_FirstHashEntry -Tcl_Flush -Tcl_FlushObjCmd -Tcl_ForCmd -Tcl_ForeachObjCmd -Tcl_ForgetImport -Tcl_FormatCmd -Tcl_Free -Tcl_FreeResult -Tcl_GetAlias -Tcl_GetAliasObj -Tcl_GetAssocData -Tcl_GetBoolean -Tcl_GetBooleanFromObj -Tcl_GetChannel -Tcl_GetChannelBufferSize -Tcl_GetChannelHandle -Tcl_GetChannelInstanceData -Tcl_GetChannelMode -Tcl_GetChannelName -Tcl_GetChannelOption -Tcl_GetChannelType -Tcl_GetCommandFromObj -Tcl_GetCommandFullName -Tcl_GetCommandInfo -Tcl_GetCommandName -Tcl_GetCurrentNamespace -Tcl_GetDouble -Tcl_GetDoubleFromObj -Tcl_GetErrno -Tcl_GetGlobalNamespace -Tcl_GetHostName -Tcl_GetIndexFromObj -Tcl_GetInt -Tcl_GetIntFromObj -Tcl_GetInterpPath -Tcl_GetLongFromObj -Tcl_GetMaster -Tcl_GetOSTypeFromObj -Tcl_GetObjResult -Tcl_GetObjType -Tcl_GetPathType -Tcl_GetServiceMode -Tcl_GetSlave -Tcl_GetStdChannel -Tcl_GetStringFromObj -Tcl_GetStringResult -Tcl_GetVar -Tcl_GetVar2 -Tcl_GetVariableFullName -Tcl_Gets -Tcl_GetsObj -Tcl_GetsObjCmd -Tcl_GlobCmd -Tcl_GlobalEval -Tcl_GlobalEvalObj -Tcl_GlobalObjCmd -Tcl_HashStats -Tcl_HideCommand -Tcl_IfCmd -Tcl_Import -Tcl_IncrCmd -Tcl_InfoObjCmd -Tcl_Init -Tcl_InitHashTable -Tcl_InitMemory -Tcl_InputBlocked -Tcl_InputBuffered -Tcl_InterpDeleted -Tcl_InterpObjCmd -Tcl_IsSafe -Tcl_JoinObjCmd -Tcl_JoinPath -Tcl_LappendObjCmd -Tcl_LindexObjCmd -Tcl_LinkVar -Tcl_LinsertObjCmd -Tcl_ListObjAppendElement -Tcl_ListObjAppendList -Tcl_ListObjCmd -Tcl_ListObjGetElements -Tcl_ListObjIndex -Tcl_ListObjLength -Tcl_ListObjReplace -Tcl_LlengthObjCmd -Tcl_LoadCmd -Tcl_LrangeObjCmd -Tcl_LreplaceObjCmd -Tcl_LsCmd -Tcl_LsearchObjCmd -Tcl_LsortObjCmd -Tcl_MacConvertTextResource -Tcl_MacEvalResource -Tcl_MacFindResource -Tcl_MacSetEventProc -Tcl_MacSourceObjCmd -Tcl_Main -Tcl_MakeSafe -Tcl_MakeTcpClientChannel -Tcl_Merge -Tcl_NamespaceObjCmd -Tcl_NewBooleanObj -Tcl_NewDoubleObj -Tcl_NewIntObj -Tcl_NewListObj -Tcl_NewLongObj -Tcl_NewOSTypeObj -Tcl_NewObj -Tcl_NewStringObj -Tcl_NextHashEntry -Tcl_NotifyChannel -Tcl_ObjGetVar2 -Tcl_ObjSetVar2 -Tcl_OpenCmd -Tcl_OpenFileChannel -Tcl_OpenTcpClient -Tcl_OpenTcpServer -Tcl_PackageCmd -Tcl_ParseVar -Tcl_PidObjCmd -Tcl_PkgProvide -Tcl_PkgRequire -Tcl_PopCallFrame -Tcl_PosixError -Tcl_Preserve -Tcl_PrintDouble -Tcl_ProcObjCmd -Tcl_PushCallFrame -Tcl_PutEnv -Tcl_PutsObjCmd -Tcl_PwdCmd -Tcl_QueueEvent -Tcl_Read -Tcl_ReadObjCmd -Tcl_Realloc -Tcl_RecordAndEval -Tcl_RegExpCompile -Tcl_RegExpExec -Tcl_RegExpMatch -Tcl_RegExpRange -Tcl_RegexpCmd -Tcl_RegisterChannel -Tcl_RegisterObjType -Tcl_RegsubCmd -Tcl_Release -Tcl_RenameObjCmd -Tcl_ResetResult -Tcl_ResourceObjCmd -Tcl_ReturnObjCmd -Tcl_ScanCmd -Tcl_ScanCountedElement -Tcl_ScanElement -Tcl_Seek -Tcl_SeekCmd -Tcl_ServiceAll -Tcl_ServiceEvent -Tcl_SetAssocData -Tcl_SetBooleanObj -Tcl_SetChannelBufferSize -Tcl_SetChannelOption -Tcl_SetCmd -Tcl_SetCommandInfo -Tcl_SetDoubleObj -Tcl_SetErrno -Tcl_SetErrorCode -Tcl_SetIntObj -Tcl_SetListObj -Tcl_SetLongObj -Tcl_SetMaxBlockTime -Tcl_SetOSTypeObj -Tcl_SetObjErrorCode -Tcl_SetObjLength -Tcl_SetObjResult -Tcl_SetPanicProc -Tcl_SetRecursionLimit -Tcl_SetResult -Tcl_SetServiceMode -Tcl_SetStdChannel -Tcl_SetStringObj -Tcl_SetTimer -Tcl_SetVar -Tcl_SetVar2 -Tcl_SignalId -Tcl_SignalMsg -Tcl_Sleep -Tcl_SocketCmd -Tcl_SourceObjCmd -Tcl_SourceRCFile -Tcl_SplitList -Tcl_SplitPath -Tcl_StaticPackage -Tcl_StringMatch -Tcl_StringObjCmd -Tcl_SubstCmd -Tcl_SwitchObjCmd -Tcl_Tell -Tcl_TellCmd -Tcl_TimeObjCmd -Tcl_TraceCmd -Tcl_TraceVar -Tcl_TraceVar2 -Tcl_TranslateFileName -Tcl_Ungets -Tcl_UnlinkVar -Tcl_UnregisterChannel -Tcl_UnsetObjCmd -Tcl_UnsetVar -Tcl_UnsetVar2 -Tcl_UntraceVar -Tcl_UntraceVar2 -Tcl_UpVar -Tcl_UpVar2 -Tcl_UpdateCmd -Tcl_UpdateLinkedVar -Tcl_UplevelObjCmd -Tcl_UpvarObjCmd -Tcl_ValidateAllMemory -Tcl_VarEval -Tcl_VarTraceInfo -Tcl_VarTraceInfo2 -Tcl_VariableObjCmd -Tcl_VwaitCmd -Tcl_WaitForEvent -Tcl_WaitPid -Tcl_WhileCmd -Tcl_Write -Tcl_WrongNumArgs -TclpAlloc -TclpCopyDirectory -TclpCopyFile -TclpCreateDirectory -TclpDeleteFile -TclpFree -TclpGetClicks -TclpGetDate -TclpGetSeconds -TclpGetTime -TclpGetTimeZone -TclpListVolumes -TclpRealloc -TclpRemoveDirectory -TclpRenameFile -TrapExists -TruncPString -UnlockRange -UnmountAndEject -Unshare -VolumeMount -WriteCharsToConsole -XGetVInfo -_Ctype -_Stderr -_Stoul -abort -abs -acosf -appMemory -asctime -asinf -atan -atan2 -atan2_d_dd -atan2_d_pdpd -atan2_r_prpr -atan2_r_rr -atan2f -atan_d_d -atan_d_pd -atan_r_pr -atan_r_r -atanf -atexit -atof -atoi -atol -bsearch -builtinFuncTable -calloc -ccommand -ceilf -chdir -clearerr -clock -close -closeUPP -completeUPP -cos -cos_d_d -cos_d_pd -cos_r_pr -cos_r_r -cosf -coshf -creat -ctime -cuserid -difftime -div -environ -errno -exec -exit -exp -exp_d_d -exp_d_pd -exp_r_pr -exp_r_r -expf -fabsf -fclose -fcntl -fdopen -feof -ferror -fflush -fgetc -fgetpos -fgets -fileno -floorf -fmodf -fopen -fprintf -fputc -fputs -fread -free -freopen -frexpf -fscanf -fseek -fsetpos -fstat -ftell -fwrite -getStdChannelsProc -getc -getchar -getcwd -getenv -getlogin -gets -gmtime -instructionTable -isalnum -isalpha -isatty -iscntrl -isdigit -isgraph -islower -isprint -ispunct -isspace -isupper -isxdigit -labs -ldexpf -ldiv -localeconv -localtime -log -log10 -log10_d_d -log10_d_pd -log10f -log_d_d -log_d_pd -logf -longjmp -lseek -malloc -mblen -mbstowcs -mbtowc -memchr -memcmp -memcpy -memmove -memset -mkdir -mktime -open -panic -panicProc -perror -pow -power_d_dd -powf -printf -putc -putchar -puts -qsort -raise -rand -read -realloc -remove -rename -resultUPP -rewind -rmdir -scanf -setbuf -setlocale -setvbuf -signal -sin -sin_d_d -sin_d_pd -sin_r_pr -sin_r_r -sinf -sinhf -sleep -sprintf -sqrt -sqrt_d_d -sqrt_d_pd -sqrt_r_pr -sqrt_r_r -sqrtf -srand -sscanf -stat -strcasecmp -strcat -strchr -strcmp -strcoll -strcpy -strcspn -strerror -strftime -strlen -strncasecmp -strncat -strncmp -strncpy -strpbrk -strrchr -strspn -strstr -strtod -strtok -strtol -strtoul -strxfrm -system -systemMemory -tanf -tanhf -tclBooleanType -tclByteCodeType -tclCmdNameType -tclDoubleType -tclDummyLinkVarPtr -tclExecutableName -tclFreeObjList -tclIndexType -tclIntType -tclListType -tclMemDumpFileName -tclNsNameType -tclPlatform -tclStringType -tclTraceCompile -tclTraceExec -tclTypeTable -tcl_MathInProgress -tclpFileAttrProcs -tclpFileAttrStrings -tell -time -tmpfile -tmpnam -tolower -toupper -ttyname -uname -ungetc -unlink -utime -utimes -vfprintf -vprintf -vsprintf -wcstombs -wctob -wctomb -write -#DTGetAPPL -#DTGetComment -#FSpDTGetAPPL -#FSpDTGetComment -#TclMacInitializeFragment -#TclMacTerminateFragment -#_Aldata -#_Assert -#_Atcount -#_Atfuns -#_Clocale -#_Closreg -#_Costate -#_Daysto -#_Dbl -#_Defloc -#_Environ -#_Environ1 -#_Fgpos -#_Files -#_Flt -#_Fopen -#_Foprep -#_Fread -#_Freeloc -#_Frprep -#_Fspos -#_Fwprep -#_Fwrite -#_Genld -#_Gentime -#_Getdst -#_Getfld -#_Getfloat -#_Getint -#_Getloc -#_Getmem -#_Getstr -#_Gettime -#_Getzone -#_Isdst -#_Ldbl -#_Ldtob -#_Litob -#_Locale -#_Locsum -#_Loctab -#_Locterm -#_Locvar -#_MWERKS_Atcount -#_MWERKS_Atfuns -#_Makeloc -#_Makestab -#_Makewct -#_Mbcurmax -#_Mbstate -#_Mbtowc -#_Nnl -#_PJP_C_Copyright -#_Printf -#_Putfld -#_Putstr -#_Puttxt -#_Randseed -#_Readloc -#_Scanf -#_Setloc -#_Skip -#_Stdin -#_Stdout -#_Stod -#_Stof -#_Stoflt -#_Stold -#_Strerror -#_Strftime -#_Strxfrm -#_Times -#_Tolower -#_Toupper -#_Ttotm -#_WCostate -#_Wcstate -#_Wctob -#_Wctomb -#_Wctrans -#_Wctype -#__CheckForSystem7 -#__RemoveConsoleHandler__ -#__aborting -#__ctopstring -#__cvt_fp2unsigned -#__getcreator -#__gettype -#__initialize -#__myraise -#__ptmf_null -#__ptr_glue -#__system7present -#__terminate -#__ttyname -#_atexit -#_exit -#_fcreator -#_ftype diff --git a/mac/tclMacSock.c b/mac/tclMacSock.c deleted file mode 100644 index dc1116c..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.8 2001/04/04 14:49:35 dgp 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, char *host, 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_((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, 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, - 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. */ - 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. */ - 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.*/ - 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 == (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. */ - char *host, /* Name of host on which to open port. */ - 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. */ - char *host, /* Host on which to open port. */ - 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. */ - 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. - * - *---------------------------------------------------------------------- - */ - -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( - 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(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(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 c3a0c22..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 e4abb26..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 = NewThreadEntryProc(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 25bf08e..0000000 --- a/mac/tclMacTime.c +++ /dev/null @@ -1,320 +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.4 2001/07/31 19:12:07 vincentdarley Exp $ - */ - -#include "tclInt.h" -#include "tclPort.h" -#include <OSUtils.h> -#include <Timer.h> -#include <time.h> - -/* - * Static variables used by the TclpGetTime 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; - -/* - * 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; -} - -/* - *---------------------------------------------------------------------- - * - * TclpGetTime -- - * - * 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 -TclpGetTime( - 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); -} - -#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 483780c..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.3 1999/04/16 00:47:22 stanton 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, &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 51759ef..0000000 --- a/mac/tclMacUtil.c +++ /dev/null @@ -1,445 +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.4 2000/04/17 01:52:56 jingham 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) || defined(__MWERKS__) -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; -} - -/* - *---------------------------------------------------------------------- - * - * GetGlobalMouse -- - * - * This procedure obtains the current mouse position in global - * coordinates. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -GetGlobalMouse( - Point *mouse) /* Mouse position. */ -{ - EventRecord event; - - OSEventAvail(0, &event); - *mouse = event.where; -} |
